KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > webdav > PropFindMethod


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.webdav;
18
19 import java.io.Serializable JavaDoc;
20 import java.util.ArrayList JavaDoc;
21 import java.util.Date JavaDoc;
22 import java.util.HashMap JavaDoc;
23 import java.util.List JavaDoc;
24 import java.util.Map JavaDoc;
25
26 import javax.servlet.http.HttpServletResponse JavaDoc;
27
28 import org.alfresco.error.AlfrescoRuntimeException;
29 import org.alfresco.model.ContentModel;
30 import org.alfresco.service.cmr.lock.LockService;
31 import org.alfresco.service.cmr.lock.LockStatus;
32 import org.alfresco.service.cmr.model.FileFolderService;
33 import org.alfresco.service.cmr.model.FileInfo;
34 import org.alfresco.service.cmr.model.FileNotFoundException;
35 import org.alfresco.service.cmr.repository.ContentData;
36 import org.alfresco.service.cmr.repository.NodeRef;
37 import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
38 import org.alfresco.service.cmr.repository.datatype.TypeConverter;
39 import org.alfresco.service.namespace.QName;
40 import org.dom4j.DocumentHelper;
41 import org.dom4j.io.XMLWriter;
42 import org.w3c.dom.Document JavaDoc;
43 import org.w3c.dom.Element JavaDoc;
44 import org.w3c.dom.Node JavaDoc;
45 import org.w3c.dom.NodeList JavaDoc;
46 import org.xml.sax.Attributes JavaDoc;
47 import org.xml.sax.helpers.AttributesImpl JavaDoc;
48
49 /**
50  * Implements the WebDAV PROPFIND method
51  *
52  * @author Gavin Cornwell
53  */

