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.ArchivaDavLocatorFactory;
27 import org.apache.maven.archiva.webdav.ArchivaDavResourceFactory;
28 import org.apache.maven.archiva.webdav.ArchivaDavSessionProvider;
29 import org.apache.maven.archiva.webdav.UnauthorizedDavException;
30 import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
31 import org.apache.jackrabbit.webdav.*;
32 import org.codehaus.plexus.redback.system.SecuritySystem;
33 import org.codehaus.plexus.redback.xwork.filter.authentication.HttpAuthenticator;
34 import org.codehaus.plexus.spring.PlexusToSpringUtils;
35 import org.springframework.web.context.WebApplicationContext;
36 import org.springframework.web.context.support.WebApplicationContextUtils;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
40 import javax.servlet.ServletConfig;
41 import javax.servlet.ServletException;
42 import javax.servlet.http.HttpServletResponse;
43 import javax.servlet.http.HttpServletRequest;
45 import java.io.IOException;
51 * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
54 public class RepositoryServlet
55 extends AbstractWebdavServlet
56 implements ConfigurationListener
58 private Logger log = LoggerFactory.getLogger(RepositoryServlet.class);
60 private SecuritySystem securitySystem;
62 private HttpAuthenticator httpAuth;
64 private ArchivaConfiguration configuration;
66 private Map<String, ManagedRepositoryConfiguration> repositoryMap;
68 private DavLocatorFactory locatorFactory;
70 private DavResourceFactory resourceFactory;
72 private DavSessionProvider sessionProvider;
74 private final Object reloadLock = new Object();
76 public void init(javax.servlet.ServletConfig servletConfig)
77 throws ServletException
79 super.init(servletConfig);
80 initServers(servletConfig);
84 * Service the given request.
85 * This method has been overridden and copy/pasted to allow better exception handling
86 * and to support different realms
90 * @throws ServletException
91 * @throws java.io.IOException
94 protected void service(HttpServletRequest request, HttpServletResponse response)
95 throws ServletException, IOException
97 WebdavRequest webdavRequest = new WebdavRequestImpl(request, getLocatorFactory());
98 // DeltaV requires 'Cache-Control' header for all methods except 'VERSION-CONTROL' and 'REPORT'.
99 int methodCode = DavMethods.getMethodCode(request.getMethod());
100 boolean noCache = DavMethods.isDeltaVMethod(webdavRequest) && !(DavMethods.DAV_VERSION_CONTROL == methodCode || DavMethods.DAV_REPORT == methodCode);
101 WebdavResponse webdavResponse = new WebdavResponseImpl(response, noCache);
103 // make sure there is a authenticated user
104 if (!getDavSessionProvider().attachSession(webdavRequest)) {
108 // check matching if=header for lock-token relevant operations
109 DavResource resource = getResourceFactory().createResource(webdavRequest.getRequestLocator(), webdavRequest, webdavResponse);
110 if (!isPreconditionValid(webdavRequest, resource)) {
111 webdavResponse.sendError(DavServletResponse.SC_PRECONDITION_FAILED);
114 if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
115 super.service(request, response);
119 catch (UnauthorizedDavException e)
121 webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue(e.getRepositoryName()));
122 webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
124 catch (DavException e) {
125 if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
126 final String msg = "Should throw " + UnauthorizedDavException.class.getName();
128 webdavResponse.sendError(e.getErrorCode(), msg);
129 } else if ( e.getCause() != null ) {
130 webdavResponse.sendError(e.getErrorCode(), e.getCause().getMessage());
132 webdavResponse.sendError(e.getErrorCode(), e.getMessage());
135 getDavSessionProvider().releaseSession(webdavRequest);
139 public synchronized void initServers( ServletConfig servletConfig )
141 WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
143 securitySystem = (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
145 (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
147 configuration = (ArchivaConfiguration) wac.getBean(
148 PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
149 configuration.addListener( this );
151 repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
153 for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
155 File repoDir = new File( repo.getLocation() );
157 if ( !repoDir.exists() )
159 if ( !repoDir.mkdirs() )
161 // Skip invalid directories.
162 log( "Unable to create missing directory for " + repo.getLocation() );
168 resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
169 locatorFactory = new ArchivaDavLocatorFactory();
170 sessionProvider = new ArchivaDavSessionProvider(wac);
173 public void configurationEvent( ConfigurationEvent event )
175 if( event.getType() == ConfigurationEvent.SAVED )
181 private void initRepositories()
183 synchronized ( repositoryMap )
185 repositoryMap.clear();
186 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
189 synchronized ( reloadLock )
191 initServers( getServletConfig() );
195 public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
197 if ( repositoryMap.isEmpty() )
199 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
201 return repositoryMap.get( prefix );
204 ArchivaConfiguration getConfiguration()
206 return configuration;
209 protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
214 public DavSessionProvider getDavSessionProvider()
216 return sessionProvider;
219 public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
221 this.sessionProvider = davSessionProvider;
224 public DavLocatorFactory getLocatorFactory()
226 return locatorFactory;
229 public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
231 locatorFactory = davLocatorFactory;
234 public DavResourceFactory getResourceFactory()
236 return resourceFactory;
239 public void setResourceFactory(final DavResourceFactory davResourceFactory)
241 resourceFactory = davResourceFactory;
244 public String getAuthenticateHeaderValue()
246 throw new UnsupportedOperationException();
249 public String getAuthenticateHeaderValue(String repository)
251 return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";