]> source.dussan.org Git - archiva.git/blob
81256c6fb63ca68a506d48859b66694b967047ae
[archiva.git] /
1 package org.apache.maven.archiva.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.archiva.discoverer.ArtifactDiscoverer;
20 import org.apache.maven.archiva.discoverer.DiscovererException;
21 import org.apache.maven.archiva.discoverer.MetadataDiscoverer;
22 import org.apache.maven.archiva.discoverer.filter.AcceptAllMetadataFilter;
23 import org.apache.maven.artifact.Artifact;
24 import org.apache.maven.artifact.InvalidArtifactRTException;
25 import org.apache.maven.artifact.factory.ArtifactFactory;
26 import org.apache.maven.artifact.repository.ArtifactRepository;
27 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
28 import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
29 import org.apache.maven.artifact.repository.layout.LegacyRepositoryLayout;
30 import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
31 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
32 import org.apache.maven.model.Model;
33 import org.apache.maven.project.MavenProject;
34 import org.apache.maven.project.MavenProjectBuilder;
35 import org.apache.maven.project.ProjectBuildingException;
36 import org.codehaus.plexus.logging.AbstractLogEnabled;
37
38 import java.io.File;
39 import java.util.Collections;
40 import java.util.Iterator;
41 import java.util.List;
42 import java.util.Map;
43
44 /**
45  * Report executor implementation.
46  *
47  * @todo should the report set be limitable by configuration?
48  * @plexus.component
49  */
50 public class DefaultReportExecutor
51     extends AbstractLogEnabled
52     implements ReportExecutor
53 {
54     /**
55      * @plexus.requirement
56      */
57     private MavenProjectBuilder projectBuilder;
58
59     /**
60      * @plexus.requirement
61      */
62     private ReportingStore reportingStore;
63
64     /**
65      * @plexus.requirement
66      */
67     private ArtifactFactory artifactFactory;
68
69     /**
70      * @plexus.requirement role="org.apache.maven.archiva.discoverer.ArtifactDiscoverer"
71      */
72     private Map artifactDiscoverers;
73
74     /**
75      * @plexus.requirement role="org.apache.maven.archiva.discoverer.MetadataDiscoverer"
76      */
77     private Map metadataDiscoverers;
78
79     private static final int ARTIFACT_BUFFER_SIZE = 1000;
80
81     public void runMetadataReports( ReportGroup reportGroup, List metadata, ArtifactRepository repository )
82         throws ReportingStoreException
83     {
84         ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
85
86         for ( Iterator i = metadata.iterator(); i.hasNext(); )
87         {
88             RepositoryMetadata repositoryMetadata = (RepositoryMetadata) i.next();
89
90             File file =
91                 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( repositoryMetadata ) );
92             reporter.cleanMetadata( repositoryMetadata, file.lastModified() );
93
94             reportGroup.processMetadata( repositoryMetadata, repository, reporter );
95         }
96
97         reportingStore.storeReports( reporter, repository );
98     }
99
100     public void runArtifactReports( ReportGroup reportGroup, List artifacts, ArtifactRepository repository )
101         throws ReportingStoreException
102     {
103         ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
104
105         for ( Iterator i = artifacts.iterator(); i.hasNext(); )
106         {
107             Artifact artifact = (Artifact) i.next();
108
109             Model model = null;
110             try
111             {
112                 Artifact pomArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(),
113                                                                               artifact.getArtifactId(),
114                                                                               artifact.getVersion() );
115                 MavenProject project =
116                     projectBuilder.buildFromRepository( pomArtifact, Collections.EMPTY_LIST, repository );
117
118                 model = project.getModel();
119             }
120             catch ( InvalidArtifactRTException e )
121             {
122                 reporter.addWarning( artifact, null, null, "Invalid artifact [" + artifact + "] : " + e );
123             }
124             catch ( ProjectBuildingException e )
125             {
126                 reporter.addWarning( artifact, null, null, "Error reading project model: " + e );
127             }
128
129             reporter.removeArtifact( artifact );
130
131             reportGroup.processArtifact( artifact, model, reporter );
132         }
133
134         reportingStore.storeReports( reporter, repository );
135     }
136
137     public ReportingDatabase getReportDatabase( ArtifactRepository repository, ReportGroup reportGroup )
138         throws ReportingStoreException
139     {
140         getLogger().debug(
141             "Reading previous report database " + reportGroup.getName() + " from repository " + repository.getId() );
142         return reportingStore.getReportsFromStore( repository, reportGroup );
143     }
144
145     public void runReports( ReportGroup reportGroup, ArtifactRepository repository, List blacklistedPatterns,
146                             ArtifactFilter filter )
147         throws DiscovererException, ReportingStoreException
148     {
149         // Flush (as in toilet, not store) the report database
150         ReportingDatabase database = getReportDatabase( repository, reportGroup );
151         database.clear();
152
153         // Discovery process
154         String layoutProperty = getRepositoryLayout( repository.getLayout() );
155         ArtifactDiscoverer discoverer = (ArtifactDiscoverer) artifactDiscoverers.get( layoutProperty );
156
157         // Save some memory by not tracking paths we won't use
158         // TODO: Plexus CDC should be able to inject this configuration
159         discoverer.setTrackOmittedPaths( false );
160
161         List artifacts = discoverer.discoverArtifacts( repository, blacklistedPatterns, filter );
162
163         if ( !artifacts.isEmpty() )
164         {
165             getLogger().info( "Discovered " + artifacts.size() + " artifacts" );
166
167             // Work through these in batches, then flush the project cache.
168             for ( int j = 0; j < artifacts.size(); j += ARTIFACT_BUFFER_SIZE )
169             {
170                 int end = j + ARTIFACT_BUFFER_SIZE;
171                 List currentArtifacts = artifacts.subList( j, end > artifacts.size() ? artifacts.size() : end );
172
173                 // TODO: proper queueing of this in case it was triggered externally (not harmful to do so at present, but not optimal)
174
175                 // run the reports.
176                 runArtifactReports( reportGroup, currentArtifacts, repository );
177
178                 // MNG-142 - the project builder retains a lot of objects in its inflexible cache. This is a hack
179                 // around that. TODO: remove when it is configurable
180                 flushProjectBuilderCacheHack();
181             }
182         }
183
184         MetadataDiscoverer metadataDiscoverer = (MetadataDiscoverer) metadataDiscoverers.get( layoutProperty );
185         List metadata =
186             metadataDiscoverer.discoverMetadata( repository, blacklistedPatterns, new AcceptAllMetadataFilter() );
187
188         if ( !metadata.isEmpty() )
189         {
190             getLogger().info( "Discovered " + metadata.size() + " metadata files" );
191
192             // run the reports
193             runMetadataReports( reportGroup, metadata, repository );
194         }
195     }
196
197     private String getRepositoryLayout( ArtifactRepositoryLayout layout )
198     {
199         // gross limitation that there is no reverse lookup of the hint for the layout.
200         if ( layout.getClass().equals( DefaultRepositoryLayout.class ) )
201         {
202             return "default";
203         }
204         else if ( layout.getClass().equals( LegacyRepositoryLayout.class ) )
205         {
206             return "legacy";
207         }
208         else
209         {
210             throw new IllegalArgumentException( "Unknown layout: " + layout );
211         }
212     }
213
214     private void flushProjectBuilderCacheHack()
215     {
216         try
217         {
218             if ( projectBuilder != null )
219             {
220                 java.lang.reflect.Field f = projectBuilder.getClass().getDeclaredField( "rawProjectCache" );
221                 f.setAccessible( true );
222                 Map cache = (Map) f.get( projectBuilder );
223                 cache.clear();
224
225                 f = projectBuilder.getClass().getDeclaredField( "processedProjectCache" );
226                 f.setAccessible( true );
227                 cache = (Map) f.get( projectBuilder );
228                 cache.clear();
229             }
230         }
231         catch ( NoSuchFieldException e )
232         {
233             throw new RuntimeException( e );
234         }
235         catch ( IllegalAccessException e )
236         {
237             throw new RuntimeException( e );
238         }
239     }
240 }