KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > webdav > WebDAVServlet


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain an
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.webdav;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Hashtable JavaDoc;
21 import java.util.List JavaDoc;
22
23 import javax.servlet.ServletConfig JavaDoc;
24 import javax.servlet.ServletException JavaDoc;
25 import javax.servlet.http.HttpServlet JavaDoc;
26 import javax.servlet.http.HttpServletRequest JavaDoc;
27 import javax.servlet.http.HttpServletResponse JavaDoc;
28 import javax.transaction.UserTransaction JavaDoc;
29
30 import org.alfresco.filesys.server.config.ServerConfiguration;
31 import org.alfresco.repo.security.authentication.AuthenticationComponent;
32 import org.alfresco.repo.transaction.TransactionUtil;
33 import org.alfresco.repo.transaction.TransactionUtil.TransactionWork;
34 import org.alfresco.service.ServiceRegistry;
35 import org.alfresco.service.cmr.repository.NodeRef;
36 import org.alfresco.service.cmr.repository.NodeService;
37 import org.alfresco.service.cmr.repository.StoreRef;
38 import org.alfresco.service.cmr.search.SearchService;
39 import org.alfresco.service.cmr.security.AuthenticationService;
40 import org.alfresco.service.namespace.NamespaceService;
41 import org.alfresco.service.transaction.TransactionService;
42 import org.apache.commons.logging.Log;
43 import org.apache.commons.logging.LogFactory;
44 import org.springframework.web.context.WebApplicationContext;
45 import org.springframework.web.context.support.WebApplicationContextUtils;
46
47 /**
48  * Servlet that accepts WebDAV requests for the hub. The request is served by the hub's content
49  * repository framework and the response sent back using the WebDAV protocol.
50  *
51  * @author gavinc
52  */

53 public class WebDAVServlet extends HttpServlet JavaDoc
54 {
55     
56     private static final long serialVersionUID = 6900069445027527165L;
57
58     // Logging
59
private static Log logger = LogFactory.getLog("org.alfresco.webdav.protocol");
60     
61     // Constants
62
public static final String JavaDoc WEBDAV_PREFIX = "webdav";
63     private static final String JavaDoc INTERNAL_SERVER_ERROR = "Internal Server Error: ";
64
65     // Init parameter names
66
public static final String JavaDoc KEY_STORE = "store";
67     public static final String JavaDoc KEY_ROOT_PATH = "rootPath";
68     
69     // Service registry, used by methods to find services to process requests
70
private ServiceRegistry m_serviceRegistry;
71     
72     // Transaction service, each request is wrapped in a transaction
73
private TransactionService m_transactionService;
74     
75     // WebDAV method handlers
76
private Hashtable JavaDoc<String JavaDoc,Class JavaDoc> m_davMethods;
77     
78     // Root node
79
private NodeRef m_rootNodeRef;
80     
81     // WebDAV helper class
82
private WebDAVHelper m_davHelper;
83     
84     /**
85      * @see javax.servlet.http.HttpServlet#service(javax.servlet.http.HttpServletRequest,
86      * javax.servlet.http.HttpServletResponse)
87      */

88     protected void service(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response) throws ServletException JavaDoc,
89             IOException JavaDoc
90     {
91         long startTime = 0;
92         if (logger.isDebugEnabled())
93         {
94             startTime = System.currentTimeMillis();
95         }
96
97         try
98         {
99             // Create the appropriate WebDAV method for the request and execute it
100
final WebDAVMethod method = createMethod(request, response);
101
102             if (method == null)
103             {
104                 if ( logger.isErrorEnabled())
105                     logger.error("WebDAV method not implemented - " + request.getMethod());
106                 
107                 // Return an error status
108

109                 response.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED);
110                 return;
111             }
112             else if (method.getRootNodeRef() == null)
113             {
114                 if ( logger.isErrorEnabled())
115                     logger.error("No root node for request");
116                 
117                 // Return an error status
118
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
119                 return;
120             }
121
122             // Execute the WebDAV request, wrapped in a transaction
123
TransactionWork<Object JavaDoc> methodWork = new TransactionWork<Object JavaDoc>()
124             {
125                 public Object JavaDoc doWork() throws Exception JavaDoc
126                 {
127                     method.execute();
128                     return null;
129                 }
130             };
131             TransactionUtil.executeInUserTransaction(m_transactionService, methodWork);
132         }
133         catch (Throwable JavaDoc e)
134         {
135             if (!(e instanceof WebDAVServerException) && e.getCause() != null)
136             {
137                 if (e.getCause() instanceof WebDAVServerException)
138                 {
139                     e = e.getCause();
140                 }
141             }
142             // Work out how to handle the error
143
if (e instanceof WebDAVServerException)
144             {
145                 WebDAVServerException error = (WebDAVServerException) e;
146                 if (error.getCause() != null)
147                 {
148                     logger.error(INTERNAL_SERVER_ERROR, error.getCause());
149                 }
150
151                 if (logger.isDebugEnabled())
152                 {
153                     // Show what status code the method sent back
154

155                     logger.debug(request.getMethod() + " is returning status code: " + error.getHttpStatusCode());
156                 }
157
158                 if (response.isCommitted())
159                 {
160                     logger.warn("Could not return the status code to the client as the response has already been committed!");
161                 }
162                 else
163                 {
164                     response.sendError(error.getHttpStatusCode());
165                 }
166             }
167             else
168             {
169                 logger.error(INTERNAL_SERVER_ERROR, e);
170
171                 if (response.isCommitted())
172                 {
173                     logger.warn("Could not return the internal server error code to the client as the response has already been committed!");
174                 }
175                 else
176                 {
177                     response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
178                 }
179             }
180         }
181         finally
182         {
183             if (logger.isDebugEnabled())
184             {
185                 long endTime = System.currentTimeMillis();
186                 long duration = endTime - startTime;
187                 logger.debug(request.getMethod() + " took " + duration + "ms to execute");
188             }
189         }
190     }
191
192     /**
193      * Create a WebDAV method handler
194      *
195      * @param request HttpServletRequest
196      * @param response HttpServletResponse
197      * @return WebDAVMethod
198      */

