KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > webdav > impl > CollectionImpl


1 package com.ibm.webdav.impl;
2
3 /*
4  * (C) Copyright IBM Corp. 2000 All rights reserved.
5  *
6  * The program is provided "AS IS" without any warranty express or
7  * implied, including the warranty of non-infringement and the implied
8  * warranties of merchantibility and fitness for a particular purpose.
9  * IBM will not be liable for any damages suffered by you as a result
10  * of using the Program. In no event will IBM be liable for any
11  * special, indirect or consequential damages or lost profits even if
12  * IBM has been advised of the possibility of their occurrence. IBM
13  * will not be liable for any third party claims against you.
14  *
15  * Portions Copyright (C) Simulacra Media Ltd, 2004.
16  */

17 import java.io.*;
18 import java.net.*;
19 import java.util.*;
20
21 import org.w3c.dom.*;
22
23 import com.ibm.webdav.*;
24 import com.ibm.webdav.Collection;
25
26 /** A CollectionImpl is a ResourceImpl that contains other
27  * resources including other CollectionImpls. It provides a
28  * concrete, server side implementation of Collection.
29  * <p>
30  * CollectionImpl should inherit from ResourceImpl and CollectionP.
31  * However, Java doesn't support multiple inheritance, so CollectionImpl
32  * must re-implement all of CollectionP's methods. Many of these methods
33  * are overridden anyway for server-side behavior.
34  */

