jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ang...@apache.org
Subject svn commit: r752480 - in /jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit: server/remoting/davex/JcrRemotingServlet.java webdav/jcr/DavResourceFactoryImpl.java webdav/jcr/JCRWebdavServerServlet.java
Date Wed, 11 Mar 2009 15:46:41 GMT
Author: angela
Date: Wed Mar 11 15:46:41 2009
New Revision: 752480

URL: http://svn.apache.org/viewvc?rev=752480&view=rev
Log:
JCR-2018 Jcr-Remoting: PathNotFoundException if item name ends with .json

Modified:
    jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java
    jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java
    jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/JCRWebdavServerServlet.java

Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java?rev=752480&r1=752479&r2=752480&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/server/remoting/davex/JcrRemotingServlet.java
Wed Mar 11 15:46:41 2009
@@ -25,10 +25,13 @@
 import org.apache.jackrabbit.webdav.DavSession;
 import org.apache.jackrabbit.webdav.WebdavRequest;
 import org.apache.jackrabbit.webdav.WebdavResponse;
+import org.apache.jackrabbit.webdav.DavResourceFactory;
+import org.apache.jackrabbit.webdav.observation.SubscriptionManager;
 import org.apache.jackrabbit.webdav.version.DeltaVConstants;
 import org.apache.jackrabbit.webdav.jcr.JcrDavException;
 import org.apache.jackrabbit.webdav.jcr.JcrDavSession;
 import org.apache.jackrabbit.webdav.jcr.JCRWebdavServerServlet;
+import org.apache.jackrabbit.webdav.jcr.transaction.TxLockManagerImpl;
 import org.apache.jackrabbit.util.Text;
 import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.server.util.RequestData;
@@ -42,6 +45,7 @@
 import javax.jcr.Workspace;
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.NodeIterator;
+import javax.jcr.PathNotFoundException;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletResponse;
@@ -191,6 +195,7 @@
      * relative to this location.
      */
     public static final String INIT_PARAM_HOME = "home";
+
     /**
      * the 'temp-directory' init parameter
      */
@@ -260,6 +265,10 @@
         super.setLocatorFactory(new DavLocatorFactoryImpl(getInitParameter(INIT_PARAM_RESOURCE_PATH_PREFIX)));
     }
 
