]> source.dussan.org Git - archiva.git/blob
6d28d12f24c30423c782288d342e7166363cbdaf
[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
30 /**
31  * RepositoryRequest is used to determine the type of request that is incoming, and convert it to an appropriate
32  * ArtifactReference.
33  *
34  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
35  * @version $Id$
36  *
37  * @plexus.component
38  *      role="org.apache.maven.archiva.repository.content.RepositoryRequest"
39  */
40 public class RepositoryRequest
41 {
42     /**
43      * @plexus.requirement
44      */
45     private FileTypes filetypes;
46
47     /**
48      * @plexus.requirement
49      */
50     private ArchivaConfiguration archivaConfiguration;
51
52     /**
53      * @plexus.requirement role-hint="default"
54      */
55     private PathParser defaultPathParser;
56
57     /**
58      * @plexus.requirement role-hint="legacy"
59      */
60     private PathParser legacyPathParser;
61
62     /**
63      * Takes an incoming requested path (in "/" format) and gleans the layout
64      * and ArtifactReference appropriate for that content.
65      *
66      * @param requestedPath the relative path to the content.
67      * @return the ArtifactReference for the requestedPath.
68      * @throws LayoutException if the request path is not layout valid.
69      */
70     public ArtifactReference toArtifactReference( String requestedPath )
71         throws LayoutException
72     {
73         if ( StringUtils.isBlank( requestedPath ) )
74         {
75             throw new LayoutException( "Blank request path is not a valid." );
76         }
77
78         String path = requestedPath;
79         while ( path.startsWith( "/" ) )
80         {
81             path = path.substring( 1 );
82
83             // Only slash? that's bad, mmm-kay?
84             if ( "/".equals( path ) )
85             {
86                 throw new LayoutException( "Invalid request path: Slash only." );
87             }
88         }
89
90         if ( isDefault( path ) )
91         {
92             return defaultPathParser.toArtifactReference( path );
93         }
94         else if ( isLegacy( path ) )
95         {
96             return legacyPathParser.toArtifactReference( path );
97         }
98         else
99         {
100             throw new LayoutException( "Not a valid request path layout, too short." );
101         }
102     }
103
104     /**
105      * <p>
106      * Tests the path to see if it conforms to the expectations of a metadata request.
107      * </p>
108      * <p>
109      * NOTE: This does a cursory check on the path's last element.  A result of true
110      * from this method is not a guarantee that the metadata is in a valid format, or
111      * that it even contains data.
112      * </p>
113      *
114      * @param requestedPath the path to test.
115      * @return true if the requestedPath is likely a metadata request.
116      */
117     public boolean isMetadata( String requestedPath )
118     {
119         return requestedPath.endsWith( "/" + MetadataTools.MAVEN_METADATA );
120     }
121
122     /**
123      * <p>
124      * Tests the path to see if it conforms to the expectations of a support file request.
125      * </p>
126      * <p>
127      * Tests for <code>.sha1</code>, <code>.md5</code>, <code>.asc</code>, and <code>.php</code>.
128      * </p>
129      * <p>
130      * NOTE: This does a cursory check on the path's extension only.  A result of true
131      * from this method is not a guarantee that the support resource is in a valid format, or
132      * that it even contains data.
133      * </p>
134      *
135      * @param requestedPath the path to test.
136      * @return true if the requestedPath is likely that of a support file request.
137      */
138     public boolean isSupportFile( String requestedPath )
139     {
140         int idx = requestedPath.lastIndexOf( '.' );
141         if ( idx <= 0 )
142         {
143             return false;
144         }
145
146         String ext = requestedPath.substring( idx );
147         return ( ".sha1".equals( ext ) || ".md5".equals( ext ) || ".asc".equals( ext ) || ".pgp".equals( ext ) );
148     }
149
150     /**
151      * <p>
152      * Tests the path to see if it conforms to the expectations of a default layout request.
153      * </p>
154      * <p>
155      * NOTE: This does a cursory check on the count of path elements only.  A result of
156      * true from this method is not a guarantee that the path sections are valid and
157      * can be resolved to an artifact reference.  use {@link #toArtifactReference(String)}
158      * if you want a more complete analysis of the validity of the path.
159      * </p>
160      *
161      * @param requestedPath the path to test.
162      * @return true if the requestedPath is likely that of a default layout request.
163      */
164     public boolean isDefault( String requestedPath )
165     {
166         if ( StringUtils.isBlank( requestedPath ) )
167         {
168             return false;
169         }
170
171         String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' );
172         return pathParts.length > 3;
173     }
174
175     /**
176      * <p>
177      * Tests the path to see if it conforms to the expectations of a legacy layout request.
178      * </p>
179      * <p>
180      * NOTE: This does a cursory check on the count of path elements only.  A result of
181      * true from this method is not a guarantee that the path sections are valid and
182      * can be resolved to an artifact reference.  use {@link #toArtifactReference(String)}
183      * if you want a more complete analysis of the validity of the path.
184      * </p>
185      *
186      * @param requestedPath the path to test.
187      * @return true if the requestedPath is likely that of a legacy layout request.
188      */
189     public boolean isLegacy( String requestedPath )
190     {
191         if ( StringUtils.isBlank( requestedPath ) )
192         {
193             return false;
194         }
195
196         String pathParts[] = StringUtils.splitPreserveAllTokens( requestedPath, '/' );
197         return pathParts.length == 3;
198     }
199
200     /**
201      * Adjust the requestedPath to conform to the native layout of the provided {@link ManagedRepositoryContent}.
202      *
203      * @param requestedPath the incoming requested path.
204      * @param repository the repository to adjust to.
205      * @return the adjusted (to native) path.
206      * @throws LayoutException if the path cannot be parsed.
207      */
208     public String toNativePath( String requestedPath, ManagedRepositoryContent repository ) throws LayoutException
209     {
210         if ( StringUtils.isBlank( requestedPath ) )
211         {
212             throw new LayoutException( "Request Path is blank." );
213         }
214
215         String referencedResource = requestedPath;
216         // No checksum by default.
217         String supportfile = "";
218
219         // Figure out support file, and actual referencedResource.
220         if( isSupportFile( requestedPath ) )
221         {
222             int idx = requestedPath.lastIndexOf( '.' );
223             referencedResource = requestedPath.substring( 0, idx );
224             supportfile = requestedPath.substring( idx );
225         }
226
227         if ( isMetadata( referencedResource ) )
228         {
229             if ( repository instanceof ManagedLegacyRepositoryContent )
230             {
231                 throw new LayoutException( "Cannot translate metadata request to legacy layout." );
232             }
233
234             /* Nothing to translate.
235              * Default layout is the only layout that can contain maven-metadata.xml files, and
236              * if the managedRepository is layout legacy, this request would never occur.
237              */
238             return requestedPath;
239         }
240
241         // Treat as an artifact reference.
242         ArtifactReference ref = toArtifactReference( referencedResource );
243         String adjustedPath = repository.toPath( ref );
244         return adjustedPath + supportfile;
245     }
246 }