54 public class PropFindMethod extends WebDAVMethod
55 {
56     // Request types
57
private static final int GET_ALL_PROPS = 0;
58     private static final int GET_NAMED_PROPS = 1;
59     private static final int FIND_PROPS = 2;
60
61     // Find depth and request type
62
private int m_depth = WebDAV.DEPTH_INFINITY;
63     private int m_mode = GET_ALL_PROPS;
64
65     // Requested properties
66
private ArrayList JavaDoc<WebDAVProperty> m_properties = null;
67
68     // Available namespaces list
69
private HashMap JavaDoc<String JavaDoc, String JavaDoc> m_namespaces = null;
70
71     /**
72      * Default constructor
73      */

74     public PropFindMethod()
75     {
76         m_namespaces = new HashMap JavaDoc<String JavaDoc, String JavaDoc>();
77     }
78
79     /**
80      * Return the property find depth
81      *
82      * @return int
83      */

84     public final int getDepth()
85     {
86         return m_depth;
87     }
88
89     /**
90      * Return the find mode
91      *
92      * @return int
93      */

94     public final int getMode()
95     {
96         return m_mode;
97     }
98
99     /**
100      * Parse the request headers
101      *
102      * @exception WebDAVServerException
103      */

104     protected void parseRequestHeaders() throws WebDAVServerException
105     {
106         // Store the Depth header as this is used by several WebDAV methods
107

108         String JavaDoc strDepth = m_request.getHeader(WebDAV.HEADER_DEPTH);
109         if (strDepth != null && strDepth.length() > 0)
110         {
111             if (strDepth.equals(WebDAV.ZERO))
112             {
113                 m_depth = WebDAV.DEPTH_0;
114             }
115             else if (strDepth.equals(WebDAV.ONE))
116             {
117                 m_depth = WebDAV.DEPTH_1;
118             }
119             else
120             {
121                 m_depth = WebDAV.DEPTH_INFINITY;
122             }
123         }
124     }
125
126     /**
127      * Parse the request body
128      *
129      * @exception WebDAVServerException
130      */

131     protected void parseRequestBody() throws WebDAVServerException
132     {
133         Document JavaDoc body = getRequestBodyAsDocument();
134         if (body != null)
135         {
136             Element JavaDoc rootElement = body.getDocumentElement();
137             NodeList JavaDoc childList = rootElement.getChildNodes();
138             Node JavaDoc node = null;
139
140             for (int i = 0; i < childList.getLength(); i++)
141             {
142                 Node JavaDoc currentNode = childList.item(i);
143                 switch (currentNode.getNodeType())
144                 {
145                 case Node.TEXT_NODE:
146                     break;
147                 case Node.ELEMENT_NODE:
148                     if (currentNode.getNodeName().endsWith(WebDAV.XML_ALLPROP))
149                     {
150                         m_mode = GET_ALL_PROPS;
151                     }
152                     else if (currentNode.getNodeName().endsWith(WebDAV.XML_PROP))
153                     {
154                         m_mode = GET_NAMED_PROPS;
155                         node = currentNode;
156                     }
157                     else if (currentNode.getNodeName().endsWith(WebDAV.XML_PROPNAME))
158                     {
159                         m_mode = FIND_PROPS;
160                     }
161
162                     break;
163                 }
164             }
165
166             if (m_mode == GET_NAMED_PROPS)
167             {
168                 m_properties = new ArrayList JavaDoc<WebDAVProperty>();
169                 childList = node.getChildNodes();
170
171                 for (int i = 0; i < childList.getLength(); i++)
172                 {
173                     Node JavaDoc currentNode = childList.item(i);
174                     switch (currentNode.getNodeType())
175                     {
176                     case Node.TEXT_NODE:
177                         break;
178                     case Node.ELEMENT_NODE:
179                         m_properties.add(createProperty(currentNode));
180                         break;
181                     }
182                 }
183             }
184         }
185     }
186
187     /**
188      * Exceute the main WebDAV request processing
189      *
190      * @exception WebDAVServerException
191      */

192     protected void executeImpl() throws WebDAVServerException, Exception JavaDoc
193     {
194         m_response.setStatus(WebDAV.WEBDAV_SC_MULTI_STATUS);
195
196         FileFolderService fileFolderService = getFileFolderService();
197
198         FileInfo pathNodeInfo = null;
199         try
200         {
201             // Check that the path exists
202
pathNodeInfo = getDAVHelper().getNodeForPath(getRootNodeRef(), m_strPath, m_request.getServletPath());
203         }
204         catch (FileNotFoundException e)
205         {
206             // The path is not valid - send a 404 error back to the client
207
throw new WebDAVServerException(HttpServletResponse.SC_NOT_FOUND);
208         }
209
210         // Set the response content type
211

212         m_response.setContentType(WebDAV.XML_CONTENT_TYPE);
213
214         // Create multistatus response
215

216         XMLWriter xml = createXMLWriter();
217
218         xml.startDocument();
219
220         String JavaDoc nsdec = generateNamespaceDeclarations(m_namespaces);
221         xml.startElement(
222                 WebDAV.DAV_NS,
223                 WebDAV.XML_MULTI_STATUS + nsdec,
224                 WebDAV.XML_NS_MULTI_STATUS + nsdec,
225                 getDAVHelper().getNullAttributes());
226
227         // Create the path for the current location in the tree
228
StringBuilder JavaDoc baseBuild = new StringBuilder JavaDoc(256);
229         baseBuild.append(getPath());
230         if (baseBuild.length() == 0 || baseBuild.charAt(baseBuild.length() - 1) != WebDAVHelper.PathSeperatorChar)
231         {
232             baseBuild.append(WebDAVHelper.PathSeperatorChar);
233         }
234         String JavaDoc basePath = baseBuild.toString();
235
236         // Output the response for the root node, depth zero
237
generateResponseForNode(xml, pathNodeInfo, basePath);
238
239         // If additional levels are required and the root node is a folder then recurse to the required
240
// level and output node details a level at a time
241
if (getDepth() != WebDAV.DEPTH_0 && pathNodeInfo.isFolder())
242         {
243             // Create the initial list of nodes to report
244
List JavaDoc<FileInfo> nodeInfos = new ArrayList JavaDoc<FileInfo>(10);
245             nodeInfos.add(pathNodeInfo);
246
247             int curDepth = WebDAV.DEPTH_1;
248
249             // Save the base path length
250
int baseLen = baseBuild.length();
251
252             // List of next level of nodes to report
253
List JavaDoc<FileInfo> nextNodeInfos = null;
254             if (getDepth() > WebDAV.DEPTH_1)
255             {
256                 nextNodeInfos = new ArrayList JavaDoc<FileInfo>(10);
257             }
258
259             // Loop reporting each level of nodes to the requested depth
260
while (curDepth <= getDepth() && nodeInfos != null)
261             {
262                 // Clear out the next level of nodes, if required
263
if (nextNodeInfos != null)
264                 {
265                     nextNodeInfos.clear();
266                 }
267
268                 // Output the current level of node(s), the node list should
269
// only contain folder nodes
270

271                 for (FileInfo curNodeInfo : nodeInfos)
272                 {
273                     // Get the list of child nodes for the current node
274
List JavaDoc<FileInfo> childNodeInfos = fileFolderService.list(curNodeInfo.getNodeRef());
275
276                     // can skip the current node if it doesn't have children
277
if (childNodeInfos.size() == 0)
278                     {
279                         continue;
280                     }
281                     
282                     // Output the child node details
283
// Generate the base path for the current parent node
284

285                     baseBuild.setLength(baseLen);
286                     try
287                     {
288                         String JavaDoc pathSnippet = getDAVHelper().getPathFromNode(pathNodeInfo.getNodeRef(), curNodeInfo.getNodeRef());
289                         baseBuild.append(pathSnippet);
290                     }
291                     catch (FileNotFoundException e)
292                     {
293                         // move to the next node
294
continue;
295                     }
296
297                     int curBaseLen = baseBuild.length();
298
299                     // Output the child node details
300
for (FileInfo curChildInfo : childNodeInfos)
301                     {
302                         // Build the path for the current child node
303
baseBuild.setLength(curBaseLen);
304
305                         baseBuild.append(curChildInfo.getName());
306
307                         // Output the current child node details
308
generateResponseForNode(xml, curChildInfo, baseBuild.toString());
309
310                         // If the child is a folder add it to the list of next level nodes
311
if (nextNodeInfos != null && curChildInfo.isFolder())
312                         {
313                             nextNodeInfos.add(curChildInfo);
314                         }
315                     }
316                 }
317
318                 // Update the current tree depth
319
curDepth++;
320
321                 // Move the next level of nodes to the current node list
322
nodeInfos = nextNodeInfos;
323             }
324         }
325
326         // Close the outer XML element
327
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_MULTI_STATUS, WebDAV.XML_NS_MULTI_STATUS);
328
329         // Send remaining data
330
xml.flush();
331     }
332
333     /**
334      * Creates a WebDAVProperty from the given XML node
335      */

