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 log.error("Should throw UnauthorizedDavException");
126 webdavResponse.sendError(e);
129 getDavSessionProvider().releaseSession(webdavRequest);
133 public synchronized void initServers( ServletConfig servletConfig )
135 WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
137 securitySystem = (SecuritySystem) wac.getBean( PlexusToSpringUtils.buildSpringId( SecuritySystem.ROLE ) );
139 (HttpAuthenticator) wac.getBean( PlexusToSpringUtils.buildSpringId( HttpAuthenticator.ROLE, "basic" ) );
141 configuration = (ArchivaConfiguration) wac.getBean(
142 PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
143 configuration.addListener( this );
145 repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
147 for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
149 File repoDir = new File( repo.getLocation() );
151 if ( !repoDir.exists() )
153 if ( !repoDir.mkdirs() )
155 // Skip invalid directories.
156 log( "Unable to create missing directory for " + repo.getLocation() );
162 resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
163 locatorFactory = new ArchivaDavLocatorFactory();
164 sessionProvider = new ArchivaDavSessionProvider(wac);
167 public void configurationEvent( ConfigurationEvent event )
169 if( event.getType() == ConfigurationEvent.SAVED )
175 private void initRepositories()
177 synchronized ( repositoryMap )
179 repositoryMap.clear();
180 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
183 synchronized ( reloadLock )
185 initServers( getServletConfig() );
189 public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
191 if ( repositoryMap.isEmpty() )
193 repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
195 return repositoryMap.get( prefix );
198 ArchivaConfiguration getConfiguration()
200 return configuration;
203 protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
208 public DavSessionProvider getDavSessionProvider()
210 return sessionProvider;
213 public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
215 this.sessionProvider = davSessionProvider;
218 public DavLocatorFactory getLocatorFactory()
220 return locatorFactory;
223 public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
225 locatorFactory = davLocatorFactory;
228 public DavResourceFactory getResourceFactory()
230 return resourceFactory;
233 public void setResourceFactory(final DavResourceFactory davResourceFactory)
235 resourceFactory = davResourceFactory;
238 public String getAuthenticateHeaderValue()
240 throw new UnsupportedOperationException("");
243 public String getAuthenticateHeaderValue(String repository)
245 return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";