001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.war.webdav;
034:
035: import com.flexive.war.webdav.catalina.ResourceAttributes;
036:
037: import javax.naming.NamingException;
038: import javax.naming.directory.DirContext;
039: import javax.servlet.ServletConfig;
040: import javax.servlet.ServletContext;
041: import javax.servlet.ServletException;
042: import javax.servlet.http.HttpServletRequest;
043: import javax.servlet.http.HttpServletResponse;
044: import java.io.IOException;
045:
046: /**
047: * Servlet which adds support for WebDAV level 2.
048: * <p/>
049: * All the basic HTTP requests are handled by the DefaultServlet.<br>
050: * WebDAV added the following methods to HTTP:<br>
051: * PROPFIND - Used to retrieve properties, persisted as XML, from a resource. It is also overloaded to allow one to
052: * retrieve the collection structure (a.k.a. directory hierarchy) of a remote system.<br>
053: * PROPPATCH - Used to change and delete multiple properties on a resource in a single atomic act.<br>
054: * MKCOL - Used to create collections (a.k.a. directory)<br>
055: * COPY - Used to copy a resource from one URI to another<br>
056: * MOVE - Used to move a resource from one URI to another<br>
057: * LOCK - Used to put a lock on a resource, WebDAV supports both shared and exclusive locks<br>
058: * UNLOCK - To remove a lock from a resource<br>
059: * <br>
060: * This is a work in progress class, the javadoc text of the webDav operations may not be
061: * implemented correctly at this time, but describes what the operations should do in the
062: * final implementation.
063: *
064: * @author Gregor Schober (gregor.schober@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
065: * @version $Rev: 1 $
066: */
067: public class FxWebDavServletBase extends DefaultServlet {
068:
069: private static final String METHOD_PROPFIND = "PROPFIND";
070: private static final String METHOD_PROPPATCH = "PROPPATCH";
071: private static final String METHOD_MKCOL = "MKCOL";
072: private static final String METHOD_COPY = "COPY";
073: private static final String METHOD_MOVE = "MOVE";
074: private static final String METHOD_LOCK = "LOCK";
075: private static final String METHOD_UNLOCK = "UNLOCK";
076: private static final String METHOD_PUT = "PUT";
077: private static final String METHOD_DELETE = "DELETE";
078: private static ServletContext servletContext;
079:
080: /**
081: * Initialize this servlets.
082: */
083: public void init() throws ServletException {
084: if (debug > 0) {
085: log("WebDavServletBase is initializing");
086: }
087: super .init();
088: }
089:
090: /**
091: * Method handling all webDav request
092: *
093: * @param request the reuqest
094: * @param resp the response
095: * @throws ServletException if the service method fails
096: * @throws IOException if a IO Exception occures
097: */
098: protected void service(HttpServletRequest request,
099: HttpServletResponse resp) throws ServletException,
100: IOException {
101: final String method = request.getMethod();
102: try {
103: // Write debug
104: if (debug > 0) {
105: log("[" + method + "] " + request.getRequestURI());
106: }
107:
108: // Toggle by mothod
109: if (method.equals("GET")) {
110: FxWebDavServlet.getDavContext().serviceResource(
111: request, resp,
112: FxWebDavUtils.getDavPath(request));
113: } else if (method.equals(METHOD_PROPFIND)) {
114: new OperationPropFind(request, resp, readOnly)
115: .writeResponse();
116: } else if (method.equals(METHOD_PROPPATCH)) {
117: new OperationProppatch(request, resp, readOnly);
118: } else if (method.equals(METHOD_MKCOL)) {
119: new OperationMkcol(request, resp, readOnly)
120: .writeResponse();
121: } else if (method.equals(METHOD_COPY)) {
122: new OperationCopy(request, resp, readOnly)
123: .writeResponse();
124: } else if (method.equals(METHOD_MOVE)) {
125: new OperationMove(request, resp, readOnly)
126: .writeResponse();
127: } else if (method.equals(METHOD_LOCK)) {
128: new OperationLock(request, resp, readOnly)
129: .writeResponse();
130: } else if (method.equals(METHOD_UNLOCK)) {
131: new OperationUnlock(request, resp, readOnly)
132: .writeResponse();
133: } else if (method.equals(METHOD_PUT)) {
134: new OperationPut(request, resp, readOnly)
135: .writeResponse();
136: } else if (method.equals(METHOD_DELETE)) {
137: new OperationDelete(request, resp, readOnly)
138: .writeResponse();
139: } else {
140: super .service(request, resp); // DefaultServlet processing
141: }
142: } catch (Exception exc) {
143: resp.setStatus(FxWebDavStatus.SC_INTERNAL_SERVER_ERROR);
144: String message = this .getClass().getName() + ": [" + method
145: + "] failed, msg=" + exc.getMessage();
146: log(message);
147: System.err.println(message);
148: }
149: }
150:
151: /**
152: * Check if the conditions specified in the optional If headers are satisfied.
153: *
154: * @param request The servlets request we are processing
155: * @param response The servlets response we are creating
156: * @param resourceAttributes The resource information
157: * @return boolean true if the resource meets all the specified conditions,
158: * and false if any of the conditions is not satisfied, in which case
159: * request processing is stopped
160: */
161: protected boolean checkIfHeaders(HttpServletRequest request,
162: HttpServletResponse response,
163: ResourceAttributes resourceAttributes) throws IOException {
164: return super .checkIfHeaders(request, response,
165: resourceAttributes);
166: }
167:
168: /**
169: * OPTIONS Method.
170: *
171: * @param req The request
172: * @param resp The response
173: * @throws ServletException If an error occurs
174: * @throws IOException If an IO error occurs
175: */
176: protected void doOptions(HttpServletRequest req,
177: HttpServletResponse resp) throws ServletException,
178: IOException {
179: resp.addHeader("DAV", "1,2");
180: resp.addHeader("DAV", "<http://apache.org/dav/propset/fs/1>");
181: resp.addHeader("MS-Author-Via", "DAV");
182: resp.addHeader("Allow", determineMethodsAllowed(resources, req)
183: .toString());
184: resp.addHeader("Content-Length", "0");
185: resp.addHeader("content-type", "httpd/unix-directory");
186: }
187:
188: /**
189: * Determines the methods normally allowed for the resource.
190: *
191: * @param resources the resources
192: * @param req the request
193: * @return the allowed methods
194: */
195: private StringBuffer determineMethodsAllowed(DirContext resources,
196: HttpServletRequest req) {
197:
198: StringBuffer methodsAllowed = new StringBuffer();
199: boolean exists = true;
200: Object object = null;
201: try {
202: String path = getRelativePath(req);
203: if (resources != null)
204: object = resources.lookup(path);
205: else
206: exists = false;
207: } catch (NamingException e) {
208: exists = false;
209: }
210:
211: if (!exists) {
212: methodsAllowed.append("OPTIONS, MKCOL, PUT, LOCK");
213: return methodsAllowed;
214: }
215:
216: methodsAllowed
217: .append("OPTIONS, GET, HEAD, POST, DELETE, TRACE");
218: methodsAllowed.append(", PROPPATCH, COPY, MOVE, LOCK, UNLOCK");
219:
220: if (listings) {
221: methodsAllowed.append(", PROPFIND");
222: }
223:
224: if (!(object instanceof DirContext)) {
225: methodsAllowed.append(", PUT");
226: }
227:
228: return methodsAllowed;
229: }
230:
231: public static String getMimeType(String filename) {
232: return servletContext.getMimeType(filename);
233: }
234:
235: public void init(ServletConfig servletConfig)
236: throws ServletException {
237: super.init(servletConfig);
238: servletContext = getServletContext();
239: }
240:
241: }
|