199     private WebDAVMethod createMethod(HttpServletRequest JavaDoc request, HttpServletResponse JavaDoc response)
200     {
201         // Get the type of the current request
202

203         String JavaDoc strHttpMethod = request.getMethod();
204
205         if (logger.isDebugEnabled())
206             logger.debug("WebDAV request " + strHttpMethod + " on path "
207                     + request.getRequestURI());
208
209         Class JavaDoc methodClass = m_davMethods.get(strHttpMethod);
210         WebDAVMethod method = null;
211
212         if ( methodClass != null)
213         {
214             try
215             {
216                 // Create the handler method
217

218                 method = (WebDAVMethod) methodClass.newInstance();
219                 method.setDetails(request, response, m_davHelper, m_rootNodeRef);
220             }
221             catch (Exception JavaDoc ex)
222             {
223                 // Debug
224

225                 if ( logger.isDebugEnabled())
226                     logger.debug(ex);
227             }
228         }
229
230         // Return the WebDAV method handler, or null if not supported
231

232         return method;
233     }
234
235     /**
236      * Initialize the servlet
237      *
238      * @param config ServletConfig
239      * @exception ServletException
240      */

241     public void init(ServletConfig JavaDoc config) throws ServletException JavaDoc
242     {
243         super.init(config);
244         
245         // Get service registry
246

247         WebApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
248         m_serviceRegistry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY);
249         
250         m_transactionService = m_serviceRegistry.getTransactionService();
251         
252         AuthenticationService authService = (AuthenticationService) context.getBean("authenticationService");
253         NodeService nodeService = (NodeService) context.getBean("NodeService");
254         SearchService searchService = (SearchService) context.getBean("SearchService");
255         NamespaceService namespaceService = (NamespaceService) context.getBean("NamespaceService");
256         
257         // Create the WebDAV helper
258

259         m_davHelper = new WebDAVHelper(m_serviceRegistry, authService);
260         
261         // Initialize the root node
262

