]> source.dussan.org Git - archiva.git/blob
140425656523b856020053573657a235711172ee
[archiva.git] /
1 package org.apache.maven.repository.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.codehaus.plexus.util.IOUtil;
25 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
26
27 import java.io.File;
28 import java.io.IOException;
29 import java.io.InputStream;
30 import java.io.InputStreamReader;
31 import java.io.Reader;
32 import java.util.jar.JarEntry;
33 import java.util.jar.JarFile;
34
35 /**
36  * Validate the location of the artifact based on the values indicated
37  * in its pom (both the pom packaged with the artifact & the pom in the
38  * file system).
39  * @plexus.component role="org.apache.maven.repository.reporting.ArtifactReportProcessor" role-hint="artifact-location"
40  */
41 public class LocationArtifactReportProcessor
42     implements ArtifactReportProcessor
43 {
44     /** @plexus.requirement */
45     private ArtifactFactory artifactFactory;
46
47     /**
48      * Check whether the artifact is in its proper location. The location of the artifact
49      * is validated first against the groupId, artifactId and versionId in the specified model
50      * object (pom in the file system). Then unpack the artifact (jar file) and get the model (pom)
51      * included in the package. If a model exists inside the package, then check if the artifact's
52      * location is valid based on the location specified in the pom. Check if the both the location
53      * specified in the file system pom and in the pom included in the package is the same.
54      *
55      * @param model      Represents the pom in the file system.
56      * @param artifact
57      * @param reporter
58      * @param repository
59      */
60     public void processArtifact( Model model, Artifact artifact, ArtifactReporter reporter,
61                                  ArtifactRepository repository )
62         throws ReportProcessorException
63     {
64         if ( !"file".equals( repository.getProtocol() ) )
65         {
66             // We can't check other types of URLs yet. Need to use Wagon, with an exists() method.
67             throw new UnsupportedOperationException(
68                 "Can't process repository '" + repository.getUrl() + "'. Only file based repositories are supported" );
69         }
70
71         //check if the artifact is located in its proper location based on the info
72         //specified in the model object/pom
73         Artifact modelArtifact = artifactFactory.createBuildArtifact( model.getGroupId(), model.getArtifactId(),
74                                                                       model.getVersion(), model.getPackaging() );
75
76         boolean failed = false;
77         String modelPath = repository.pathOf( modelArtifact );
78         String artifactPath = repository.pathOf( artifact );
79         if ( modelPath.equals( artifactPath ) )
80         {
81             //get the location of the artifact itself
82             File file = new File( repository.getBasedir(), artifactPath );
83
84             if ( file.exists() )
85             {
86                 //unpack the artifact (using the groupId, artifactId & version specified in the artifact object itself
87                 //check if the pom is included in the package
88                 Model extractedModel = readArtifactModel( file, artifact.getGroupId(), artifact.getArtifactId() );
89
90                 if ( extractedModel != null )
91                 {
92                     Artifact extractedArtifact = artifactFactory.createBuildArtifact( extractedModel.getGroupId(),
93                                                                                       extractedModel.getArtifactId(),
94                                                                                       extractedModel.getVersion(),
95                                                                                       extractedModel.getPackaging() );
96                     if ( !repository.pathOf( extractedArtifact ).equals( artifactPath ) )
97                     {
98                         reporter.addFailure( artifact,
99                                              "The artifact is out of place. It does not match the specified location in the packaged pom." );
100                         failed = true;
101                     }
102                 }
103             }
104             else
105             {
106                 reporter.addFailure( artifact,
107                                      "The artifact is out of place. It does not exist at the specified location in the repository pom." );
108                 failed = true;
109             }
110         }
111         else
112         {
113             reporter.addFailure( artifact,
114                                  "The artifact is out of place. It does not match the specified location in the repository pom." );
115             failed = true;
116         }
117
118         if ( !failed )
119         {
120             reporter.addSuccess( artifact );
121         }
122     }
123
124     /**
125      * Extract the contents of the artifact/jar file.
126      *
127      * @param file
128      * @param groupId
129      * @param artifactId
130      */
131     private Model readArtifactModel( File file, String groupId, String artifactId )
132         throws ReportProcessorException
133     {
134         Model model = null;
135
136         JarFile jar = null;
137         try
138         {
139             jar = new JarFile( file );
140
141             //Get the entry and its input stream.
142             JarEntry entry = jar.getJarEntry( "META-INF/maven/" + groupId + "/" + artifactId + "/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         }
150         catch ( IOException e )
151         {
152             // TODO: should just warn and continue?
153             throw new ReportProcessorException( "Unable to read artifact to extract model", e );
154         }
155         catch ( XmlPullParserException e )
156         {
157             // TODO: should just warn and continue?
158             throw new ReportProcessorException( "Unable to read artifact to extract model", e );
159         }
160         finally
161         {
162             if ( jar != null )
163             {
164                 //noinspection UnusedCatchParameter
165                 try
166                 {
167                     jar.close();
168                 }
169                 catch ( IOException e )
170                 {
171                     // ignore
172                 }
173             }
174         }
175         return model;
176     }
177
178     private Model readModel( InputStream entryStream )
179         throws IOException, XmlPullParserException
180     {
181         Reader isReader = new InputStreamReader( entryStream );
182
183         Model model;
184         try
185         {
186             MavenXpp3Reader pomReader = new MavenXpp3Reader();
187             model = pomReader.read( isReader );
188         }
189         finally
190         {
191             IOUtil.close( isReader );
192         }
193         return model;
194     }
195
196 }