336     private WebDAVProperty createProperty(Node JavaDoc node)
337     {
338         WebDAVProperty property = null;
339
340         String JavaDoc strName = node.getLocalName();
341         String JavaDoc strNamespaceUri = node.getNamespaceURI();
342
343         if (strNamespaceUri.equals(WebDAV.DEFAULT_NAMESPACE_URI))
344         {
345             property = new WebDAVProperty(strName);
346         }
347         else
348         {
349             property = new WebDAVProperty(strName, strNamespaceUri, getNamespaceName(strNamespaceUri));
350         }
351
352         return property;
353     }
354
355     /**
356      * Retrieves the namespace name for the given namespace URI, one is
357      * generated if it doesn't exist
358      */

359     private String JavaDoc getNamespaceName(String JavaDoc strNamespaceUri)
360     {
361         String JavaDoc strNamespaceName = m_namespaces.get(strNamespaceUri);
362         if (strNamespaceName == null)
363         {
364             strNamespaceName = "ns" + m_namespaces.size();
365             m_namespaces.put(strNamespaceUri, strNamespaceName);
366         }
367
368         return strNamespaceName;
369     }
370
371     /**
372      * Generates the required response XML for the current node
373      *
374      * @param xml XMLWriter
375      * @param node NodeRef
376      * @param path String
377      */

