001: /*
002: * Copyright (c) 2000, Jacob Smullyan.
003: *
004: * This is part of SkunkDAV, a WebDAV client. See http://skunkdav.sourceforge.net/
005: * for the latest version.
006: *
007: * SkunkDAV is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License as published
009: * by the Free Software Foundation; either version 2, or (at your option)
010: * any later version.
011: *
012: * SkunkDAV is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with SkunkDAV; see the file COPYING. If not, write to the Free
019: * Software Foundation, 59 Temple Place - Suite 330, Boston, MA
020: * 02111-1307, USA.
021: */
022:
023: package org.skunk.dav.client;
024:
025: import java.lang.reflect.InvocationTargetException;
026: import java.lang.reflect.Method;
027: import java.util.ListIterator;
028: import org.skunk.minixml.XMLCData;
029: import org.skunk.minixml.XMLElement;
030: import org.skunk.trace.Debug;
031:
032: public class PropertyHandler {
033: private static Class[] paramTypeArray = new Class[] {
034: DAVFile.class, XMLElement.class };
035: //prefix for handler methods invoked through reflection
036: public static final String HANDLER_METHOD_PREFIX = "handle";
037:
038: public static void handleProperty(DAVFile file, XMLElement elem) {
039: try {
040: Method handler = getHandlerMethod(elem.getElementName());
041: handler.invoke(null, new Object[] { file, elem });
042: } catch (NoSuchMethodException noSoap) {
043: handleCustomProperty(file, elem);
044: } catch (SecurityException sucky) {
045: Debug.trace(PropertyHandler.class, Debug.DP2, sucky);
046: } catch (IllegalAccessException illack) {
047: Debug.trace(PropertyHandler.class, Debug.DP2, illack);
048: } catch (IllegalArgumentException illarg) {
049: Debug.trace(PropertyHandler.class, Debug.DP4, //should only occur during development
050: illarg);
051: } catch (InvocationTargetException invook) {
052: Debug.trace(PropertyHandler.class, Debug.DP2, invook);
053: }
054: }
055:
056: private static Method getHandlerMethod(String propertyName)
057: throws NoSuchMethodException, SecurityException {
058: if (propertyName == null || propertyName.length() == 0)
059: return null;
060: String methodName = HANDLER_METHOD_PREFIX
061: + Character.toUpperCase(propertyName.charAt(0))
062: + propertyName.substring(1);
063: Method handlerMethod = PropertyHandler.class.getDeclaredMethod(
064: methodName, paramTypeArray);
065: return handlerMethod;
066: }
067:
068: private static void handleCustomProperty(DAVFile file,
069: XMLElement elem) {
070: // handling of dead and other special properties
071: file.setCustomProperty((new DAVProperty(elem)),
072: getChildAsString(elem));
073: }
074:
075: private static void handleCreationdate(DAVFile file, XMLElement elem) {
076: file.setCreationDate(getChildAsString(elem));
077: }
078:
079: private static void handleDisplayname(DAVFile file, XMLElement elem) {
080: file.setDisplayName(getChildAsString(elem));
081: }
082:
083: private static void handleGetetag(DAVFile file, XMLElement elem) {
084: file.setEtag(getChildAsString(elem));
085: ;
086: }
087:
088: private static void handleGetlastmodified(DAVFile file,
089: XMLElement elem) {
090: file.setLastModified(getChildAsString(elem));
091: }
092:
093: private static void handleResourcetype(DAVFile file, XMLElement elem) {
094: if (elem.getChild(DAVConstants.COLLECTION_ELEM) != null)
095: file.setResourceType(DAVConstants.COLLECTION_ELEM);
096: else
097: file.setResourceType(null);
098: }
099:
100: private static void handleSupportedlock(DAVFile file,
101: XMLElement elem) {
102: for (ListIterator lit = elem.children(); lit.hasNext();) {
103: Object o = lit.next();
104: if (!(o instanceof XMLElement))
105: continue;
106: XMLElement lockEntry = (XMLElement) o;
107: if (!lockEntry.getElementName().equals(
108: DAVConstants.LOCKENTRY_ELEM)) {
109: Debug.trace(PropertyHandler.class, Debug.DP3,
110: "bizarre child encountered in supported lock element: "
111: + lockEntry);
112: continue;
113: }
114: XMLElement lockScope = lockEntry
115: .getChild(DAVConstants.LOCKSCOPE_ELEM);
116: XMLElement scopeCharacterization = lockScope
117: .getChildElement(0);
118: XMLElement lockType = lockEntry
119: .getChild(DAVConstants.LOCKTYPE_ELEM);
120: XMLElement typeCharacterization = lockType
121: .getChildElement(0);
122:
123: LockScope scopeArg = null;
124: if (scopeCharacterization != null) {
125: String name = scopeCharacterization.getElementName();
126: if (name.equals(DAVConstants.SHARED_ELEM))
127: scopeArg = LockScope.SHARED;
128: else if (name.equals(DAVConstants.EXCLUSIVE_ELEM))
129: scopeArg = LockScope.EXCLUSIVE;
130: }
131: LockType typeArg = null;
132: if (typeCharacterization != null) {
133: String name = typeCharacterization.getElementName();
134: if (name.equals(DAVConstants.WRITE_ELEM))
135: typeArg = LockType.WRITE;
136: }
137: if (scopeArg != null || typeArg != null) //tolerant to a fault
138: file.addSupportedLock(new Lock(scopeArg, typeArg));
139: }
140: }
141:
142: private static void handleGetcontentlanguage(DAVFile file,
143: XMLElement elem) {
144: file.setContentLanguage(getChildAsString(elem));
145: }
146:
147: private static void handleGetcontenttype(DAVFile file,
148: XMLElement elem) {
149: file.setContentType(getChildAsString(elem));
150: }
151:
152: private static void handleGetcontentlength(DAVFile file,
153: XMLElement elem) {
154: String lengthStr = getChildAsString(elem);
155: if (lengthStr != null) {
156: try {
157: file.setContentLength(Long.decode(lengthStr));
158: } catch (NumberFormatException nafta) {
159: Debug.trace(PropertyHandler.class, Debug.DP2, nafta);
160: }
161: }
162: }
163:
164: private static void handleLockdiscovery(DAVFile file,
165: XMLElement elem) {
166: for (ListIterator lit = elem.children(); lit.hasNext();) {
167: Object o = lit.next();
168: if (!(o instanceof XMLElement))
169: continue;
170: XMLElement activelock = (XMLElement) o;
171: if (!activelock.getElementName().equals(
172: DAVConstants.ACTIVELOCK_ELEM)) {
173: Debug.trace(PropertyHandler.class, Debug.DP3,
174: "weird child encountered in activelock: "
175: + activelock);
176: continue;
177: }
178: LockType lt = null;
179: LockScope ls = null;
180: Depth depth = null;
181: String owner = null;
182: Timeout timeout = null;
183: String lockToken = null;
184:
185: for (ListIterator lit2 = activelock.children(); lit2
186: .hasNext();) {
187: Object o2 = lit2.next();
188: if (!(o2 instanceof XMLElement))
189: continue;
190: XMLElement subElem = (XMLElement) o2;
191: String name = subElem.getElementName();
192: if (name.equals(DAVConstants.LOCKTYPE_ELEM)) {
193: XMLElement typeElem = subElem.getChildElement(0);
194: if (typeElem != null) {
195: String typeStr = typeElem.getElementName();
196: if (DAVConstants.WRITE_ELEM.equals(typeStr)) {
197: lt = LockType.WRITE;
198: }
199: //the only recognized value at this time, others will be ignored
200: }
201: } else if (name.equals(DAVConstants.LOCKSCOPE_ELEM)) {
202: XMLElement scopeElem = subElem.getChildElement(0);
203: if (scopeElem != null) {
204: String scopeStr = scopeElem.getElementName();
205: if (DAVConstants.SHARED_ELEM.equals(scopeStr)) {
206: ls = LockScope.SHARED;
207: } else if (DAVConstants.EXCLUSIVE_ELEM
208: .equals(scopeStr)) {
209: ls = LockScope.EXCLUSIVE;
210: }
211: }
212: } else if (name.equals(DAVConstants.DEPTH_ELEM)) {
213: String depthStr = getChildAsString(subElem);
214: depth = Depth.getDepth(depthStr);
215: } else if (name.equals(DAVConstants.OWNER_ELEM)) {
216: XMLElement hrefElem = subElem
217: .getChild(DAVConstants.HREF_ELEM);
218: /**
219: * mod_dav puts a href element inside the owner tag. RFC2518
220: * does not require this (the DTD allows any element inside an
221: * owner tag), but all its examples include it.
222: */
223: owner = (hrefElem == null) ? getChildAsString(subElem)
224: : getChildAsString(hrefElem);
225: } else if (name.equals(DAVConstants.TIMEOUT_ELEM)) {
226: timeout = Timeout
227: .getTimeout(getChildAsString(subElem));
228: } else if (name.equals(DAVConstants.LOCKTOKEN_ELEM)) {
229: XMLElement hrefElem = subElem
230: .getChild(DAVConstants.HREF_ELEM);
231: if (hrefElem != null)
232: lockToken = getChildAsString(hrefElem);
233: }
234: }
235: Lock daLock = new Lock(ls, lt, depth, timeout, lockToken,
236: owner);
237: file.addLock(daLock);
238: }
239: }
240:
241: private static void handleSource(DAVFile file, XMLElement elem) {
242: for (ListIterator lit = elem.children(); lit.hasNext();) {
243: Object subObj = lit.next();
244: if (!(subObj instanceof XMLElement))
245: continue;
246: XMLElement linkElem = (XMLElement) subObj;
247: if (!linkElem.getElementName().equals(
248: DAVConstants.LINK_ELEM)) {
249: Debug
250: .trace(PropertyHandler.class, Debug.DP3,
251: "unrecognized child of source tag: "
252: + linkElem);
253: continue;
254: }
255: XMLElement srcElem = linkElem
256: .getChild(DAVConstants.SRC_ELEM);
257: XMLElement dstElem = linkElem
258: .getChild(DAVConstants.DST_ELEM);
259: if (srcElem != null && dstElem != null) {
260: Link daLink = new Link(getChildAsString(srcElem),
261: getChildAsString(dstElem));
262: file.addLink(daLink);
263: }
264: }
265: }
266:
267: private static String getChildAsString(XMLElement elem) {
268: Object o = elem.getChild(0);
269: return (o == null) ? null
270: : ((o instanceof XMLCData) ? ((XMLCData) o).getData()
271: : o.toString());
272: }
273: }
274:
275: /* $Log: PropertyHandler.java,v $
276: /* Revision 1.9 2001/07/17 03:01:22 smulloni
277: /* Handle CDATA in properties in a more appropriate manner (thanks to Jim
278: /* Whitehead for nudging me to do this).
279: /*
280: /* Revision 1.8 2001/06/13 01:09:03 smulloni
281: /* Some improvements to the network customizer (which is still buggy).
282: /* Also improvements for using the doAllprop switch, and for the layout of
283: /* the PropertiesDialog.
284: /*
285: /* Revision 1.7 2000/12/19 22:06:15 smulloni
286: /* adding documentation.
287: /*
288: /* Revision 1.6 2000/12/03 23:53:25 smulloni
289: /* added license and copyright preamble to java files.
290: /*
291: /* Revision 1.5 2000/11/09 23:34:53 smullyan
292: /* log added to every Java file, with the help of python. Lock stealing
293: /* implemented, and treatment of locks made more robust.
294: /* */
|