KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > ibm > webdav > PropertyResponse


1 package com.ibm.webdav;
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 org.w3c.dom.*;
18 import java.util.*;
19
20
21 import java.text.ParseException JavaDoc;
22
23 /** A PropertyResponse describes the properties returned as the
24  * result of a method send on a resource, e.g., getProperties(). A
25  * <code>MultiStatus</code> contains a collection of Response instances,
26  * one for each resource effected by the method sent.</p>
27  * <p>
28  * PropertyResponse also has convenience methods for all the DAV properties.
29  * The method names correspond to the DAV property names suitably
30  * modified to fit JavaBean conventions. If the property was not requested,
31  * these convenience methods will return null or some other suitable value
32  * to indicate the property value is unknown.</p>
33  * @author Jim Amsden &lt;jamsden@us.ibm.com&gt;
34  * @see com.ibm.webdav.MethodResponse
35  * @see com.ibm.webdav.MultiStatus
36  */

37 public class PropertyResponse extends Response implements java.io.Serializable JavaDoc {
38
39    // a Dictionary whose key is a PropertyName and whose value is a PropertyValue
40
private Hashtable pnproperties = new Hashtable();
41
42    // a Dictionary matching a property name string into a PropertyName.
43
// All PropertyNames in this dictionary have entries in the
44
// pnproperites Dictionary.
45
//
46
// The property name string is the property's XML namespace concatenated with the
47
// element local tag name (the name without the prefix and :). This is consistent
48
// with the current WebDAV semantics for XML namespaces
49
private Hashtable strxproperties = new Hashtable();
50
51    //Table of property definitions
52
private Hashtable propertydefs = new Hashtable();
53
54 /** Construct a Response from an XML DAV:response element
55  *
56  * @param document the document that will contain the Response
57  * when output as XML.
58  * @param response the XML DAV:response element that is the source
59  * @exception com.ibm.webdav.ServerException thrown if the XML for the response is incorrect
60  * of this response
61  */

62 public PropertyResponse(Document document, Element response) throws ServerException {
63     super(document);
64     try {
65         // get the identity of the resource this is a response on
66
Element href = (Element) response.getElementsByTagNameNS("DAV:","href").item(0);
67         setResource(((Text) href.getFirstChild()).getData());
68
69         // get the properties in the response, and their statuses
70
NodeList propstats = response.getElementsByTagNameNS("DAV:","propstat");
71         Element propstat = null;
72         for (int i = 0; i < propstats.getLength(); i++) {
73             propstat = (Element) propstats.item(i);
74             // get the properties in the propstat. Note that there should be at most
75
// one prop in the propstat, and it contains the actual properties
76
Element prop = (Element) propstat.getElementsByTagNameNS("DAV:","prop").item(0);
77
78             // this is the status for all properties in this propstat
79
Element status = (Element) propstat.getElementsByTagNameNS("DAV:","status").item(0);
80             String JavaDoc statusMessage = ((Text) status.getFirstChild()).getData();
81             StringTokenizer statusFields = new StringTokenizer(statusMessage, " ");
82             statusFields.nextToken(); // skip the HTTP version
83
int statusCode = Integer.parseInt(statusFields.nextToken());
84             NodeList properties = prop.getChildNodes();
85             Node property = null;
86             for (int j = 0; j < properties.getLength(); j++) {
87                 property = (Node) properties.item(j);
88                 // skip ignorable TXText elements
89
if (property.getNodeType() == Node.ELEMENT_NODE) {
90                     Element el = (Element)property;
91                     //el.collectNamespaceAttributes();
92
PropertyName propname = new PropertyName( el );
93                     addProperty(propname, (Element) property, statusCode);
94                 }
95             }
96         }
97         Element responseDescription = (Element) response.getElementsByTagNameNS("DAV:","responsedescription").item(0);
98         if (responseDescription != null) {
99             setDescription(((Text) responseDescription.getFirstChild()).getData());
100         }
101     } catch (Exception JavaDoc exc) {
102         exc.printStackTrace();
103         throw new ServerException(WebDAVStatus.SC_INTERNAL_SERVER_ERROR, "Invalid PropertyResponse");
104     }
105 }
106 /** Construct an empty Response for some resource.
107  *
108  * @param url the URL of the resource this is a response for
109  *
110  */

111 public PropertyResponse(String JavaDoc url) {
112     super(url);
113 }
114 /** Add a property and its status to the collection of properties generated
115  * as a result of sending a method to a resource.
116  *
117  * @param propertyName the name of the property to add.
118  * @param propertyElement the value of the property
119  * @param status its status
120  * @exception com.ibm.webdav.ServerException thrown if the property is already in this response
121  */

122 public void addProperty( PropertyName propertyName, Element propertyElement, int status) throws ServerException {
123     if (pnproperties.contains(propertyName)) {
124         throw new ServerException(WebDAVStatus.SC_INTERNAL_SERVER_ERROR, "Duplicate property in a Response");
125     } else {
126         pnproperties.put(propertyName, new PropertyValue(propertyElement, status));
127         strxproperties.put(propertyName.asExpandedString(), propertyName);
128     }
129 }
130
131 /** Translate this Response into an XML response element.
132  * @return a DAV:response XML element
133  */

134 public Element asXML() {
135
136     Element response = document.createElementNS("DAV:","D:response");
137
138     Element href = document.createElementNS("DAV:","D:href");
139
140     href.appendChild(document.createTextNode(getResource()));
141     response.appendChild(href);
142
143     // group the properties having the same status
144
Hashtable byStatus = new Hashtable();
145     Enumeration propertyNames = getPropertyNamesPN();
146     while (propertyNames.hasMoreElements()) {
147         PropertyName propertyName = (PropertyName) propertyNames.nextElement();
148         PropertyValue propertyValue = getProperty(propertyName);
149         Integer JavaDoc status = new Integer JavaDoc(propertyValue.status);
150
151         // keep a Vector of property names having this status
152
Vector props = null;
153         if (byStatus.containsKey(status)) {
154             props = (Vector) byStatus.get(status);
155         } else {
156             props = new Vector();
157             byStatus.put(status, props);
158         }
159         props.addElement(propertyName);
160     }
161     // generate XML for the propstat
162
Enumeration statuses = byStatus.keys();
163
164     // if there are no properties, construct a propstat with a prop with no elements and
165
// an SC_OK status,
166
if (!statuses.hasMoreElements()) {
167         Element propstat = document.createElementNS("DAV:","D:propstat");
168
169                 Element prop = document.createElementNS("DAV:","D:prop");
170
171         propstat.appendChild(prop);
172         Element statusElement = document.createElementNS("DAV:","D:status");
173
174         String JavaDoc statusText = HTTPVersion + " " + WebDAVStatus.SC_OK + " " + WebDAVStatus.getStatusMessage(WebDAVStatus.SC_OK);
175         statusElement.appendChild(document.createTextNode(statusText));
176         propstat.appendChild(statusElement);
177         response.appendChild(propstat);
178     }
179
180     // create a propstat for all those properties having the same status.
181
while (statuses.hasMoreElements()) {
182         Integer JavaDoc status = (Integer JavaDoc) statuses.nextElement();
183         Enumeration propertiesHavingThisStatus = ((Vector) byStatus.get(status)).elements();
184         Element propstat = document.createElementNS("DAV:","D:propstat");
185
186         Element prop = document.createElementNS("DAV:","D:prop");
187
188
189         // put all the properties having this status in the current prop element
190
while (propertiesHavingThisStatus.hasMoreElements()) {
191             PropertyName propertyName = (PropertyName) propertiesHavingThisStatus.nextElement();
192             PropertyValue propertyValue = getProperty(propertyName);
193             //Element property = document.createElement(pn2);
194

195             try {
196                 prop.appendChild(document.importNode(propertyValue.value,true));
197             } catch(NullPointerException JavaDoc e) {
198                 System.err.println("Null pointer for property - " + propertyName);
199                 throw e;
200             }
201             
202         }
203         propstat.appendChild(prop);
204         String JavaDoc statusText = HTTPVersion + " " + status + " " + WebDAVStatus.getStatusMessage(status.intValue());
205         Element statusElement = document.createElementNS("DAV:","D:status");
206
207         statusElement.appendChild(document.createTextNode(statusText));
208         propstat.appendChild(statusElement);
209         response.appendChild(propstat);
210     }
211
212         Enumeration defKeys = propertydefs.keys();
213
214         if(defKeys.hasMoreElements()) {
215           Element propdefn = document.createElementNS("DAV:","D:propdefn");
216           response.appendChild(propdefn);
217
218           while(defKeys.hasMoreElements()) {
219             Object JavaDoc key = defKeys.nextElement();
220             PropertyDefinition propdef = (PropertyDefinition)propertydefs.get(key);
221
222             propdefn.appendChild(document.importNode(propdef.asXML(),true));
223           }
224
225         }
226
227     if (getDescription() != null) {
228         Element description = document.createElementNS("DAV:","D:responsedescription");
229
230         description.appendChild(document.createTextNode(getDescription()));
231         response.appendChild(description);
232     }
233     return response;
234 }
235 /** Get the active locks in the property response if any.
236  *
237  * @return a Vector of ActiveLock objects containing information about locks
238  * on the resource. The Vector will be empty if the lockdiscovery property
239  * was not requested.
240  * @exception com.ibm.webdav.WebDAVException
241  */

242 public Vector getActiveLocks() throws WebDAVException {
243     Vector allLocks = new Vector();
244     PropertyValue prop = getProp("DAV:lockdiscovery");
245     if (prop != null) {
246         NodeList activeLocks = ((Element) prop.value).getElementsByTagNameNS("DAV:","activelock");
247         Element activeLock = null;
248         for (int i = 0; i < activeLocks.getLength(); i++) {
249             activeLock = (Element) activeLocks.item(i);
250             allLocks.addElement(new ActiveLock(activeLock));
251         }
252     }
253     return allLocks;
254 }
255 /** The author of this resource. That is, the principal id of the user agent that
256  * initially created the resource.
257  * @return the DAV:author property or null if the property was not requested.
258  */

259 public String JavaDoc getAuthor() {
260     String JavaDoc author = null;
261     PropertyValue prop = getProp("DAV:author");
262     if (prop != null) {
263         Text pcdata = (Text) prop.value.getFirstChild();
264         if (pcdata != null) {
265             author = pcdata.getData();
266         }
267     }
268     return author;
269 }
270 /** The date the resource revision was checked in.
271  * @return the DAV:checkin-date property or null if the property was not requested
272  * or the resource is not versioned or checked in.
273  */

274 public Date getCheckinDate() {
275     Date date = null;
276     PropertyValue prop = getProp("DAV:checkin-date");
277     if (prop != null) {
278         Text pcdata = (Text) prop.value.getFirstChild();
279         if (pcdata != null) {
280             String JavaDoc dateString = pcdata.getData();
281             try {
282                 date = (new SimpleISO8601DateFormat()).parse(dateString);
283             } catch (ParseException JavaDoc exc) {
284                 System.err.println("Invalid date format for creationdate in " + getResource());
285             }
286         }
287     }
288     return date;
289 }
290 /** The comment associated this resource.
291  * @return the DAV:comment property or null if the property was not requested.
292  */

293 public String JavaDoc getComment() {
294     String JavaDoc comment = null;
295     PropertyValue prop = getProp("DAV:comment");
296     if (prop != null) {
297         Text pcdata = (Text) prop.value.getFirstChild();
298         if (pcdata != null) {
299             comment = pcdata.getData();
300         }
301     }
302     return comment;
303 }
304 /** The language the content is written in.
305  * @return the value of the DAV:getcontentlanguage property of null if the property was not requested
306  */

307 public String JavaDoc getContentLanguage() {
308     String JavaDoc contentLanguage = null;
309     PropertyValue prop = getProp("DAV:getcontentlanguage");
310     if (prop != null) {
311         Text pcdata = (Text) prop.value.getFirstChild();
312         if (pcdata != null) {
313             contentLanguage = pcdata.getData();
314         }
315     }
316     return contentLanguage;
317 }
318 /** The length of the content of the resource or -1 if content length is not applicable.
319  * @return the DAV:getcontentlength property or -1 if the property was not requested.
320  */

321 public int getContentLength() {
322     int length = -1;
323     PropertyValue prop = getProp("DAV:getcontentlength");
324     if (prop != null) {
325         Text pcdata = (Text) prop.value.getFirstChild();
326         if (pcdata != null) {
327             try {
328                 length = Integer.parseInt(pcdata.getData());
329             } catch (NumberFormatException JavaDoc exc) {
330                 System.err.println("Bad contentlength property in " + getResource());
331             }
332         }
333     }
334     return length;
335 }
336 /** The MIME content type of the resource.
337  * @return the DAV:getcontenttype property or null if the property was not requested.
338  */

339 public String JavaDoc getContentType() {
340     String JavaDoc contentType = null;
341     PropertyValue prop = getProp("DAV:getcontenttype");
342     if (prop != null) {
343         Text pcdata = (Text) prop.value.getFirstChild();
344         if (pcdata != null) {
345             contentType = pcdata.getData();
346         }
347     }
348     return contentType;
349 }
350 /** The date the resource was created.
351  * @return the DAV:creationdate property or null if the property was not requested.
352  */

353 public Date getCreationDate() {
354     Date date = null;
355     PropertyValue prop = getProp("DAV:creationdate");
356     if (prop != null) {
357         Text pcdata = (Text) prop.value.getFirstChild();
358         if (pcdata != null) {
359             String JavaDoc dateString = pcdata.getData();
360             try {
361                 date = (new SimpleISO8601DateFormat()).parse(dateString);
362             } catch (ParseException JavaDoc exc) {
363                 System.err.println("Invalid date format for creationdate in " + getResource());
364             }
365         }
366     }
367     return date;
368 }
369 /** A name for this resource suitable for display by client applications.
370  * @return the DAV:displayname property or null if the property was not requested.
371  */

372 public String JavaDoc getDisplayName() {
373     String JavaDoc displayName = null;
374     PropertyValue prop = getProp("DAV:displayname");
375     if (prop != null) {
376         Text pcdata = (Text) prop.value.getFirstChild();
377         if (pcdata != null) {
378             displayName = pcdata.getData();
379         }
380     }
381     return displayName;
382 }
383 /** The resource entity tag, useful for verifying the state of a cached resource.
384  * @return The DAV:getetag property or null if the property was not requested.
385  */

386 public String JavaDoc getETag() {
387     String JavaDoc eTag = null;
388     PropertyValue prop = getProp("DAV:getetag");
389     if (prop != null) {
390         Text pcdata = (Text) prop.value.getFirstChild();
391         if (pcdata != null) {
392             eTag = pcdata.getData();
393         }
394     }
395     return eTag;
396 }
397 /** The date on which the resource was last modified.
398  * @return the DAV:getlastmodified property or null if the property was not requested.
399  */

400 public Date getLastModifiedDate() {
401     Date date = null;
402     PropertyValue prop = getProp("DAV:getlastmodified");
403     if (prop != null) {
404         Text pcdata = (Text) prop.value.getFirstChild();
405         if (pcdata != null) {
406             String JavaDoc dateString = pcdata.getData();
407             try {
408                 date = (new SimpleRFC1123DateFormat()).parse(dateString);
409             } catch (ParseException JavaDoc exc) {
410                 System.err.println("Invalid date format for getlastmodified in " + getResource());
411             }
412         }
413     }
414     return date;
415 }
416 /** Internal helper method that returns the value
417  * of a property given its name.
418  * <p>
419  * If an invalid property name string (see
420  * PropertyName(String) constructor for definition)
421  * is provided, this routine will throw a runtime
422  * exception. This can be convenient if you know
423  * the property name string is valid and dont want
424  * to clean up exceptions that will never be thrown.
425  * (Runtime exceptions don't need to be declared.)
426  * If you need to find the value of a property and
427  * have a property name that you can't be sure is
428  * valid, use getProperty instead of this method.
429  *
430  * @return a PropertyValue for a given property name... or
431  * null if that property was not found.
432  *
433  * @exception RuntimeException
434  */

435 private PropertyValue getProp( String JavaDoc pnstr ) {
436
437     PropertyName pn;
438     try {
439         pn = new PropertyName( pnstr );
440     } catch (InvalidPropertyNameException excc) {
441         throw new RuntimeException JavaDoc( "internal error: bad property: "+pnstr );
442     }
443     PropertyValue prop = getProperty( pn );
444     return prop;
445 }
446 /** Get all the properties and their statuses in this Response.
447  *
448  * @return a Dictionary whose keys are PropertyNames, and whose values are
449  * PropertyValues.
450  */

451 public Dictionary getPropertiesByPropName() {
452     return pnproperties;
453 }
454
455 public Dictionary getPropertyDefinitionsByPropName() {
456   return this.propertydefs;
457 }
458 /** Get the value of a property contained in a PropertyResponse. The
459  * values were set when a method was invoked that returned a MultiStatus
460  * containing one or more PropertyResponses.
461  *
462  * @param name the name of the property to get,
463  * @return the property value for the named property
464  */

465 public PropertyValue getProperty( PropertyName name) {
466     return (PropertyValue) pnproperties.get(name);
467 }
468 /** Get the names of the properties contained in a PropertyResponse. The
469  * values were set when a method was invoked that returned a MultiStatus
470  * containing one or more PropertyResponses. The values here are instances
471  * of the class PropertyName... not String.
472  */

473 public Enumeration getPropertyNamesPN() {
474     return pnproperties.keys();
475 }
476 /** Get the resource type for the resource associated with this PropertyResponse.
477  * This is the tagName of the first child of the DAV:resourcetype property.
478  * @return The DAV:resourcetype DAV property or null if the property was not requested.
479  */

480 public String JavaDoc getResourceType() {
481     String JavaDoc resourceType = null;
482     PropertyValue prop = getProp("DAV:resourcetype");
483     if (prop != null) {
484         Element type = (Element) prop.value.getFirstChild();
485         if (type != null) {
486             resourceType = type.getTagName();
487         }
488     }
489     return resourceType;
490 }
491 /** Check to see if this response does not contain an error.
492  *
493  * @return true if all property statuses are less than 300.
494  */

495 public boolean isOK() {
496     boolean isOk = true;
497     Enumeration propertyValues = getPropertiesByPropName().elements();
498     while (isOk && propertyValues.hasMoreElements()) {
499         PropertyValue propertyValue = (PropertyValue) propertyValues.nextElement();
500         isOk = isOk && propertyValue.status < 300;
501     }
502     return isOk;
503 }
504 /** See if this property response is on a collection. That is, see
505  * if it contains a resourcetype property having a collection element.
506  *
507  * @return true if this PropertyResponse is on a collection resource
508  */

509 public boolean isOnACollection() {
510     PropertyValue resourcetype = getProp("DAV:resourcetype");
511     boolean isACollection = false;
512     if (resourcetype != null) {
513         Element value = (Element) resourcetype.value;
514         isACollection = value.getElementsByTagNameNS("DAV:","collection").getLength()>0;
515     }
516     return isACollection;
517 }
518 /** Remove a property from the collection of properties generated
519  * as a result of sending a method to a resource.
520  *
521  * @param propertyName the property to remove.
522  * @exception com.ibm.webdav.ServerException
523  */

524 public void removeProperty( PropertyName propertyName) throws ServerException {
525     if (pnproperties.contains(propertyName)) {
526         strxproperties.remove( propertyName.asExpandedString() );
527         pnproperties.remove( propertyName );
528     }
529 }
530 /** Set the value of a property.
531  *
532  * @param name the name of the property to set.
533  * @param value the property value for the named property
534  */

535 public void setProperty( PropertyName name, PropertyValue value) {
536     strxproperties.put( name.asExpandedString(), name);
537     pnproperties.put(name, value);
538 }
539 /** Convert this Response to a PropertyResponse.
540  * This method is used to convert MethodResponses to PropertyResponses
541  * when an error occurred accessing the properties of some member.
542  *
543  */

544 public PropertyResponse toPropertyResponse() {
545     return this;
546 }
547 }
548
Popular Tags