378     private void generateResponseForNode(XMLWriter xml, FileInfo nodeInfo, String JavaDoc path) throws Exception JavaDoc
379     {
380         NodeRef nodeRef = nodeInfo.getNodeRef();
381         boolean isFolder = nodeInfo.isFolder();
382         
383         // Output the response block for the current node
384
xml.startElement(
385                 WebDAV.DAV_NS,
386                 WebDAV.XML_RESPONSE,
387                 WebDAV.XML_NS_RESPONSE,
388                 getDAVHelper().getNullAttributes());
389
390         // Build the href string for the current node
391
String JavaDoc strHRef = WebDAV.getURLForPath(m_request, path, isFolder);
392
393         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_HREF, WebDAV.XML_NS_HREF, getDAVHelper().getNullAttributes());
394         xml.write(strHRef);
395         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_HREF, WebDAV.XML_NS_HREF);
396
397         switch (m_mode)
398         {
399         case GET_NAMED_PROPS:
400             generateNamedPropertiesResponse(xml, nodeInfo);
401             break;
402         case GET_ALL_PROPS:
403             generateAllPropertiesResponse(xml, nodeRef, isFolder);
404             break;
405         case FIND_PROPS:
406             generateFindPropertiesResponse(xml, nodeRef, isFolder);
407             break;
408         }
409
410         // Close off the response element
411
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_RESPONSE, WebDAV.XML_NS_RESPONSE);
412     }
413
414     /**
415      * Generates the XML response for a PROPFIND request that asks for a
416      * specific set of properties
417      *
418      * @param xml XMLWriter
419      * @param node NodeRef
420      * @param isDir boolean
421      */

422     private void generateNamedPropertiesResponse(XMLWriter xml, FileInfo nodeInfo) throws Exception JavaDoc
423     {
424         NodeRef nodeRef = nodeInfo.getNodeRef();
425         boolean isFolder = nodeInfo.isFolder();
426         
427         // Get the properties for the node
428
Map JavaDoc<QName, Serializable JavaDoc> props = getNodeService().getProperties(nodeRef);
429
430         // Output the start of the properties element
431
Attributes JavaDoc nullAttr = getDAVHelper().getNullAttributes();
432
433         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT, nullAttr);
434         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP, nullAttr);
435
436         ArrayList JavaDoc<WebDAVProperty> propertiesNotFound = new ArrayList JavaDoc<WebDAVProperty>();
437
438         TypeConverter typeConv = DefaultTypeConverter.INSTANCE;
439
440         // Loop through the requested property list
441
for (WebDAVProperty property : m_properties)
442         {
443             // Get the requested property details
444

445             String JavaDoc propName = property.getName();
446             String JavaDoc propNamespaceUri = property.getNamespaceUri();
447 // String propNamespaceName = property.getNamespaceName();
448

449             // Check if the property is a standard WebDAV property
450

451             Object JavaDoc davValue = null;
452
453             if (propNamespaceUri.equals(WebDAV.DEFAULT_NAMESPACE_URI))
454             {
455                 // Check if the client is requesting lock information
456
if (propName.equals(WebDAV.XML_LOCK_DISCOVERY)) // && metaData.isLocked())
457
{
458                     generateLockDiscoveryResponse(xml, nodeRef, isFolder);
459                 }
460                 else if (propName.equals(WebDAV.XML_SUPPORTED_LOCK))
461                 {
462                     // Output the supported lock types
463
writeLockTypes(xml);
464                 }
465
466                 // Check if the client is requesting the resource type
467

468                 else if (propName.equals(WebDAV.XML_RESOURCE_TYPE))
469                 {
470                     // If the node is a folder then return as a collection type
471

472                     xml.startElement(WebDAV.DAV_NS, WebDAV.XML_RESOURCE_TYPE, WebDAV.XML_NS_RESOURCE_TYPE, nullAttr);
473                     if (isFolder)
474                     {
475                         xml.write(DocumentHelper.createElement(WebDAV.XML_NS_COLLECTION));
476                     }
477                     xml.endElement(WebDAV.DAV_NS, WebDAV.XML_RESOURCE_TYPE, WebDAV.XML_NS_RESOURCE_TYPE);
478                 }
479                 else if (propName.equals(WebDAV.XML_DISPLAYNAME))
480                 {
481                     // Get the node name
482
if (getRootNodeRef().equals(nodeRef))
483                     {
484                         // Output an empty name for the root node
485
xml.write(DocumentHelper.createElement(WebDAV.XML_NS_SOURCE));
486                     }
487                     else
488                     {
489                         // Get the node name
490
davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_DISPLAYNAME);
491
492                         // Output the node name
493
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_DISPLAYNAME, WebDAV.XML_NS_DISPLAYNAME, nullAttr);
494                         if (davValue != null)
495                         {
496                             String JavaDoc name = typeConv.convert(String JavaDoc.class, davValue);
497                             if (name == null || name.length() == 0)
498                             {
499                                 logger.error("WebDAV name is null, value=" + davValue.getClass().getName() + ", node=" + nodeRef);
500                             }
501                             xml.write(name);
502                         }
503                         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_DISPLAYNAME, WebDAV.XML_NS_DISPLAYNAME);
504                     }
505                 }
506                 else if (propName.equals(WebDAV.XML_SOURCE))
507                 {
508                     // NOTE: source is always a no content element in our
509
// implementation
510

511                     xml.write(DocumentHelper.createElement(WebDAV.XML_NS_SOURCE));
512                 }
513                 else if (propName.equals(WebDAV.XML_GET_LAST_MODIFIED))
514                 {
515                     // Get the modifed date/time
516

517                     davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_GET_LAST_MODIFIED);
518
519                     // Output the last modified date of the node
520

