]> source.dussan.org Git - archiva.git/blob
e43bf073f1550cf5aeac16064c90785e9d5a2bc5
[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.common.utils.VersionUtil;
24 import org.apache.maven.archiva.model.ArtifactReference;
25 import org.apache.maven.archiva.repository.layout.LayoutException;
26
27 /**
28  * DefaultPathParser is a parser for maven 2 (default layout) paths to ArtifactReference.
29  *
30  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
31  * @version $Id$
32  *
33  * @plexus.component role="org.apache.maven.archiva.repository.content.PathParser" role-hint="default"
34  */
35 public class DefaultPathParser implements PathParser
36 {
37     private static final String INVALID_ARTIFACT_PATH = "Invalid path to Artifact: ";
38
39     /**
40      * {@inheritDoc}
41      * @see org.apache.maven.archiva.repository.content.PathParser#toArtifactReference(java.lang.String)
42      */
43     public ArtifactReference toArtifactReference( String path )
44         throws LayoutException
45     {
46         if ( StringUtils.isBlank( path ) )
47         {
48             throw new LayoutException( "Unable to convert blank path." );
49         }
50
51         ArtifactReference artifact = new ArtifactReference();
52
53         String normalizedPath = StringUtils.replace( path, "\\", "/" );
54         String pathParts[] = StringUtils.split( normalizedPath, '/' );
55
56         /* Minimum parts.
57          *
58          *   path = "commons-lang/commons-lang/2.1/commons-lang-2.1.jar"
59          *   path[0] = "commons-lang";        // The Group ID
60          *   path[1] = "commons-lang";        // The Artifact ID
61          *   path[2] = "2.1";                 // The Version
62          *   path[3] = "commons-lang-2.1.jar" // The filename.
63          */
64
65         if ( pathParts.length < 4 )
66         {
67             // Illegal Path Parts Length.
68             throw new LayoutException( "Not enough parts to the path [" + path
69                 + "] to construct an ArchivaArtifact from. (Requires at least 4 parts)" );
70         }
71
72         // Maven 2.x path.
73         int partCount = pathParts.length;
74         int filenamePos = partCount - 1;
75         int baseVersionPos = partCount - 2;
76         int artifactIdPos = partCount - 3;
77         int groupIdPos = partCount - 4;
78
79         // Second to last is the baseVersion (the directory version)
80         String baseVersion = pathParts[baseVersionPos];
81
82         // Third to last is the artifact Id.
83         artifact.setArtifactId( pathParts[artifactIdPos] );
84
85         // Remaining pieces are the groupId.
86         for ( int i = 0; i <= groupIdPos; i++ )
87         {
88             if ( i == 0 )
89             {
90                 artifact.setGroupId( pathParts[i] );
91             }
92             else
93             {
94                 artifact.setGroupId( artifact.getGroupId() + "." + pathParts[i] );
95             }
96         }
97
98         try
99         {
100             // Last part is the filename
101             String filename = pathParts[filenamePos];
102
103             // Now we need to parse the filename to get the artifact version Id.
104             if ( StringUtils.isBlank( filename ) )
105             {
106                 throw new IllegalArgumentException( INVALID_ARTIFACT_PATH + "Unable to split blank filename." );
107             }
108
109             FilenameParser parser = new FilenameParser( filename );
110
111             // Expect the filename to start with the artifactId.
112             artifact.setArtifactId( parser.expect( artifact.getArtifactId() ) );
113
114             if ( artifact.getArtifactId() == null )
115             {
116                 throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid, "
117                     + "should start with artifactId as stated in path." );
118             }
119
120             // Process the version.
121             artifact.setVersion( parser.expect( baseVersion ) );
122
123             if ( artifact.getVersion() == null )
124             {
125                 // We working with a snapshot?
126                 if ( VersionUtil.isSnapshot( baseVersion ) )
127                 {
128                     artifact.setVersion( parser.nextVersion() );
129                     if ( !VersionUtil.isUniqueSnapshot( artifact.getVersion() ) )
130                     {
131                         throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid,"
132                             + "expected timestamp format in filename." );
133                     }
134                 }
135                 else
136                 {
137                     throw new LayoutException( INVALID_ARTIFACT_PATH + "filename format is invalid, "
138                         + "expected version as stated in path." );
139                 }
140             }
141
142             // Do we have a classifier?
143             switch(parser.seperator())
144             {
145                 case '-':
146                     // Definately a classifier.
147                     artifact.setClassifier( parser.remaining() );
148
149                     // Set the type.
150                     artifact.setType( ArtifactExtensionMapping.mapExtensionAndClassifierToType( artifact.getClassifier(), parser.getExtension() ) );
151                     break;
152                 case '.':
153                     // We have an dual extension possibility.
154                     String extension = parser.remaining() + '.' + parser.getExtension();
155                     artifact.setType( extension.replace( '.', '-' ) );
156                     break;
157                 case 0:
158                     // End of the filename, only a simple extension left. - Set the type.
159                     String type = ArtifactExtensionMapping.mapExtensionToType( parser.getExtension() );
160                     if ( type == null )
161                     {
162                         throw new LayoutException( "Invalid artifact: no type was specified" );
163                     }
164                     artifact.setType( type );
165                     break;
166             }
167
168             // Special case for maven plugins
169             if ( StringUtils.equals( "jar", artifact.getType() ) &&
170                  ArtifactExtensionMapping.isMavenPlugin( artifact.getArtifactId() ) )
171             {
172                 artifact.setType( ArtifactExtensionMapping.MAVEN_PLUGIN );
173             }
174         }
175         catch ( LayoutException e )
176         {
177             throw e;
178         }
179
180         // Sanity Checks.
181
182         // Do we have a snapshot version?
183         if ( VersionUtil.isSnapshot( artifact.getVersion() ) )
184         {
185             // Rules are different for SNAPSHOTS
186             if ( !VersionUtil.isGenericSnapshot( baseVersion ) )
187             {
188                 String filenameBaseVersion = VersionUtil.getBaseVersion( artifact.getVersion() );
189                 throw new LayoutException( "Invalid snapshot artifact location, version directory should be "
190                     + filenameBaseVersion );
191             }
192         }
193         else
194         {
195             // Non SNAPSHOT rules.
196             // Do we pass the simple test?
197             if ( !StringUtils.equals( baseVersion, artifact.getVersion() ) )
198             {
199                 throw new LayoutException( "Invalid artifact: version declared in directory path does"
200                     + " not match what was found in the artifact filename." );
201             }
202         }
203
204         return artifact;
205     }
206
207 }