View Javadoc

1   package org.apache.maven.plugins.enforcer.utils;
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 java.io.File;
23  import java.io.IOException;
24  import java.io.Reader;
25  import java.util.ArrayList;
26  import java.util.List;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.factory.ArtifactFactory;
30  import org.apache.maven.artifact.repository.ArtifactRepository;
31  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
32  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
33  import org.apache.maven.artifact.resolver.ArtifactResolver;
34  import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
35  import org.apache.maven.model.Model;
36  import org.apache.maven.model.Parent;
37  import org.apache.maven.model.Plugin;
38  import org.apache.maven.model.ReportPlugin;
39  import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
40  import org.apache.maven.plugin.logging.Log;
41  import org.apache.maven.project.MavenProject;
42  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
43  import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
44  import org.codehaus.plexus.util.ReaderFactory;
45  import org.codehaus.plexus.util.StringUtils;
46  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
47  
48  // TODO: Auto-generated Javadoc
49  /**
50   * The Class EnforcerRuleUtils.
51   *
52   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
53   */
54  public class EnforcerRuleUtils
55  {
56  
57      /** The factory. */
58      ArtifactFactory factory;
59  
60      /** The resolver. */
61      ArtifactResolver resolver;
62  
63      /** The local. */
64      ArtifactRepository local;
65  
66      /** The remote repositories. */
67      List<ArtifactRepository> remoteRepositories;
68  
69      /** The log. */
70      Log log;
71  
72      /** The project. */
73      MavenProject project;
74  
75      private EnforcerRuleHelper helper;
76  
77      /**
78       * Instantiates a new enforcer rule utils.
79       *
80       * @param theFactory the the factory
81       * @param theResolver the the resolver
82       * @param theLocal the the local
83       * @param theRemoteRepositories the the remote repositories
84       * @param project the project
85       * @param theLog the the log
86       */
87      public EnforcerRuleUtils( ArtifactFactory theFactory, ArtifactResolver theResolver, ArtifactRepository theLocal,
88                                List<ArtifactRepository> theRemoteRepositories, MavenProject project, Log theLog )
89      {
90          super();
91          this.factory = theFactory;
92          this.resolver = theResolver;
93          this.local = theLocal;
94          this.remoteRepositories = theRemoteRepositories;
95          this.log = theLog;
96          this.project = project;
97      }
98  
99      /**
100      * Instantiates a new enforcer rule utils.
101      *
102      * @param helper the helper
103      */
104     @SuppressWarnings( "unchecked" )
105     public EnforcerRuleUtils( EnforcerRuleHelper helper )
106     {
107 
108         this.helper = helper;
109         // get the various expressions out of the
110         // helper.
111         try
112         {
113             factory = (ArtifactFactory) helper.getComponent( ArtifactFactory.class );
114             resolver = (ArtifactResolver) helper.getComponent( ArtifactResolver.class );
115             local = (ArtifactRepository) helper.evaluate( "${localRepository}" );
116             project = (MavenProject) helper.evaluate( "${project}" );
117             remoteRepositories = project.getRemoteArtifactRepositories();
118         }
119         catch ( ComponentLookupException e )
120         {
121             // TODO Auto-generated catch block
122             e.printStackTrace();
123         }
124         catch ( ExpressionEvaluationException e )
125         {
126             // TODO Auto-generated catch block
127             e.printStackTrace();
128         }
129     }
130 
131     /**
132      * Gets the pom model for this file.
133      *
134      * @param pom the pom
135      *
136      * @return the model
137      *
138      * @throws IOException Signals that an I/O exception has occurred.
139      * @throws XmlPullParserException the xml pull parser exception
140      */
141     private Model readModel ( File pom )
142         throws IOException, XmlPullParserException
143     {
144         Reader reader = ReaderFactory.newXmlReader( pom );
145         MavenXpp3Reader xpp3 = new MavenXpp3Reader();
146         Model model = null;
147         try
148         {
149             model = xpp3.read( reader );
150         }
151         finally
152         {
153             reader.close();
154             reader = null;
155         }
156         return model;
157     }
158 
159     /**
160      * This method gets the model for the defined artifact.
161      * Looks first in the filesystem, then tries to get it
162      * from the repo.
163      *
164      * @param groupId the group id
165      * @param artifactId the artifact id
166      * @param version the version
167      * @param pom the pom
168      *
169      * @return the pom model
170      *
171      * @throws ArtifactResolutionException the artifact resolution exception
172      * @throws ArtifactNotFoundException the artifact not found exception
173      * @throws XmlPullParserException the xml pull parser exception
174      * @throws IOException Signals that an I/O exception has occurred.
175      */
176     private Model getPomModel ( String groupId, String artifactId, String version, File pom )
177         throws ArtifactResolutionException, ArtifactNotFoundException, IOException, XmlPullParserException
178     {
179         Model model = null;
180 
181         // do we want to look in the reactor like the
182         // project builder? Would require @aggregator goal
183         // which causes problems in maven core right now
184         // because we also need dependency resolution in
185         // other
186         // rules. (MNG-2277)
187 
188         // look in the location specified by pom first.
189         boolean found = false;
190         try
191         {
192             model = readModel( pom );
193 
194             // i found a model, lets make sure it's the one
195             // I want
196             found = checkIfModelMatches( groupId, artifactId, version, model );
197         }
198         catch ( IOException e )
199         {
200             // nothing here, but lets look in the repo
201             // before giving up.
202         }
203         catch ( XmlPullParserException e )
204         {
205             // nothing here, but lets look in the repo
206             // before giving up.
207         }
208 
209         // i didn't find it in the local file system, go
210         // look in the repo
211         if ( !found )
212         {
213             Artifact pomArtifact = factory.createArtifact( groupId, artifactId, version, null, "pom" );
214             resolver.resolve( pomArtifact, remoteRepositories, local );
215             model = readModel( pomArtifact.getFile() );
216         }
217 
218         return model;
219     }
220 
221     /**
222      * This method loops through all the parents, getting
223      * each pom model and then its parent.
224      *
225      * @param groupId the group id
226      * @param artifactId the artifact id
227      * @param version the version
228      * @param pom the pom
229      *
230      * @return the models recursively
231      *
232      * @throws ArtifactResolutionException the artifact resolution exception
233      * @throws ArtifactNotFoundException the artifact not found exception
234      * @throws IOException Signals that an I/O exception has occurred.
235      * @throws XmlPullParserException the xml pull parser exception
236      */
237     public List<Model> getModelsRecursively ( String groupId, String artifactId, String version, File pom )
238         throws ArtifactResolutionException, ArtifactNotFoundException, IOException, XmlPullParserException
239     {
240         List<Model> models = null;
241         Model model = getPomModel( groupId, artifactId, version, pom );
242 
243         Parent parent = model.getParent();
244 
245         // recurse into the parent
246         if ( parent != null )
247         {
248             // get the relative path
249             String relativePath = parent.getRelativePath();
250             if ( StringUtils.isEmpty( relativePath ) )
251             {
252                 relativePath = "../pom.xml";
253             }
254             // calculate the recursive path
255             File parentPom = new File( pom.getParent(), relativePath );
256 
257             // if relative path is a directory, append pom.xml
258             if ( parentPom.isDirectory() )
259             {
260                 parentPom = new File( parentPom, "pom.xml" );
261             }
262 
263             models = getModelsRecursively( parent.getGroupId(), parent.getArtifactId(), parent.getVersion(), parentPom );
264         }
265         else
266         {
267             // only create it here since I'm not at the top
268             models = new ArrayList<Model>();
269         }
270         models.add( model );
271 
272         return models;
273     }
274 
275     /**
276      * Make sure the model is the one I'm expecting.
277      *
278      * @param groupId the group id
279      * @param artifactId the artifact id
280      * @param version the version
281      * @param model Model being checked.
282      *
283      * @return true, if check if model matches
284      */
285     protected boolean checkIfModelMatches ( String groupId, String artifactId, String version, Model model )
286     {
287         // try these first.
288         String modelGroup = model.getGroupId();
289         String modelArtifactId = model.getArtifactId();
290         String modelVersion = model.getVersion();
291 
292         try
293         {
294             if ( StringUtils.isEmpty( modelGroup ) )
295             {
296                 modelGroup = model.getParent().getGroupId();
297             }
298             else
299             {
300                 // MENFORCER-30, handle cases where the value is a property like ${project.parent.groupId}
301                 modelGroup = (String) helper.evaluate( modelGroup );
302             }
303 
304             if ( StringUtils.isEmpty( modelVersion ) )
305             {
306                 modelVersion = model.getParent().getVersion();
307             }
308             else
309             {
310                 // MENFORCER-30, handle cases where the value is a property like ${project.parent.version}
311                 modelVersion = (String) helper.evaluate( modelVersion );
312             }
313             
314             // Is this only required for Maven2?
315             modelArtifactId = (String) helper.evaluate( modelArtifactId );
316         }
317         catch ( NullPointerException e )
318         {
319             // this is probably bad. I don't have a valid
320             // group or version and I can't find a
321             // parent????
322             // lets see if it's what we're looking for
323             // anyway.
324         }
325         catch ( ExpressionEvaluationException e )
326         {
327             // as above
328         }
329         return ( StringUtils.equals( groupId, modelGroup ) && StringUtils.equals( version, modelVersion ) && StringUtils
330             .equals( artifactId, modelArtifactId ) );
331     }
332     
333  
334     private void resolve( Plugin plugin )
335     {
336         try
337         {
338             plugin.setGroupId( (String) helper.evaluate( plugin.getGroupId() ) );
339             plugin.setArtifactId( (String) helper.evaluate( plugin.getArtifactId() ) );
340             plugin.setVersion( (String) helper.evaluate( plugin.getVersion() ) );
341         }
342         catch ( ExpressionEvaluationException e )
343         {
344             // this should have gone already before
345         }
346     }
347     
348     private void resolve( ReportPlugin plugin )
349     {
350         try
351         {
352             plugin.setGroupId( (String) helper.evaluate( plugin.getGroupId() ) );
353             plugin.setArtifactId( (String) helper.evaluate( plugin.getArtifactId() ) );
354             plugin.setVersion( (String) helper.evaluate( plugin.getVersion() ) );
355         }
356         catch ( ExpressionEvaluationException e )
357         {
358             // this should have gone already before
359         }
360     }
361     
362     public List<Plugin> resolvePlugins( List<Plugin> plugins )
363     {
364         for ( Plugin plugin : plugins )
365         {
366             resolve( plugin );
367         }
368         return plugins;
369     }
370     
371     public List<ReportPlugin> resolveReportPlugins( List<ReportPlugin> reportPlugins )
372     {
373         for ( ReportPlugin plugin : reportPlugins )
374         {
375             resolve( plugin );
376         }
377         return reportPlugins;
378     }
379 
380 
381 }