]> source.dussan.org Git - archiva.git/blob
732b97bf1a643c5bb062b978e5245076a72d8910
[archiva.git] /
1 package org.apache.maven.archiva.web.repository;
2
3 /*
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
11  *
12  *  http://www.apache.org/licenses/LICENSE-2.0
13  *
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
19  * under the License.
20  */
21
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;
34
35 import javax.servlet.ServletConfig;
36 import javax.servlet.ServletException;
37 import javax.servlet.http.HttpServletResponse;
38 import javax.servlet.http.HttpServletRequest;
39 import java.io.File;
40 import java.io.IOException;
41 import java.util.Map;
42
43 /**
44  * RepositoryServlet
45  *
46  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
47  * @version $Id$
48  */
49 public class RepositoryServlet
50     extends AbstractWebdavServlet
51     implements ConfigurationListener
52 {
53     private Logger log = LoggerFactory.getLogger(RepositoryServlet.class);
54
55     private ArchivaConfiguration configuration;
56
57     private Map<String, ManagedRepositoryConfiguration> repositoryMap;
58
59     private DavLocatorFactory locatorFactory;
60
61     private DavResourceFactory resourceFactory;
62
63     private DavSessionProvider sessionProvider;
64
65     private final Object reloadLock = new Object();
66
67     public void init(javax.servlet.ServletConfig servletConfig)
68         throws ServletException
69     {
70         super.init(servletConfig);
71         initServers(servletConfig);
72     }
73
74     /**
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
78      *
79      * @param request
80      * @param response
81      * @throws ServletException
82      * @throws java.io.IOException
83      */
84     @Override
85     protected void service(HttpServletRequest request, HttpServletResponse response)
86             throws ServletException, IOException
87     {
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);
93         try {
94             // make sure there is a authenticated user
95             if (!getDavSessionProvider().attachSession(webdavRequest)) {
96                 return;
97             }
98
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);
103                 return;
104             }
105             if (!execute(webdavRequest, webdavResponse, methodCode, resource)) {
106                 super.service(request, response);
107             }
108
109         }
110         catch (UnauthorizedDavException e)
111         {
112             webdavResponse.setHeader("WWW-Authenticate", getAuthenticateHeaderValue(e.getRepositoryName()));
113             webdavResponse.sendError(e.getErrorCode(), e.getStatusPhrase());
114         }
115         catch (BrowserRedirectException e)
116         {
117             response.sendRedirect(e.getLocation());
118         }
119         catch (DavException e)
120         {
121             if (e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED) {
122                 final String msg = "Should throw " + UnauthorizedDavException.class.getName();
123                 log.error(msg);
124                 webdavResponse.sendError(e.getErrorCode(), msg);
125             } else if ( e.getCause() != null ) {
126                 webdavResponse.sendError(e.getErrorCode(), e.getCause().getMessage());
127             } else {
128                 webdavResponse.sendError(e.getErrorCode(), e.getMessage());
129             }
130         } finally {
131             getDavSessionProvider().releaseSession(webdavRequest);
132         }
133     }
134
135     public synchronized void initServers( ServletConfig servletConfig )
136     {
137         WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
138
139         configuration = (ArchivaConfiguration) wac.getBean(
140             PlexusToSpringUtils.buildSpringId( ArchivaConfiguration.class.getName() ) );
141         configuration.addListener( this );
142
143         repositoryMap = configuration.getConfiguration().getManagedRepositoriesAsMap();
144
145         for ( ManagedRepositoryConfiguration repo : repositoryMap.values() )
146         {
147             File repoDir = new File( repo.getLocation() );
148
149             if ( !repoDir.exists() )
150             {
151                 if ( !repoDir.mkdirs() )
152                 {
153                     // Skip invalid directories.
154                     log( "Unable to create missing directory for " + repo.getLocation() );
155                     continue;
156                 }
157             }
158         }
159
160         resourceFactory = (DavResourceFactory)wac.getBean(PlexusToSpringUtils.buildSpringId(ArchivaDavResourceFactory.class));
161         locatorFactory = new ArchivaDavLocatorFactory();
162         sessionProvider = new ArchivaDavSessionProvider(wac);
163     }
164     
165     public void configurationEvent( ConfigurationEvent event )
166     {
167         if( event.getType() == ConfigurationEvent.SAVED )
168         {
169             initRepositories();
170         }
171     }
172
173     private void initRepositories()
174     {
175         synchronized ( repositoryMap )
176         {
177             repositoryMap.clear();
178             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
179         }
180
181         synchronized ( reloadLock )
182         {
183             initServers( getServletConfig() );
184         }
185     }
186
187     public synchronized ManagedRepositoryConfiguration getRepository( String prefix )
188     {
189         if ( repositoryMap.isEmpty() )
190         {
191             repositoryMap.putAll( configuration.getConfiguration().getManagedRepositoriesAsMap() );
192         }
193         return repositoryMap.get( prefix );
194     }
195
196     ArchivaConfiguration getConfiguration()
197     {
198         return configuration;
199     }
200
201     protected boolean isPreconditionValid(final WebdavRequest request, final DavResource davResource)
202     {
203         return true;
204     }
205
206     public DavSessionProvider getDavSessionProvider()
207     {
208         return sessionProvider;
209     }
210
211     public void setDavSessionProvider(final DavSessionProvider davSessionProvider)
212     {
213         this.sessionProvider = davSessionProvider;
214     }
215
216     public DavLocatorFactory getLocatorFactory()
217     {
218         return locatorFactory;
219     }
220
221     public void setLocatorFactory(final DavLocatorFactory davLocatorFactory)
222     {
223         locatorFactory = davLocatorFactory;
224     }
225
226     public DavResourceFactory getResourceFactory()
227     {
228         return resourceFactory;
229     }
230
231     public void setResourceFactory(final DavResourceFactory davResourceFactory)
232     {
233         resourceFactory = davResourceFactory;
234     }
235
236     public String getAuthenticateHeaderValue()
237     {
238         throw new UnsupportedOperationException();
239     }
240
241     public String getAuthenticateHeaderValue(String repository)
242     {
243         return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";
244     }
245 }