+    public DavResourceFactory getResourceFactory() {
+        return new ResourceFactoryImpl(txMgr, subscriptionMgr);
+    }
+
     protected void doGet(WebdavRequest webdavRequest,
                          WebdavResponse webdavResponse,
                          DavResource davResource) throws IOException, DavException {
@@ -270,9 +279,9 @@
                 if (item.isNode()) {
                     webdavResponse.setContentType("text/plain;charset=utf-8");
                     webdavResponse.setStatus(DavServletResponse.SC_OK);
-                    
+
                     JsonWriter writer = new JsonWriter(webdavResponse.getWriter());
-                    int depth = ((WrappingLocator) davResource.getLocator()).depth;
+                    int depth = ((WrappingLocator) davResource.getLocator()).getDepth();
                     if (depth < BatchReadConfig.DEPTH_INFINITE) {
                         depth = getDepth((Node) item);
                     }
@@ -343,7 +352,8 @@
         DavResourceLocator locator = davResource.getLocator();
         switch (methodCode) {
             case DavMethods.DAV_GET:
-                return davResource.exists() && ((WrappingLocator) locator).isJson;
+                return davResource.exists() && (locator instanceof WrappingLocator)
+                        && ((WrappingLocator) locator).isJsonRequest;
             case DavMethods.DAV_POST:
                 String ct = request.getContentType();
                 return ct.startsWith("multipart/form-data") ||
@@ -529,8 +539,7 @@
 
     //--------------------------------------------------------------------------
     /**
-     * TODO: TOBEFIXED will not behave properly if resource path (i.e. item name)
-     * TODO            ends with .json extension and/or contains a depth-selector pattern.
+     * Locator factory that specially deals with hrefs having a .json extension.
      */
     private static class DavLocatorFactoryImpl extends org.apache.jackrabbit.webdav.jcr.DavLocatorFactoryImpl
{
 
@@ -538,72 +547,73 @@
             super(s);
         }
 
-        public DavResourceLocator createResourceLocator(String string, String string1) {
-            return new WrappingLocator(super.createResourceLocator(string, string1), isJson(string1),
getDepth(string1));
-        }
-
-        public DavResourceLocator createResourceLocator(String string, String string1, String
string2) {
-            return super.createResourceLocator(string, string1, string2);
-        }
-
-        public DavResourceLocator createResourceLocator(String string, String string1, String
string2, boolean b) {
-            return super.createResourceLocator(string, string1, string2, b);
+        public DavResourceLocator createResourceLocator(String prefix, String href) {
+            DavResourceLocator loc = super.createResourceLocator(prefix, href);
+            if (endsWithJson(href)) {
+                loc = new WrappingLocator(super.createResourceLocator(prefix, href));
+            }
+            return loc;
         }
 
-        protected String getRepositoryPath(String resourcePath, String wspPath) {
-            if (resourcePath == null) {
-                return null;
+        public DavResourceLocator createResourceLocator(String prefix, String workspacePath,
String path, boolean isResourcePath) {
+            DavResourceLocator loc = super.createResourceLocator(prefix, workspacePath, path,
isResourcePath);
+            if (isResourcePath && endsWithJson(path)) {
+                loc = new WrappingLocator(loc);
             }
-            String rp = resourcePath;
-            if (isJson(rp)) {
-                rp = resourcePath.substring(0, resourcePath.lastIndexOf('.'));
-                int pos = rp.lastIndexOf(".");
-                if (pos > -1) {
-                    String depthStr = rp.substring(pos + 1);
-                    try {
-                        Integer.parseInt(depthStr);
-                        rp = rp.substring(0, pos);
-                    } catch (NumberFormatException e) {
-                        // ignore return rp
-                    }
-                }
-            }
-            return super.getRepositoryPath(rp, wspPath);
+            return loc;
         }
 
-        private static boolean isJson(String s) {
+        private static boolean endsWithJson(String s) {
             return s.endsWith(".json");
         }
-
-        private static int getDepth(String s) {
-            int depth = Integer.MIN_VALUE;
-            if (isJson(s)) {
-                String tmp = s.substring(0, s.lastIndexOf('.'));
-                int pos = tmp.lastIndexOf(".");
-                if (pos > -1) {
-                    String depthStr = tmp.substring(pos + 1);
-                    try {
-                        depth = Integer.parseInt(depthStr);
-                    } catch (NumberFormatException e) {
-                        // missing depth
-                    }
-                }
-            }
-            return depth;
-        }
     }
 
+    /**
+     * Resource locator that removes trailing .json extensions and depth
+     * selector that do not form part of the repository path.
+     * As the locator and it's factory do not have access to a JCR session
+     * the <code>extraJson</code> flag may be reset later on.
+     *
+     * @see ResourceFactoryImpl#getItem(org.apache.jackrabbit.webdav.jcr.JcrDavSession, org.apache.jackrabbit.webdav.DavResourceLocator)
 
+     */
     private static class WrappingLocator implements DavResourceLocator {
 
         private final DavResourceLocator loc;
-        private final boolean isJson;
-        private final int depth;
+        private boolean isJsonRequest = true;
+        private int depth = Integer.MIN_VALUE;
+        private String repositoryPath;
 
-        private WrappingLocator(DavResourceLocator loc, boolean isJson, int depth) {
+        private WrappingLocator(DavResourceLocator loc) {
             this.loc = loc;
-            this.isJson = isJson;
-            this.depth = depth;
         }
+
+        private void extract() {
+            String rp = loc.getRepositoryPath();
+            rp = rp.substring(0, rp.lastIndexOf('.'));
+            int pos = rp.lastIndexOf(".");
+            if (pos > -1) {
+                String depthStr = rp.substring(pos + 1);
+                try {
+                    depth = Integer.parseInt(depthStr);
+                    rp = rp.substring(0, pos);
+                } catch (NumberFormatException e) {
+                    // apparently no depth-info -> ignore
+                }
+            }
+            repositoryPath = rp;
+        }
+
+        private int getDepth() {
+            if (isJsonRequest) {
+                if (repositoryPath == null) {
+                    extract();
+                }
+                return depth;
+            } else {
+                return Integer.MIN_VALUE;
+            }
+        }
+
         public String getPrefix() {
             return loc.getPrefix();
         }
@@ -632,7 +642,47 @@
             return loc.getFactory();
         }
         public String getRepositoryPath() {
-            return loc.getRepositoryPath();
+            if (isJsonRequest) {
+                if (repositoryPath == null) {
+                    extract();
+                }
+                return repositoryPath;
+            } else {
+                return loc.getRepositoryPath();
+            }
+        }
+    }
+
+    /**
+     * Resource factory used to make sure that the .json extension was properly
+     * interpreted.
+     */
+    private static class ResourceFactoryImpl extends org.apache.jackrabbit.webdav.jcr.DavResourceFactoryImpl
{
+
+        /**
+         * Create a new <code>DavResourceFactoryImpl</code>.
+         *
+         * @param txMgr
+         * @param subsMgr
+         */
+        public ResourceFactoryImpl(TxLockManagerImpl txMgr, SubscriptionManager subsMgr)
{
+            super(txMgr, subsMgr);
+        }
+
+        protected Item getItem(JcrDavSession sessionImpl, DavResourceLocator locator) throws
PathNotFoundException, RepositoryException {
+            if (locator instanceof WrappingLocator && ((WrappingLocator)locator).isJsonRequest)
{
+                // check if the .json extension has been correctly interpreted.
+                Session s = sessionImpl.getRepositorySession();
+                if (s.itemExists(((WrappingLocator)locator).loc.getRepositoryPath())) {
+                    // an item exists with the original calculated repo-path
+                    // -> assume that the repository item path ends with .json
+                    // or .depth.json. i.e. .json wasn't an extra extension
+                    // appended to request the json-serialization of the node.
+                    // -> change the flag in the WrappingLocator correspondingly.
+                    ((WrappingLocator) locator).isJsonRequest = false;
+                }
+            }
+            return super.getItem(sessionImpl, locator);
         }
     }
 }

Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java?rev=752480&r1=752479&r2=752480&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/DavResourceFactoryImpl.java
Wed Mar 11 15:46:41 2009
@@ -201,7 +201,7 @@
         return resource;
     }
 
-    private Item getItem(JcrDavSession sessionImpl, DavResourceLocator locator)
+    protected Item getItem(JcrDavSession sessionImpl, DavResourceLocator locator)
         throws PathNotFoundException, RepositoryException {
         return sessionImpl.getRepositorySession().getItem(locator.getRepositoryPath());
     }

Modified: jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/JCRWebdavServerServlet.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/JCRWebdavServerServlet.java?rev=752480&r1=752479&r2=752480&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/JCRWebdavServerServlet.java
(original)
+++ jackrabbit/trunk/jackrabbit-jcr-server/src/main/java/org/apache/jackrabbit/webdav/jcr/JCRWebdavServerServlet.java
Wed Mar 11 15:46:41 2009
@@ -1,251 +1,251 @@
-/*
- * 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.jackrabbit.webdav.jcr;
-
-import org.apache.jackrabbit.server.BasicCredentialsProvider;
-import org.apache.jackrabbit.server.SessionProviderImpl;
-import org.apache.jackrabbit.server.jcr.JCRWebdavServer;
-import org.apache.jackrabbit.webdav.DavException;
-import org.apache.jackrabbit.webdav.DavLocatorFactory;
-import org.apache.jackrabbit.webdav.DavResource;
-import org.apache.jackrabbit.webdav.DavResourceFactory;
-import org.apache.jackrabbit.webdav.DavSessionProvider;
-import org.apache.jackrabbit.webdav.WebdavRequest;
-import org.apache.jackrabbit.webdav.jcr.observation.SubscriptionManagerImpl;
-import org.apache.jackrabbit.webdav.jcr.transaction.TxLockManagerImpl;
-import org.apache.jackrabbit.webdav.observation.SubscriptionManager;
-import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.jcr.Repository;
-import javax.jcr.Session;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-
-/**
- * JCRWebdavServerServlet provides request/response handling for the
- * JCRWebdavServer.
- * <p>
- * Implementations of this abstract class must implement the
- * {@link #getRepository()} method to access the repository.
- */
-public abstract class JCRWebdavServerServlet extends AbstractWebdavServlet {
-
-    /**
-     * the default logger
-     */
-    private static Logger log = LoggerFactory.getLogger(JCRWebdavServerServlet.class);
-
-    /**
-     * Init parameter specifying the prefix used with the resource path.
-     */
-    public static final String INIT_PARAM_RESOURCE_PATH_PREFIX = "resource-path-prefix";
-
-    /**
-     * Name of the optional init parameter that defines the value of the
-     * 'WWW-Authenticate' header.<p/>
-     * If the parameter is omitted the default value
-     * {@link #DEFAULT_AUTHENTICATE_HEADER "Basic Realm=Jackrabbit Webdav Server"}
-     * is used.
-     *
-     * @see #getAuthenticateHeaderValue()
-     */
-    public static final String INIT_PARAM_AUTHENTICATE_HEADER = "authenticate-header";
-
-    /** the 'missing-auth-mapping' init parameter */
-    public final static String INIT_PARAM_MISSING_AUTH_MAPPING = "missing-auth-mapping";
-
-    /**
-     * Servlet context attribute used to store the path prefix instead of
-     * having a static field with this servlet. The latter causes problems
-     * when running multiple
-     */
-    public static final String CTX_ATTR_RESOURCE_PATH_PREFIX = "jackrabbit.webdav.jcr.resourcepath";
-
-    private String pathPrefix;
-    private String authenticate_header;
-
-    private JCRWebdavServer server;
-    private DavResourceFactory resourceFactory;
-    private DavLocatorFactory locatorFactory;
-    private TxLockManagerImpl txMgr;
-    private SubscriptionManager subscriptionMgr;
-
-    /**
-     * Initializes the servlet set reads the following parameter from the
-     * servlet configuration:
-     * <ul>
-     * <li>resource-path-prefix: optional prefix for all resources.</li>
-     * </ul>
-     *
-     * @throws ServletException
-     */
-    public void init() throws ServletException {
-        super.init();
-
-        // set resource path prefix
-        pathPrefix = getInitParameter(INIT_PARAM_RESOURCE_PATH_PREFIX);
-        getServletContext().setAttribute(CTX_ATTR_RESOURCE_PATH_PREFIX, pathPrefix);
-        log.debug(INIT_PARAM_RESOURCE_PATH_PREFIX + " = " + pathPrefix);
-
-        authenticate_header = getInitParameter(INIT_PARAM_AUTHENTICATE_HEADER);
-        if (authenticate_header == null) {
-            authenticate_header = DEFAULT_AUTHENTICATE_HEADER;
-        }
-        log.debug(INIT_PARAM_AUTHENTICATE_HEADER + " = " + authenticate_header);
-
-        txMgr = new TxLockManagerImpl();
-        subscriptionMgr = new SubscriptionManagerImpl();
-        txMgr.addTransactionListener((SubscriptionManagerImpl) subscriptionMgr);
-
-        // todo: ev. make configurable
-        resourceFactory = new DavResourceFactoryImpl(txMgr, subscriptionMgr);
-        locatorFactory = new DavLocatorFactoryImpl(pathPrefix);
-    }
-
-    /**
-     * Returns true if the preconditions are met. This includes validation of
-     * {@link WebdavRequest#matchesIfHeader(DavResource) If header} and validation
-     * of {@link org.apache.jackrabbit.webdav.transaction.TransactionConstants#HEADER_TRANSACTIONID
-     * TransactionId header}. This method will also return false if the requested
-     * resource resides within a differenct workspace as is assigned to the repository
-     * session attached to the given request.
-     *
-     * @see AbstractWebdavServlet#isPreconditionValid(WebdavRequest, DavResource)
-     */
-    protected boolean isPreconditionValid(WebdavRequest request, DavResource resource) {
-        // first check matching If header
-        if (!request.matchesIfHeader(resource)) {
-            return false;
-        }
-
-        // test if the requested path matches to the existing session
-        // this may occur if the session was retrieved from the cache.
-        try {
-            Session repositorySesssion = JcrDavSession.getRepositorySession(request.getDavSession());
-            String reqWspName = resource.getLocator().getWorkspaceName();
-            String wsName = repositorySesssion.getWorkspace().getName();
-            //  compare workspace names if the req. resource is not the root-collection.
-            if (reqWspName != null && !reqWspName.equals(wsName)) {
-                return false;
-            }
-        } catch (DavException e) {
-            log.error("Internal error: " + e.toString());
-            return false;
-        }
-
-
-        // make sure, the TransactionId header is valid
-        String txId = request.getTransactionId();
-        return txId == null || txMgr.hasLock(txId, resource);
-    }
-
-    /**
-     * Returns the <code>DavSessionProvider</code>
-     *
-     * @return server
-     * @see AbstractWebdavServlet#getDavSessionProvider()
-     */
-    public DavSessionProvider getDavSessionProvider() {
-        if (server == null) {
-            Repository repository = getRepository();
-            server = new JCRWebdavServer(repository, new SessionProviderImpl(
-                    new BasicCredentialsProvider(
-                            getInitParameter(INIT_PARAM_MISSING_AUTH_MAPPING)))
-            );
-        }
-        return server;
-    }
-
-    /**
-     * Throws <code>UnsupportedOperationException</code>.
-     *
-     * @see AbstractWebdavServlet#setDavSessionProvider(DavSessionProvider)
-     */
-    public void setDavSessionProvider(DavSessionProvider davSessionProvider) {
-        throw new UnsupportedOperationException("Not implemented. DavSession(s) are provided
by the 'JCRWebdavServer'");
-    }
-
-    /**
-     * Returns the <code>DavLocatorFactory</code>
-     *
-     * @see AbstractWebdavServlet#getLocatorFactory()
-     */
-    public DavLocatorFactory getLocatorFactory() {
-        if (locatorFactory == null) {
-            locatorFactory = new DavLocatorFactoryImpl(pathPrefix);
-        }
-        return locatorFactory;
-    }
-
-    /**
-     * Sets the <code>DavLocatorFactory</code>
-     *
-     * @see AbstractWebdavServlet#setLocatorFactory(DavLocatorFactory)
-     */
-    public void setLocatorFactory(DavLocatorFactory locatorFactory) {
-        this.locatorFactory = locatorFactory;
-    }
-
-    /**
-     * Returns the <code>DavResourceFactory</code>.
-     *
-     * @see AbstractWebdavServlet#getResourceFactory()
-     */
-    public DavResourceFactory getResourceFactory() {
-        if (resourceFactory == null) {
-            resourceFactory = new DavResourceFactoryImpl(txMgr, subscriptionMgr);
-        }
-        return resourceFactory;
-    }
-
-    /**
-     * Sets the <code>DavResourceFactory</code>.
-     *
-     * @see AbstractWebdavServlet#setResourceFactory(org.apache.jackrabbit.webdav.DavResourceFactory)
-     */
-    public void setResourceFactory(DavResourceFactory resourceFactory) {
-        this.resourceFactory = resourceFactory;
-    }
-
-    /**
-     * Returns the init param of the servlet configuration or
-     * {@link #DEFAULT_AUTHENTICATE_HEADER} as default value.
-     *
-     * @return corresponding init parameter or {@link #DEFAULT_AUTHENTICATE_HEADER}.
-     * @see #INIT_PARAM_AUTHENTICATE_HEADER
-     */
-    public String getAuthenticateHeaderValue() {
-        return authenticate_header;
-    }
-
-    /**
-     * Returns the configured path prefix
-     *
-     * @return resourcePathPrefix
-     * @see #INIT_PARAM_RESOURCE_PATH_PREFIX
-     */
-    public static String getPathPrefix(ServletContext ctx) {
-        return (String) ctx.getAttribute(CTX_ATTR_RESOURCE_PATH_PREFIX);
-    }
-
-    /**
-     * Returns the repository to be used by this servlet.
-     */
-    protected abstract Repository getRepository();
-}
+/*
+ * 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.jackrabbit.webdav.jcr;
+
+import org.apache.jackrabbit.server.BasicCredentialsProvider;
+import org.apache.jackrabbit.server.SessionProviderImpl;
+import org.apache.jackrabbit.server.jcr.JCRWebdavServer;
+import org.apache.jackrabbit.webdav.DavException;
+import org.apache.jackrabbit.webdav.DavLocatorFactory;
+import org.apache.jackrabbit.webdav.DavResource;
+import org.apache.jackrabbit.webdav.DavResourceFactory;
+import org.apache.jackrabbit.webdav.DavSessionProvider;
+import org.apache.jackrabbit.webdav.WebdavRequest;
+import org.apache.jackrabbit.webdav.jcr.observation.SubscriptionManagerImpl;
+import org.apache.jackrabbit.webdav.jcr.transaction.TxLockManagerImpl;
+import org.apache.jackrabbit.webdav.observation.SubscriptionManager;
+import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.jcr.Repository;
+import javax.jcr.Session;
+import javax.servlet.ServletContext;
+import javax.servlet.ServletException;
+
+/**
+ * JCRWebdavServerServlet provides request/response handling for the
+ * JCRWebdavServer.
+ * <p>
+ * Implementations of this abstract class must implement the
+ * {@link #getRepository()} method to access the repository.
+ */
+public abstract class JCRWebdavServerServlet extends AbstractWebdavServlet {
+
+    /**
+     * the default logger
+     */
+    private static Logger log = LoggerFactory.getLogger(JCRWebdavServerServlet.class);
+
+    /**
+     * Init parameter specifying the prefix used with the resource path.
+     */
+    public static final String INIT_PARAM_RESOURCE_PATH_PREFIX = "resource-path-prefix";
+
+    /**
+     * Name of the optional init parameter that defines the value of the
+     * 'WWW-Authenticate' header.<p/>
+     * If the parameter is omitted the default value
+     * {@link #DEFAULT_AUTHENTICATE_HEADER "Basic Realm=Jackrabbit Webdav Server"}
+     * is used.
+     *
+     * @see #getAuthenticateHeaderValue()
+     */
+    public static final String INIT_PARAM_AUTHENTICATE_HEADER = "authenticate-header";
+
+    /** the 'missing-auth-mapping' init parameter */
+    public final static String INIT_PARAM_MISSING_AUTH_MAPPING = "missing-auth-mapping";
+
+    /**
+     * Servlet context attribute used to store the path prefix instead of
+     * having a static field with this servlet. The latter causes problems
+     * when running multiple
+     */
+    public static final String CTX_ATTR_RESOURCE_PATH_PREFIX = "jackrabbit.webdav.jcr.resourcepath";
+
+    private String pathPrefix;
+    private String authenticate_header;
+
+    private JCRWebdavServer server;
+    private DavResourceFactory resourceFactory;
+    private DavLocatorFactory locatorFactory;
+    protected TxLockManagerImpl txMgr;
+    protected SubscriptionManager subscriptionMgr;
+
+    /**
+     * Initializes the servlet set reads the following parameter from the
+     * servlet configuration:
+     * <ul>
+     * <li>resource-path-prefix: optional prefix for all resources.</li>
+     * </ul>
+     *
+     * @throws ServletException
+     */
+    public void init() throws ServletException {
+        super.init();
+
+        // set resource path prefix
+        pathPrefix = getInitParameter(INIT_PARAM_RESOURCE_PATH_PREFIX);
+        getServletContext().setAttribute(CTX_ATTR_RESOURCE_PATH_PREFIX, pathPrefix);
+        log.debug(INIT_PARAM_RESOURCE_PATH_PREFIX + " = " + pathPrefix);
+
+        authenticate_header = getInitParameter(INIT_PARAM_AUTHENTICATE_HEADER);
+        if (authenticate_header == null) {
+            authenticate_header = DEFAULT_AUTHENTICATE_HEADER;
+        }
+        log.debug(INIT_PARAM_AUTHENTICATE_HEADER + " = " + authenticate_header);
+
+        txMgr = new TxLockManagerImpl();
+        subscriptionMgr = new SubscriptionManagerImpl();
+        txMgr.addTransactionListener((SubscriptionManagerImpl) subscriptionMgr);
+
+        // todo: ev. make configurable
+        resourceFactory = new DavResourceFactoryImpl(txMgr, subscriptionMgr);
+        locatorFactory = new DavLocatorFactoryImpl(pathPrefix);
+    }
+
+    /**
+     * Returns true if the preconditions are met. This includes validation of
+     * {@link WebdavRequest#matchesIfHeader(DavResource) If header} and validation
+     * of {@link org.apache.jackrabbit.webdav.transaction.TransactionConstants#HEADER_TRANSACTIONID
+     * TransactionId header}. This method will also return false if the requested
+     * resource resides within a differenct workspace as is assigned to the repository
+     * session attached to the given request.
+     *
+     * @see AbstractWebdavServlet#isPreconditionValid(WebdavRequest, DavResource)
+     */
+    protected boolean isPreconditionValid(WebdavRequest request, DavResource resource) {
+        // first check matching If header
+        if (!request.matchesIfHeader(resource)) {
+            return false;
+        }
+
+        // test if the requested path matches to the existing session
+        // this may occur if the session was retrieved from the cache.
+        try {
+            Session repositorySesssion = JcrDavSession.getRepositorySession(request.getDavSession());
+            String reqWspName = resource.getLocator().getWorkspaceName();
+            String wsName = repositorySesssion.getWorkspace().getName();
+            //  compare workspace names if the req. resource is not the root-collection.
+            if (reqWspName != null && !reqWspName.equals(wsName)) {
+                return false;
+            }
+        } catch (DavException e) {
+            log.error("Internal error: " + e.toString());
+            return false;
+        }
+
+
+        // make sure, the TransactionId header is valid
+        String txId = request.getTransactionId();
+        return txId == null || txMgr.hasLock(txId, resource);
+    }
+
+    /**
+     * Returns the <code>DavSessionProvider</code>
+     *
+     * @return server
+     * @see AbstractWebdavServlet#getDavSessionProvider()
+     */
+    public DavSessionProvider getDavSessionProvider() {
+        if (server == null) {
+            Repository repository = getRepository();
+            server = new JCRWebdavServer(repository, new SessionProviderImpl(
+                    new BasicCredentialsProvider(
+                            getInitParameter(INIT_PARAM_MISSING_AUTH_MAPPING)))
+            );
+        }
+        return server;
+    }
+
+    /**
+     * Throws <code>UnsupportedOperationException</code>.
+     *
+     * @see AbstractWebdavServlet#setDavSessionProvider(DavSessionProvider)
+     */
+    public void setDavSessionProvider(DavSessionProvider davSessionProvider) {
+        throw new UnsupportedOperationException("Not implemented. DavSession(s) are provided
by the 'JCRWebdavServer'");
+    }
+
+    /**
+     * Returns the <code>DavLocatorFactory</code>
+     *
+     * @see AbstractWebdavServlet#getLocatorFactory()
+     */
+    public DavLocatorFactory getLocatorFactory() {
+        if (locatorFactory == null) {
+            locatorFactory = new DavLocatorFactoryImpl(pathPrefix);
+        }
+        return locatorFactory;
+    }
+
+    /**
+     * Sets the <code>DavLocatorFactory</code>
+     *
+     * @see AbstractWebdavServlet#setLocatorFactory(DavLocatorFactory)
+     */
+    public void setLocatorFactory(DavLocatorFactory locatorFactory) {
+        this.locatorFactory = locatorFactory;
+    }
+
+    /**
+     * Returns the <code>DavResourceFactory</code>.
+     *
+     * @see AbstractWebdavServlet#getResourceFactory()
+     */
+    public DavResourceFactory getResourceFactory() {
+        if (resourceFactory == null) {
+            resourceFactory = new DavResourceFactoryImpl(txMgr, subscriptionMgr);
+        }
+        return resourceFactory;
+    }
+
+    /**
+     * Sets the <code>DavResourceFactory</code>.
+     *
+     * @see AbstractWebdavServlet#setResourceFactory(org.apache.jackrabbit.webdav.DavResourceFactory)
+     */
+    public void setResourceFactory(DavResourceFactory resourceFactory) {
+        this.resourceFactory = resourceFactory;
+    }
+
+    /**
+     * Returns the init param of the servlet configuration or
+     * {@link #DEFAULT_AUTHENTICATE_HEADER} as default value.
+     *
+     * @return corresponding init parameter or {@link #DEFAULT_AUTHENTICATE_HEADER}.
+     * @see #INIT_PARAM_AUTHENTICATE_HEADER
+     */
+    public String getAuthenticateHeaderValue() {
+        return authenticate_header;
+    }
+
+    /**
+     * Returns the configured path prefix
+     *
+     * @return resourcePathPrefix
+     * @see #INIT_PARAM_RESOURCE_PATH_PREFIX
+     */
+    public static String getPathPrefix(ServletContext ctx) {
+        return (String) ctx.getAttribute(CTX_ATTR_RESOURCE_PATH_PREFIX);
+    }
+
+    /**
+     * Returns the repository to be used by this servlet.
+     */
+    protected abstract Repository getRepository();
+}



Mime
View raw message