1 package org.apache.maven.archiva.web.repository;
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
22 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
23 import org.apache.maven.archiva.configuration.ConfigurationEvent;
24 import org.apache.maven.archiva.configuration.ConfigurationListener;
25 import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
26 import org.apache.maven.archiva.webdav.*;
27 import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
28 import org.apache.jackrabbit.webdav.*;
29 import org.codehaus.plexus.spring.PlexusToSpringUtils;
30 import org.springframework.web.context.WebApplicationContext;
31 import org.springframework.web.context.support.WebApplicationContextUtils;
32 import org.slf4j.Logger;
33 import org.slf4j.LoggerFactory;
35 import javax.servlet.ServletConfig;
36 import javax.servlet.ServletException;
37 import javax.servlet.http.HttpServletResponse;
38 import javax.servlet.http.HttpServletRequest;
40 import java.io.IOException;
46 * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
49 public class RepositoryServlet
50 extends AbstractWebdavServlet
51 implements ConfigurationListener
53 private Logger log = LoggerFactory.getLogger(RepositoryServlet.class);
55 private ArchivaConfiguration configuration;
57 private Map<String, ManagedRepositoryConfiguration> repositoryMap;
59 private DavLocatorFactory locatorFactory;
61 private DavResourceFactory resourceFactory;
63 private DavSessionProvider sessionProvider;
65 private final Object reloadLock = new Object();
67 public void init(javax.servlet.ServletConfig servletConfig)
68 throws ServletException
70 super.init(servletConfig);
71 initServers(servletConfig);
75 * Service the given request.
76 * This method has been overridden and copy/pasted to allow better exception handling
77 * and to support different realms
81 * @throws ServletException
82 * @throws java.io.IOException
85 protected void service(HttpServletRequest request, HttpServletResponse response)
86 throws ServletException, IOException
88 WebdavRequest webdavRequest = new WebdavRequestImpl(request, getLocatorFactory());
89 // DeltaV requires 'Cache-Control' header for all methods except 'VERSION-CONTROL' and 'REPORT'.
90 int methodCode = DavMethods.getMethodCode(request.getMethod());
91 boolean noCache = DavMethods.isDeltaVMethod(webdavRequest) && !(DavMethods.DAV_VERSION_CONTROL == methodCode || DavMethods.DAV_REPORT == methodCode);
92 WebdavResponse webdavResponse = new WebdavResponseImpl(response, noCache);
94 // make sure there is a authenticated user
95 if (!getDavSessionProvider().attachSession(webdavRequest)) {
99 // check matching if=header for lock-token relevant operations
100 DavResource resource = getResourceFactory().createResource(webdavRequest.getRequestLocator(), webdavRequest, webdavResponse);
101 if (!isPreconditionValid(webdavRequest, resource)) {
102 webdavResponse.sendError(DavServletResponse.SC_PRECONDITION_FAILED);
105 if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
106 super.service(request, response);
110 catch (UnauthorizedDavException e)
112 webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue(e.getRepositoryName()));
113 webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
115 catch (BrowserRedirectException e)
117 response.sendRedirect(e.getLocation());
119 catch (DavException e)
121 if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
122 final String msg = "Should throw " + UnauthorizedDavException.class.getName();
124 webdavResponse.sendError(e.getErrorCode(), msg);
125 } else if ( e.getCause() != null ) {
126 webdavResponse.sendError(e.getErrorCode(), e.getCause().getMessage());
128 webdavResponse.sendError(e.getErrorCode(), e.getMessage());
131 getDavSessionProvider().releaseSession(webdavRequest);
135 public synchronized void initServers( ServletConfig servletConfig )
137 WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
139 configuration = (ArchivaConfiguration) wac.getBean(
140 PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
141 configuration.addListener( this );
143 repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
145 for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
147 File repoDir = new File( repo.getLocation() );
149 if ( !repoDir.exists() )
151 if ( !repoDir.mkdirs() )
153 // Skip invalid directories.
154 log( "Unable to create missing directory for " + repo.getLocation() );
160 resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
161 locatorFactory = new ArchivaDavLocatorFactory();
162 sessionProvider = new ArchivaDavSessionProvider(wac);
165 public void configurationEvent( ConfigurationEvent event )
167 if( event.getType() == ConfigurationEvent.SAVED )
173 private void initRepositories()
175 synchronized ( repositoryMap )
177 repositoryMap.clear();
178 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
181 synchronized ( reloadLock )
183 initServers( getServletConfig() );
187 public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
189 if ( repositoryMap.isEmpty() )
191 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
193 return repositoryMap.get( prefix );
196 ArchivaConfiguration getConfiguration()
198 return configuration;
201 protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
206 public DavSessionProvider getDavSessionProvider()
208 return sessionProvider;
211 public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
213 this.sessionProvider = davSessionProvider;
216 public DavLocatorFactory getLocatorFactory()
218 return locatorFactory;
221 public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
223 locatorFactory = davLocatorFactory;
226 public DavResourceFactory getResourceFactory()
228 return resourceFactory;
231 public void setResourceFactory(final DavResourceFactory davResourceFactory)
233 resourceFactory = davResourceFactory;
236 public String getAuthenticateHeaderValue()
238 throw new UnsupportedOperationException();
241 public String getAuthenticateHeaderValue(String repository)
243 return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";