263         ServerConfiguration fileSrvConfig = (ServerConfiguration) context.getBean(ServerConfiguration.SERVER_CONFIGURATION);
264         if ( fileSrvConfig == null)
265             throw new ServletException JavaDoc("File server configuration not available");
266
267         // Use the system user as the authenticated context for the filesystem initialization
268

269         AuthenticationComponent authComponent = fileSrvConfig.getAuthenticationComponent();
270         authComponent.setCurrentUser( authComponent.getSystemUserName());
271         
272         // Wrap the initialization in a transaction
273

274         UserTransaction JavaDoc tx = m_transactionService.getUserTransaction(true);
275         
276         try
277         {
278             // Start the transaction
279

280             if ( tx != null)
281                 tx.begin();
282             
283             // Get the store
284

285             String JavaDoc storeValue = config.getInitParameter(KEY_STORE);
286             if (storeValue == null)
287             {
288                 throw new ServletException JavaDoc("Device missing init value: " + KEY_STORE);
289             }
290             StoreRef storeRef = new StoreRef(storeValue);
291             
292             // Connect to the repo and ensure that the store exists
293

294             if (! nodeService.exists(storeRef))
295             {
296                 throw new ServletException JavaDoc("Store not created prior to application startup: " + storeRef);
297             }
298             NodeRef storeRootNodeRef = nodeService.getRootNode(storeRef);
299             
300             // Get the root path
301

302             String JavaDoc rootPath = config.getInitParameter(KEY_ROOT_PATH);
303             if (rootPath == null)
304             {
305                 throw new ServletException JavaDoc("Device missing init value: " + KEY_ROOT_PATH);
306             }
307             
308             // Find the root node for this device
309

310             List JavaDoc<NodeRef> nodeRefs = searchService.selectNodes(storeRootNodeRef, rootPath, null, namespaceService, false);
311             
312             if (nodeRefs.size() > 1)
313             {
314                 throw new ServletException JavaDoc("Multiple possible roots for device: \n" +
315                         " root path: " + rootPath + "\n" +
316                         " results: " + nodeRefs);
317             }
318             else if (nodeRefs.size() == 0)
319             {
320                 // nothing found
321
throw new ServletException JavaDoc("No root found for device: \n" +
322                         " root path: " + rootPath);
323             }
324             else
325             {
326                 // we found a node
327
m_rootNodeRef = nodeRefs.get(0);
328             }
329             
330             // Commit the transaction
331

332             tx.commit();
333         }
334         catch (Exception JavaDoc ex)
335         {
336             logger.error(ex);
337         }
338         finally
339         {
340             // Clear the current system user
341

342             authComponent.clearCurrentSecurityContext();
343         }
344         
345         // Create the WebDAV methods table
346

347         m_davMethods = new Hashtable JavaDoc<String JavaDoc,Class JavaDoc>();
348         
349         m_davMethods.put(WebDAV.METHOD_PROPFIND, PropFindMethod.class);
350         m_davMethods.put(WebDAV.METHOD_COPY, CopyMethod.class);
351         m_davMethods.put(WebDAV.METHOD_DELETE, DeleteMethod.class);
352         m_davMethods.put(WebDAV.METHOD_GET, GetMethod.class);
353         m_davMethods.put(WebDAV.METHOD_HEAD, HeadMethod.class);
354         m_davMethods.put(WebDAV.METHOD_LOCK, LockMethod.class);
355         m_davMethods.put(WebDAV.METHOD_MKCOL, MkcolMethod.class);
356         m_davMethods.put(WebDAV.METHOD_MOVE, MoveMethod.class);
357         m_davMethods.put(WebDAV.METHOD_OPTIONS, OptionsMethod.class);
358         m_davMethods.put(WebDAV.METHOD_POST, PostMethod.class);
359         m_davMethods.put(WebDAV.METHOD_PUT, PutMethod.class);
360         m_davMethods.put(WebDAV.METHOD_UNLOCK, UnlockMethod.class);
361     }
362 }
363
Popular Tags