View Javadoc

1   package org.apache.maven.report.projectinfo;
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.maven.artifact.Artifact;
23  import org.apache.maven.artifact.factory.ArtifactFactory;
24  import org.apache.maven.artifact.manager.WagonManager;
25  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
26  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
27  import org.apache.maven.artifact.resolver.ArtifactCollector;
28  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
29  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
30  import org.apache.maven.project.MavenProjectBuilder;
31  import org.apache.maven.report.projectinfo.dependencies.Dependencies;
32  import org.apache.maven.report.projectinfo.dependencies.DependenciesReportConfiguration;
33  import org.apache.maven.report.projectinfo.dependencies.RepositoryUtils;
34  import org.apache.maven.report.projectinfo.dependencies.renderer.DependenciesRenderer;
35  import org.apache.maven.settings.Settings;
36  import org.apache.maven.shared.dependency.tree.DependencyNode;
37  import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
38  import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
39  import org.apache.maven.shared.jar.classes.JarClassesAnalysis;
40  import org.codehaus.plexus.PlexusConstants;
41  import org.codehaus.plexus.PlexusContainer;
42  import org.codehaus.plexus.context.Context;
43  import org.codehaus.plexus.context.ContextException;
44  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
45  import org.codehaus.plexus.util.IOUtil;
46  import org.codehaus.plexus.util.ReaderFactory;
47  
48  import java.io.File;
49  import java.io.FileOutputStream;
50  import java.io.IOException;
51  import java.io.InputStream;
52  import java.io.InputStreamReader;
53  import java.io.LineNumberReader;
54  import java.util.List;
55  import java.util.Locale;
56  
57  /**
58   * Generates the Project Dependencies report.
59   *
60   * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
61   * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton </a>
62   * @version $Id: DependenciesReport.java 679796 2008-07-25 13:14:34Z vsiveton $
63   * @since 2.0
64   * @goal dependencies
65   * @requiresDependencyResolution test
66   */
67  public class DependenciesReport
68      extends AbstractProjectInfoReport
69      implements Contextualizable
70  {
71      /** Images resources dir */
72      private static final String RESOURCES_DIR = "org/apache/maven/report/projectinfo/resources";
73  
74      // ----------------------------------------------------------------------
75      // Mojo components
76      // ----------------------------------------------------------------------
77  
78      /**
79       * Maven Project Builder component.
80       *
81       * @component
82       */
83      private MavenProjectBuilder mavenProjectBuilder;
84  
85      /**
86       * Artifact metadata source component.
87       *
88       * @component
89       */
90      protected ArtifactMetadataSource artifactMetadataSource;
91  
92      /**
93       * Artifact collector component.
94       *
95       * @component
96       */
97      private ArtifactCollector collector;
98  
99      /**
100      * Wagon manager component.
101      *
102      * @since 2.1
103      * @component
104      */
105     private WagonManager wagonManager;
106 
107     /**
108      * Dependency tree builder component.
109      *
110      * @since 2.1
111      * @component
112      */
113     private DependencyTreeBuilder dependencyTreeBuilder;
114 
115     /**
116      * Jar classes analyzer component.
117      *
118      * @since 2.1
119      * @component
120      */
121     private JarClassesAnalysis classesAnalyzer;
122 
123     /**
124      * Repository metadata component.
125      *
126      * @since 2.1
127      * @component
128      */
129     private RepositoryMetadataManager repositoryMetadataManager;
130 
131     /**
132      * Maven Artifact Factory component.
133      *
134      * @component
135      * @since 2.1
136      */
137     private ArtifactFactory artifactFactory;
138 
139     // ----------------------------------------------------------------------
140     // Mojo parameters
141     // ----------------------------------------------------------------------
142 
143     /**
144      * The current user system settings for use in Maven.
145      *
146      * @since 2.1
147      * @parameter expression="${settings}"
148      * @required
149      * @readonly
150      */
151     private Settings settings;
152 
153     /**
154      * Remote repositories used for the project.
155      *
156      * @since 2.1
157      * @parameter expression="${project.remoteArtifactRepositories}"
158      * @required
159      * @readonly
160      */
161     private List remoteRepositories;
162 
163     /**
164      * Display file details for each dependency, such as: file size, number of
165      * classes, number of packages etc.
166      *
167      * @since 2.1
168      * @parameter expression="${dependency.details.enabled}" default-value="true"
169      */
170     private boolean dependencyDetailsEnabled;
171 
172     /**
173      * Display the repository locations of the dependencies. If Maven is configured to be offline, this parameter
174      * will be ignored.
175      *
176      * @since 2.1
177      * @parameter expression="${dependency.locations.enabled}" default-value="true"
178      */
179     private boolean dependencyLocationsEnabled;
180 
181     /**
182      * Plexus container to play with logger manager.
183      *
184      * @since 2.1
185      */
186     private PlexusContainer container;
187 
188     // ----------------------------------------------------------------------
189     // Public methods
190     // ----------------------------------------------------------------------
191 
192     /** {@inheritDoc} */
193     public String getName( Locale locale )
194     {
195         return i18n.getString( "project-info-report", locale, "report.dependencies.name" );
196     }
197 
198     /** {@inheritDoc} */
199     public String getDescription( Locale locale )
200     {
201         return i18n.getString( "project-info-report", locale, "report.dependencies.description" );
202     }
203 
204     /** {@inheritDoc} */
205     public void executeReport( Locale locale )
206     {
207         if ( settings.isOffline() && dependencyLocationsEnabled )
208         {
209             getLog().warn( "The parameter 'dependencyLocationsEnabled' is ignored in offline mode." );
210             dependencyLocationsEnabled = false;
211         }
212 
213         try
214         {
215             copyResources( new File( getOutputDirectory() ) );
216         }
217         catch ( IOException e )
218         {
219             getLog().error( "Cannot copy ressources", e );
220         }
221 
222         RepositoryUtils repoUtils = new RepositoryUtils( getLog(), container.getLoggerManager(), wagonManager,
223                                                          settings, mavenProjectBuilder, factory, resolver, project
224                                                              .getRemoteArtifactRepositories(), project
225                                                              .getPluginArtifactRepositories(), localRepository,
226                                                          repositoryMetadataManager );
227 
228         DependencyNode dependencyTreeNode = resolveProject();
229 
230         Dependencies dependencies = new Dependencies( project, dependencyTreeNode, classesAnalyzer );
231 
232         DependenciesReportConfiguration config = new DependenciesReportConfiguration( dependencyDetailsEnabled,
233                                                                                       dependencyLocationsEnabled );
234 
235         DependenciesRenderer r =
236             new DependenciesRenderer( getSink(), locale, i18n, getLog(), settings, dependencies,
237                                       dependencyTreeNode, config, repoUtils, artifactFactory,
238                                       mavenProjectBuilder, remoteRepositories, localRepository );
239         r.render();
240     }
241 
242     /** {@inheritDoc} */
243     public String getOutputName()
244     {
245         return "dependencies";
246     }
247 
248     /** {@inheritDoc} */
249     public void contextualize( Context context )
250         throws ContextException
251     {
252         this.container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY );
253     }
254 
255     // ----------------------------------------------------------------------
256     // Private methods
257     // ----------------------------------------------------------------------
258 
259     /**
260      * @return resolve the dependency tree
261      */
262     private DependencyNode resolveProject()
263     {
264         try
265         {
266             ArtifactFilter artifactFilter = new ScopeArtifactFilter( Artifact.SCOPE_TEST );
267             return dependencyTreeBuilder.buildDependencyTree( project, localRepository, factory,
268                                                               artifactMetadataSource, artifactFilter, collector );
269         }
270         catch ( DependencyTreeBuilderException e )
271         {
272             getLog().error( "Unable to build dependency tree.", e );
273             return null;
274         }
275     }
276 
277     /**
278      * @param outputDirectory the wanted output directory
279      * @throws IOException if any
280      */
281     private void copyResources( File outputDirectory )
282         throws IOException
283     {
284         InputStream resourceList = getClass().getClassLoader().getResourceAsStream( RESOURCES_DIR + "/resources.txt" );
285 
286         if ( resourceList != null )
287         {
288             LineNumberReader reader =
289                 new LineNumberReader( new InputStreamReader( resourceList, ReaderFactory.US_ASCII ) );
290 
291             String line = reader.readLine();
292 
293             while ( line != null )
294             {
295                 InputStream is = getClass().getClassLoader().getResourceAsStream( RESOURCES_DIR + "/" + line );
296 
297                 if ( is == null )
298                 {
299                     throw new IOException( "The resource " + line + " doesn't exist." );
300                 }
301 
302                 File outputFile = new File( outputDirectory, line );
303 
304                 if ( !outputFile.getParentFile().exists() )
305                 {
306                     outputFile.getParentFile().mkdirs();
307                 }
308 
309                 FileOutputStream w = new FileOutputStream( outputFile );
310 
311                 IOUtil.copy( is, w );
312 
313                 IOUtil.close( is );
314 
315                 IOUtil.close( w );
316 
317                 line = reader.readLine();
318             }
319         }
320     }
321 }