]> source.dussan.org Git - archiva.git/blob
7a67cf75f696f06ce381df0d98de47898090bada
[archiva.git] /
1 package org.apache.maven.archiva.repository.content;
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.commons.lang.StringUtils;
23 import org.apache.maven.archiva.configuration.ArchivaConfiguration;
24 import org.apache.maven.archiva.configuration.FileTypes;
25 import org.apache.maven.archiva.model.ArtifactReference;
26 import org.apache.maven.archiva.repository.ManagedRepositoryContent;
27 import org.apache.maven.archiva.repository.layout.LayoutException;
28 import org.apache.maven.archiva.repository.metadata.MetadataTools;
29 import org.codehaus.plexus.personality.plexus.lifecycle.phase.Initializable;
30 import org.codehaus.plexus.personality.plexus.lifecycle.phase.InitializationException;
31 import org.codehaus.plexus.registry.Registry;
32 import org.codehaus.plexus.registry.RegistryListener;
33 import org.codehaus.plexus.util.SelectorUtils;
34
35 import java.util.ArrayList;
36 import java.util.Iterator;
37 import java.util.List;
38
39 /**
40  * RepositoryRequest is used to determine the type of request that is incoming, and convert it to an appropriate
41  * ArtifactReference.  
42  *
43  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
44  * @version $Id$
45  * 
46  * @plexus.component 
47  *      role="org.apache.maven.archiva.repository.content.RepositoryRequest"
48  */
49 public class RepositoryRequest
50     implements RegistryListener, Initializable
51 {
52     /**
53      * @plexus.requirement
54      */
55     private FileTypes filetypes;
56
57     /**
58      * @plexus.requirement
59      */
60     private ArchivaConfiguration archivaConfiguration;
61
62     private List<String> artifactPatterns;
63
64     /**
65      * Test path to see if it is an artifact being requested (or not).
66      * 
67      * @param requestedPath the path to test.
68      * @return true if it is an artifact being requested.
69      */
70     public boolean isArtifact( String requestedPath )
71     {
72         // Correct the slash pattern.
73         String relativePath = requestedPath.replace( '\\', '/' );
74
75         Iterator<String> it = this.artifactPatterns.iterator();
76         while ( it.hasNext() )
77         {
78             String pattern = it.next();
79
80             if ( SelectorUtils.matchPath( pattern, relativePath, false ) )
81             {
82                 // Found match
83                 return true;
84             }
85         }
86
87         // No match.
88         return false;
89     }
90
91     /**
92      * Takes an incoming requested path (in "/" format) and gleans the layout
93      * and ArtifactReference appropriate for that content.
94      * 
95      * @param requestedPath the relative path to the content.
96      * @return the ArtifactReference for the requestedPath.
97      * @throws LayoutException if the request path is not layout valid. 
98      */
99     public ArtifactReference toArtifactReference( String requestedPath )
100         throws LayoutException
101     {
102         if ( StringUtils.isBlank( requestedPath ) )
103         {
104             throw new LayoutException( "Blank request path is not a valid." );
105         }
106         
107         String path = requestedPath;
108         while ( path.startsWith( "/" ) )
109         {
110             path = path.substring( 1 );
111
112             // Only slash? that's bad, mmm-kay?
113             if ( "/".equals( path ) )
114             {
115                 throw new LayoutException( "Invalid request path: Slash only." );
116             }
117         }
118
119         if ( isDefault( path ) )
120         {
121             return DefaultPathParser.toArtifactReference( path );
122         }
123         else if ( isLegacy( path ) )
124         {
125             return LegacyPathParser.toArtifactReference( path );
126         }
127         else
128         {
129             throw new LayoutException( "Not a valid request path layout, too short." );
130         }
131     }
132     
133     /**
134      * <p>
135      * Tests the path to see if it conforms to the expectations of a metadata request.
136      * </p>
137      * <p>
138      * NOTE: This does a cursory check on the path's last element.  A result of true
139      * from this method is not a guarantee that the metadata is in a valid format, or
140      * that it even contains data.
141      * </p> 
142      * 
143      * @param requestedPath the path to test.
144      * @return true if the requestedPath is likely a metadata request.
145      */
146     public boolean isMetadata( String requestedPath )
147     {
148         return requestedPath.endsWith( "/" + MetadataTools.MAVEN_METADATA );
149     }
150     
151     /**
152      * <p>
153      * Tests the path to see if it conforms to the expectations of a support file request.
154      * </p>
155      * <p>
156      * Tests for <code>.sha1</code>, <code>.md5</code>, <code>.asc</code>, and <code>.php</code>.
157      * </p>
158      * <p>
159      * NOTE: This does a cursory check on the path's extension only.  A result of true
160      * from this method is not a guarantee that the support resource is in a valid format, or
161      * that it even contains data.
162      * </p> 
163      * 
164      * @param requestedPath the path to test.
165      * @return true if the requestedPath is likely that of a support file request.
166      */
167     public boolean isSupportFile( String requestedPath )
168     {
169         int idx = requestedPath.lastIndexOf( '.' );
170         if ( idx <= 0 )
171         {
172             return false;
173         }
174
175         String ext = requestedPath.substring( idx );
176         return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) );
177     }
178     
179     /**
180      * <p>
181      * Tests the path to see if it conforms to the expectations of a default layout request.
182      * </p>
183      * <p>
184      * NOTE: This does a cursory check on the count of path elements only.  A result of
185      * true from this method is not a guarantee that the path sections are valid and
186      * can be resolved to an artifact reference.  use {@link #toArtifactReference(String)} 
187      * if you want a more complete analysis of the validity of the path.
188      * </p>
189      * 
190      * @param requestedPath the path to test.
191      * @return true if the requestedPath is likely that of a default layout request.
192      */
193     public boolean isDefault( String requestedPath )
194     {
195         if ( StringUtils.isBlank( requestedPath ) )
196         {
197             return false;
198         }
199         
200         String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' );
201         return pathParts.length > 3;
202     }
203     
204     /**
205      * <p>
206      * Tests the path to see if it conforms to the expectations of a legacy layout request.
207      * </p>
208      * <p>
209      * NOTE: This does a cursory check on the count of path elements only.  A result of
210      * true from this method is not a guarantee that the path sections are valid and
211      * can be resolved to an artifact reference.  use {@link #toArtifactReference(String)} 
212      * if you want a more complete analysis of the validity of the path.
213      * </p>
214      * 
215      * @param requestedPath the path to test.
216      * @return true if the requestedPath is likely that of a legacy layout request.
217      */
218     public boolean isLegacy( String requestedPath )
219     {
220         if ( StringUtils.isBlank( requestedPath ) )
221         {
222             return false;
223         }
224         
225         String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' );
226         return pathParts.length == 3;
227     }
228     
229     /**
230      * Adjust the requestedPath to conform to the native layout of the provided {@link ManagedRepositoryContent}.
231      * 
232      * @param requestedPath the incoming requested path.
233      * @param repository the repository to adjust to.
234      * @return the adjusted (to native) path.
235      * @throws LayoutException if the path cannot be parsed. 
236      */
237     public String toNativePath( String requestedPath, ManagedRepositoryContent repository ) throws LayoutException
238     {
239         if ( StringUtils.isBlank( requestedPath ) )
240         {
241             throw new LayoutException( "Request Path is blank." );
242         }
243         
244         String referencedResource = requestedPath;
245         // No checksum by default.
246         String supportfile = "";
247         
248         // Figure out support file, and actual referencedResource.
249         if( isSupportFile( requestedPath ) )
250         {
251             int idx = requestedPath.lastIndexOf( '.' );
252             referencedResource = requestedPath.substring( 0, idx );
253             supportfile = requestedPath.substring( idx );
254         }
255
256         if ( isMetadata( referencedResource ) )
257         {
258             if ( repository instanceof ManagedLegacyRepositoryContent )
259             {
260                 throw new LayoutException( "Cannot translate metadata request to legacy layout." );
261             }
262             
263             /* Nothing to translate.
264              * Default layout is the only layout that can contain maven-metadata.xml files, and
265              * if the managedRepository is layout legacy, this request would never occur.
266              */
267             return requestedPath;
268         }
269
270         // Treat as an artifact reference.
271         ArtifactReference ref = toArtifactReference( referencedResource );
272         String adjustedPath = repository.toPath( ref );
273         return adjustedPath + supportfile;
274     }
275
276     public void initialize()
277         throws InitializationException
278     {
279         this.artifactPatterns = new ArrayList<String>();
280         initVariables();
281         this.archivaConfiguration.addChangeListener( this );
282     }
283
284     private void initVariables()
285     {
286         synchronized ( this.artifactPatterns )
287         {
288             this.artifactPatterns.clear();
289             this.artifactPatterns.addAll( filetypes.getFileTypePatterns( FileTypes.ARTIFACTS ) );
290         }
291     }
292
293     public void afterConfigurationChange( Registry registry, String propertyName, Object propertyValue )
294     {
295         if ( propertyName.contains( "fileType" ) )
296         {
297             initVariables();
298         }
299     }
300
301     public void beforeConfigurationChange( Registry registry, String propertyName, Object propertyValue )
302     {
303         /* nothing to do */
304
305     }
306 }