521                     xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_LAST_MODIFIED, WebDAV.XML_NS_GET_LAST_MODIFIED,
522                             nullAttr);
523                     if (davValue != null)
524                         xml.write(WebDAV.formatModifiedDate(typeConv.convert(Date JavaDoc.class, davValue)));
525                     xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_LAST_MODIFIED, WebDAV.XML_NS_GET_LAST_MODIFIED);
526                 }
527                 else if (propName.equals(WebDAV.XML_GET_CONTENT_LANGUAGE) && !isFolder)
528                 {
529                     // Get the content language
530
// TODO:
531
// Output the content language
532
xml.startElement(
533                             WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LANGUAGE,
534                             WebDAV.XML_NS_GET_CONTENT_LANGUAGE, nullAttr);
535                     // TODO:
536
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LANGUAGE, WebDAV.XML_NS_GET_CONTENT_LANGUAGE);
537                 }
538                 else if (propName.equals(WebDAV.XML_GET_CONTENT_TYPE) && !isFolder)
539                 {
540                     // Get the content type
541
davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_GET_CONTENT_TYPE);
542
543                     // Output the content type
544
xml.startElement(
545                             WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_TYPE,
546                             WebDAV.XML_NS_GET_CONTENT_TYPE, nullAttr);
547                     if (davValue != null)
548                         xml.write(typeConv.convert(String JavaDoc.class, davValue));
549                     xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_TYPE, WebDAV.XML_NS_GET_CONTENT_TYPE);
550                 }
551                 else if (propName.equals(WebDAV.XML_GET_ETAG) && !isFolder)
552                 {
553                     // Output the etag
554

555                     xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG, nullAttr);
556                     xml.write(getDAVHelper().makeETag(nodeRef));
557                     xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG);
558                 }
559                 else if (propName.equals(WebDAV.XML_GET_CONTENT_LENGTH))
560                 {
561                     // Get the content length, if it's not a folder
562
long len = 0;
563
564                     if (!isFolder)
565                     {
566                         ContentData contentData = (ContentData) props.get(ContentModel.PROP_CONTENT);
567                         if (contentData != null)
568                             len = contentData.getSize();
569                     }
570
571                     // Output the content length
572
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LENGTH, WebDAV.XML_NS_GET_CONTENT_LENGTH,
573                             nullAttr);
574                     xml.write("" + len);
575                     xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LENGTH, WebDAV.XML_NS_GET_CONTENT_LENGTH);
576                 }
577                 else if (propName.equals(WebDAV.XML_CREATION_DATE))
578                 {
579                     // Get the creation date
580
davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_CREATION_DATE);
581
582                     // Output the creation date
583
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_CREATION_DATE, WebDAV.XML_NS_CREATION_DATE, nullAttr);
584                     if (davValue != null)
585                         xml.write(WebDAV.formatCreationDate(typeConv.convert(Date JavaDoc.class, davValue)));
586                     xml.endElement(WebDAV.DAV_NS, WebDAV.XML_CREATION_DATE, WebDAV.XML_NS_CREATION_DATE);
587                 }
588                 else
589                 {
590                     // Could not map the requested property to an Alfresco property
591
if (property.getName().equals(WebDAV.XML_HREF) == false)
592                         propertiesNotFound.add(property);
593                 }
594             }
595             else
596             {
597                 // Look in the custom properties
598

599                 // TODO: Custom properties lookup
600
// String qualifiedName = propNamespaceUri + WebDAV.NAMESPACE_SEPARATOR + propName;
601
propertiesNotFound.add(property);
602             }
603         }
604
605         // Close off the successful part of the response
606

