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 java.io.File;
23  import java.io.FileOutputStream;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.io.LineNumberReader;
28  import java.util.List;
29  import java.util.Locale;
30  
31  import org.apache.maven.artifact.Artifact;
32  import org.apache.maven.artifact.factory.ArtifactFactory;
33  import org.apache.maven.artifact.manager.WagonManager;
34  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
35  import org.apache.maven.artifact.repository.metadata.RepositoryMetadataManager;
36  import org.apache.maven.artifact.resolver.ArtifactCollector;
37  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
38  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
39  import org.apache.maven.project.MavenProjectBuilder;
40  import org.apache.maven.report.projectinfo.dependencies.Dependencies;
41  import org.apache.maven.report.projectinfo.dependencies.DependenciesReportConfiguration;
42  import org.apache.maven.report.projectinfo.dependencies.RepositoryUtils;
43  import org.apache.maven.report.projectinfo.dependencies.renderer.DependenciesRenderer;
44  import org.apache.maven.settings.Settings;
45  import org.apache.maven.shared.dependency.tree.DependencyNode;
46  import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
47  import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
48  import org.apache.maven.shared.jar.classes.JarClassesAnalysis;
49  import org.codehaus.plexus.PlexusConstants;
50  import org.codehaus.plexus.PlexusContainer;
51  import org.codehaus.plexus.context.Context;
52  import org.codehaus.plexus.context.ContextException;
53  import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
54  import org.codehaus.plexus.util.IOUtil;
55  import org.codehaus.plexus.util.ReaderFactory;
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 748351 2009-02-26 23:39:03Z 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 =
223             new RepositoryUtils( getLog(), container.getLoggerManager(), wagonManager, settings,
224                                  mavenProjectBuilder, factory, resolver, project.getRemoteArtifactRepositories(),
225                                  project.getPluginArtifactRepositories(), localRepository,
226                                  repositoryMetadataManager );
227 
228         DependencyNode dependencyTreeNode = resolveProject();
229 
230         Dependencies dependencies = new Dependencies( project, dependencyTreeNode, classesAnalyzer );
231 
232         DependenciesReportConfiguration config =
233             new DependenciesReportConfiguration( dependencyDetailsEnabled, dependencyLocationsEnabled );
234 
235         DependenciesRenderer r =
236             new DependenciesRenderer( getSink(), locale, i18n, getLog(), settings, dependencies,
237                                       dependencyTreeNode, config, repoUtils, artifactFactory, mavenProjectBuilder,
238                                       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 =
285             getClass().getClassLoader().getResourceAsStream( RESOURCES_DIR + "/resources.txt" );
286 
287         if ( resourceList != null )
288         {
289             LineNumberReader reader =
290                 new LineNumberReader( new InputStreamReader( resourceList, ReaderFactory.US_ASCII ) );
291 
292             String line = reader.readLine();
293 
294             while ( line != null )
295             {
296                 InputStream is = getClass().getClassLoader().getResourceAsStream( RESOURCES_DIR + "/" + line );
297 
298                 if ( is == null )
299                 {
300                     throw new IOException( "The resource " + line + " doesn't exist." );
301                 }
302 
303                 File outputFile = new File( outputDirectory, line );
304 
305                 if ( !outputFile.getParentFile().exists() )
306                 {
307                     outputFile.getParentFile().mkdirs();
308                 }
309 
310                 FileOutputStream w = new FileOutputStream( outputFile );
311 
312                 IOUtil.copy( is, w );
313 
314                 IOUtil.close( is );
315 
316                 IOUtil.close( w );
317 
318                 line = reader.readLine();
319             }
320         }
321     }
322 }