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.
88 * @throws ServletException
89 * @throws java.io.IOException
92 protected void service(HttpServletRequest request, HttpServletResponse response)
93 throws ServletException, IOException
95 WebdavRequest webdavRequest = new WebdavRequestImpl(request, getLocatorFactory());
96 // DeltaV requires 'Cache-Control' header for all methods except 'VERSION-CONTROL' and 'REPORT'.
97 int methodCode = DavMethods.getMethodCode(request.getMethod());
98 boolean noCache = DavMethods.isDeltaVMethod(webdavRequest) && !(DavMethods.DAV_VERSION_CONTROL == methodCode || DavMethods.DAV_REPORT == methodCode);
99 WebdavResponse webdavResponse = new WebdavResponseImpl(response, noCache);
101 // make sure there is a authenticated user
102 if (!getDavSessionProvider().attachSession(webdavRequest)) {
106 // check matching if=header for lock-token relevant operations
107 DavResource resource = getResourceFactory().createResource(webdavRequest.getRequestLocator(), webdavRequest, webdavResponse);
108 if (!isPreconditionValid(webdavRequest, resource)) {
109 webdavResponse.sendError(DavServletResponse.SC_PRECONDITION_FAILED);
112 if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
113 super.service(request, response);
117 catch (UnauthorizedDavException e)
119 webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue(e.getRepositoryName()));
120 webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
122 catch (DavException e) {
123 if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
124 final String msg = "Should throw " + UnauthorizedDavException.class.getName();
126 webdavResponse.sendError(e.getErrorCode(), msg);
128 webdavResponse.sendError(e);
131 getDavSessionProvider().releaseSession(webdavRequest);
135 public synchronized void initServers( ServletConfig servletConfig )
137 WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
139 securitySystem = (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
141 (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
143 configuration = (ArchivaConfiguration) wac.getBean(
144 PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
145 configuration.addListener( this );
147 repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
149 for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
151 File repoDir = new File( repo.getLocation() );
153 if ( !repoDir.exists() )
155 if ( !repoDir.mkdirs() )
157 // Skip invalid directories.
158 log( "Unable to create missing directory for " + repo.getLocation() );
164 resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
165 locatorFactory = new ArchivaDavLocatorFactory();
166 sessionProvider = new ArchivaDavSessionProvider(wac);
169 public void configurationEvent( ConfigurationEvent event )
171 if( event.getType() == ConfigurationEvent.SAVED )
177 private void initRepositories()
179 synchronized ( repositoryMap )
181 repositoryMap.clear();
182 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
185 synchronized ( reloadLock )
187 initServers( getServletConfig() );
191 public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
193 if ( repositoryMap.isEmpty() )
195 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
197 return repositoryMap.get( prefix );
200 ArchivaConfiguration getConfiguration()
202 return configuration;
205 protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
210 public DavSessionProvider getDavSessionProvider()
212 return sessionProvider;
215 public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
217 this.sessionProvider = davSessionProvider;
220 public DavLocatorFactory getLocatorFactory()
222 return locatorFactory;
225 public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
227 locatorFactory = davLocatorFactory;
230 public DavResourceFactory getResourceFactory()
232 return resourceFactory;
235 public void setResourceFactory(final DavResourceFactory davResourceFactory)
237 resourceFactory = davResourceFactory;
240 public String getAuthenticateHeaderValue()
242 throw new UnsupportedOperationException("");
245 public String getAuthenticateHeaderValue(String repository)
247 return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";