Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/slide/webdav/WebdavServlet.java


1   /*
2    * $Header: /home/cvs/jakarta-slide/src/webdav/server/org/apache/slide/webdav/WebdavServlet.java,v 1.63.2.1 2004/10/30 18:29:16 ozeigermann Exp $
3    * $Revision: 1.63.2.1 $
4    * $Date: 2004/10/30 18:29:16 $
5    *
6    * ====================================================================
7    *
8    * Copyright 1999-2002 The Apache Software Foundation 
9    *
10   * Licensed under the Apache License, Version 2.0 (the "License");
11   * you may not use this file except in compliance with the License.
12   * You may obtain a copy of the License at
13   *
14   *     http://www.apache.org/licenses/LICENSE-2.0
15   *
16   * Unless required by applicable law or agreed to in writing, software
17   * distributed under the License is distributed on an "AS IS" BASIS,
18   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19   * See the License for the specific language governing permissions and
20   * limitations under the License.
21   *
22   */
23  
24  package org.apache.slide.webdav;
25  
26  import java.io.IOException;
27  import java.net.URL;
28  import java.text.SimpleDateFormat;
29  import java.util.Date;
30  
31  import javax.servlet.RequestDispatcher;
32  import javax.servlet.ServletConfig;
33  import javax.servlet.ServletException;
34  import javax.servlet.UnavailableException;
35  import javax.servlet.http.HttpServlet;
36  import javax.servlet.http.HttpServletRequest;
37  import javax.servlet.http.HttpServletResponse;
38  import javax.xml.parsers.DocumentBuilderFactory;
39  import javax.xml.parsers.FactoryConfigurationError;
40  import javax.xml.parsers.ParserConfigurationException;
41  
42  import org.apache.slide.authenticate.SecurityToken;
43  import org.apache.slide.common.Domain;
44  import org.apache.slide.common.DomainInitializationFailedError;
45  import org.apache.slide.common.NamespaceAccessToken;
46  import org.apache.slide.common.SlideException;
47  import org.apache.slide.common.SlideToken;
48  import org.apache.slide.common.SlideTokenWrapper;
49  import org.apache.slide.security.AccessDeniedException;
50  import org.apache.slide.structure.LinkedObjectNotFoundException;
51  import org.apache.slide.structure.ObjectNotFoundException;
52  import org.apache.slide.util.logger.Logger;
53  import org.apache.slide.webdav.util.DirectoryIndexGenerator;
54  import org.apache.slide.webdav.util.WebdavConstants;
55  import org.apache.slide.webdav.util.WebdavStatus;
56  import org.apache.slide.webdav.util.WebdavUtils;
57  
58  /**
59   * The WebDAV servlet. It is responsible for dispatching incoming requests to
60   * implementations of the WebdavMethod interface.
61   *
62   * @version $Revision: 1.63.2.1 $
63   */
64  public class WebdavServlet extends HttpServlet {
65      
66      // -------------------------------------------------------------- Constants
67      
68      
69      /**
70       * Name of the log channel used by the WebDAV servlet.
71       */
72      private static final String LOG_CHANNEL = WebdavServlet.class.getName();
73      
74      
75      /**
76       * Name under which the namespace access token is stored in the application
77       * attributes. This is used when the WebDAV servlet doesn't initialize
78       * Slide itself, but rather the initialization is done outside.
79       */
80      public static final String ATTRIBUTE_NAME =
81          "org.apache.slide.NamespaceAccessToken";
82      
83      
84      // ----------------------------------------------------- Instance Variables
85      
86      
87      /**
88       * Access token to the namespace.
89       */
90      protected NamespaceAccessToken token;
91      
92      
93      /**
94       * Directory browsing enabled.
95       */
96      protected boolean directoryBrowsing = true;
97      
98      
99      /**
100      * RequestDispatcher to the directory browsing template, if specified.
101      */
102     protected RequestDispatcher directoryBrowsingTemplate;
103     
104     
105     /**
106      * Directory browsing enabled.
107      */
108     protected DirectoryIndexGenerator directoryIndexGenerator;
109     
110     
111     /**
112      * Set to true if the servlet is handling the lifecycle of the domain.
113      */
114     protected boolean handleLifecycle = true;
115     
116     
117     /**
118      * Instance of the WebdavMethodFactory to use by this servlet.
119      */
120     protected WebdavMethodFactory methodFactory;
121     
122     
123     // -------------------------------------------------------- Servlet Methods
124     
125     
126     protected void service (HttpServletRequest req, HttpServletResponse resp)
127         throws ServletException, IOException {
128         
129         SimpleDateFormat sdf = new SimpleDateFormat();
130         if( token.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG) )
131             token.getLogger().log("==> "+req.getMethod()+" start: "+sdf.format(new Date(System.currentTimeMillis()))+" ["+Thread.currentThread().getName()+"]", LOG_CHANNEL, Logger.DEBUG);
132         
133         req.setAttribute("slide_uri", WebdavUtils.getRelativePath(req, (WebdavServletConfig) getServletConfig()));
134         
135         try {
136             
137             if (token == null) {
138                 String namespaceName = req.getContextPath();
139                 if ((namespaceName == null) || (namespaceName.equals(""))) {
140                     namespaceName = Domain.getDefaultNamespace();
141                 }
142                 while (namespaceName.startsWith("/")) {
143                     namespaceName = namespaceName.substring(1);
144                 }
145                 token = Domain.accessNamespace(new SecurityToken(this), namespaceName);
146             }
147             
148             resp.setStatus(WebdavStatus.SC_OK);
149             
150             String methodName = req.getMethod();
151             WebdavMethod method = methodFactory.createMethod(methodName);
152             if (method == null) {
153                 throw new WebdavException(WebdavStatus.SC_METHOD_NOT_ALLOWED);
154             } else {
155                 method.run(req, resp);
156             }
157         } catch (WebdavException e) {
158             // There has been an error somewhere ...
159             token.getLogger().log(e,LOG_CHANNEL, Logger.ERROR);
160             try { resp.sendError(e.getStatusCode()); } catch (Throwable ex) { }
161         } catch (Throwable e) {
162             // If something goes really wrong ...
163             token.getLogger().log(e,LOG_CHANNEL, Logger.ERROR);
164             try { resp.sendError(WebdavStatus.SC_INTERNAL_SERVER_ERROR); } catch (Throwable ex) { }
165         }
166         finally {
167             if( token.getLogger().isEnabled(LOG_CHANNEL, Logger.DEBUG) )
168                 token.getLogger().log("<== "+req.getMethod()+" end: "+sdf.format(new Date(System.currentTimeMillis()))+" ["+Thread.currentThread().getName()+"]", LOG_CHANNEL, Logger.DEBUG);
169         }
170         
171     }
172     
173     private boolean isExtTx(HttpServletRequest req) {
174         String hTxIdStr = req.getHeader(WebdavConstants.H_TRANSACTION);
175         return (hTxIdStr != null);
176     }
177     
178     private boolean isCollection(HttpServletRequest req) {
179         SlideToken slideToken = new SlideTokenWrapper(WebdavUtils.getSlideToken(req));
180         // necessary as no transaction has been started, yet
181         slideToken.setForceStoreEnlistment(false);
182         slideToken.setForceSecurity(false);
183         slideToken.setForceLock(false);
184         
185         return WebdavUtils.isCollection(token, slideToken, WebdavUtils.getRelativePath(req, (WebdavServletConfig)getServletConfig()));
186     }
187     
188     /**
189      * Implemented to wrap the ServletConfig object inside a
190      * WebdavServletConfig
191      */
192     public void init(ServletConfig config)
193         throws ServletException {
194         
195         super.init(new WebdavServletConfig(config));
196         
197         // all the actual initialization is inside init()
198     }
199     
200     
201     /**
202      * Manages some initialization stuff on the server.
203      */
204     public void init()
205         throws ServletException {
206         
207         if (!isDomLevel2Parser()) {
208             System.out.println("======================================================");
209             System.out.println("!!! Unable to start Slide Servlet !!!");
210             System.out.println("------------------------------------------------------");
211             System.out.println("You are using using an incorrect older XML parser");
212             System.out.println("that doesn't provide Element::getElementsByTagNameNS");
213             System.out.println("consult the documentation for a list of valid XML parsers.");
214             System.out.println("======================================================");
215             
216             log("======================================================");
217             log("!!! Unable to start Slide Servlet !!!");
218             log("------------------------------------------------------");
219             log("======================================================");
220             log("You are using using an incorrect older XML parser");
221             log("that doesn't provide Element::getElementsByTagNameNS");
222             log("consult the documentation for a list of valid XML parsers.");
223             log("======================================================");
224             throw new ServletException("Invalid XML parser");
225         }
226         
227         String value = null;
228         
229         // Lookup for the NAT using JNDI
230         // FIXME
231         
232         // Lookup for the NAT using the servlet context
233         token = (NamespaceAccessToken)
234             getServletContext().getAttribute(ATTRIBUTE_NAME);
235         if (token == null) {
236             // Dafault initialization
237             String namespaceName = null;
238             String domainConfigFile = null;
239             value = getInitParameter("namespace");
240             if (value != null) {
241                 namespaceName = value;
242             }
243             value = getInitParameter("domain");
244             if (value != null) {
245                 domainConfigFile = value;
246             }
247             try {
248                 
249                 if (domainConfigFile != null) {
250                     URL domainConfigFileURL =
251                         getServletContext().getResource(domainConfigFile);
252                     if (domainConfigFileURL != null) {
253                         Domain.init(domainConfigFileURL);
254                     }
255                 }
256                 
257                 if (namespaceName == null) {
258                     namespaceName = Domain.getDefaultNamespace();
259                     log("No namespace specified, will use default namespace: " +
260                             namespaceName);
261                 }
262                 
263                 token = Domain.accessNamespace
264                     (new SecurityToken(this), namespaceName);
265                 if (token == null) {
266                     log("Could not access namespace " + namespaceName + ".");
267                     throw new UnavailableException("Namespace " + namespaceName +
268                                                        " not accessible");
269                 }
270                 getServletContext().setAttribute(ATTRIBUTE_NAME, token);
271                 
272             } catch (DomainInitializationFailedError e) {
273                 log("Could not initialize domain", e);
274                 throw new UnavailableException(e.toString());
275             } catch (Throwable t) {
276                 t.printStackTrace();
277                 throw new ServletException(t.toString());
278             }
279         } else {
280             handleLifecycle = false;
281         }
282         
283         // Setup the method factory
284         methodFactory =
285             WebdavMethodFactory.newInstance((WebdavServletConfig)getServletConfig());
286         
287         // Check whether directory browsing is enabled, and how it should be
288         // accomplished
289 //        value = getInitParameter("directory-browsing");
290 //        if (value != null) {
291 //            if (value.startsWith("/")) {
292 //                directoryBrowsingTemplate =
293 //                    getServletContext().getRequestDispatcher(value);
294 //                if (directoryBrowsingTemplate == null) {
295 //                    directoryBrowsing = false;
296 //                }
297 //            } else {
298 //                directoryBrowsing = Boolean.valueOf(value).booleanValue();
299 //            }
300 //        }
301 //        if (directoryBrowsing) {
302 //            directoryIndexGenerator =
303 //                new DirectoryIndexGenerator
304 //                (token, (WebdavServletConfig)getServletConfig());
305 //        }
306     }
307     
308     
309     /**
310      * Destroy servlet.
311      */
312     public void destroy() {
313         
314         if (handleLifecycle) {
315             if (token != null) {
316                 Domain.closeNamespace(token);
317             }
318         }
319     }
320     
321     
322     
323     // ------------------------------------------------------ Protected Methods
324     
325     
326     /**
327      * Handle a GET request on a collection resource.
328      */
329 //    protected void doGet(HttpServletRequest req, HttpServletResponse res)
330 //        throws ServletException, IOException {
331 //        
332 //        if (directoryBrowsing) {
333 //            if (directoryBrowsingTemplate != null) {
334 //                // attributes used by the tag library
335 //                req.setAttribute("org.apache.slide.NamespaceName",
336 //                                 token.getName());
337 //                // attributes for general use
338 //                req.setAttribute("slide_namespace", token.getName());
339 //                directoryBrowsingTemplate.forward(req, res);
340 //            } else {
341 //                try {
342 //                    directoryIndexGenerator.generate(req, res);
343 //                } catch (AccessDeniedException e) {
344 //                    res.sendError(WebdavStatus.SC_FORBIDDEN);
345 //                } catch (ObjectNotFoundException e) {
346 //                    res.sendError(WebdavStatus.SC_NOT_FOUND);
347 //                } catch (LinkedObjectNotFoundException e) {
348 //                    res.sendError(WebdavStatus.SC_NOT_FOUND);
349 //                } catch (SlideException e) {
350 //                    res.setStatus(WebdavStatus.SC_INTERNAL_SERVER_ERROR);
351 //                }
352 //            }
353 //        } else {
354 //            res.sendError(WebdavStatus.SC_FORBIDDEN);
355 //        }
356 //    }
357     
358     static boolean isDomLevel2Parser() {
359         try {
360             return DocumentBuilderFactory.newInstance().newDocumentBuilder()
361                 .getDOMImplementation().hasFeature("Core", "2.0");
362         } catch (ParserConfigurationException e) {
363             return false;
364         } catch (FactoryConfigurationError e) {
365             return false;
366         }
367     }
368 
369 }
370