607         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP);
608
609         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS, nullAttr);
610         xml.write(WebDAV.HTTP1_1 + " " + HttpServletResponse.SC_OK + " " + WebDAV.SC_OK_DESC);
611         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS);
612
613         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT);
614
615         // If some of the requested properties were not found return another
616
// status section
617

618         if (propertiesNotFound.size() > 0)
619         {
620             // Start the second status section
621

622             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT, nullAttr);
623             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP, nullAttr);
624
625             // Loop through the list of properties that were not found
626

627             for (WebDAVProperty property : propertiesNotFound)
628             {
629                 // Output the property not found status block
630

631                 String JavaDoc propName = property.getName();
632                 String JavaDoc propNamespaceName = property.getNamespaceName();
633                 String JavaDoc propQName = propName;
634                 if (propNamespaceName != null && propNamespaceName.length() > 0)
635                     propQName = propNamespaceName + ":" + propName;
636
637                 xml.write(DocumentHelper.createElement(propQName));
638             }
639
640             // Close the unsuccessful part of the response
641

642             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP);
643
644             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS, nullAttr);
645             xml.write(WebDAV.HTTP1_1 + " " + HttpServletResponse.SC_NOT_FOUND + " " + WebDAV.SC_NOT_FOUND_DESC);
646             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS);
647
648             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT);
649         }
650     }
651
652     /**
653      * Generates the XML response for a PROPFIND request that asks for all known
654      * properties
655      *
656      * @param xml XMLWriter
657      * @param node NodeRef
658      * @param isDir boolean
659      */

660     private void generateAllPropertiesResponse(XMLWriter xml, NodeRef node, boolean isDir) throws Exception JavaDoc
661     {
662         // Get the properties for the node
663

664         Map JavaDoc<QName, Serializable JavaDoc> props = getNodeService().getProperties(node);
665
666         // Output the start of the properties element
667

668         Attributes JavaDoc nullAttr = getDAVHelper().getNullAttributes();
669
670         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT, nullAttr);
671         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP, nullAttr);
672
673         // Generate a lock status report, if locked
674

675         generateLockDiscoveryResponse(xml, node, isDir);
676
677         // Output the supported lock types
678

679         writeLockTypes(xml);
680
681         // If the node is a folder then return as a collection type
682