35 public class CollectionImpl extends ResourceImpl implements IRCollection {
36     private Vector members = null;
37     // lazy retrieve the members of the collection for the server
38
public CollectionImpl() {
39         super();
40     }
41     /** Construct a CollectionImpl for the given URL.
42     *
43     * @param url the URL of the resource
44     * @param localName a translation of the URL (filePortion) into
45     * a name that has local meaning to a server.
46     * @param targetSelector the revision target selector for this Collection
47     * @exception com.ibm.webdav.WebDAVException
48     */

49     public CollectionImpl(
50         URL url,
51         String JavaDoc localName,
52         TargetSelector targetSelector)
53         throws WebDAVException {
54         super(url, localName);
55         String JavaDoc file = url.getFile();
56         if (!file.endsWith("/")) {
57             file = file + "/";
58             try {
59                 this.url = new URL(url, file);
60             } catch (java.net.MalformedURLException JavaDoc exc) {
61                 throw new WebDAVException(
62                     WebDAVStatus.SC_BAD_REQUEST,
63                     "Malformed URL");
64             }
65
66         }
67     }
68     /** Copy this resource to the destination URL.
69     * Partial results are possible, check the returned status for details.
70     *
71     * @param destinationURL the destination
72     * @param overwrite true implies overrite the destination if it exists
73     * @param propertiesToCopy a collection of properties that must be copied or
74     * the method will fail. propertiesToCopy may have one of the following values:
75     * <ul>
76     * <li>null - ignore properties that cannot be copied</li>
77     * <li>empty collection - all properties must be copied or the method will fail</li>
78     * <li>a collection of URIs - a list of the properties that must be copied
79     * or the method will fail</li>
80     * </ul>
81     *
82     * @return the status of the copy operation for each resource copied
83     * @exception com.ibm.webdav.WebDAVException
84     */

85     public MultiStatus copy(
86         ResourceContext context,
87         String JavaDoc destinationURL,
88         boolean overwrite,
89         Vector propertiesToCopy)
90         throws WebDAVException {
91         return copy(
92             context,
93             destinationURL,
94             overwrite,
95             propertiesToCopy,
96             Collection.deep);
97     }
98     /** Copy this resource to the destination URL.
99     * Partial results are possible, check the returned status for details.
100     *
101     * @param destinationURL the destination
102     * @param overwrite true implies overrite the destination if it exists
103     * @param propertiesToCopy a collection of properties that must be copied or
104     * the method will fail. propertiesToCopy may have one of the following values:
105     * <ul>
106     * <li>null - ignore properties that cannot be copied</li>
107     * <li>empty collection - all properties must be copied or the method will fail</li>
108     * <li>a collection of URIs - a list of the properties that must be copied
109     * or the method will fail</li>
110     * </ul>
111     * @param depth an indicator for immediate members or recursively all children.
112     * <ul>
113     * <li>shallow: copy only this resource</li>
114     * <li>deep: copy this resource and recursively all of its children</li>
115     * </ul>
116     *
117     * @return the status of the copy operation for each resource copied
118     * @exception com.ibm.webdav.WebDAVException
119     */

120     public MultiStatus copy(
121         ResourceContext context,
122         String JavaDoc destinationURL,
123         boolean overwrite,
124         Vector propertiesToCopy,
125         String JavaDoc depth)
126         throws WebDAVException {
127         this.context = context;
128
129         setStatusCode(WebDAVStatus.SC_CREATED);
130
131         // create a MultiStatus to hold the results
132
MultiStatus result = new MultiStatus();
133
134         // validate the uri
135
if (!hasValidURI()) {
136             throw new WebDAVException(
137                 WebDAVStatus.SC_BAD_REQUEST,
138                 "Invalid URI");
139         }
140
141         // check the depth parameter
142
if (!(depth.equals(Collection.shallow)
143             || depth.equals(Collection.deep))) {
144             throw new WebDAVException(
145                 WebDAVStatus.SC_BAD_REQUEST,
146                 "Invalid depth on copy");
147         }
148
149         // make sure the resource exists
150
if (!exists()) {
151             throw new WebDAVException(
152                 WebDAVStatus.SC_NOT_FOUND,
153                 "Resource does not exist");
154         }
155
156         // the destination may be a relative URL
157
Collection destination = null;
158         try {
159             URL destURL = new URL(getURL(), destinationURL);
160             destination = new Collection(destURL.toString());
161         } catch (WebDAVException exc) {
162             throw exc;
163         } catch (java.net.MalformedURLException JavaDoc exc) {
164         } catch (java.io.IOException JavaDoc exc) {
165             throw new WebDAVException(
166                 WebDAVStatus.SC_BAD_REQUEST,
167                 "Malformed URL");
168         }
169
170         // are the source and destination the same?
171
if (this.equals(destination)) {
172             throw new WebDAVException(
173                 WebDAVStatus.SC_FORBIDDEN,
174                 "Can't copy source on top of itself");
175         }
176
177         // is the destination locked?
178
destination.getRequestContext().precondition(
179             getRequestContext().precondition());
180         destination.getRequestContext().authorization(
181             getRequestContext().authorization());
182         if (destination.exists()
183             && destination.isLocked()
184             && !destination.isLockedByMe()) {
185             throw new WebDAVException(
186                 WebDAVStatus.SC_LOCKED,
187                 "Destination resource is locked");
188         }
189
190         // check to see if the destination exists and its OK to overwrite it
191
if (destination.exists() && !overwrite) {
192             throw new WebDAVException(
193                 WebDAVStatus.SC_PRECONDITION_FAILED,
194                 "Destination exists and overwrite not specified");
195         }
196
197         // Ready to copy. For collections, copy the members
198
// First, create the destination collection
199
if (destination.exists()) {
200             destination.delete();
201             setStatusCode(WebDAVStatus.SC_NO_CONTENT);
202         }
203         destination.createCollection();
204
205         // now copy the members if necessary
206
if (depth.equals(Collection.deep)) {
207             Enumeration members = namespaceManager.getMembers().elements();
208             while (members.hasMoreElements()) {
209                 ResourceImpl member = (ResourceImpl) members.nextElement();
210                 // calculate the destination URL
211
String JavaDoc thisURL = getURL().toString();
212                 String JavaDoc memberURL = member.getURL().toString();
213                 String JavaDoc memberPart = memberURL.substring(thisURL.length());
214                 String JavaDoc dest = destination.getURL().toString() + memberPart;
215                 try {
216                     MultiStatus memberResult = null;
217                     if (member.isCollection()) {
218                         memberResult =
219                             ((CollectionImpl) member).copy(
220                                 context,
221                                 dest,
222                                 overwrite,
223                                 propertiesToCopy,
224                                 depth);
225                     } else {
226                         memberResult =
227                             member.copy(
228                                 context,
229                                 dest,
230                                 overwrite,
231                                 propertiesToCopy);
232                     }
233                     if (!memberResult.isOK()) {
234                         result.mergeWith(memberResult);
235                     }
236                 } catch (WebDAVException exc) {
237                     MethodResponse response =
238                         new MethodResponse(
239                             member.getURL().toString(),
240                             exc.getStatusCode());
241                     result.addResponse(response);
242                 } catch (Exception JavaDoc e) {
243                     e.printStackTrace();
244                     throw new WebDAVException(
245                         WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
246                         "unable to delete resource");
247                 }
248             }
249         }
250
251         // copy the properties
252
WebDAVStatus savedStatusCode = context.getStatusCode();
253         // might be overritten by copying proerties or unlocking
254
MultiStatus ms2 = copyProperties(destination, propertiesToCopy);
255         if (!ms2.isOK()) {
256             // todo: add code here to back out this partial copy. That might require
257
// restoring the resource that used to be at the destination. For now, we'll throw
258
// an exception.
259
throw new WebDAVException(
260                 WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
261                 "problem copying properties");
262         }
263
264         // remove all locks on the destination. Copy doesn't copy locks
265
// become super-user for this operation
266
String JavaDoc authorization = getRequestContext().authorization();
267         destination.getRequestContext().setBasicAuthorization("root", "");
268         Enumeration locks = destination.getLocks().elements();
269         while (locks.hasMoreElements()) {
270             ActiveLock lock = (ActiveLock) locks.nextElement();
271             // ignore exceptions, the unlock should work
272
try {
273                 destination.unlock(lock.getLockToken());
274             } catch (Exception JavaDoc exc) {
275             }
276         }
277         destination.getRequestContext().authorization(authorization);
278         context.setStatusCode(savedStatusCode);
279
280         // everything must have gone OK, there
281
// is no response for a successful delete
282
getResponseContext().contentType("text/xml");
283         return result;
284     }
285     /** Actually create the collection in the repository. The resource indicated
286     * by the URL must not already exist. All ancestors of this URL must already
287     * exist.
288     *
289     * @param contents an XML Document describing the members of this collection, bodies
290     * of members, and properties on the collections or members. Not completely defined in
291     * version 10 of the WebDAV specification
292     *
293     * @return Multistatus describing the result
294     * of the operation
295     * @exception com.ibm.webdav.WebDAVException
296     */

297     public MultiStatus createCollection(
298         ResourceContext context,
299         Document contents)
300         throws WebDAVException {
301         this.context = context;
302
303         setStatusCode(WebDAVStatus.SC_CREATED);
304         String JavaDoc fileName = ResourceFactory.getRealPath(getURL());
305
306         // validate the uri
307
if (!hasValidURI() || fileName.indexOf(File.separator) < 0) {
308             throw new WebDAVException(
309                 WebDAVStatus.SC_BAD_REQUEST,
310                 "Invalid URI");
311         }
312
313         // see if the resource already exists
314
if (exists()) {
315             if (isCollection()) {
316                 throw new WebDAVException(
317                     WebDAVStatus.SC_METHOD_NOT_ALLOWED,
318                     "Collection already exists");
319             } else {
320                 throw new WebDAVException(
321                     WebDAVStatus.SC_METHOD_NOT_ALLOWED,
322                     "Resource already exists");
323             }
324         }
325
326         // make sure the parent collection exists
327
CollectionImpl parent = (CollectionImpl) getParentCollection();
328         if (parent != null && !parent.exists()) {
329             throw new WebDAVException(
330                 WebDAVStatus.SC_CONFLICT,
331                 "Parent collection does not exist");
332         }
333
334         // make sure the parent collection is not locked, or is locked by this user
335
if (parent != null) {
336             parent.getRequestContext().precondition(
337                 getRequestContext().precondition());
338             parent.getRequestContext().authorization(
339                 getRequestContext().authorization());
340             if (parent.isLocked() && !parent.isLockedByMe()) {
341                 throw new WebDAVException(
342                     WebDAVStatus.SC_LOCKED,
343                     "Parent collection is locked by another user");
344             }
345         }
346
347         // check for an unsupported contents argument. The request entity format
348
// for MKCOL is not yet defined, so all contents are unsupported
349
if (contents != null) {
350             throw new WebDAVException(
351                 WebDAVStatus.SC_UNSUPPORTED_MEDIA_TYPE,
352                 "Creating collections from contents not supported yet");
353         }
354
355         // create the collection
356
namespaceManager.createCollection(
357             ResourceFactory.getRealPath(getURL()));
358
359         // get the default properties, and write them out too.
360
Document properties = loadProperties();
361         saveProperties(properties);
362
363         // inherit any deep locks on the parent collection
364
inheritParentDeepLocks();
365         MultiStatus status = new MultiStatus();
366         MethodResponse response =
367             new MethodResponse(getURL().toString(), WebDAVStatus.SC_CREATED);
368         status.addResponse(response);
369         getResponseContext().contentType("text/xml");
370         return status;
371     }
372     /** Delete this resouce collection and all its members from the server.
373      * The actual effect of the delete operation is determined by the underlying
374      * repository manager. The visible effect to WebDAV is that the resource
375      * is no longer available.
376      *
377      * @return a MultiStatus containing the status of the delete method on each
378      * effected resource.
379      * @exception com.ibm.webdav.WebDAVException
380      */

381     public MultiStatus delete(ResourceContext context) throws WebDAVException {
382         this.context = context;
383
384         MultiStatus result = new MultiStatus();
385
386         // delete all the members first
387
Enumeration members = namespaceManager.getMembers().elements();
388         while (members.hasMoreElements()) {
389             ResourceImpl member = (ResourceImpl) members.nextElement();
390             try {
391                 MultiStatus memberResult = null;
392                 memberResult = member.delete(context);
393                 if (!memberResult.isOK()) {
394                     result.mergeWith(memberResult);
395                 }
396             } catch (WebDAVException exc) {
397                 MethodResponse response =
398                     new MethodResponse(member.getURL().toString(), exc);
399                 result.addResponse(response);
400             } catch (Exception JavaDoc e) {
401                 e.printStackTrace();
402                 throw new WebDAVException(
403                     WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
404                     "unable to delete resource");
405             }
406         }
407
408         // now delete this collection
409
if (result.isOK()) {
410             try {
411                 MultiStatus thisResult = super.delete(context);
412                 if (!thisResult.isOK()) {
413                     result.mergeWith(thisResult);
414                 }
415             } catch (WebDAVException exc) {
416                 //MethodResponse response = new MethodResponse(getURL().toString(), exc.getStatusCode());
417
MethodResponse response =
418                     new MethodResponse(getURL().toString(), exc);
419                 result.addResponse(response);
420             } catch (Exception JavaDoc e) {
421                 e.printStackTrace();
422                 throw new WebDAVException(
423                     WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
424                     "unable to delete resource");
425             }
426         }
427         getResponseContext().contentType("text/xml");
428         return result;
429     }
430     /** Unlock the lock identified by the lockToken on this resource. This method
431      * is used internally to unlock resources copied or moved as well as unlocked.
432      * For a resource collection, unlock all the members that are locked with the
433      * same lock token.
434      *
435      * @param lockToken the lock token obtained from the ActiveLock of a previous <code>lock() </code>
436      * or <code>getLocks()</code>.
437      *
438      * @return a MultiStatus containing any responses on resources that could not
439      * be unlocked.
440      * @exception com.ibm.webdav.WebDAVException
441      */

442     protected MultiStatus doUnlock(String JavaDoc lockToken) throws WebDAVException {
443         // find all the locks identified by this lockToken, and unlock them.
444

445         MultiStatus result = new MultiStatus();
446
447         // get the ActiveLock to unlock
448
ActiveLock lockToUnlock = null;
449         Enumeration activeLocks = getLocks().elements();
450         while (activeLocks.hasMoreElements()) {
451             ActiveLock activeLock = (ActiveLock) activeLocks.nextElement();
452             if (activeLock.getLockToken().equals(lockToken)) {
453                 lockToUnlock = activeLock;
454                 break;
455             }
456         }
457
458         // unlock the lock on this collection and then check all its
459
// members for a lock using the same lockToken.
460
if (lockToUnlock != null
461             && lockToUnlock.getDepth().equals(Collection.deep)) {
462             Enumeration members = namespaceManager.getMembers().elements();
463             while (members.hasMoreElements()) {
464                 ResourceImpl member = (ResourceImpl) members.nextElement();
465                 member.getRequestContext().precondition(
466                     getRequestContext().precondition());
467                 member.getRequestContext().authorization(
468                     getRequestContext().authorization());
469                 try {
470                     MultiStatus memberResult = member.doUnlock(lockToken);
471                     result.mergeWith(memberResult);
472                 } catch (WebDAVException exc) {
473                     MethodResponse response =
474                         new MethodResponse(
475                             member.getURL().toString(),
476                             exc.getStatusCode());
477                     result.addResponse(response);
478                 } catch (Exception JavaDoc e) {
479                     e.printStackTrace();
480                     throw new WebDAVException(
481                         WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
482                         "unable to delete resource");
483                 }
484             }
485         }
486
487         // Unlock this lock
488
MultiStatus r = super.doUnlock(lockToken);
489         if (!r.isOK()) {
490             result.mergeWith(r);
491         }
492         getResponseContext().contentType("text/xml");
493         return result;
494     }
495     /** Get the URL of a child of this resource treating the resource
496     * as a collection
497     *
498     * @param childName the local repository name for the child resource
499     * @return the child URL
500     * @exception com.ibm.webdav.WebDAVException
501     */

502     public URL getChildURL(String JavaDoc childName) throws WebDAVException {
503         String JavaDoc uri = getURL().getFile();
504         if (!uri.endsWith("/")) {
505             uri = uri + "/";
506         }
507         URL child = null;
508         try {
509             child = new URL(getURL(), uri + childName);
510         } catch (java.net.MalformedURLException JavaDoc exc) {
511             throw new WebDAVException(
512                 WebDAVStatus.SC_BAD_REQUEST,
513                 "Malformed URL");
514         }
515         return child;
516     }
517     /** The WebDAV spec does not explicitly define the contents of a collection.
518     * Rather it obtains the members of a collection by doing a PROPFIND with
519     * depth="infinity" and gets the href elements from the response elements
520     * to determine the members of a collection. This implementation returns
521     * and XML document containing the URLs of the members of the collection.
522     * @return an InputStream on an XML document containing the members of this collection
523     * @exception com.ibm.webdav.WebDAVException
524     */

525     public InputStream getContentsInputStream() throws WebDAVException {
526         // validate the uri
527
if (!hasValidURI()) {
528             throw new WebDAVException(
529                 WebDAVStatus.SC_BAD_REQUEST,
530                 "Invalid URI");
531         }
532         InputStream is = namespaceManager.getContentsInputStream();
533
534         // set the content type
535
getResponseContext().contentType("text/xml");
536         return is;
537     }
538     /** WebDAV does not allow PUT to collections. Use Collection.createCollection()
539     * (MKCOL) instead.
540     * @return nothing
541     * @exception com.ibm.webdav.WebDAVException throws METHOD_NOT_ALLOWED for all collections
542     */

543     public OutputStream getContentsOutputStream() throws WebDAVException {
544         throw new WebDAVException(
545             WebDAVStatus.SC_METHOD_NOT_ALLOWED,
546             "Cannot use PUT on collections, use MKCOL instead.");
547     }
548     /** Get the members of this Collection.
549     * @return an Vector of CollectionMembers
550     * @exception com.ibm.webdav.WebDAVException
551     * @see CollectionMember
552     */

553     public Vector getMembers() throws WebDAVException {
554         return namespaceManager.getMembers();
555     }
556     /** Get the named properties for this resource and (potentially) its children.
557     *
558     * @param names an array of PropertyNames to retrieve.
559     * @param depth an indicator for immediate members or recursively all children.
560     * <ul>
561     * <li>immediateMembers: propeprties of this resource and its immediate children</li>
562     * <li>allMembers: properties of this resource and recursively all its children</li>
563     * </ul>
564     *
565     * @return a MultiStatus of PropertyResponses
566     * @exception com.ibm.webdav.WebDAVException
567     */

568     public MultiStatus getProperties(
569         ResourceContext context,
570         PropertyName names[],
571         String JavaDoc depth)
572         throws WebDAVException {
573         this.context = context;
574
575         // check the depth parameter
576
if (!(depth.equals(Collection.thisResource)
577             || depth.equals(Collection.immediateMembers)
578             || depth.equals(Collection.allMembers))) {
579             throw new WebDAVException(
580                 WebDAVStatus.SC_BAD_REQUEST,
581                 "Invalid depth on copy");
582         }
583
584         MultiStatus result = super.getProperties(context, names);
585         String JavaDoc memberDepth = depth;
586         if (depth.equals(Collection.immediateMembers)) {
587             memberDepth = Collection.thisResource;
588         }
589
590         // now get the properties of the members if necessary
591
if (!depth.equals(Collection.thisResource)) {
592             Enumeration members = namespaceManager.getMembers().elements();
593             while (members.hasMoreElements()) {
594                 ResourceImpl member = (ResourceImpl) members.nextElement();
595                 try {
596                     MultiStatus memberResult = null;
597                     if (member.isCollection()) {
598                         memberResult =
599                             ((CollectionImpl) member).getProperties(
600                                 context,
601                                 names,
602                                 memberDepth);
603                     } else {
604                         memberResult = member.getProperties(context, names);
605                     }
606                     result.mergeWith(memberResult);
607                 } catch (WebDAVException exc) {
608                     exc.printStackTrace();
609                     MethodResponse response =
610                         new MethodResponse(
611                             member.getURL().toString(),
612                             exc.getStatusCode());
613                     result.addResponse(response);
614                 } catch (Exception JavaDoc e) {
615                     e.printStackTrace();
616                     throw new WebDAVException(
617                         WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
618                         "Error getting properties");
619                 }
620             }
621         }
622         getResponseContext().contentType("text/xml");
623         return result;
624     }
625
626     /** Get all the properties for this resource and (potentially) its children.
627     *
628     * @param depth an indicator for immediate members or recursively all children.
629     * <ul>
630     * <li>thisResource: propeprties of this resource</li>
631     * <li>immediateMembers: propeprties of this resource and its immediate children</li>
632     * <li>allMembers: properties of this resource and recursively all its children</li>
633     * </ul>
634     *
635     * @return a MultiStatus of PropertyResponses
636     * @exception com.ibm.webdav.WebDAVException
637     */

638     public MultiStatus getProperties(ResourceContext context, String JavaDoc depth)
639         throws WebDAVException {
640         this.context = context;
641
642         // check the depth parameter
643
if (!(depth.equals(Collection.thisResource)
644             || depth.equals(Collection.immediateMembers)
645             || depth.equals(Collection.allMembers))) {
646             throw new WebDAVException(
647                 WebDAVStatus.SC_BAD_REQUEST,
648                 "Invalid depth on copy");
649         }
650
651         MultiStatus result = super.getProperties(context);
652         String JavaDoc memberDepth = depth;
653         if (depth.equals(Collection.immediateMembers)) {
654             memberDepth = Collection.thisResource;
655         }
656
657         // now get the properties of the members if necessary
658
if (!depth.equals(Collection.thisResource)) {
659             Enumeration members = namespaceManager.getMembers().elements();
660             while (members.hasMoreElements()) {
661                 ResourceImpl member = (ResourceImpl) members.nextElement();
662                 try {
663                     MultiStatus memberResult = null;
664                     if (member.isCollection()) {
665                         memberResult =
666                             ((CollectionImpl) member).getProperties(
667                                 context,
668                                 memberDepth);
669                     } else {
670                         memberResult = member.getProperties(context);
671                     }
672                     result.mergeWith(memberResult);
673                 } catch (WebDAVException exc) {
674                     exc.printStackTrace();
675                     MethodResponse response =
676                         new MethodResponse(
677                             member.getURL().toString(),
678                             exc.getStatusCode());
679                     result.addResponse(response);
680                 } catch (Exception JavaDoc e) {
681                     e.printStackTrace();
682                     throw new WebDAVException(
683                         WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
684                         "unable to get properties");
685                 }
686             }
687         }
688         getResponseContext().contentType("text/xml");
689         return result;
690     }
691
692     /** Get the names of all properties for this resource and (potentially) its children.
693     *
694     * @param depth an indicator for immediate members or recursively all children.
695     * <ul>
696     * <li>thisResource: propeprties of this resource</li>
697     * <li>immediateMembers: propeprties of this resource and its immediate children</li>
698     * <li>allMembers: properties of this resource and recursively all its children</li>
699     * </ul>
700     *
701     * @return a MultiStatus of PropertyResponses
702     * (PropertyValue.value is always null, PropertyValue.status contains the status)
703     * @exception com.ibm.webdav.WebDAVException
704     */

705     public MultiStatus getPropertyNames(ResourceContext context, String JavaDoc depth)
706         throws WebDAVException {
707         this.context = context;
708
709         // check the depth parameter
710
if (!(depth.equals(Collection.thisResource)
711             || depth.equals(Collection.immediateMembers)
712             || depth.equals(Collection.allMembers))) {
713             throw new WebDAVException(
714                 WebDAVStatus.SC_BAD_REQUEST,
715                 "Invalid depth on copy");
716         }
717         MultiStatus result = super.getPropertyNames(context);
718         String JavaDoc memberDepth = depth;
719         if (depth.equals(Collection.immediateMembers)) {
720             memberDepth = Collection.thisResource;
721         }
722
723         // now get the properties of the members if necessary
724
if (!depth.equals(Collection.thisResource)) {
725             Enumeration members = namespaceManager.getMembers().elements();
726             while (members.hasMoreElements()) {
727                 ResourceImpl member = (ResourceImpl) members.nextElement();
728                 try {
729                     MultiStatus memberResult = null;
730                     if (member.isCollection()) {
731                         memberResult =
732                             ((CollectionImpl) member).getPropertyNames(
733                                 context,
734                                 memberDepth);
735                     } else {
736                         memberResult = member.getPropertyNames(context);
737                     }
738                     result.mergeWith(memberResult);
739                 } catch (WebDAVException exc) {
740                     exc.printStackTrace();
741                     MethodResponse response =
742                         new MethodResponse(
743                             member.getURL().toString(),
744                             exc.getStatusCode());
745                     result.addResponse(response);
746                 } catch (Exception JavaDoc e) {
747                     e.printStackTrace();
748                     throw new WebDAVException(
749                         WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
750                         "unable to delete resource");
751                 }
752             }
753         }
754         getResponseContext().contentType("text/xml");
755         return result;
756     }
757     /** Returns true if this Resource is a collection. Returns false otherwise.
758      *
759      * @return true if this Resource is a collection.
760      * @exception com.ibm.webdav.WebDAVException
761      */

762     public boolean isCollection() throws WebDAVException {
763         return true;
764     }
765     /** Lock this resource with the information contained in the given active lock.
766     * @param activeLock information about the lock
767     * @return a MultiStatus containing a lockdiscovery property indicating
768     * @exception com.ibm.webdav.WebDAVException
769     */

770     protected MultiStatus lock(ActiveLock activeLock) throws WebDAVException {
771         // get the locks on this resource
772
Enumeration locks = getLocks().elements();
773         while (locks.hasMoreElements()) {
774             ActiveLock lock = (ActiveLock) locks.nextElement();
775             if (lock.getScope().equals(ActiveLock.exclusive)) {
776                 throw new WebDAVException(
777                     WebDAVStatus.SC_LOCKED,
778                     "Resource has an exclusive lock");
779             }
780             if (lock.getScope().equals(ActiveLock.shared)
781                 && activeLock.getScope().equals(ActiveLock.exclusive)) {
782                 throw new WebDAVException(
783                     WebDAVStatus.SC_LOCKED,
784                     "Resource already has a shared lock");
785             }
786             if (lock.getScope().equals(ActiveLock.shared)
787                 && lock.getPrincipal().equals(activeLock.getPrincipal())) {
788                 throw new WebDAVException(
789                     WebDAVStatus.SC_LOCKED,
790                     "The principal already has a lock on this resource");
791             }
792         }
793
794         // first lock this collection
795
MultiStatus result = super.lock(activeLock);
796
797         // now lock all the members if necessary
798
if (activeLock.getDepth().equals(Collection.deep)) {
799             Enumeration members = namespaceManager.getMembers().elements();
800             while (members.hasMoreElements()) {
801                 ResourceImpl member = (ResourceImpl) members.nextElement();
802                 member.getRequestContext().precondition(
803                     getRequestContext().precondition());
804                 member.getRequestContext().authorization(
805                     getRequestContext().authorization());
806                 try {
807                     MultiStatus memberResult = member.lock(activeLock);
808                     result.mergeWith(memberResult);
809                 } catch (WebDAVException exc) {
810                     MethodResponse response =
811                         new MethodResponse(
812                             member.getURL().toString(),
813                             exc.getStatusCode());
814                     result.addResponse(response);
815                 } catch (Exception JavaDoc e) {
816                     e.printStackTrace();
817                     throw new WebDAVException(
818                         WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
819                         "unable to delete resource");
820                 }
821             }
822         }
823
824         return result;
825     }
826     /** Lock this resource collection and potentially all its members
827     * based on the given parameters. This allows control of the lock
828     * scope (exclusive or shared) the lock type (write), owner information, etc.
829     *
830     * @param scope the scope of the lock, exclusive or shared
831     * @param type the type of the lock, currently only write
832     * @param timeout the number of seconds before the lock times out or
833     * 0 for infinite timeout.
834     * @param owner an XML element containing useful information that can be
835     * used to identify the owner of the lock. An href to a home page, an
836     * email address, phone number, etc. Can be null if no owner information
837     * is provided.
838     *
839     * @return a MultiStatus containing a lockdiscovery property indicating
840     * the results of the lock operation.
841     * @exception com.ibm.webdav.WebDAVException
842     */

843     public MultiStatus lock(
844         ResourceContext context,
845         String JavaDoc scope,
846         String JavaDoc type,
847         int timeout,
848         Element owner)
849         throws WebDAVException {
850         return lock(context, scope, type, timeout, owner, Collection.deep);
851     }
852     /** Lock this resource collection and potentially all its members
853     * based on the given parameters. This allows control of the lock
854     * scope (exclusive or shared) the lock type (write), owner information, etc.
855     *
856     * @param scope the scope of the lock, exclusive or shared
857     * @param type the type of the lock, currently only write
858     * @param timeout the number of seconds before the lock times out or
859     * 0 for infinite timeout.
860     * @param owner an XML element containing useful information that can be
861     * used to identify the owner of the lock. An href to a home page, an
862     * email address, phone number, etc. Can be null if no owner information
863     * is provided.
864     * @param depth
865     * <ul>
866     * <li>shallow lock only this resource</li>
867     * <li>deep lock this resource and all its children</li>
868     * </ul>
869     *
870     * @return a MultiStatus containing a lockdiscovery property indicating
871     * the results of the lock operation.
872     * @exception com.ibm.webdav.WebDAVException
873     */

874     public MultiStatus lock(
875         ResourceContext context,
876         String JavaDoc scope,
877         String JavaDoc type,
878         int timeout,
879         Element owner,
880         String JavaDoc depth)
881         throws WebDAVException {
882         this.context = context;
883
884         // check the depth parameter
885
if (!(depth.equals(Collection.shallow)
886             || depth.equals(Collection.deep))) {
887             throw new WebDAVException(
888                 WebDAVStatus.SC_BAD_REQUEST,
889                 "Invalid depth on copy");
890         }
891
892         // lock the collection, and use the same lock token for all its members
893
ActiveLock activeLock = getActiveLockFor(scope, type, timeout, owner);
894         activeLock.setDepth(depth);
895         MultiStatus result = lock(activeLock);
896
897         // remove all granted locks if all the requests couldn't be satisfied
898
if (!result.isOK()) {
899             try {
900                 unlock(context, activeLock.getLockToken());
901             } catch (Exception JavaDoc exc) {
902             }
903             // remove all the lockdiscovery elements from the result for the locks
904
// that were unlocked
905
result.removeOKResponses();
906         }
907
908         // return the granted lock token in the lockToken response context
909
getResponseContext().lockToken(activeLock.getLockToken());
910         getResponseContext().contentType("text/xml");
911         return result;
912     }
913     /** Refresh the lock on this resource collection and all its members locked
914      * by the same lock token by resetting the lock timeout.
915      * The context must contain the proper authorization for the requesting
916      * principal.
917      *
918      * @param lockToken the lock token identifying the lock.
919      * @param timeout the new timeout in seconds. -1 means infinite timeout.
920      * @return updated information about the lock status of this resource
921      * @exception com.ibm.webdav.WebDAVException
922      */

923     public MultiStatus refreshLock(
924         ResourceContext context,
925         String JavaDoc lockToken,
926         int timeout)
927         throws WebDAVException {
928         this.context = context;
929
930         // find all the locks identified by this lockToken, and refresh them.
931

932         // first, is this the root parent collection locked by this lockToken
933
if (parentIsLockedWith(lockToken)) {
934             throw new WebDAVException(
935                 WebDAVStatus.SC_METHOD_NOT_ALLOWED,
936                 "Must refresh depth lock from root collection having the lock.");
937         }
938
939         // Refresh this lock
940
MultiStatus result = super.refreshLock(context, lockToken, timeout);
941
942         // get the new ActiveLock
943
ActiveLock lockToRefresh = null;
944         Enumeration activeLocks = getLocks().elements();
945         while (activeLocks.hasMoreElements()) {
946             ActiveLock activeLock = (ActiveLock) activeLocks.nextElement();
947             if (activeLock.getLockToken().equals(lockToken)) {
948                 lockToRefresh = activeLock;
949                 break;
950             }
951         }
952
953         // refresh the lock on this collection and then check all its
954
// members for a lock using the same lockToken.
955
if (lockToRefresh.getDepth().equals(Collection.deep)) {
956             Enumeration members = namespaceManager.getMembers().elements();
957             while (members.hasMoreElements()) {
958                 Resource member = (Resource) members.nextElement();
959                 member.getRequestContext().precondition(
960                     getRequestContext().precondition());
961                 member.getRequestContext().authorization(
962                     getRequestContext().authorization());
963                 try {
964                     MultiStatus memberResult =
965                         member.refreshLock(lockToken, timeout);
966                     result.mergeWith(memberResult);
967                 } catch (WebDAVException exc) {
968                     MethodResponse response =
969                         new MethodResponse(
970                             member.getURL().toString(),
971                             exc.getStatusCode());
972                     result.addResponse(response);
973                 } catch (Exception JavaDoc e) {
974                     e.printStackTrace();
975                     throw new WebDAVException(
976                         WebDAVStatus.SC_INTERNAL_SERVER_ERROR,
977                         "unable to delete resource");
978                 }
979             }
980         }
981         getResponseContext().contentType("text/xml");
982         return result;
983     }
984
985     /**
986      * Sets the ordering of the members of this collection
987      *
988      * @param context
989      * @param orderPatch
990      * @throws WebDAVException
991      */

992     public MultiStatus setOrdering(
993         ResourceContext context,
994         Document orderPatch)
995         throws WebDAVException {
996         // make sure the resource exists.
997
if (exists() == false) {
998             throw new WebDAVException(
999                 WebDAVStatus.SC_NOT_FOUND,
1000                "Resource does not exist");
1001        }
1002
1003        if (isCollection() == false) {
1004            throw new WebDAVException(
1005                WebDAVStatus.SC_BAD_REQUEST,
1006                "Resource is not collection");
1007        }
1008
1009        // check to see if the resource is locked by another user
1010
if (isLocked() && isLockedByMe() == false) {
1011            throw new WebDAVException(
1012                WebDAVStatus.SC_LOCKED,
1013                "Resource is locked by another user");
1014        }
1015
1016        MultiStatus result = new MultiStatus();
1017
1018        try {
1019            namespaceManager.setOrdering(orderPatch);
1020        } catch (WebDAVException e) {
1021            //TODO sort out proper error reporting
1022
result.addResponse(new MethodResponse(getURL().getPath(),e));
1023        }
1024
1025        return result;
1026    }
1027}
1028
Popular Tags