]> source.dussan.org Git - archiva.git/blob
a7121138e31b5d416c594bb0dc5adbdc6cbf3a56
[archiva.git] /
1 package org.apache.maven.archiva.reporting;
2
3 /*
4  * Copyright 2005-2006 The Apache Software Foundation.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import org.apache.maven.artifact.Artifact;
20 import org.apache.maven.artifact.factory.ArtifactFactory;
21 import org.apache.maven.artifact.repository.ArtifactRepository;
22 import org.apache.maven.model.Model;
23 import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
24 import org.apache.maven.project.MavenProjectBuilder;
25 import org.codehaus.plexus.util.IOUtil;
26 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.io.InputStream;
31 import java.io.InputStreamReader;
32 import java.io.Reader;
33 import java.util.Arrays;
34 import java.util.HashSet;
35 import java.util.Set;
36 import java.util.jar.JarEntry;
37 import java.util.jar.JarFile;
38
39 /**
40  * Validate the location of the artifact based on the values indicated
41  * in its pom (both the pom packaged with the artifact & the pom in the
42  * file system).
43  *
44  * @plexus.component role="org.apache.maven.archiva.reporting.ArtifactReportProcessor" role-hint="artifact-location"
45  */
46 public class LocationArtifactReportProcessor
47     implements ArtifactReportProcessor
48 {
49     /**
50      * @plexus.requirement
51      */
52     private ArtifactFactory artifactFactory;
53
54     // TODO: share with other code with the same
55     private static final Set JAR_FILE_TYPES =
56         new HashSet( Arrays.asList( new String[]{"jar", "war", "par", "ejb", "ear", "rar", "sar"} ) );
57
58     /**
59      * @plexus.requirement
60      */
61     private MavenProjectBuilder projectBuilder;
62
63     /**
64      * Check whether the artifact is in its proper location. The location of the artifact
65      * is validated first against the groupId, artifactId and versionId in the specified model
66      * object (pom in the file system). Then unpack the artifact (jar file) and get the model (pom)
67      * included in the package. If a model exists inside the package, then check if the artifact's
68      * location is valid based on the location specified in the pom. Check if the both the location
69      * specified in the file system pom and in the pom included in the package is the same.
70      */
71     public void processArtifact( Artifact artifact, Model model, ReportingDatabase reporter )
72     {
73         ArtifactRepository repository = artifact.getRepository();
74
75         if ( !"file".equals( repository.getProtocol() ) )
76         {
77             // We can't check other types of URLs yet. Need to use Wagon, with an exists() method.
78             throw new UnsupportedOperationException(
79                 "Can't process repository '" + repository.getUrl() + "'. Only file based repositories are supported" );
80         }
81
82         String artifactPath = repository.pathOf( artifact );
83
84         if ( model != null )
85         {
86             //check if the artifact is located in its proper location based on the info
87             //specified in the model object/pom
88             Artifact modelArtifact = artifactFactory.createBuildArtifact( model.getGroupId(), model.getArtifactId(),
89                                                                           model.getVersion(), model.getPackaging() );
90
91             String modelPath = repository.pathOf( modelArtifact );
92             if ( !modelPath.equals( artifactPath ) )
93             {
94                 reporter.addFailure( artifact,
95                                      "The artifact is out of place. It does not match the specified location in the repository pom." );
96             }
97         }
98
99         //get the location of the artifact itself
100         File file = new File( repository.getBasedir(), artifactPath );
101
102         if ( file.exists() )
103         {
104             if ( JAR_FILE_TYPES.contains( artifact.getType() ) )
105             {
106                 //unpack the artifact (using the groupId, artifactId & version specified in the artifact object itself
107                 //check if the pom is included in the package
108                 Model extractedModel = readArtifactModel( file, artifact, reporter );
109
110                 if ( extractedModel != null )
111                 {
112                     Artifact extractedArtifact = artifactFactory.createBuildArtifact( extractedModel.getGroupId(),
113                                                                                       extractedModel.getArtifactId(),
114                                                                                       extractedModel.getVersion(),
115                                                                                       extractedModel.getPackaging() );
116                     if ( !repository.pathOf( extractedArtifact ).equals( artifactPath ) )
117                     {
118                         reporter.addFailure( artifact,
119                                              "The artifact is out of place. It does not match the specified location in the packaged pom." );
120                     }
121                 }
122             }
123         }
124         else
125         {
126             reporter.addFailure( artifact,
127                                  "The artifact is out of place. It does not exist at the specified location in the repository pom." );
128         }
129     }
130
131     private Model readArtifactModel( File file, Artifact artifact, ReportingDatabase reporter )
132     {
133         Model model = null;
134
135         JarFile jar = null;
136         try
137         {
138             jar = new JarFile( file );
139
140             //Get the entry and its input stream.
141             JarEntry entry = jar.getJarEntry(
142                 "META-INF/maven/" + artifact.getGroupId() + "/" + artifact.getArtifactId() + "/pom.xml" );
143
144             // If the entry is not null, extract it.
145             if ( entry != null )
146             {
147                 model = readModel( jar.getInputStream( entry ) );
148
149                 if ( model.getGroupId() == null )
150                 {
151                     model.setGroupId( model.getParent().getGroupId() );
152                 }
153                 if ( model.getVersion() == null )
154                 {
155                     model.setVersion( model.getParent().getVersion() );
156                 }
157             }
158         }
159         catch ( IOException e )
160         {
161             reporter.addWarning( artifact, "Unable to read artifact to extract model: " + e );
162         }
163         catch ( XmlPullParserException e )
164         {
165             reporter.addWarning( artifact, "Unable to parse extracted model: " + e );
166         }
167         finally
168         {
169             if ( jar != null )
170             {
171                 //noinspection UnusedCatchParameter
172                 try
173                 {
174                     jar.close();
175                 }
176                 catch ( IOException e )
177                 {
178                     // ignore
179                 }
180             }
181         }
182         return model;
183     }
184
185     private Model readModel( InputStream entryStream )
186         throws IOException, XmlPullParserException
187     {
188         Reader isReader = new InputStreamReader( entryStream );
189
190         Model model;
191         try
192         {
193             MavenXpp3Reader pomReader = new MavenXpp3Reader();
194             model = pomReader.read( isReader );
195         }
196         finally
197         {
198             IOUtil.close( isReader );
199         }
200         return model;
201     }
202
203 }