683         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_RESOURCE_TYPE, WebDAV.XML_NS_RESOURCE_TYPE, nullAttr);
684         if (isDir)
685             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_COLLECTION));
686         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_RESOURCE_TYPE, WebDAV.XML_NS_RESOURCE_TYPE);
687
688         // Get the node name
689

690         Object JavaDoc davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_DISPLAYNAME);
691
692         TypeConverter typeConv = DefaultTypeConverter.INSTANCE;
693
694         // Output the node name
695

696         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_DISPLAYNAME, WebDAV.XML_NS_DISPLAYNAME, nullAttr);
697         if (davValue != null)
698         {
699             String JavaDoc name = typeConv.convert(String JavaDoc.class, davValue);
700             if (name == null || name.length() == 0)
701             {
702                 logger.error("WebDAV name is null, value=" + davValue.getClass().getName() + ", node=" + node);
703             }
704             xml.write(name);
705         }
706         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_DISPLAYNAME, WebDAV.XML_NS_DISPLAYNAME);
707
708         // Output the source
709
//
710
// NOTE: source is always a no content element in our implementation
711

712         xml.write(DocumentHelper.createElement(WebDAV.XML_NS_SOURCE));
713
714         // Get the creation date
715

716         davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_CREATION_DATE);
717
718         // Output the creation date
719

720         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_CREATION_DATE, WebDAV.XML_NS_CREATION_DATE, nullAttr);
721         if (davValue != null)
722             xml.write(WebDAV.formatCreationDate(typeConv.convert(Date JavaDoc.class, davValue)));
723         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_CREATION_DATE, WebDAV.XML_NS_CREATION_DATE);
724
725         // Get the modifed date/time
726

727         davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_GET_LAST_MODIFIED);
728
729         // Output the last modified date of the node
730

731         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_LAST_MODIFIED, WebDAV.XML_NS_GET_LAST_MODIFIED, nullAttr);
732         if (davValue != null)
733             xml.write(WebDAV.formatModifiedDate(typeConv.convert(Date JavaDoc.class, davValue)));
734         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_LAST_MODIFIED, WebDAV.XML_NS_GET_LAST_MODIFIED);
735
736         // For a file node output the content language and content type
737

738         if (isDir == false)
739         {
740             // Get the content language
741

742             // TODO:
743
// Output the content language
744

745             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LANGUAGE, WebDAV.XML_NS_GET_CONTENT_LANGUAGE,
746                     nullAttr);
747             // TODO:
748
xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LANGUAGE, WebDAV.XML_NS_GET_CONTENT_LANGUAGE);
749
750             // Get the content type
751
davValue = WebDAV.getDAVPropertyValue(props, WebDAV.XML_GET_CONTENT_TYPE);
752
753             // Output the content type
754
xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_TYPE, WebDAV.XML_NS_GET_CONTENT_TYPE, nullAttr);
755             if (davValue != null)
756                 xml.write(typeConv.convert(String JavaDoc.class, davValue));
757             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_TYPE, WebDAV.XML_NS_GET_CONTENT_TYPE);
758
759             // Output the etag
760

761             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG, nullAttr);
762             xml.write(getDAVHelper().makeETag(node));
763             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_ETAG, WebDAV.XML_NS_GET_ETAG);
764         }
765
766         // Get the content length, if it's not a folder
767

768         long len = 0;
769
770         if (isDir == false)
771         {
772             ContentData contentData = (ContentData) props.get(ContentModel.PROP_CONTENT);
773             if (contentData != null)
774                 len = contentData.getSize();
775         }
776
777         // Output the content length
778

779         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LENGTH, WebDAV.XML_NS_GET_CONTENT_LENGTH, nullAttr);
780         xml.write("" + len);
781         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_GET_CONTENT_LENGTH, WebDAV.XML_NS_GET_CONTENT_LENGTH);
782
783         // Print out all the custom properties
784

785         // TODO: Output custom properties
786

787         // Close off the response
788

