This project has retired. For details please refer to its
Attic page.
RepositoryServlet xref
1 package org.apache.archiva.webdav;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.archiva.admin.model.RepositoryAdminException;
23 import org.apache.archiva.admin.model.beans.ManagedRepository;
24 import org.apache.archiva.admin.model.managed.ManagedRepositoryAdmin;
25 import org.apache.archiva.configuration.ArchivaConfiguration;
26 import org.apache.archiva.configuration.ConfigurationEvent;
27 import org.apache.archiva.configuration.ConfigurationListener;
28 import org.apache.archiva.redback.integration.filter.authentication.HttpAuthenticator;
29 import org.apache.archiva.security.ServletAuthenticator;
30 import org.apache.jackrabbit.webdav.DavException;
31 import org.apache.jackrabbit.webdav.DavLocatorFactory;
32 import org.apache.jackrabbit.webdav.DavMethods;
33 import org.apache.jackrabbit.webdav.DavResource;
34 import org.apache.jackrabbit.webdav.DavResourceFactory;
35 import org.apache.jackrabbit.webdav.DavServletResponse;
36 import org.apache.jackrabbit.webdav.DavSessionProvider;
37 import org.apache.jackrabbit.webdav.WebdavRequest;
38 import org.apache.jackrabbit.webdav.WebdavRequestImpl;
39 import org.apache.jackrabbit.webdav.WebdavResponse;
40 import org.apache.jackrabbit.webdav.WebdavResponseImpl;
41 import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet;
42 import org.slf4j.Logger;
43 import org.slf4j.LoggerFactory;
44 import org.springframework.context.ConfigurableApplicationContext;
45 import org.springframework.web.context.WebApplicationContext;
46 import org.springframework.web.context.support.WebApplicationContextUtils;
47
48 import javax.servlet.ServletConfig;
49 import javax.servlet.ServletException;
50 import javax.servlet.http.HttpServletRequest;
51 import javax.servlet.http.HttpServletResponse;
52 import java.io.File;
53 import java.io.IOException;
54 import java.util.Map;
55
56
57
58
59 public class RepositoryServlet
60 extends AbstractWebdavServlet
61 implements ConfigurationListener
62 {
63 private Logger log = LoggerFactory.getLogger( RepositoryServlet.class );
64
65 private ArchivaConfiguration configuration;
66
67 private ManagedRepositoryAdmin managedRepositoryAdmin;
68
69 private Map<String, ManagedRepository> repositoryMap;
70
71 private DavLocatorFactory locatorFactory;
72
73 private DavResourceFactory resourceFactory;
74
75 private DavSessionProvider sessionProvider;
76
77 private final Object reloadLock = new Object();
78
79 @Override
80 public void init( ServletConfig servletConfig )
81 throws ServletException
82 {
83 super.init( servletConfig );
84 try
85 {
86 initServers( servletConfig );
87 }
88 catch ( RepositoryAdminException e )
89 {
90 log.error( e.getMessage(), e );
91 throw new ServletException( e.getMessage(), e );
92 }
93 }
94
95
96
97
98
99
100
101
102
103
104 @Override
105 protected void service( HttpServletRequest request, HttpServletResponse response )
106 throws ServletException, IOException
107 {
108 WebdavRequest webdavRequest = new WebdavRequestImpl( request, getLocatorFactory() );
109
110 int methodCode = DavMethods.getMethodCode( request.getMethod() );
111 boolean noCache = DavMethods.isDeltaVMethod( webdavRequest ) && !( DavMethods.DAV_VERSION_CONTROL == methodCode
112 || DavMethods.DAV_REPORT == methodCode );
113 WebdavResponse webdavResponse = new WebdavResponseImpl( response, noCache );
114 DavResource resource = null;
115
116 try
117 {
118
119 if ( !getDavSessionProvider().attachSession( webdavRequest ) )
120 {
121 return;
122 }
123
124
125 resource =
126 getResourceFactory().createResource( webdavRequest.getRequestLocator(), webdavRequest, webdavResponse );
127
128 if ( !isPreconditionValid( webdavRequest, resource ) )
129 {
130 webdavResponse.sendError( DavServletResponse.SC_PRECONDITION_FAILED );
131 return;
132 }
133 if ( !execute( webdavRequest, webdavResponse, methodCode, resource ) )
134 {
135 super.service( request, response );
136 }
137
138 }
139 catch ( UnauthorizedDavException e )
140 {
141 webdavResponse.setHeader( "WWW-Authenticate", getAuthenticateHeaderValue( e.getRepositoryName() ) );
142 webdavResponse.sendError( e.getErrorCode(), e.getStatusPhrase() );
143 }
144 catch ( BrowserRedirectException e )
145 {
146 response.sendRedirect( e.getLocation() );
147 }
148 catch ( DavException e )
149 {
150 if ( e.getErrorCode() == HttpServletResponse.SC_UNAUTHORIZED )
151 {
152 final String msg = "Should throw " + UnauthorizedDavException.class.getName();
153 log.error( msg );
154 webdavResponse.sendError( e.getErrorCode(), msg );
155 }
156 else if ( e.getCause() != null )
157 {
158 webdavResponse.sendError( e.getErrorCode(), e.getCause().getMessage() );
159 }
160 else
161 {
162 webdavResponse.sendError( e.getErrorCode(), e.getMessage() );
163 }
164 }
165 finally
166 {
167 getDavSessionProvider().releaseSession( webdavRequest );
168 }
169 }
170
171 public synchronized void initServers( ServletConfig servletConfig )
172 throws RepositoryAdminException
173 {
174
175 long start = System.currentTimeMillis();
176
177 WebApplicationContext wac =
178 WebApplicationContextUtils.getRequiredWebApplicationContext( servletConfig.getServletContext() );
179
180 configuration = wac.getBean( "archivaConfiguration#default", ArchivaConfiguration.class );
181 configuration.addListener( this );
182
183 managedRepositoryAdmin = wac.getBean( ManagedRepositoryAdmin.class );
184
185 repositoryMap = managedRepositoryAdmin.getManagedRepositoriesAsMap();
186
187 for ( ManagedRepository repo : repositoryMap.values() )
188 {
189 File repoDir = new File( repo.getLocation() );
190
191 if ( !repoDir.exists() )
192 {
193 if ( !repoDir.mkdirs() )
194 {
195
196 log.info( "Unable to create missing directory for {}", repo.getLocation() );
197 continue;
198 }
199 }
200 }
201
202 resourceFactory = wac.getBean( "davResourceFactory#archiva", DavResourceFactory.class );
203 locatorFactory = new ArchivaDavLocatorFactory();
204
205 ServletAuthenticator servletAuth = wac.getBean( ServletAuthenticator.class );
206 HttpAuthenticator httpAuth = wac.getBean( "httpAuthenticator#basic", HttpAuthenticator.class );
207
208 sessionProvider = new ArchivaDavSessionProvider( servletAuth, httpAuth );
209
210 long end = System.currentTimeMillis();
211
212 log.info( "initServers done in {} ms", (end - start) );
213 }
214
215 @Override
216 public void configurationEvent( ConfigurationEvent event )
217 {
218 if ( event.getType() == ConfigurationEvent.SAVED )
219 {
220 try
221 {
222 initRepositories();
223 }
224 catch ( RepositoryAdminException e )
225 {
226 log.error( e.getMessage(), e );
227 throw new RuntimeException( e.getMessage(), e );
228 }
229 }
230 }
231
232 private void initRepositories()
233 throws RepositoryAdminException
234 {
235 synchronized ( repositoryMap )
236 {
237 repositoryMap.clear();
238 repositoryMap.putAll( managedRepositoryAdmin.getManagedRepositoriesAsMap() );
239 }
240
241 synchronized ( reloadLock )
242 {
243 initServers( getServletConfig() );
244 }
245 }
246
247 public synchronized ManagedRepository getRepository( String prefix )
248 throws RepositoryAdminException
249 {
250 if ( repositoryMap.isEmpty() )
251 {
252 repositoryMap.putAll( managedRepositoryAdmin.getManagedRepositoriesAsMap() );
253 }
254 return repositoryMap.get( prefix );
255 }
256
257 ArchivaConfiguration getConfiguration()
258 {
259 return configuration;
260 }
261
262 @Override
263 protected boolean isPreconditionValid( final WebdavRequest request, final DavResource davResource )
264 {
265
266
267 return true;
268 }
269
270 @Override
271 public DavSessionProvider getDavSessionProvider()
272 {
273 return sessionProvider;
274 }
275
276 @Override
277 public void setDavSessionProvider( final DavSessionProvider davSessionProvider )
278 {
279 this.sessionProvider = davSessionProvider;
280 }
281
282 @Override
283 public DavLocatorFactory getLocatorFactory()
284 {
285 return locatorFactory;
286 }
287
288 @Override
289 public void setLocatorFactory( final DavLocatorFactory davLocatorFactory )
290 {
291 locatorFactory = davLocatorFactory;
292 }
293
294 @Override
295 public DavResourceFactory getResourceFactory()
296 {
297 return resourceFactory;
298 }
299
300 @Override
301 public void setResourceFactory( final DavResourceFactory davResourceFactory )
302 {
303 resourceFactory = davResourceFactory;
304 }
305
306 @Override
307 public String getAuthenticateHeaderValue()
308 {
309 throw new UnsupportedOperationException();
310 }
311
312 public String getAuthenticateHeaderValue( String repository )
313 {
314 return "Basic realm=\"Repository Archiva Managed " + repository + " Repository\"";
315 }
316
317 @Override
318 public void destroy()
319 {
320 configuration.removeListener( this );
321
322 resourceFactory = null;
323 configuration = null;
324 locatorFactory = null;
325 sessionProvider = null;
326 repositoryMap.clear();
327 repositoryMap = null;
328
329 WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext( getServletContext() );
330
331 if ( wac instanceof ConfigurableApplicationContext )
332 {
333 ( (ConfigurableApplicationContext) wac ).close();
334 }
335 super.destroy();
336 }
337 }