Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/components/XUpdateCollectionViewer.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/components/XUpdateCollectionViewer.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/components/XUpdateCollectionViewer.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/components/XUpdateCollectionViewer.java Thu May 24 18:43:39 2007
@@ -34,134 +34,131 @@
import org.apache.xindice.webadmin.viewer.*;
import org.apache.xindice.webadmin.viewer.HtmlViewerComponent;
import org.apache.xindice.xml.NamespaceMap;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* Xindice Html Viewer for collection xupdate searches.
*
- * @avalon.component
- * @avalon.service type=HtmlCollectionViewer
- * @x-avalon.info name=xupdate
- * @x-avalon.lifestyle type=singleton
- *
* @author <a href="mailto:[email protected]">Jan Metzner</a>
* @version $Id$
*/
-public class XUpdateCollectionViewer
- extends HtmlViewerComponent
- implements HtmlCollectionViewer {
-
- public void execute(HttpServletRequest req, HttpServletResponse res,
- Collection col)
- throws ServletException, IOException {
-
- String path = col.getCanonicalName();
- String title = "XUpdate for "+path;
-
- ServletOutputStream output = startViewer(title, path, res);
-
- String xupdate = req.getParameter("xupdate");
- if(xupdate == null) {
- xupdate = "";
- } else if(xupdate.length() > 0) {
- // do xupdate
- try {
- NodeSet result = col.queryCollection("XUpdate", xupdate,
- new NamespaceMap());
- printResult(result, output);
- } catch (DBException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- printStartTable(title, output);
- printStartSingleTableBox(output);
- output.print(XUPDATE_FORM_START);
- output.print(xupdate);
- output.print(XUPDATE_FORM_END);
- printEndSingleTableBox(output);
- printEndTable(output);
-
- output.println("<br />");
- printStartTable("Examples", output);
- printStartSingleTableBox(output);
- output.println(XUPDATE_EXAMPLES);
- printEndSingleTableBox(output);
- printEndTable(output);
-
- finishViewer(output);
+public class XUpdateCollectionViewer extends HtmlViewerComponent implements HtmlCollectionViewer {
+
+ private static final Log log = LogFactory.getLog(XUpdateCollectionViewer.class);
+
+ public void execute(HttpServletRequest req, HttpServletResponse res, Collection col)
+ throws ServletException, IOException {
+
+ String path = col.getCanonicalName();
+ String title = "XUpdate for " + path;
+
+ ServletOutputStream output = startViewer(title, path, res);
+
+ String xupdate = req.getParameter("xupdate");
+ if(xupdate == null) {
+ xupdate = "";
+ } else if(xupdate.length() > 0) {
+ // do xupdate
+ try {
+ NodeSet result = col.queryCollection("XUpdate", xupdate, new NamespaceMap());
+ printResult(result, output);
+ } catch (DBException e) {
+ log.error(e);
+ }
+ }
+
+ printStartTable(title, output);
+ printStartSingleTableBox(output);
+ output.print(XUPDATE_FORM_START);
+ output.print(xupdate);
+ output.print(XUPDATE_FORM_END);
+ printEndSingleTableBox(output);
+ printEndTable(output);
+
+ output.println("<br />");
+ printStartTable("Examples", output);
+ printStartSingleTableBox(output);
+ output.println(XUPDATE_EXAMPLES);
+ printEndSingleTableBox(output);
+ printEndTable(output);
+
+ finishViewer(output);
+ }
+
+ private void printResult(NodeSet result, ServletOutputStream output) throws IOException {
+ if(result != null && result.hasMoreNodes()) {
+ Object node = result.getNextNode();
+ String modified;
+ if(node instanceof Node) {
+ modified = ((Node)node).getFirstChild().getNodeValue();
+ } else {
+ // TODO print something, that makes sense
+ modified = "Sorry something went wrong!";
+ }
+ printStartTable("XUpdate Result", output);
+ printStartSingleTableBox(output);
+ output.println("Modified <b>"+modified+"</b> Nodes!");
+ printEndSingleTableBox(output);
+ printEndTable(output);
+ output.println("<br />");
+ }
}
-
- protected void printResult(NodeSet result, ServletOutputStream output)
- throws IOException {
- if(result != null && result.hasMoreNodes()) {
- Object node = result.getNextNode();
- String modified;
- if(node instanceof Node) {
- modified = ((Node)node).getFirstChild().getNodeValue();
- } else {
- // TODO print something, that makes sense
- modified = "Sorry something went wrong!";
- }
- printStartTable("XUpdate Result", output);
- printStartSingleTableBox(output);
- output.println("Modified <b>"+modified+"</b> Nodes!");
- printEndSingleTableBox(output);
- printEndTable(output);
- output.println("<br />");
- }
+
+ private static final String XUPDATE_FORM_START =
+ "<form action=\"\" method=\"post\"> \n" +
+ "<table class=\"upload-form\"> \n" +
+ "<tr><td> \n" +
+ "<textarea name=\"xupdate\" cols=\"80\" rows=\"15\">\n" ;
+
+ private static final String XUPDATE_FORM_END =
+ "</textarea> \n" +
+ "</td></tr><tr><td> \n" +
+ "<input type=\"submit\" name=\"submit\" value=\"xupdate\" /> \n" +
+ "</td></tr></table></form> \n";
+
+ private static final String XUPDATE_EXAMPLES =
+ "<b>Basic XUpdate Insert Command</b>" +
+ "<pre><xupdate:modifications version=\"1.0\" \n" +
+ " xmlns:xupdate=\"http://www.xmldb.org/xupdate\"> \n\n" +
+ " <xupdate:insert-after select=\"/addresses/address[1]\" > \n" +
+ " <xupdate:element name=\"address\"> \n" +
+ " <xupdate:attribute name=\"id\">2</xupdate:attribute> \n" +
+ " <fullname>John Smith</fullname> \n" +
+ " <born day='2' month='12' year='1974'/> \n" +
+ " <country>Germany</country> \n" +
+ " </xupdate:element> \n\n" +
+ " </xupdate:insert-after> \n" +
+ "</xupdate:modifications> \n" +
+ " </pre>" +
+ "<b>XUpdate Commands</b><ul>" +
+ "<li><code>xupdate:insert-before</code> " +
+ " - Inserts a new node in document order before the selected node.</li> \n" +
+ "<li><code>xupdate:insert-after</code>" +
+ " - Inserts a new node in document order after the selected node.</li> \n" +
+ "<li><code>xupdate:update</code>" +
+ " - Replaces all child nodes of the selected node with the specified nodes.</li> \n" +
+ "<li><code>xupdate:append</code>" +
+ " - Appends the specified node to the content of the selected node.</li> \n" +
+ "<li><code>xupdate:remove</code>" +
+ " - Remove the selected node</li> \n" +
+ "<li><code>xupdate:rename</code>" +
+ " - Renames the selected node</li> \n" +
+ "<li><code>xupdate:variable</code>" +
+ " - Defines a variable containing a node list that can be reused in later operations.</li> \n" +
+ "</ul><b>XUpdate Node Construction</b><ul>" +
+ "<li><code>xupdate:element</code>" +
+ " - Creates a new element in the document.</li> \n" +
+ "<li><code>xupdate:attribute</code>" +
+ " - Creates a new attribute node associated with an <code>xupdate:element</code>.</li> \n" +
+ "<li><code>xupdate:text</code>" +
+ " - Creates a text content node in the document.</li> \n" +
+ "<li><code>xupdate:processing-instruction</code>" +
+ " - Creates a processing instruction node in the document.</li> \n" +
+ "<li><code>xupdate:comment</code>" +
+ " - Creates a new comment node in the document.</li> </ul>\n";
+
+ protected String getName() {
+ return "xupdate";
}
-
- protected static final String XUPDATE_FORM_START =
- "<form action=\"\" method=\"post\"> \n" +
- "<table class=\"upload-form\"> \n" +
- "<tr><td> \n" +
- "<textarea name=\"xupdate\" cols=\"80\" rows=\"15\">\n" ;
-
- protected static final String XUPDATE_FORM_END =
- "</textarea> \n" +
- "</td></tr><tr><td> \n" +
- "<input type=\"submit\" name=\"submit\" value=\"xupdate\" /> \n" +
- "</td></tr></table></form> \n";
-
- protected static final String XUPDATE_EXAMPLES =
- "<b>Basic XUpdate Insert Command</b>" +
- "<pre><xupdate:modifications version=\"1.0\" \n" +
- " xmlns:xupdate=\"http://www.xmldb.org/xupdate\"> \n\n" +
- " <xupdate:insert-after select=\"/addresses/address[1]\" > \n" +
- " <xupdate:element name=\"address\"> \n" +
- " <xupdate:attribute name=\"id\">2</xupdate:attribute> \n" +
- " <fullname>John Smith</fullname> \n" +
- " <born day='2' month='12' year='1974'/> \n" +
- " <country>Germany</country> \n" +
- " </xupdate:element> \n\n" +
- " </xupdate:insert-after> \n" +
- "</xupdate:modifications> \n" +
- " </pre>" +
- "<b>XUpdate Commands</b><ul>" +
- "<li><code>xupdate:insert-before</code> " +
- " - Inserts a new node in document order before the selected node.</li> \n" +
- "<li><code>xupdate:insert-after</code>" +
- " - Inserts a new node in document order after the selected node.</li> \n" +
- "<li><code>xupdate:update</code>" +
- " - Replaces all child nodes of the selected node with the specified nodes.</li> \n" +
- "<li><code>xupdate:append</code>" +
- " - Appends the specified node to the content of the selected node.</li> \n" +
- "<li><code>xupdate:remove</code>" +
- " - Remove the selected node</li> \n" +
- "<li><code>xupdate:rename</code>" +
- " - Renames the selected node</li> \n" +
- "<li><code>xupdate:variable</code>" +
- " - Defines a variable containing a node list that can be reused in later operations.</li> \n" +
- "</ul><b>XUpdate Node Construction</b><ul>" +
- "<li><code>xupdate:element</code>" +
- " - Creates a new element in the document.</li> \n" +
- "<li><code>xupdate:attribute</code>" +
- " - Creates a new attribute node associated with an <code>xupdate:element</code>.</li> \n" +
- "<li><code>xupdate:text</code>" +
- " - Creates a text content node in the document.</li> \n" +
- "<li><code>xupdate:processing-instruction</code>" +
- " - Creates a processing instruction node in the document.</li> \n" +
- "<li><code>xupdate:comment</code>" +
- " - Creates a new comment node in the document.</li> </ul>\n";
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/viewer/components/XUpdateCollectionViewer.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Added: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVRequest.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVRequest.java?view=auto&rev=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVRequest.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVRequest.java Thu May 24 18:43:39 2007
@@ -0,0 +1,263 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.xindice.webadmin.webdav;
+
+import org.w3c.dom.Document;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.xml.sax.InputSource;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.ServletInputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+/**
+ * This is a wrapper class that provides additional DAV-specific functionality
+ */
+public class DAVRequest {
+ public static final int DEPTH_0 = 0;
+ public static final int DEPTH_1 = 1;
+ public static final int DEPTH_INFINITY = -1;
+
+ protected Document requestDoc;
+ private boolean documentInit = false;
+ protected String location;
+ private HttpServletRequest httpRequest;
+
+ private static final Log log = LogFactory.getLog(DAVRequest.class);
+
+ /**
+ * Creates new instance of DAVRequest based on incoming HTTP request.
+ *
+ * @param request HttpServletRequest
+ */
+ public DAVRequest(HttpServletRequest request) {
+ httpRequest = request;
+ location = getLocationPath();
+ }
+
+ /**
+ * Retreives request document if incoming request has any.
+ *
+ * @return Parsed request document if request body has one or null if
+ * request body was empty or does not have a valid XML.
+ * @throws IOException ServletInputStream IOException
+ */
+ public Document getRequestDoc() throws IOException {
+ if (!documentInit) {
+ documentInit = true;
+ requestDoc = parseRequestContent();
+ }
+
+ return requestDoc;
+ }
+
+ /**
+ * Wrapper method, gets servlet path info.
+ * @return Called servlet path.
+ */
+ public String getPath() {
+ return httpRequest.getPathInfo();
+ }
+
+ /**
+ * Wrapper method, gets HTTP request header.
+ * @param name Header name
+ * @return Header value
+ */
+ public String getHeader(String name) {
+ return httpRequest.getHeader(name);
+ }
+
+ /**
+ * Retrieves Overwrite header value from HTTP request. Possible values
+ * are "T" or "F" (true of false). By default value is "T".
+ *
+ * @return False if HTTP request has a header "Overwrite: F", true othewise.
+ */
+ public boolean getOverwrite() {
+ // Parsing overwrite header
+ boolean overwrite = true;
+ String overwriteHeader = httpRequest.getHeader("Overwrite");
+ if (overwriteHeader != null) {
+ overwrite = !overwriteHeader.equalsIgnoreCase("F");
+ }
+ return overwrite;
+ }
+
+ /**
+ * Retrieves Depth header value from HTTP request. Possible values
+ * are "0", "1", and "infinity". By default, value is "infinity".
+ *
+ * @return 0, 1, -1 for "0", "1", "infinity" header values respectively.
+ */
+ public int getDepth() {
+ String value = httpRequest.getHeader("Depth");
+ int depth = -1;
+ if ("0".equals(value)) {
+ depth = 0;
+ } else if ("1".equals(value)) {
+ depth = 1;
+ } else if (value == null || "infinity".equals(value)) {
+ depth = -1;
+ }
+
+ return depth;
+ }
+
+ /**
+ * Retrieves Destination header value from HTTP request. Its value is URL,
+ * it can be absolute or relative. This method returns only local path,
+ * deleting protocol, server name and context path.
+ *
+ * @return Local part of the destination path
+ */
+ public String getDestinationPath() {
+
+ String destinationPath = httpRequest.getHeader("Destination");
+ if (destinationPath == null) {
+ return null;
+ }
+
+ int protocolIndex = destinationPath.indexOf("://");
+ if (protocolIndex >= 0) {
+ // if the Destination URL contains the protocol, we can safely
+ // trim everything upto the first "/" character after "://"
+ int firstSeparator = destinationPath.indexOf("/", protocolIndex + 4);
+ if (firstSeparator < 0) {
+ destinationPath = "/";
+ } else {
+ destinationPath = destinationPath.substring(firstSeparator);
+ }
+ } else {
+ String hostName = httpRequest.getServerName();
+ if ((hostName != null) && (destinationPath.startsWith(hostName))) {
+ destinationPath = destinationPath.substring(hostName.length());
+ }
+
+ int portIndex = destinationPath.indexOf(":");
+ if (portIndex >= 0) {
+ destinationPath = destinationPath.substring(portIndex);
+ }
+
+ if (destinationPath.startsWith(":")) {
+ int firstSeparator = destinationPath.indexOf("/");
+ if (firstSeparator < 0) {
+ destinationPath = "/";
+ } else {
+ destinationPath = destinationPath.substring(firstSeparator);
+ }
+ }
+ }
+
+ String contextPath = httpRequest.getContextPath();
+ if ((contextPath != null) && (destinationPath.startsWith(contextPath))) {
+ destinationPath = destinationPath.substring(contextPath.length());
+ }
+
+ String pathInfo = httpRequest.getPathInfo();
+ if (pathInfo != null) {
+ String servletPath = httpRequest.getServletPath();
+ if ((servletPath != null) && (destinationPath.startsWith(servletPath))) {
+ destinationPath = destinationPath.substring(servletPath.length());
+ }
+ }
+
+ try {
+ destinationPath = URLDecoder.decode(destinationPath, "utf-8");
+ } catch (UnsupportedEncodingException e) {
+ // won't happen
+ log.error(e);
+ destinationPath = null;
+ }
+
+ return destinationPath;
+ }
+
+ /**
+ * Wrapper method, gets servlet context path.
+ * @return Called servlet context path.
+ */
+ public String getContextPath() {
+ return location;
+ }
+
+ private Document parseRequestContent() throws IOException {
+ if (httpRequest.getContentLength() != 0) {
+ DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
+ dbf.setNamespaceAware(true);
+ try {
+ DocumentBuilder documentBuilder = dbf.newDocumentBuilder();
+ return documentBuilder.parse(new InputSource(httpRequest.getInputStream()));
+ } catch (IOException e) {
+ throw e;
+ } catch (Exception e) {
+ if (log.isWarnEnabled()) {
+ log.warn("Cannot parse request document", e);
+ }
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @return the path to calling servlet (not null and no ending '/')
+ */
+ private String getLocationPath() {
+ StringBuffer path = new StringBuffer();
+ path.append(httpRequest.getContextPath());
+ path.append(httpRequest.getServletPath());
+ if (path.length() > 0 && path.charAt(path.length() - 1) == '/') {
+ path.deleteCharAt(path.length() - 1);
+ }
+
+ return path.toString();
+ }
+
+ /**
+ * Wrapper method, gets servlet input stream.
+ * @return Servlet input stream.
+ */
+ public ServletInputStream getInputStream() throws IOException {
+ return httpRequest.getInputStream();
+ }
+
+ /**
+ * Wrapper method, gets HTTP request parameter.
+ *
+ * @param name Parameter name
+ * @return Parameter value
+ */
+ public String getParameter(String name) {
+ return httpRequest.getParameter(name);
+ }
+
+ /**
+ * Wrapper method, gets request protocol.
+ *
+ * @return Request protocol and version.
+ */
+ public String getProtocol() {
+ return httpRequest.getProtocol();
+ }
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVRequest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVRequest.java
------------------------------------------------------------------------------
svn:keywords = Id Revision Author Date
Added: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVResponse.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVResponse.java?view=auto&rev=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVResponse.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVResponse.java Thu May 24 18:43:39 2007
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.xindice.webadmin.webdav;
+
+import org.apache.xindice.webadmin.PartialResponse;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.ServletOutputStream;
+import java.io.IOException;
+
+/**
+ * This is a wrapper class that provides additional DAV-specific functionality
+ */
+public class DAVResponse {
+ public static final String DAV_NS = "DAV:";
+
+ protected final ServletOutputStream out;
+
+ private boolean isMultistatus;
+ private final HttpServletResponse response;
+ private String protocol;
+
+ private static final Log log = LogFactory.getLog(DAVResponse.class);
+
+ /**
+ * Creates new instance of DAVRequest.
+ *
+ * @param response HttpServletResponse
+ */
+ public DAVResponse(HttpServletResponse response) throws IOException {
+ this.response = response;
+ this.out = response.getOutputStream();
+ }
+
+ /**
+ * For multi-status responses, send a partial response. This method resets
+ * HTTP response status to 207 (Multi-Status).
+ *
+ * @param res partial response information
+ * @throws IOException Servlet IOException
+ */
+ public void sendMultiStatusResponse(PartialResponse res) throws IOException {
+ if (!isMultistatus) {
+ if (log.isDebugEnabled()) {
+ log.debug("Sending response for HREF " + res.getHref());
+ }
+ response.setStatus(WebdavStatus.SC_MULTI_STATUS);
+ out.println("<?xml version='1.0' encoding='utf-8' ?>");
+ out.println("<multistatus xmlns='DAV:'>");
+ isMultistatus = true;
+ }
+
+ out.println(res.toString());
+ }
+
+ /**
+ * For multi-status responses, close the response document. Method does not
+ * affect not multi-status responses.
+ * HTTP response status to 207 (Multi-Status).
+ *
+ * @throws IOException Servlet IOException
+ */
+ public void closeMultistatusResponse() throws IOException {
+ if (isMultistatus) {
+ out.println("</multistatus>");
+ }
+ }
+
+ /**
+ * Wrapper method, sets HTTP response status.
+ * @param status
+ */
+ public void setStatus(int status) {
+ response.setStatus(status);
+ }
+
+ /**
+ * Wrapper method, adds header to HTTP response.
+ * @param header Header name
+ * @param value Header value
+ */
+ public void addHeader(String header, String value) {
+ response.addHeader(header, value);
+ }
+
+ /**
+ * Wrapper method, adds date header to HTTP response.
+ * @param header Header name
+ * @param date Header value
+ */
+ public void addDateHeader(String header, long date) {
+ response.addDateHeader(header, date);
+ }
+
+ /**
+ * Wrapper method, sets HTTP response content type
+ * @param mimeType
+ */
+ public void setContentType(String mimeType) {
+ response.setContentType(mimeType);
+ }
+
+ /**
+ * Wrapper method, sets HTTP response content length
+ * @param contentLength
+ */
+ public void setContentLength(int contentLength) {
+ response.setContentLength(contentLength);
+ }
+
+ /**
+ * Wrapper method, returns HTTP response output stream
+ * @return Servlet output stream
+ */
+ public ServletOutputStream getOutputStream() throws IOException {
+ return response.getOutputStream();
+ }
+
+ /**
+ * Wrapper method, sends redirect
+ * @param redirect
+ */
+ public void sendRedirect(String redirect) throws IOException {
+ response.sendRedirect(redirect);
+ }
+
+ /**
+ * Sets protocol/version string that is used for multi status responses.
+ *
+ * @param protocol Protocol name and version (e.g. HTTP/1.1)
+ */
+ public void setProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ /**
+ * Returns protocol/version.
+ * @return Protocol name and version (e.g. HTTP/1.1)
+ */
+ public String getProtocol() {
+ return protocol;
+ }
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVResponse.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/DAVResponse.java
------------------------------------------------------------------------------
svn:keywords = Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/WebdavStatus.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/WebdavStatus.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/WebdavStatus.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/WebdavStatus.java Thu May 24 18:43:39 2007
@@ -19,106 +19,75 @@
package org.apache.xindice.webadmin.webdav;
-import java.util.Hashtable;
+import java.util.Map;
+import java.util.HashMap;
import javax.servlet.http.HttpServletResponse;
-// -------------------------------------------------------- WebdavStatus Class
-
-
/**
- * Wraps the HttpServletResponse class to abstract the
- * specific protocol used. To support other protocols
- * we would only need to modify this class and the
- * WebDavRetCode classes.
+ * Wraps the HttpServletResponse class to abstract the specific protocol
+ * used. To support other protocols we would only need to modify this class.
*
* @author Marc Eaddy
* @version 1.0, 16 Nov 1997
*/
public class WebdavStatus {
-
- // ----------------------------------------------------- Instance Variables
-
-
- /**
- * This Hashtable contains the mapping of HTTP and WebDAV
- * status codes to descriptive text. This is a static
- * variable.
- */
- private static Hashtable mapStatusCodes = new Hashtable();
-
-
// ------------------------------------------------------ HTTP Status Codes
-
/**
* Status code (200) indicating the request succeeded normally.
*/
public static final int SC_OK = HttpServletResponse.SC_OK;
-
/**
* Status code (201) indicating the request succeeded and created
* a new resource on the server.
*/
public static final int SC_CREATED = HttpServletResponse.SC_CREATED;
-
/**
* Status code (202) indicating that a request was accepted for
* processing, but was not completed.
*/
public static final int SC_ACCEPTED = HttpServletResponse.SC_ACCEPTED;
-
/**
* Status code (204) indicating that the request succeeded but that
* there was no new information to return.
*/
public static final int SC_NO_CONTENT = HttpServletResponse.SC_NO_CONTENT;
-
/**
* Status code (301) indicating that the resource has permanently
* moved to a new location, and that future references should use a
* new URI with their requests.
*/
- public static final int SC_MOVED_PERMANENTLY =
- HttpServletResponse.SC_MOVED_PERMANENTLY;
-
+ public static final int SC_MOVED_PERMANENTLY = HttpServletResponse.SC_MOVED_PERMANENTLY;
/**
* Status code (302) indicating that the resource has temporarily
* moved to another location, but that future references should
* still use the original URI to access the resource.
*/
- public static final int SC_MOVED_TEMPORARILY =
- HttpServletResponse.SC_MOVED_TEMPORARILY;
-
+ public static final int SC_MOVED_TEMPORARILY = HttpServletResponse.SC_MOVED_TEMPORARILY;
/**
* Status code (304) indicating that a conditional GET operation
* found that the resource was available and not modified.
*/
- public static final int SC_NOT_MODIFIED =
- HttpServletResponse.SC_NOT_MODIFIED;
-
+ public static final int SC_NOT_MODIFIED = HttpServletResponse.SC_NOT_MODIFIED;
/**
* Status code (400) indicating the request sent by the client was
* syntactically incorrect.
*/
- public static final int SC_BAD_REQUEST =
- HttpServletResponse.SC_BAD_REQUEST;
-
+ public static final int SC_BAD_REQUEST = HttpServletResponse.SC_BAD_REQUEST;
/**
* Status code (401) indicating that the request requires HTTP
* authentication.
*/
- public static final int SC_UNAUTHORIZED =
- HttpServletResponse.SC_UNAUTHORIZED;
-
+ public static final int SC_UNAUTHORIZED = HttpServletResponse.SC_UNAUTHORIZED;
/**
* Status code (403) indicating the server understood the request
@@ -126,46 +95,36 @@
*/
public static final int SC_FORBIDDEN = HttpServletResponse.SC_FORBIDDEN;
-
/**
* Status code (404) indicating that the requested resource is not
* available.
*/
public static final int SC_NOT_FOUND = HttpServletResponse.SC_NOT_FOUND;
-
/**
* Status code (500) indicating an error inside the HTTP service
* which prevented it from fulfilling the request.
*/
- public static final int SC_INTERNAL_SERVER_ERROR =
- HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
-
+ public static final int SC_INTERNAL_SERVER_ERROR = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
/**
* Status code (501) indicating the HTTP service does not support
* the functionality needed to fulfill the request.
*/
- public static final int SC_NOT_IMPLEMENTED =
- HttpServletResponse.SC_NOT_IMPLEMENTED;
-
+ public static final int SC_NOT_IMPLEMENTED = HttpServletResponse.SC_NOT_IMPLEMENTED;
/**
* Status code (502) indicating that the HTTP server received an
* invalid response from a server it consulted when acting as a
* proxy or gateway.
*/
- public static final int SC_BAD_GATEWAY =
- HttpServletResponse.SC_BAD_GATEWAY;
-
+ public static final int SC_BAD_GATEWAY = HttpServletResponse.SC_BAD_GATEWAY;
/**
* Status code (503) indicating that the HTTP service is
* temporarily overloaded, and unable to handle the request.
*/
- public static final int SC_SERVICE_UNAVAILABLE =
- HttpServletResponse.SC_SERVICE_UNAVAILABLE;
-
+ public static final int SC_SERVICE_UNAVAILABLE = HttpServletResponse.SC_SERVICE_UNAVAILABLE;
/**
* Status code (100) indicating the client may continue with
@@ -173,39 +132,34 @@
* client that the initial part of the request has been
* received and has not yet been rejected by the server.
*/
- public static final int SC_CONTINUE = 100;
-
+ public static final int SC_CONTINUE = HttpServletResponse.SC_CONTINUE;
/**
* Status code (405) indicating the method specified is not
* allowed for the resource.
*/
- public static final int SC_METHOD_NOT_ALLOWED = 405;
-
+ public static final int SC_METHOD_NOT_ALLOWED = HttpServletResponse.SC_METHOD_NOT_ALLOWED;
/**
* Status code (409) indicating that the request could not be
* completed due to a conflict with the current state of the
* resource.
*/
- public static final int SC_CONFLICT = 409;
-
+ public static final int SC_CONFLICT = HttpServletResponse.SC_CONFLICT;
/**
* Status code (412) indicating the precondition given in one
* or more of the request-header fields evaluated to false
* when it was tested on the server.
*/
- public static final int SC_PRECONDITION_FAILED = 412;
-
+ public static final int SC_PRECONDITION_FAILED = HttpServletResponse.SC_PRECONDITION_FAILED;
/**
* Status code (413) indicating the server is refusing to
* process a request because the request entity is larger
* than the server is willing or able to process.
*/
- public static final int SC_REQUEST_TOO_LONG = 413;
-
+ public static final int SC_REQUEST_ENTITY_TOO_LARGE = HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE;
/**
* Status code (415) indicating the server is refusing to service
@@ -213,48 +167,36 @@
* not supported by the requested resource for the requested
* method.
*/
- public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
-
+ public static final int SC_UNSUPPORTED_MEDIA_TYPE = HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE;
// -------------------------------------------- Extended WebDav status code
-
/**
* Status code (207) indicating that the response requires
* providing status for multiple independent operations.
*/
public static final int SC_MULTI_STATUS = 207;
- // This one colides with HTTP 1.1
- // "207 Parital Update OK"
-
/**
- * Status code (418) indicating the entity body submitted with
+ * Status code (422) indicating the entity body submitted with
* the PATCH method was not understood by the resource.
*/
- public static final int SC_UNPROCESSABLE_ENTITY = 418;
- // This one colides with HTTP 1.1
- // "418 Reauthentication Required"
-
+ public static final int SC_UNPROCESSABLE_ENTITY = 422;
/**
- * Status code (419) indicating that the resource does not have
+ * Status code (507) indicating that the resource does not have
* sufficient space to record the state of the resource after the
* execution of this method.
*/
- public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 419;
- // This one colides with HTTP 1.1
- // "419 Proxy Reauthentication Required"
-
+ public static final int SC_INSUFFICIENT_SPACE_ON_RESOURCE = 507;
/**
- * Status code (420) indicating the method was not executed on
+ * Status code (424) indicating the method was not executed on
* a particular resource within its scope because some part of
* the method's execution failed causing the entire method to be
* aborted.
*/
- public static final int SC_METHOD_FAILURE = 420;
-
+ public static final int SC_FAILED_DEPENDENCY = 424;
/**
* Status code (423) indicating the destination resource of a
@@ -264,12 +206,13 @@
*/
public static final int SC_LOCKED = 423;
-
- // ------------------------------------------------------------ Initializer
-
-
+ /**
+ * This Hashtable contains the mapping of HTTP and WebDAV
+ * status codes to descriptive text.
+ */
+ private static Map mapStatusCodes = new HashMap();
static {
- // HTTP 1.0 tatus Code
+ // HTTP 1.1 status codes
addStatusCodeMap(SC_OK, "OK");
addStatusCodeMap(SC_CREATED, "Created");
addStatusCodeMap(SC_ACCEPTED, "Accepted");
@@ -289,32 +232,26 @@
addStatusCodeMap(SC_METHOD_NOT_ALLOWED, "Method Not Allowed");
addStatusCodeMap(SC_CONFLICT, "Conflict");
addStatusCodeMap(SC_PRECONDITION_FAILED, "Precondition Failed");
- addStatusCodeMap(SC_REQUEST_TOO_LONG, "Request Too Long");
+ addStatusCodeMap(SC_REQUEST_ENTITY_TOO_LARGE, "Request Too Long");
addStatusCodeMap(SC_UNSUPPORTED_MEDIA_TYPE, "Unsupported Media Type");
- // WebDav Status Codes
+ // WebDav status sodes
addStatusCodeMap(SC_MULTI_STATUS, "Multi-Status");
addStatusCodeMap(SC_UNPROCESSABLE_ENTITY, "Unprocessable Entity");
- addStatusCodeMap(SC_INSUFFICIENT_SPACE_ON_RESOURCE,
- "Insufficient Space On Resource");
- addStatusCodeMap(SC_METHOD_FAILURE, "Method Failure");
+ addStatusCodeMap(SC_INSUFFICIENT_SPACE_ON_RESOURCE, "Insufficient Space On Resource");
+ addStatusCodeMap(SC_FAILED_DEPENDENCY, "Failed Dependency");
addStatusCodeMap(SC_LOCKED, "Locked");
}
-
- // --------------------------------------------------------- Public Methods
-
-
/**
* Returns the HTTP status text for the HTTP or WebDav status code
- * specified by looking it up in the static mapping. This is a
- * static function.
+ * specified by looking it up in the mapping.
*
- * @param nHttpStatusCode [IN] HTTP or WebDAV status code
+ * @param statusCode HTTP or WebDAV status code
* @return A string with a short descriptive phrase for the
* HTTP status code (e.g., "OK").
*/
- public static String getStatusText(int nHttpStatusCode) {
- Integer intKey = new Integer(nHttpStatusCode);
+ public static String getStatusText(int statusCode) {
+ Integer intKey = new Integer(statusCode);
if (!mapStatusCodes.containsKey(intKey)) {
return "";
@@ -323,21 +260,15 @@
}
}
-
- // -------------------------------------------------------- Private Methods
-
-
/**
* Adds a new status code -> status text mapping. This is a static
* method because the mapping is a static variable.
*
- * @param nKey [IN] HTTP or WebDAV status code
- * @param strVal [IN] HTTP status text
+ * @param key HTTP or WebDAV status code
+ * @param strVal HTTP status text
*/
- private static void addStatusCodeMap(int nKey, String strVal) {
- mapStatusCodes.put(new Integer(nKey), strVal);
+ private static void addStatusCodeMap(int key, String strVal) {
+ mapStatusCodes.put(new Integer(key), strVal);
}
-
-
-};
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/WebdavStatus.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Copy.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Copy.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Copy.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Copy.java Thu May 24 18:43:39 2007
@@ -20,73 +20,131 @@
package org.apache.xindice.webadmin.webdav.components;
import java.io.IOException;
+import java.util.Iterator;
+import java.util.Map;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.avalon.fortress.impl.DefaultContainer;
-import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.xindice.core.Collection;
import org.apache.xindice.core.DBException;
import org.apache.xindice.webadmin.util.DAVOperations;
-import org.apache.xindice.webadmin.webdav.*;
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
import org.apache.xindice.webadmin.webdav.WebdavStatus;
+import org.apache.xindice.webadmin.PartialResponse;
+import org.apache.xindice.webadmin.Location;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
-/**
+/**
* This class implements the Copy command for WebDAV operations on
- * Xindice.
- *
- * @avalon.component
- * @avalon.service type=DAVComponent
- * @x-avalon.info name=COPY
- * @x-avalon.lifestyle type=singleton
- *
+ * Xindice. <br>
+ * <br>
+ * COPY commans instructs that the collection or resource be moved to
+ * the URI specified in the Destination header. It can overwrite
+ * existing collection/resource, and this behavior can be changed by
+ * using Overwrite flag in request header.<br>
+ * <br>
+ * COPY request for collection can have header Depth set to 0 or
+ * infinity, where infinity means that the entire subtree of child
+ * collections and resources will be copied to the new location,
+ * and 0 means only collection itself will be copied.<br>
+ * <br>
+ * Operation possible status codes include: <ul>
+ * <li>
+ * 201 (Created) - The source resource was successfully copied. The
+ * copy operation resulted in the creation of a new resource.
+ * <li>
+ * 204 (No Content) - The source resource was successfully copied to a
+ * pre-existing destination resource.
+ * <li>
+ * 403 (Forbidden) - The source and destination URIs are the same.
+ * <li>
+ * 409 (Conflict) - A resource cannot be created at the destination
+ * until one or more intermediate collections have been created.
+ * <li>
+ * 412 (Precondition Failed) - The server was unable to maintain the
+ * liveness of the properties listed in the propertybehavior XML element
+ * or the Overwrite header is "F" and the state of the destination
+ * resource is non-null.
+ * </ul>
+ *
* @author <a href="mailto:[email protected]">Jan Metzner</a>
* @author <a href="mailto:[email protected]">Gianugo Rabellino</a>
- * @version $Id$
+ * @version $Id$
*/
-public class Copy extends DefaultContainer implements DAVComponent {
+public class Copy implements DAVComponent {
+ private static final Log log = LogFactory.getLog(Copy.class);
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection col)
- throws ServletException, IOException {
-
- try {
- Collection parentCol = col.getParentCollection();
- String resourceName = col.getName();
- execute(req, res, parentCol, resourceName);
- } catch (DBException e) {
- throw new ServletException(e);
+ public void execute(DAVRequest req, DAVResponse res, Location target) throws ServletException, IOException {
+ if (target.isRoot()) {
+ res.setStatus(WebdavStatus.SC_FORBIDDEN);
+ return;
}
+
+ Collection col = target.getCollection();
+ String name = target.getName();
+
+ if (col == null) {
+ res.setStatus(WebdavStatus.SC_NOT_FOUND);
+ return;
+ }
+
+ String dest = req.getDestinationPath();
+ if (dest == null) {
+ res.setStatus(WebdavStatus.SC_BAD_REQUEST);
+ return;
+ }
+
+ if (dest.equals(req.getPath())) {
+ res.setStatus(WebdavStatus.SC_FORBIDDEN);
+ return;
+ }
+
+ if (name == null) { // copying collection
+ try {
+ boolean deep = req.getDepth() != 0;
+ Map results = DAVOperations.copy(col, dest, req.getOverwrite(), deep);
+ interpretResults(results, res, dest);
+
+ } catch (DBException e) {
+ log.error("Failed to copy collection " + col.getCanonicalName(), e);
+ throw new ServletException(e);
+ }
+
+ } else { // copying resource
+ try {
+ int status = DAVOperations.copy(col, name, dest, req.getOverwrite());
+ res.setStatus(status);
+ } catch (DBException e) {
+ log.error("Failed to copy resource " + name + " from collection " + col.getCanonicalName(), e);
+ throw new ServletException(e);
+ }
+ }
+
}
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection parentCol,
- String resourceName)
- throws ServletException, IOException {
-
- int status = WebdavStatus.SC_OK;
- try {
- DAVOperations davOps;
- Object object = m_serviceManager.lookup(DAVOperations.ROLE);
- if (object instanceof ServiceSelector) {
- davOps =
- (DAVOperations) ((ServiceSelector)object).select(
- "dav-operations");
- } else {
- davOps = (DAVOperations)object;
+ private void interpretResults(Map results, DAVResponse res, String dest) throws IOException {
+ for (Iterator i = results.keySet().iterator(); i.hasNext(); ) {
+ String url = (String) i.next();
+ int status = ((Integer) results.get(url)).intValue();
+ if (url.equals(dest)) {
+ res.setStatus(status);
+ return;
}
- status = davOps.copy(req, parentCol, resourceName);
- } catch (Exception e) {
- e.printStackTrace();
- throw new ServletException(e);
+
+ /*
+ * If an error in executing the COPY method occurs with a resource other
+ * than the resource identified in the Request-URI then the response
+ * MUST be a 207 (Multi-Status).
+ */
+ PartialResponse part = new PartialResponse(dest);
+ String st = res.getProtocol() + " " + status + " " + WebdavStatus.getStatusText(status);
+ part.addContent("status", st);
+ res.sendMultiStatusResponse(part);
}
- res.setStatus(status);
+
+ res.closeMultistatusResponse();
}
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Copy.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Added: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/DAVComponent.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/DAVComponent.java?view=auto&rev=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/DAVComponent.java (added)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/DAVComponent.java Thu May 24 18:43:39 2007
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * CVS $Id$
+ */
+
+package org.apache.xindice.webadmin.webdav.components;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
+import org.apache.xindice.webadmin.Location;
+
+/**
+ * The main WebDAV interface for requests to different kind
+ * of resources.
+ *
+ * @author <a href="[email protected]">Gianugo Rabellino</a>
+ * @version $Id$
+ */
+public interface DAVComponent {
+
+ /**
+ * Executes request to a target location, that can be either root ("/"),
+ * collection, resource or an unknown location.
+ *
+ * @param req WebDAV request
+ * @param res WebDAV servlet
+ * @param target target location
+ */
+ public void execute(DAVRequest req, DAVResponse res, Location target) throws ServletException, IOException;
+
+}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/DAVComponent.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/DAVComponent.java
------------------------------------------------------------------------------
svn:keywords = Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Delete.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Delete.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Delete.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Delete.java Thu May 24 18:43:39 2007
@@ -22,77 +22,85 @@
import java.io.IOException;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.avalon.fortress.impl.DefaultContainer;
import org.apache.xindice.core.Collection;
import org.apache.xindice.core.DBException;
-import org.apache.xindice.webadmin.webdav.*;
+import org.apache.xindice.core.FaultCodes;
+import org.apache.xindice.core.Database;
import org.apache.xindice.webadmin.webdav.WebdavStatus;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.Location;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
-/**
+/**
* This class implements the Delete command for WebDAV operations on
- * Xindice.
- *
- * @avalon.component
- * @avalon.service type=DAVComponent
- * @x-avalon.info name=DELETE
- * @x-avalon.lifestyle type=singleton
- *
+ * Xindice.<br>
+ * <br>
+ * DELETE command deletes target collection or resource. For collections,
+ * it deletes the entire subtree, so Depth header in request cannot be
+ * 0 or 1, but it can be omitted.<br>
+ * <br>
+ * The default success status code is 204 (No Content)
+ *
* @author <a href="mailto:[email protected]">Jan Metzner</a>
* @author <a href="mailto:[email protected]">Gianugo Rabellino</a>
- * @version $Id $
+ * @version $Id $
*/
-public class Delete extends DefaultContainer implements DAVComponent {
+public class Delete implements DAVComponent {
+ private final Log log = LogFactory.getLog(Delete.class);
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection col)
- throws ServletException, IOException {
-
- try {
- Collection parentCol = col.getParentCollection();
- parentCol.dropCollection(col);
- res.setStatus(WebdavStatus.SC_NO_CONTENT);
- } catch (DBException e) {
- throw new ServletException(e);
+ public void execute(DAVRequest req, DAVResponse res, Location target) throws ServletException, IOException {
+ if (target.isRoot()) {
+ res.setStatus(WebdavStatus.SC_FORBIDDEN);
+ return;
}
- }
+ Collection col = target.getCollection();
+ String name = target.getName();
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection parentCol,
- String resourceName)
- throws ServletException, IOException {
-
- Object object = null;
- try {
- object = parentCol.getEntry(resourceName);
- } catch (DBException e) {
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug("could not get entry " + resourceName);
- }
- object = null;
+ if (col == null) {
+ res.setStatus(WebdavStatus.SC_NOT_FOUND);
+ return;
}
- if (object == null) {
- res.setStatus(WebdavStatus.SC_NOT_FOUND);
- } else {
+ if (col instanceof Database) {
+ res.setStatus(WebdavStatus.SC_FORBIDDEN);
+ return;
+ }
+
+ if (req.getDepth() != DAVRequest.DEPTH_INFINITY) {
+ res.setStatus(WebdavStatus.SC_BAD_REQUEST);
+ return;
+ }
+
+ // TODO: set SC_FORBIDDEN for system collections
+ if (name == null) { // deleting collection
try {
- parentCol.remove(resourceName);
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug(
- "entry " + resourceName + " deleted");
- }
- res.setStatus(WebdavStatus.SC_NO_CONTENT);
+ col.getDatabase().dropCollection(col);
} catch (DBException e) {
+ log.error("Failed to delete collection " + col.getCanonicalName(), e);
throw new ServletException(e);
}
+ } else { // deleting resource
+ try {
+ col.remove(name);
+ if (log.isDebugEnabled()) {
+ log.debug("entry " + name + " deleted");
+ }
+ } catch (DBException e) {
+ if (e.faultCode == FaultCodes.COL_DOCUMENT_NOT_FOUND) {
+ res.setStatus(WebdavStatus.SC_NOT_FOUND);
+ return;
+ } else {
+ log.error("Failed to delete resource " + name + " from collection " + col.getCanonicalName(), e);
+ throw new ServletException(e);
+ }
+ }
}
+
+ res.setStatus(WebdavStatus.SC_NO_CONTENT);
}
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Delete.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Get.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Get.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Get.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Get.java Thu May 24 18:43:39 2007
@@ -23,110 +23,92 @@
import java.io.OutputStream;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.avalon.fortress.impl.DefaultContainer;
-import org.apache.avalon.framework.service.ServiceException;
import org.apache.xindice.core.Collection;
import org.apache.xindice.core.DBException;
-import org.apache.xindice.core.data.Key;
-import org.apache.xindice.core.data.Record;
+import org.apache.xindice.core.data.Entry;
import org.apache.xindice.webadmin.util.MimeTable;
-import org.apache.xindice.webadmin.util.MimeTableImpl;
-import org.apache.xindice.webadmin.webdav.*;
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
+import org.apache.xindice.webadmin.Location;
import org.apache.xindice.xml.TextWriter;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
-/**
- * This class implements the Get command for WebDAV operations on
- * Xindice.
- *
- * @avalon.component
- * @avalon.service type=DAVComponent
- * @x-avalon.info name=GET
- * @x-avalon.lifestyle type=singleton
- *
+/**
+ * This class implements the Get HTTP command for WebDAV operations on
+ * Xindice.
+ *
* @author <a href="mailto:[email protected]">Jan Metzner</a>
* @author <a href="mailto:[email protected]">Gianugo Rabellino</a>
- * @version $Id$
+ * @version $Id$
*/
-public class Get extends DefaultContainer implements DAVComponent {
+public class Get implements DAVComponent {
- public void execute(HttpServletRequest req, HttpServletResponse res,
- Collection col) throws ServletException, IOException {
+ private static final Log log = LogFactory.getLog(Get.class);
+
+ public void execute(DAVRequest req, DAVResponse res, Location target) throws ServletException, IOException {
+ if (target.getName() == null) {
+ // test if viewer is already specified
+ String viewer = req.getParameter("viewer");
+ if (viewer != null && viewer.length() != 0) {
+ res.setStatus(HttpServletResponse.SC_NOT_IMPLEMENTED);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("WEBDAV Get redirected to HtmlViewer");
+ }
+
+ // redirect if path does not end with /
+ String reqPath = req.getPath();
+ if (reqPath == null || !reqPath.endsWith("/")) {
+ if (reqPath == null) {
+ reqPath = "";
+ }
+ String redirect = req.getContextPath() + reqPath + "/?viewer=default";
+ res.sendRedirect(redirect);
+ } else {
+ res.sendRedirect("?viewer=default");
+ }
- // test if viewer is already specified
- String viewer = req.getParameter("viewer");
- if(viewer != null && viewer.length() != 0) {
- res.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
- }
-
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug("WEBDAV Get redirected to HtmlViewer");
- }
-
- // redirect if path does not end with /
- String reqPath = req.getPathInfo();
- if(reqPath == null || !reqPath.endsWith("/")) {
- if(reqPath == null) {
- reqPath = "";
- }
- String redirect = req.getContextPath()+reqPath+"/?viewer=default";
- res.sendRedirect(redirect);
- } else {
- res.sendRedirect("?viewer=default");
- }
- }
-
- public void execute(HttpServletRequest req, HttpServletResponse res,
- Collection parentCol, String resourceName) throws ServletException, IOException {
-
- try {
- Object resource = parentCol.getEntry(resourceName);
-
- if(resource != null) {
-
- long creationDate = 0;
- long modificationDate = 0;
- Record record = parentCol.getFiler().readRecord(new Key(resourceName));
- creationDate =((Long)record.getMetaData(Record.CREATED)).longValue();
- modificationDate =((Long)record.getMetaData(Record.MODIFIED)).longValue();
-
- byte[] resultBytes = null;
- if(resource instanceof Document) {
- resultBytes = TextWriter.toString((Document)resource).getBytes();
- res.setContentType(MimeTableImpl.XML_MIME_TYPE);
} else {
- resultBytes = (byte[]) resource;
- try {
- MimeTable mimeTable =
- (MimeTable) m_serviceManager.lookup(MimeTable.ROLE);
- res.setContentType(mimeTable.getMimeType(resourceName, false));
- } catch (ServiceException e) {
- e.printStackTrace();
- res.setContentType(MimeTable.BINARY_MIME_TYPE);
- }
+ Collection col = target.getCollection();
+ String name = target.getName();
+
+ try {
+ Entry resource = col.getEntry(name);
+
+ if (resource != null) {
+
+ byte[] resultBytes;
+ if (resource.getEntryType() == Entry.DOCUMENT) {
+ resultBytes = TextWriter.toString((Document) resource.getValue()).getBytes();
+ res.setContentType(MimeTable.XML_MIME_TYPE);
+ } else {
+ resultBytes = (byte[]) resource.getValue();
+ res.setContentType(MimeTable.getMimeType(name));
+ }
+
+ if (resource.getModificationTime() != 0) {
+ res.addDateHeader("Last-Modified", resource.getModificationTime());
+ }
+ res.setContentLength(resultBytes.length);
+
+ OutputStream output = res.getOutputStream();
+ output.write(resultBytes);
+ output.flush();
+ } else {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ }
+ } catch (DBException e) {
+ log.error("Could not get resource " + name + " from collection " + col.getCanonicalName(), e);
+ throw new ServletException(e);
+ }
+
}
- int contentLength = resultBytes.length;
- res.addDateHeader("Last-Modified", modificationDate);
- res.addHeader("ETag", contentLength+"-"+creationDate);
- res.setContentLength(contentLength );
-
- OutputStream output = res.getOutputStream();
- output.write(resultBytes);
- output.flush();
- } else {
- res.sendError(HttpServletResponse.SC_NOT_FOUND);
- }
- } catch(DBException e) {
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug("Could not get Document "+resourceName);
- }
- e.printStackTrace();
- res.sendError(HttpServletResponse.SC_NOT_FOUND);
}
- }
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Get.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Head.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Head.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Head.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Head.java Thu May 24 18:43:39 2007
@@ -22,88 +22,72 @@
import java.io.IOException;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.apache.avalon.fortress.impl.DefaultContainer;
-import org.apache.avalon.framework.service.ServiceException;
import org.apache.xindice.core.Collection;
import org.apache.xindice.core.DBException;
-import org.apache.xindice.core.data.Key;
-import org.apache.xindice.core.data.Record;
+import org.apache.xindice.core.data.Entry;
import org.apache.xindice.webadmin.util.MimeTable;
-import org.apache.xindice.webadmin.webdav.*;
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
+import org.apache.xindice.webadmin.Location;
+import org.apache.xindice.xml.TextWriter;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.logging.Log;
+import org.w3c.dom.Document;
-/**
- * This class implements the Head command for WebDAV operations on
+/**
+ * This class implements the Head HTTP command for WebDAV operations on
* Xindice.
*
- * @avalon.component
- * @avalon.service type=DAVComponent
- * @x-avalon.info name=HEAD
- * @x-avalon.lifestyle type=singleton
- *
* @author <a href="mailto:[email protected]">Jan Metzner</a>
* @author <a href="mailto:[email protected]">Gianugo Rabellino</a>
* @version $Id$
*/
-public class Head extends DefaultContainer implements DAVComponent {
+public class Head implements DAVComponent {
+ private static final Log log = LogFactory.getLog(Head.class);
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection col)
- throws ServletException, IOException {
-
- if (this.getLogger().isDebugEnabled())
- this.getLogger().debug("Method Head not allowed on collections!");
- res.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
- }
-
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection parentCol,
- String resourceName)
- throws ServletException, IOException {
+ public void execute(DAVRequest req, DAVResponse res, Location target) throws ServletException, IOException {
+ Collection col = target.getCollection();
+ String name = target.getName();
+
+ if (target.isRoot() || (col != null && name == null)) {
+ if (log.isDebugEnabled()) {
+ log.debug("Method Head not allowed on collections!");
+ }
+ res.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
+ return;
+ }
+
+ if (col == null) {
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
+ return;
+ }
try {
- Object resource = parentCol.getEntry(resourceName);
+ Entry resource = col.getEntry(name);
if (resource != null) {
- long creationDate = 0;
- long modificationDate = 0;
- int contentLength = 0;
- Record record =
- parentCol.getFiler().readRecord(new Key(resourceName));
- creationDate =
- ((Long)record.getMetaData(Record.CREATED)).longValue();
- modificationDate =
- ((Long)record.getMetaData(Record.MODIFIED)).longValue();
- contentLength = record.getValue().getLength();
-
- try {
- MimeTable mimeTable =
- (MimeTable)m_serviceManager.lookup(MimeTable.ROLE);
- res.setContentType(
- mimeTable.getMimeType(resource, resourceName));
- } catch (ServiceException e) {
- e.printStackTrace();
+
+ byte[] resultBytes;
+ if (resource.getEntryType() == Entry.DOCUMENT) {
+ resultBytes = TextWriter.toString((Document) resource.getValue()).getBytes();
res.setContentType(MimeTable.XML_MIME_TYPE);
+ } else {
+ resultBytes = (byte[]) resource.getValue();
+ res.setContentType(MimeTable.getMimeType(name));
}
- res.addDateHeader("Last-Modified", modificationDate);
- res.addHeader("ETag", contentLength + "-" + creationDate);
- res.setContentLength(contentLength);
+ if (resource.getModificationTime() != 0) {
+ res.addDateHeader("Last-Modified", resource.getModificationTime());
+ }
+ res.setContentLength(resultBytes.length);
} else {
- res.sendError(HttpServletResponse.SC_NOT_FOUND);
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
} catch (DBException e) {
- if (this.getLogger().isDebugEnabled())
- this.getLogger().debug(
- "Could not get Document " + resourceName);
- e.printStackTrace();
- res.sendError(HttpServletResponse.SC_NOT_FOUND);
+ log.error("Could not get resource " + name + " from collection " + col.getCanonicalName(), e);
+ res.setStatus(HttpServletResponse.SC_NOT_FOUND);
}
}
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Head.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Mkcol.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Mkcol.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Mkcol.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Mkcol.java Thu May 24 18:43:39 2007
@@ -22,99 +22,111 @@
import java.io.IOException;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.avalon.fortress.impl.DefaultContainer;
-import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.xindice.core.Collection;
import org.apache.xindice.core.DBException;
+import org.apache.xindice.core.FaultCodes;
import org.apache.xindice.webadmin.util.CollectionConfigurationHelper;
-import org.apache.xindice.webadmin.webdav.*;
import org.apache.xindice.webadmin.webdav.WebdavStatus;
-import org.w3c.dom.Document;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.Location;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
-/**
+/**
* This class implements the Mkcol command for WebDAV operations on
- * Xindice.
- *
- * @avalon.component
- * @avalon.service type=DAVComponent
- * @x-avalon.info name=MKCOL
- * @x-avalon.lifestyle type=singleton
- *
+ * Xindice.<br>
+ * <br>
+ * MKCOL command creates new collection at a specified location. There must be
+ * no existing collection at the specified location. Newly created collection
+ * will be empty. WebDAV specification allows request to have a body that may
+ * contain instructions for creating child resources, but this behavior is
+ * not suppoted. <br>
+ * <br>
+ * Operation possible status codes include: <ul>
+ * <li>
+ * 201 (Created) - The collection or structured resource was created in
+ * its entirety.
+ * <li>
+ * 403 (Forbidden) - This indicates at least one of two conditions: 1)
+ * the server does not allow the creation of collections at the given
+ * location in its namespace, or 2) the parent collection of the
+ * Request-URI exists but cannot accept members.
+ * <li>
+ * 405 (Method Not Allowed) - MKCOL can only be executed on a
+ * deleted/non-existent resource.
+ * <li>
+ * 409 (Conflict) - A collection cannot be made at the Request-URI until
+ * one or more intermediate collections have been created.
+ * <li>
+ * 415 (Unsupported Media Type)- The server does not support the request
+ * type of the body.
+ * </ul>
+ *
* @author <a href="mailto:[email protected]">Jan Metzner</a>
* @author <a href="mailto:[email protected]">Gianugo Rabellino</a>
- * @version $Id $
+ * @version $Id $
*/
-public class Mkcol extends DefaultContainer implements DAVComponent {
+public class Mkcol implements DAVComponent {
+ private final Log log = LogFactory.getLog(Mkcol.class);
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection col)
- throws ServletException, IOException {
-
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug("collection already exists");
+ public void execute(DAVRequest req, DAVResponse res, Location target) throws ServletException, IOException {
+ if (target.isRoot()) {
+ res.setStatus(WebdavStatus.SC_METHOD_NOT_ALLOWED);
+ return;
}
- res.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
- }
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection parentCol,
- String resourceName)
- throws ServletException, IOException {
+ Collection col = target.getCollection();
+ String name = target.getName();
- Document resource = null;
- try {
- resource = parentCol.getDocument(resourceName);
- } catch (DBException e) {
- resource = null;
+ if (name != null && req.getRequestDoc() != null) {
+ // request body is not supported
+ res.setStatus(WebdavStatus.SC_UNSUPPORTED_MEDIA_TYPE);
+ return;
}
- if (resource != null) {
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug(
- "cannot create collection: existing resource "
- + resourceName);
+ if (col == null) { // parent collection does not exist
+ res.setStatus(WebdavStatus.SC_CONFLICT);
+ return;
+ }
+
+ if (name == null) {
+ if (log.isDebugEnabled()) {
+ log.debug("Collection already exists");
}
- res.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
+ res.setStatus(WebdavStatus.SC_METHOD_NOT_ALLOWED);
} else {
-
try {
- CollectionConfigurationHelper helper;
- Object object =
- m_serviceManager.lookup(CollectionConfigurationHelper.ROLE);
- if (object instanceof ServiceSelector) {
- helper =
- (CollectionConfigurationHelper)
- ((ServiceSelector)object).select(
- "col-config");
- } else {
- helper = (CollectionConfigurationHelper)object;
- }
-
- parentCol.createCollection(
- resourceName,
- helper.createDefaultConfiguration(resourceName));
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug(
- "collection " + resourceName + " created");
- }
- } catch (Exception e) {
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug(
- "cannot create collection: " + e.getMessage());
- e.printStackTrace();
- }
- res.sendError(WebdavStatus.SC_METHOD_NOT_ALLOWED);
- return;
+ res.setStatus(createCollection(col, name));
+ } catch (DBException e) {
+ log.error("Failed to create collection " + col.getCanonicalName() + "/" + name, e);
+ throw new ServletException(e);
}
}
- res.setStatus(WebdavStatus.SC_CREATED);
+ }
+
+ private int createCollection(Collection parent, String name) throws DBException {
+ try {
+ parent.createCollection(name, CollectionConfigurationHelper.createDefaultConfiguration(name));
+ if (log.isDebugEnabled()) {
+ log.debug("Collection " + name + " created");
+ }
+
+ // TODO: set SC_FORBIDDEN for system collections
+ } catch (DBException e) {
+ if (e.faultCode == FaultCodes.COL_DUPLICATE_COLLECTION) {
+ return WebdavStatus.SC_METHOD_NOT_ALLOWED;
+ } else if (e.faultCode == FaultCodes.COL_COLLECTION_NOT_FOUND) {
+ return WebdavStatus.SC_METHOD_NOT_ALLOWED;
+ } else if (e.faultCode == FaultCodes.COL_CANNOT_CREATE) {
+ return WebdavStatus.SC_FORBIDDEN;
+ }
+
+ throw e;
+ }
+
+ return WebdavStatus.SC_CREATED;
}
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Mkcol.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
Modified: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Move.java
URL: http://svn.apache.org/viewvc/xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Move.java?view=diff&rev=541504&r1=541498&r2=541504
==============================================================================
--- xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Move.java (original)
+++ xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Move.java Thu May 24 18:43:39 2007
@@ -20,108 +20,149 @@
package org.apache.xindice.webadmin.webdav.components;
import java.io.IOException;
+import java.util.Map;
+import java.util.Iterator;
import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import org.apache.avalon.fortress.impl.DefaultContainer;
-import org.apache.avalon.framework.service.ServiceSelector;
import org.apache.xindice.core.Collection;
import org.apache.xindice.core.DBException;
+import org.apache.xindice.core.FaultCodes;
import org.apache.xindice.webadmin.util.DAVOperations;
-import org.apache.xindice.webadmin.webdav.*;
import org.apache.xindice.webadmin.webdav.WebdavStatus;
+import org.apache.xindice.webadmin.webdav.DAVRequest;
+import org.apache.xindice.webadmin.webdav.DAVResponse;
+import org.apache.xindice.webadmin.PartialResponse;
+import org.apache.xindice.webadmin.Location;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
-/**
+/**
* This class implements the Move command for WebDAV operations on
- * Xindice.
- *
- * @avalon.component
- * @avalon.service type=DAVComponent
- * @x-avalon.info name=MOVE
- * @x-avalon.lifestyle type=singleton
- *
+ * Xindice.<br>
+ * <br>
+ * MOVE commans instructs that the collection or resource be moved to the
+ * URI specified in the Destination header. In case of collection, all
+ * resources and child collections are to be moved to locations relative
+ * to it, recursively through all levels of the collection hierarchy.<br>
+ * <br>
+ * MOVE can overwrite existing resource/collection, and this behavior can
+ * be changed by using Overwrite flag in request header.<br>
+ * <br>
+ * For collections, Depth header cannot have any value other than infinity.<br>
+ * <br>
+ * Operation possible status codes include: <ul>
+ * <li>
+ * 201 (Created) - The source resource was successfully moved, and a new
+ * resource was created at the destination.
+ *
+ * 204 (No Content) - The source resource was successfully moved to a
+ * pre-existing destination resource.
+ *
+ * 403 (Forbidden) _ The source and destination URIs are the same.
+ *
+ * 409 (Conflict) _ A resource cannot be created at the destination
+ * until one or more intermediate collections have been created.
+ *
+ * 412 (Precondition Failed) - The server was unable to maintain the
+ * liveness of the properties listed in the propertybehavior XML element
+ * or the Overwrite header is "F" and the state of the destination
+ * resource is non-null.
+ *
* @author <a href="mailto:[email protected]">Jan Metzner</a>
* @author <a href="mailto:[email protected]">Gianugo Rabellino</a>
- * @version $Id$
+ * @version $Id$
*/
-public class Move extends DefaultContainer implements DAVComponent {
+public class Move implements DAVComponent {
+ private static final Log log = LogFactory.getLog(Move.class);
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection col)
- throws ServletException, IOException {
-
- int status = WebdavStatus.SC_OK;
- try {
- DAVOperations davOps;
- Object object = m_serviceManager.lookup(DAVOperations.ROLE);
- if (object instanceof ServiceSelector) {
- davOps =
- (DAVOperations) ((ServiceSelector)object).select(
- "dav-operations");
- } else {
- davOps = (DAVOperations)object;
- }
+ public void execute(DAVRequest req, DAVResponse res, Location target) throws ServletException, IOException {
+ if (target.isRoot()) {
+ res.setStatus(WebdavStatus.SC_FORBIDDEN);
+ return;
+ }
- status = davOps.copy(req, col.getParentCollection(), col.getName());
- if (status == WebdavStatus.SC_NO_CONTENT
- || status == WebdavStatus.SC_CREATED) {
- Collection parentCol = col.getParentCollection();
- parentCol.dropCollection(col);
- }
- } catch (Exception e) {
- e.printStackTrace();
- throw new ServletException(e);
+ Collection col = target.getCollection();
+ String name = target.getName();
+
+ if (col == null) {
+ res.setStatus(WebdavStatus.SC_NOT_FOUND);
+ return;
}
- res.setStatus(status);
- }
- public void execute(
- HttpServletRequest req,
- HttpServletResponse res,
- Collection parentCol,
- String resourceName)
- throws ServletException, IOException {
-
- Object object = null;
- try {
- object = parentCol.getEntry(resourceName);
- } catch (DBException e) {
- if (this.getLogger().isDebugEnabled()) {
- this.getLogger().debug(
- "could not get document " + resourceName);
- }
- object = null;
+ String dest = req.getDestinationPath();
+ if (dest == null) {
+ res.setStatus(WebdavStatus.SC_BAD_REQUEST);
+ return;
}
- if (object == null) {
- res.setStatus(WebdavStatus.SC_NOT_FOUND);
- } else {
+ if (dest.equals(req.getPath())) {
+ res.setStatus(WebdavStatus.SC_FORBIDDEN);
+ return;
+ }
+
+ int depth = req.getDepth();
+ if (depth != DAVRequest.DEPTH_INFINITY) {
+ res.setStatus(WebdavStatus.SC_BAD_REQUEST);
+ return;
+ }
+
+ if (name == null) { // moving collection
try {
- DAVOperations davOps;
- Object service = m_serviceManager.lookup(DAVOperations.ROLE);
- if (service instanceof ServiceSelector) {
- davOps =
- (DAVOperations) ((ServiceSelector)service).select(
- "dav-operations");
- } else {
- davOps = (DAVOperations)service;
+ Map results = DAVOperations.copy(col, req.getDestinationPath(), req.getOverwrite(), true);
+ interpretResults(results, res, dest, col);
+ } catch (DBException e) {
+ log.error("Failed to move collection " + col.getCanonicalName(), e);
+ throw new ServletException(e);
+ }
+ } else { // moving resource
+ try {
+ int status = DAVOperations.copy(col, name, req.getDestinationPath(), req.getOverwrite());
+ if (status == WebdavStatus.SC_NO_CONTENT || status == WebdavStatus.SC_CREATED) {
+ col.remove(name);
}
+ res.setStatus(status);
+ } catch (DBException e) {
+ log.error("Failed to move resource " + name + " from collection " + col.getCanonicalName(), e);
+ throw new ServletException(e);
+ }
+ }
+ }
- int status = davOps.copy(req, parentCol, resourceName);
- if (status == WebdavStatus.SC_NO_CONTENT
- || status == WebdavStatus.SC_CREATED) {
- parentCol.remove(resourceName);
+ private void interpretResults(Map results, DAVResponse res, String dest, Collection col) throws IOException {
+ for (Iterator i = results.keySet().iterator(); i.hasNext(); ) {
+ String url = (String) i.next();
+ int status = ((Integer) results.get(url)).intValue();
+ if (url.equals(dest)) {
+ if (status == WebdavStatus.SC_CREATED || status == WebdavStatus.SC_NO_CONTENT) {
+ try {
+ col.getDatabase().dropCollection(col);
+ } catch (DBException e) {
+ if (e.faultCode == FaultCodes.COL_CANNOT_DROP) {
+ // cannot drop database
+ status = WebdavStatus.SC_FORBIDDEN;
+ } else if (e.faultCode != FaultCodes.COL_COLLECTION_NOT_FOUND) {
+ status = WebdavStatus.SC_INTERNAL_SERVER_ERROR;
+ }
+ }
}
+
res.setStatus(status);
- } catch (Exception e) {
- throw new ServletException(e);
+ return;
}
+
+ /*
+ * If an error in executing the MOVE method occurs with a resource other
+ * than the resource identified in the Request-URI then the response
+ * MUST be a 207 (Multi-Status).
+ */
+ PartialResponse part = new PartialResponse(dest);
+ String st = res.getProtocol() + " " + status + " " + WebdavStatus.getStatusText(status);
+ part.addContent("status", st);
+ res.sendMultiStatusResponse(part);
}
+ res.closeMultistatusResponse();
}
}
Propchange: xml/xindice/trunk/java/src/org/apache/xindice/webadmin/webdav/components/Move.java
------------------------------------------------------------------------------
--- svn:keywords (original)
+++ svn:keywords Thu May 24 18:43:39 2007
@@ -1 +1 @@
-Author Date Id Revision
+Id Revision Author Date
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.