789         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP);
790
791         xml.startElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS, nullAttr);
792         xml.write(WebDAV.HTTP1_1 + " " + HttpServletResponse.SC_OK + " " + WebDAV.SC_OK_DESC);
793         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS);
794
795         xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT);
796     }
797
798     /**
799      * Generates the XML response for a PROPFIND request that asks for a list of
800      * all known properties
801      *
802      * @param xml XMLWriter
803      * @param node NodeRef
804      * @param isDir boolean
805      */

806     private void generateFindPropertiesResponse(XMLWriter xml, NodeRef node, boolean isDir)
807     {
808         try
809         {
810             // Output the start of the properties element
811

812             Attributes JavaDoc nullAttr = getDAVHelper().getNullAttributes();
813
814             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT, nullAttr);
815             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP, nullAttr);
816
817             // Output the well-known properties
818

819             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_LOCK_DISCOVERY));
820             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_SUPPORTED_LOCK));
821             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_RESOURCE_TYPE));
822             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_DISPLAYNAME));
823             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_GET_LAST_MODIFIED));
824             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_GET_CONTENT_LENGTH));
825             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_CREATION_DATE));
826             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_GET_ETAG));
827
828             if (isDir)
829             {
830                 xml.write(DocumentHelper.createElement(WebDAV.XML_NS_GET_CONTENT_LANGUAGE));
831                 xml.write(DocumentHelper.createElement(WebDAV.XML_NS_GET_CONTENT_TYPE));
832             }
833
834             // Output the custom properties
835

836             // TODO: Custom properties
837

838             // Close off the response
839

840             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROP, WebDAV.XML_NS_PROP);
841
842             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS, nullAttr);
843             xml.write(WebDAV.HTTP1_1 + " " + HttpServletResponse.SC_OK + " " + WebDAV.SC_OK_DESC);
844             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_STATUS, WebDAV.XML_NS_STATUS);
845
846             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_PROPSTAT, WebDAV.XML_NS_PROPSTAT);
847         }
848         catch (Exception JavaDoc ex)
849         {
850             // Convert to a runtime exception
851

852             throw new AlfrescoRuntimeException("XML processing error", ex);
853         }
854     }
855
856     /**
857      * Generates the XML response snippet showing the lock information for the
858      * given path
859      *
860      * @param xml XMLWriter
861      * @param node NodeRef
862      * @param isDir boolean
863      */

864     private void generateLockDiscoveryResponse(XMLWriter xml, NodeRef node, boolean isDir) throws Exception JavaDoc
865     {
866         // Get the lock status for the node
867

868         LockService lockService = getLockService();
869         LockStatus lockSts = lockService.getLockStatus(node);
870
871         // Output the lock status reponse
872

873         if (lockSts != LockStatus.NO_LOCK)
874             generateLockDiscoveryXML(xml, node);
875     }
876
877     /**
878      * Output the supported lock types XML element
879      *
880      * @param xml XMLWriter
881      */

882     private void writeLockTypes(XMLWriter xml)
883     {
884         try
885         {
886             AttributesImpl JavaDoc nullAttr = getDAVHelper().getNullAttributes();
887
888             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_SUPPORTED_LOCK, WebDAV.XML_NS_SUPPORTED_LOCK, nullAttr);
889
890             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE, nullAttr);
891             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_EXCLUSIVE));
892             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_SCOPE, WebDAV.XML_NS_LOCK_SCOPE);
893
894             xml.startElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE, nullAttr);
895             xml.write(DocumentHelper.createElement(WebDAV.XML_NS_WRITE));
896             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_LOCK_TYPE, WebDAV.XML_NS_LOCK_TYPE);
897
898             xml.endElement(WebDAV.DAV_NS, WebDAV.XML_SUPPORTED_LOCK, WebDAV.XML_NS_SUPPORTED_LOCK);
899         }
900         catch (Exception JavaDoc ex)
901         {
902             throw new AlfrescoRuntimeException("XML write error", ex);
903         }
904     }
905 }
906
Popular Tags