Hello Michael,
I like your solution of adding a test for NOT_FOUND.
I will work on this as soon as I can.
Best regards,
Antoine
On Feb 13, 2007, at 7:23 PM, Michael Christoff wrote:
I was wondering how we could better code this method. As it stands
it is unusable for the following reason:
If one attempts to create a WebdavResource object for a resource
that does not exist, the WebdavResource constructor will throw an
exception and hence one can never even call exists(). So the if
one can successfully call exists() it implies the resource DOES
exist making the method of limited use.
Why is this happening? It is due to the a) the way WebdavResource
objects are constructed, and b) the WebDAV specification itself.
First off, almost all of WebdavResources constructors call
setHttpURL at some point. setHttpURL in turn calls setProperties.
setProperties (by virtue of one of the methods called in its switch
statement) ends up calling setNamedProp, which in turn calls the
propFindMethod.
propFindMethod queries the WebDAV server as to what properties the
requested resource has. It does so by generating a WebDAV PROPFIND
request. Now according to the WebDAV spec:
"If there is an error retrieving a property then a proper error
result MUST be included in the response. A request to retrieve the
value of a property which does not exist is an error and MUST be
noted, if the response uses a multistatus XML element, with a
response XML element which contains a 404 (Not Found) status
value." [1]
[1] 8.1 PROPFIND http://www.webdav.org/specs/
rfc2518.html#http.methods.for.distributed.authoring
So what's happening is that WebdavResource is using PROPFIND to get
properties for a resource that does not exist which--according to
the Webdav spec--is an error. Hence a correct WebDAV server must
return a 404 (Not Found) response. The code in propFindMethod (see
snippet below) checks the response status and throws an exception
if it doesn't recieve an XML multistatus response or an HTTP 200
(OK) response.
if (status != HttpStatus.SC_MULTI_STATUS
&& status != HttpStatus.SC_OK) {
HttpException ex = new HttpException();
ex.setReasonCode(status);
throw ex;
}
Now while this behaviour may be ok when one checks properties on an
already-instantiated object, its less clear whether it makes sense
to do this in WebdavResource's constructor. One would assume
(principal of least astonishment) that a WebdavResource object
would behave more like a standard java File object, in that many of
java.io.File's properties are lazy-loaded at method-call time vs
instantiation time. But this would require the propFindMethod know
whether the caller was a constructor or not. (For a some potential
solutions, see the end of this post).
In lieu of a fix, one can get around this issue (in an albeit
kludgey way), by using the following static method to determine
whether a resource exists:
public class WebdavResourceUtils
{
public static WebdavResource getResource(HttpURL url)
throws IOException, HttpException
{
WebdavResource wdr = null;
try {
wdr = new WebdavResource(url);
} catch(HttpException httpe) {
if (httpe.getReasonCode() == HttpStatus.SC_NOT_FOUND)
return null; // failed because resource does
not exist
else
throw httpe; // failed for some other reason
}
return wdr;
}
}
But this is both redundant and requires a strange 'util' class.
---
///////// POSSIBLE SOLUTION #1 ///////////
Here is one I thought of. We simply add the following to this
conditional:
if (status != HttpStatus.SC_MULTI_STATUS
&& status != HttpStatus.SC_OK
&& status != HttpStatus.SC_NOT_FOUND // <---
) {
HttpException ex = new HttpException();
ex.setReasonCode(status);
throw ex;
}
What this essentially says is "if the property does not exist, we
simply won't add it to the Enumeration of properties, but we won't
throw an exception unless there is a server error". So if the user
loops through the Enumeration without finding the requested
property, the client must assume it doesn't exist.
** However, I haven't looked into this enough to determine whether
it will cause any strange side-effects. **
///////// POSSIBLE SOLUTION #2 ///////////
See http://issues.apache.org/bugzilla/show_bug.cgi?id=16642 for
another possible solution to this issue.
Cheers!
Michael N. Christoff
[EMAIL PROTECTED]
Michael N. Christoff
Site Administrator
Continuing Professional Education Online
Centre for Addiction and Mental Health
33 Russell Street
Toronto, Ontario M5S 2S1
Phone: (416) 535-8501 x6655
Fax: (416) 595-6617
e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]