| /* |
| * Copyright 2005 The Apache Software Foundation. |
| * |
| * Licensed 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.j2ee; |
| |
| import org.apache.jackrabbit.server.AbstractWebdavServlet; |
| import org.apache.jackrabbit.server.BasicCredentialsProvider; |
| import org.apache.jackrabbit.server.SessionProvider; |
| import org.apache.jackrabbit.server.SessionProviderImpl; |
| import org.apache.jackrabbit.webdav.DavException; |
| import org.apache.jackrabbit.webdav.DavLocatorFactory; |
| import org.apache.jackrabbit.webdav.DavMethods; |
| 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.WebdavResponse; |
| import org.apache.jackrabbit.webdav.jcr.DavLocatorFactoryImpl; |
| import org.apache.jackrabbit.webdav.lock.LockManager; |
| import org.apache.jackrabbit.webdav.lock.SimpleLockManager; |
| import org.apache.jackrabbit.webdav.simple.DavSessionProviderImpl; |
| import org.apache.jackrabbit.webdav.simple.ResourceConfig; |
| import org.apache.jackrabbit.webdav.simple.ResourceFactoryImpl; |
| import org.apache.log4j.Logger; |
| |
| import javax.jcr.Repository; |
| import javax.servlet.ServletContext; |
| import javax.servlet.ServletException; |
| import java.io.IOException; |
| import java.net.MalformedURLException; |
| |
| /** |
| * WebdavServlet provides webdav support (level 1 and 2 complient) for repository |
| * resources. |
| */ |
| public class SimpleWebdavServlet extends AbstractWebdavServlet { |
| |
| /** |
| * the default logger |
| */ |
| private static final Logger log = Logger.getLogger(SimpleWebdavServlet.class); |
| |
| /** |
| * init param name of the repository prefix |
| */ |
| 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"; |
| |
| /** |
| * Name of the init parameter that specify a separate configuration used |
| * for filtering the resources displayed. |
| */ |
| public static final String INIT_PARAM_RESOURCE_CONFIG = "resource-config"; |
| |
| /** |
| * 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.simple.resourcepath"; |
| |
| /** |
| * the resource path prefix |
| */ |
| private String resourcePathPrefix; |
| |
| /** |
| * Header value as specified in the {@link #INIT_PARAM_AUTHENTICATE_HEADER} parameter. |
| */ |
| private String authenticate_header; |
| |
| /** |
| * Map used to remember any webdav lock created without being reflected |
| * in the underlying repository. |
| * This is needed because some clients rely on a successful locking |
| * mechanism in order to perform properly (e.g. mac OSX built-in dav client) |
| */ |
| private LockManager lockManager; |
| |
| /** |
| * the resource factory |
| */ |
| private DavResourceFactory resourceFactory; |
| |
| /** |
| * the locator factory |
| */ |
| private DavLocatorFactory locatorFactory; |
| |
| /** |
| * the jcr repository |
| */ |
| private Repository repository; |
| |
| /** |
| * the webdav session provider |
| */ |
| private DavSessionProvider davSessionProvider; |
| |
| /** |
| * the repository session provider |
| */ |
| private SessionProvider sessionProvider; |
| |
| /** |
| * The config |
| */ |
| private ResourceConfig config; |
| |
| /** |
| * Init this servlet |
| * |
| * @throws ServletException |
| */ |
| public void init() throws ServletException { |
| super.init(); |
| |
| resourcePathPrefix = getInitParameter(INIT_PARAM_RESOURCE_PATH_PREFIX); |
| if (resourcePathPrefix == null) { |
| log.debug("Missing path prefix > setting to empty string."); |
| resourcePathPrefix = ""; |
| } else if (resourcePathPrefix.endsWith("/")) { |
| log.debug("Path prefix ends with '/' > removing trailing slash."); |
| resourcePathPrefix = resourcePathPrefix.substring(0, resourcePathPrefix.length() - 1); |
| } |
| getServletContext().setAttribute(CTX_ATTR_RESOURCE_PATH_PREFIX, resourcePathPrefix); |
| log.info(INIT_PARAM_RESOURCE_PATH_PREFIX + " = '" + resourcePathPrefix + "'"); |
| |
| authenticate_header = getInitParameter(INIT_PARAM_AUTHENTICATE_HEADER); |
| if (authenticate_header == null) { |
| authenticate_header = DEFAULT_AUTHENTICATE_HEADER; |
| } |
| log.info("WWW-Authenticate header = '" + authenticate_header + "'"); |
| |
| String configParam = getInitParameter(INIT_PARAM_RESOURCE_CONFIG); |
| if (configParam != null) { |
| try { |
| config = new ResourceConfig(); |
| config.parse(getServletContext().getResource(configParam)); |
| } catch (MalformedURLException e) { |
| log.debug("Unable to build resource filter provider."); |
| } |
| } |
| } |
| |
| /** |
| * Executes the respective method in the given webdav context. |
| * The method is overridden since not all webdav methods should be |
| * supported by this servlet. |
| * |
| * @param request |
| * @param response |
| * @param method |
| * @param resource |
| * @return |
| * @throws ServletException |
| * @throws IOException |
| * @throws org.apache.jackrabbit.webdav.DavException |
| */ |
| protected boolean execute(WebdavRequest request, WebdavResponse response, |
| int method, DavResource resource) |
| throws ServletException, IOException, DavException { |
| switch (method) { |
| case DavMethods.DAV_HEAD: |
| doHead(request, response, resource); |
| break; |
| case DavMethods.DAV_GET: |
| doGet(request, response, resource); |
| break; |
| case DavMethods.DAV_OPTIONS: |
| doOptions(request, response, resource); |
| break; |
| case DavMethods.DAV_PROPFIND: |
| doPropFind(request, response, resource); |
| break; |
| case DavMethods.DAV_PROPPATCH: |
| doPropPatch(request, response, resource); |
| break; |
| case DavMethods.DAV_PUT: |
| doPut(request, response, resource); |
| break; |
| case DavMethods.DAV_POST: |
| doPost(request, response, resource); |
| break; |
| case DavMethods.DAV_DELETE: |
| doDelete(request, response, resource); |
| break; |
| case DavMethods.DAV_COPY: |
| doCopy(request, response, resource); |
| break; |
| case DavMethods.DAV_MOVE: |
| doMove(request, response, resource); |
| break; |
| case DavMethods.DAV_MKCOL: |
| doMkCol(request, response, resource); |
| break; |
| case DavMethods.DAV_LOCK: |
| doLock(request, response, resource); |
| break; |
| case DavMethods.DAV_UNLOCK: |
| doUnlock(request, response, resource); |
| break; |
| default: |
| // any other method |
| return false; |
| } |
| return true; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| protected boolean isPreconditionValid(WebdavRequest request, |
| DavResource resource) { |
| return !resource.exists() || request.matchesIfHeader(resource); |
| } |
| |
| /** |
| * Returns the configured path prefix |
| * |
| * @return resourcePathPrefix |
| * @see #INIT_PARAM_RESOURCE_PATH_PREFIX |
| */ |
| public String getPathPrefix() { |
| return resourcePathPrefix; |
| } |
| |
| /** |
| * 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 <code>DavLocatorFactory</code>. If no locator factory has |
| * been set or created a new instance of {@link org.apache.jackrabbit.webdav.simple.LocatorFactoryImpl} is |
| * returned. |
| * |
| * @return the locator factory |
| * @see AbstractWebdavServlet#getLocatorFactory() |
| */ |
| public DavLocatorFactory getLocatorFactory() { |
| if (locatorFactory == null) { |
| locatorFactory = new DavLocatorFactoryImpl(resourcePathPrefix); |
| } |
| return locatorFactory; |
| } |
| |
| /** |
| * Sets the <code>DavLocatorFactory</code>. |
| * |
| * @param locatorFactory |
| * @see AbstractWebdavServlet#setLocatorFactory(DavLocatorFactory) |
| */ |
| public void setLocatorFactory(DavLocatorFactory locatorFactory) { |
| this.locatorFactory = locatorFactory; |
| } |
| |
| /** |
| * Returns the <code>LockManager</code>. If no lock manager has |
| * been set or created a new instance of {@link SimpleLockManager} is |
| * returned. |
| * |
| * @return the lock manager |
| */ |
| public LockManager getLockManager() { |
| if (lockManager == null) { |
| lockManager = new SimpleLockManager(); |
| } |
| return lockManager; |
| } |
| |
| /** |
| * Sets the <code>LockManager</code>. |
| * |
| * @param lockManager |
| */ |
| public void setLockManager(LockManager lockManager) { |
| this.lockManager = lockManager; |
| } |
| |
| /** |
| * Returns the <code>DavResourceFactory</code>. If no request factory has |
| * been set or created a new instance of {@link ResourceFactoryImpl} is |
| * returned. |
| * |
| * @return the resource factory |
| * @see org.apache.jackrabbit.server.AbstractWebdavServlet#getResourceFactory() |
| */ |
| public DavResourceFactory getResourceFactory() { |
| if (resourceFactory == null) { |
| resourceFactory = new ResourceFactoryImpl(getLockManager(), getResourceConfig()); |
| } |
| return resourceFactory; |
| } |
| |
| /** |
| * Sets the <code>DavResourceFactory</code>. |
| * |
| * @param resourceFactory |
| * @see AbstractWebdavServlet#setResourceFactory(org.apache.jackrabbit.webdav.DavResourceFactory) |
| */ |
| public void setResourceFactory(DavResourceFactory resourceFactory) { |
| this.resourceFactory = resourceFactory; |
| } |
| |
| /** |
| * Returns the <code>SessionProvider</code>. If no session provider has been |
| * set or created a new instance of {@link SessionProviderImpl} that extracts |
| * credentials from the request's <code>Authorization</code> header is |
| * returned. |
| * |
| * @return the session provider |
| */ |
| public synchronized SessionProvider getSessionProvider() { |
| if (sessionProvider == null) { |
| sessionProvider = new SessionProviderImpl( |
| new BasicCredentialsProvider( |
| getInitParameter(INIT_PARAM_MISSING_AUTH_MAPPING)) |
| ); |
| } |
| return sessionProvider; |
| } |
| |
| /** |
| * Sets the <code>SessionProvider</code>. |
| * |
| * @param sessionProvider |
| */ |
| public synchronized void setSessionProvider(SessionProvider sessionProvider) { |
| this.sessionProvider = sessionProvider; |
| } |
| |
| /** |
| * Returns the <code>DavSessionProvider</code>. If no session provider has |
| * been set or created a new instance of {@link DavSessionProviderImpl} |
| * is returned. |
| * |
| * @return the session provider |
| * @see org.apache.jackrabbit.server.AbstractWebdavServlet#getDavSessionProvider() |
| */ |
| public synchronized DavSessionProvider getDavSessionProvider() { |
| if (davSessionProvider == null) { |
| davSessionProvider = |
| new DavSessionProviderImpl(getRepository(), getSessionProvider()); |
| } |
| return davSessionProvider; |
| } |
| |
| /** |
| * Sets the <code>DavSessionProvider</code>. |
| * |
| * @param sessionProvider |
| * @see AbstractWebdavServlet#setDavSessionProvider(org.apache.jackrabbit.webdav.DavSessionProvider) |
| */ |
| public synchronized void setDavSessionProvider(DavSessionProvider sessionProvider) { |
| this.davSessionProvider = sessionProvider; |
| } |
| |
| /** |
| * Returns the header value retrieved from the {@link #INIT_PARAM_AUTHENTICATE_HEADER} |
| * init parameter. If the parameter is missing, the value defaults to |
| * {@link #DEFAULT_AUTHENTICATE_HEADER}. |
| * |
| * @return the header value retrieved from the corresponding init parameter |
| * or {@link #DEFAULT_AUTHENTICATE_HEADER}. |
| * @see org.apache.jackrabbit.server.AbstractWebdavServlet#getAuthenticateHeaderValue() |
| */ |
| public String getAuthenticateHeaderValue() { |
| return authenticate_header; |
| } |
| |
| /** |
| * Returns the resource configuration to be applied |
| * |
| * @return the resource configuration. |
| */ |
| public ResourceConfig getResourceConfig() { |
| // fallback if no config present |
| if (config == null) { |
| config = new ResourceConfig(); |
| } |
| return config; |
| } |
| |
| /** |
| * Set the resource configuration |
| * |
| * @param config |
| */ |
| public void setResourceConfig(ResourceConfig config) { |
| this.config = config; |
| } |
| |
| /** |
| * Returns the <code>Repository</code>. If no repository has been set or |
| * created the repository initialized by <code>RepositoryAccessServlet</code> |
| * is returned. |
| * |
| * @return repository |
| * @see RepositoryAccessServlet#getRepository(ServletContext) |
| */ |
| public Repository getRepository() { |
| if (repository == null) { |
| repository = RepositoryAccessServlet.getRepository(getServletContext()); |
| } |
| return repository; |
| } |
| |
| /** |
| * Sets the <code>Repository</code>. |
| * |
| * @param repository |
| */ |
| public void setRepository(Repository repository) { |
| this.repository = repository; |
| } |
| } |