PageRenderTime 38ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 0ms

/webdavclient/clientlib/src/java/org/apache/webdav/lib/methods/PropFindMethod.java

https://github.com/markkimsal/pengyou-clients
Java | 422 lines | 187 code | 79 blank | 156 comment | 33 complexity | 3fe321a746a2bbd1988c16d4a00b16ae MD5 | raw file
  1. /*
  2. * $Header$
  3. * $Revision: 207563 $
  4. * $Date: 2004-08-02 23:45:51 +0800 (Mon, 02 Aug 2004) $
  5. *
  6. * ====================================================================
  7. *
  8. * Copyright 1999-2002 The Apache Software Foundation
  9. *
  10. * Licensed under the Apache License, Version 2.0 (the "License");
  11. * you may not use this file except in compliance with the License.
  12. * You may obtain a copy of the License at
  13. *
  14. * http://www.apache.org/licenses/LICENSE-2.0
  15. *
  16. * Unless required by applicable law or agreed to in writing, software
  17. * distributed under the License is distributed on an "AS IS" BASIS,
  18. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  19. * See the License for the specific language governing permissions and
  20. * limitations under the License.
  21. *
  22. */
  23. package org.apache.webdav.lib.methods;
  24. import java.io.IOException;
  25. import java.util.Enumeration;
  26. import java.util.Vector;
  27. import org.apache.commons.httpclient.HttpConnection;
  28. import org.apache.commons.httpclient.HttpException;
  29. import org.apache.commons.httpclient.HttpState;
  30. import org.apache.webdav.lib.PropertyName;
  31. import org.apache.webdav.lib.util.XMLPrinter;
  32. /**
  33. * This class implements the WebDAV PROPFIND Method.
  34. *
  35. * <P> The PROPFIND method retrieves properties defined on the resource
  36. * identified by the Request-URI, if the resource does not have any internal
  37. * members, or on the resource identified by the Request-URI and potentially
  38. * its member resources, if the resource is a collection that has internal
  39. * member URIs.
  40. *
  41. * <P> A typical request looks like this:
  42. *
  43. * <PRE>
  44. *
  45. * PROPFIND /file HTTP/1.1
  46. * Host: www.foo.bar
  47. * Content-type: text/xml; charset="utf-8"
  48. * Content-Length: xxxx
  49. *
  50. * &lt;?xml version="1.0" encoding="utf-8" ?&gt;
  51. * &lt;D:propfind xmlns:D="DAV:"&gt;
  52. * &lt;D:prop xmlns:R="http://www.foo.bar/boxschema/"&gt;
  53. * &lt;R:bigbox/&gt;
  54. * &lt;R:author/&gt;
  55. * &lt;R:DingALing/&gt;
  56. * &lt;R:Random/&gt;
  57. * &lt;/D:prop&gt;
  58. * &lt;/D:propfind&gt;
  59. * </PRE>
  60. *
  61. */
  62. public class PropFindMethod extends XMLResponseMethodBase
  63. implements DepthSupport {
  64. // -------------------------------------------------------------- Constants
  65. /**
  66. * Request of named properties.
  67. */
  68. public static final int BY_NAME = 0;
  69. /**
  70. * Request of all properties name and value.
  71. */
  72. public static final int ALL = 1;
  73. /**
  74. * Request of all properties name.
  75. */
  76. public static final int NAMES = 2;
  77. // ----------------------------------------------------------- Constructors
  78. /**
  79. * Method constructor.
  80. */
  81. public PropFindMethod() {
  82. }
  83. /**
  84. * Method constructor.
  85. */
  86. public PropFindMethod(String path) {
  87. super(path);
  88. }
  89. /**
  90. * Method constructor.
  91. */
  92. public PropFindMethod(String path, int depth) {
  93. this(path);
  94. setDepth(depth);
  95. }
  96. /**
  97. * Method constructor.
  98. */
  99. public PropFindMethod(String path, int depth, int type) {
  100. this(path);
  101. setDepth(depth);
  102. setType(type);
  103. }
  104. /**
  105. * Method constructor.
  106. */
  107. public PropFindMethod(String path, Enumeration propertyNames) {
  108. this(path);
  109. setDepth(1);
  110. setPropertyNames(propertyNames);
  111. setType(BY_NAME);
  112. }
  113. /**
  114. * Method constructor.
  115. */
  116. public PropFindMethod(String path, int depth, Enumeration propertyNames) {
  117. this(path);
  118. setDepth(depth);
  119. setPropertyNames(propertyNames);
  120. setType(BY_NAME);
  121. }
  122. // ----------------------------------------------------- Instance Variables
  123. /**
  124. * Type of the Propfind.
  125. */
  126. protected int type = ALL;
  127. /**
  128. * Property name list.
  129. */
  130. protected PropertyName[] propertyNames;
  131. /**
  132. * Depth.
  133. */
  134. protected int depth = DEPTH_INFINITY;
  135. /**
  136. * The namespace abbreviation that prefixes DAV tags
  137. */
  138. protected String prefix = null;
  139. // ------------------------------------------------------------- Properties
  140. /**
  141. * Set a request header value, redirecting the special case of the "Depth" header
  142. * to invoke {@link #setDepth} instead.
  143. *
  144. * @param headerName Header name
  145. * @param headerValue Header value
  146. */
  147. public void setRequestHeader(String headerName, String headerValue) {
  148. if (headerName.equalsIgnoreCase("Depth")){
  149. int depth = -1;
  150. if (headerValue.equals("0")){
  151. depth = DEPTH_0;
  152. }
  153. else if (headerValue.equals("1")){
  154. depth = DEPTH_1;
  155. }
  156. else if (headerValue.equalsIgnoreCase("infinity")){
  157. depth = DEPTH_INFINITY;
  158. }
  159. setDepth(depth);
  160. }
  161. else{
  162. super.setRequestHeader(headerName, headerValue);
  163. }
  164. }
  165. /**
  166. * Type setter.
  167. *
  168. * @param type New type value
  169. */
  170. public void setType(int type) {
  171. checkNotUsed();
  172. this.type = type;
  173. }
  174. /**
  175. * Type getter.
  176. *
  177. * @return int type value
  178. */
  179. public int getType() {
  180. return type;
  181. }
  182. /**
  183. * Depth setter.
  184. *
  185. * @param depth New depth value
  186. */
  187. public void setDepth(int depth) {
  188. checkNotUsed();
  189. this.depth = depth;
  190. }
  191. /**
  192. * Depth getter.
  193. *
  194. * @return int depth value
  195. */
  196. public int getDepth() {
  197. return depth;
  198. }
  199. /**
  200. * Property names setter.
  201. * The enumeration may contain strings with or without a namespace prefix
  202. * but the preferred way is to provide PropertyName objects.
  203. *
  204. * @param propertyNames List of the property names
  205. */
  206. public void setPropertyNames(Enumeration propertyNames) {
  207. checkNotUsed();
  208. Vector list = new Vector();
  209. while (propertyNames.hasMoreElements()) {
  210. Object item = propertyNames.nextElement();
  211. if (item instanceof PropertyName)
  212. {
  213. list.add(item);
  214. }
  215. else if (item instanceof String)
  216. {
  217. String propertyName = (String) item;
  218. int length = propertyName.length();
  219. boolean found = false;
  220. int i = 1;
  221. while (!found && (i <= length)) {
  222. char chr = propertyName.charAt(length - i);
  223. if (!Character.isUnicodeIdentifierPart(chr)
  224. && chr!='-' && chr!='_' && chr!='.') {
  225. found = true;
  226. } else {
  227. i++;
  228. }
  229. }
  230. if ((i == 1) || (i >= length)) {
  231. list.add(new PropertyName("DAV:",propertyName));
  232. } else {
  233. String namespace = propertyName.substring(0, length + 1 - i);
  234. String localName = propertyName.substring(length + 1 - i);
  235. list.add(new PropertyName(namespace,localName));
  236. }
  237. }
  238. else
  239. {
  240. // unknown type
  241. // ignore
  242. }
  243. }
  244. this.propertyNames = (PropertyName[])list.toArray(new PropertyName[list.size()]);
  245. }
  246. // --------------------------------------------------- WebdavMethod Methods
  247. public void recycle() {
  248. super.recycle();
  249. prefix = null;
  250. }
  251. public String getName() {
  252. return "PROPFIND";
  253. }
  254. /**
  255. * Generate additional headers needed by the request.
  256. *
  257. * @param state State token
  258. * @param conn The connection being used to make the request.
  259. */
  260. public void addRequestHeaders(HttpState state, HttpConnection conn)
  261. throws IOException, HttpException {
  262. // set the default utf-8 encoding, if not already present
  263. if (getRequestHeader("Content-Type") == null ) super.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
  264. super.addRequestHeaders(state, conn);
  265. switch (depth) {
  266. case DEPTH_0:
  267. super.setRequestHeader("Depth", "0");
  268. break;
  269. case DEPTH_1:
  270. super.setRequestHeader("Depth", "1");
  271. break;
  272. case DEPTH_INFINITY:
  273. super.setRequestHeader("Depth", "infinity");
  274. break;
  275. }
  276. }
  277. /**
  278. * DAV requests that contain a body must override this function to
  279. * generate that body.
  280. *
  281. * <p>The default behavior simply returns an empty body.</p>
  282. */
  283. protected String generateRequestBody() {
  284. XMLPrinter printer = new XMLPrinter();
  285. printer.writeXMLHeader();
  286. printer.writeElement("D", "DAV:", "propfind",
  287. XMLPrinter.OPENING);
  288. switch (type) {
  289. case ALL:
  290. printer.writeElement("D", "allprop", XMLPrinter.NO_CONTENT);
  291. break;
  292. case NAMES:
  293. printer.writeElement("D", "propname", XMLPrinter.NO_CONTENT);
  294. break;
  295. case BY_NAME:
  296. printer.writeElement("D", "prop", XMLPrinter.OPENING);
  297. for (int i=0 ; i<propertyNames.length ; i++)
  298. {
  299. String namespace = propertyNames[i].getNamespaceURI();
  300. String localname = propertyNames[i].getLocalName();
  301. if ("DAV:".equals(namespace)) {
  302. printer.writeElement("D", localname, XMLPrinter.NO_CONTENT);
  303. } else {
  304. if (namespace.length() > 0) {
  305. printer.writeElement("ZZ", namespace, localname,
  306. XMLPrinter.NO_CONTENT);
  307. } else {
  308. printer.writeElement(null, null, localname,
  309. XMLPrinter.NO_CONTENT);
  310. }
  311. }
  312. }
  313. printer.writeElement("D", "prop", XMLPrinter.CLOSING);
  314. break;
  315. }
  316. printer.writeElement("D", "propfind", XMLPrinter.CLOSING);
  317. return printer.toString();
  318. }
  319. /**
  320. * This method returns an enumeration of URL paths. If the PropFindMethod
  321. * was sent to the URL of a collection, then there will be multiple URLs.
  322. * The URLs are picked out of the <code>&lt;D:href&gt;</code> elements
  323. * of the response.
  324. *
  325. * @return an enumeration of URL paths as Strings
  326. */
  327. public Enumeration getAllResponseURLs() {
  328. checkUsed();
  329. return getResponseURLs().elements();
  330. }
  331. /**
  332. * Returns an enumeration of <code>Property</code> objects.
  333. */
  334. public Enumeration getResponseProperties(String urlPath) {
  335. checkUsed();
  336. Response response = (Response) getResponseHashtable().get(urlPath);
  337. if (response != null) {
  338. return response.getProperties();
  339. } else {
  340. return (new Vector()).elements();
  341. }
  342. }
  343. }