Re: Possible solutions to WebdavResource.exists() method
Antoine Levy-Lambert <[email protected]> Sun, 25 Feb 2007 16:46:24 -0500
| Newsgroups | gmane.comp.jakarta.slide.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello Michael,
could you create a bugzilla issue for this problem ?
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]