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