1 package org.apache.maven.archiva.reporting.executor;
4 * Copyright 2005-2006 The Apache Software Foundation.
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
10 * http://www.apache.org/licenses/LICENSE-2.0
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.
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.archiva.reporting.group.ReportGroup;
24 import org.apache.maven.archiva.reporting.executor.ReportExecutor;
25 import org.apache.maven.archiva.reporting.store.ReportingStore;
26 import org.apache.maven.archiva.reporting.store.ReportingStoreException;
27 import org.apache.maven.archiva.reporting.database.ReportingDatabase;
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.artifact.InvalidArtifactRTException;
30 import org.apache.maven.artifact.factory.ArtifactFactory;
31 import org.apache.maven.artifact.repository.ArtifactRepository;
32 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
33 import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
34 import org.apache.maven.artifact.repository.layout.LegacyRepositoryLayout;
35 import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
36 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
37 import org.apache.maven.model.Model;
38 import org.apache.maven.project.MavenProject;
39 import org.apache.maven.project.MavenProjectBuilder;
40 import org.apache.maven.project.ProjectBuildingException;
41 import org.codehaus.plexus.logging.AbstractLogEnabled;
44 import java.util.Collections;
45 import java.util.Iterator;
46 import java.util.List;
50 * Report executor implementation.
52 * @todo should the report set be limitable by configuration?
55 public class DefaultReportExecutor
56 extends AbstractLogEnabled
57 implements ReportExecutor
62 private MavenProjectBuilder projectBuilder;
67 private ReportingStore reportingStore;
72 private ArtifactFactory artifactFactory;
75 * @plexus.requirement role="org.apache.maven.archiva.discoverer.ArtifactDiscoverer"
77 private Map artifactDiscoverers;
80 * @plexus.requirement role="org.apache.maven.archiva.discoverer.MetadataDiscoverer"
82 private Map metadataDiscoverers;
84 private static final int ARTIFACT_BUFFER_SIZE = 1000;
86 public void runMetadataReports( ReportGroup reportGroup, List metadata, ArtifactRepository repository )
87 throws ReportingStoreException
89 ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
91 for ( Iterator i = metadata.iterator(); i.hasNext(); )
93 RepositoryMetadata repositoryMetadata = (RepositoryMetadata) i.next();
96 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( repositoryMetadata ) );
97 reporter.cleanMetadata( repositoryMetadata, file.lastModified() );
99 reportGroup.processMetadata( repositoryMetadata, repository, reporter );
102 reportingStore.storeReports( reporter, repository );
105 public void runArtifactReports( ReportGroup reportGroup, List artifacts, ArtifactRepository repository )
106 throws ReportingStoreException
108 ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
110 for ( Iterator i = artifacts.iterator(); i.hasNext(); )
112 Artifact artifact = (Artifact) i.next();
117 Artifact pomArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(),
118 artifact.getArtifactId(),
119 artifact.getVersion() );
120 MavenProject project =
121 projectBuilder.buildFromRepository( pomArtifact, Collections.EMPTY_LIST, repository );
123 model = project.getModel();
125 catch ( InvalidArtifactRTException e )
127 reporter.addWarning( artifact, null, null, "Invalid artifact [" + artifact + "] : " + e );
129 catch ( ProjectBuildingException e )
131 reporter.addWarning( artifact, null, null, "Error reading project model: " + e );
134 reporter.removeArtifact( artifact );
136 reportGroup.processArtifact( artifact, model, reporter );
139 reportingStore.storeReports( reporter, repository );
142 public ReportingDatabase getReportDatabase( ArtifactRepository repository, ReportGroup reportGroup )
143 throws ReportingStoreException
146 "Reading previous report database " + reportGroup.getName() + " from repository " + repository.getId() );
147 return reportingStore.getReportsFromStore( repository, reportGroup );
150 public void runReports( ReportGroup reportGroup, ArtifactRepository repository, List blacklistedPatterns,
151 ArtifactFilter filter )
152 throws DiscovererException, ReportingStoreException
154 // Flush (as in toilet, not store) the report database
155 ReportingDatabase database = getReportDatabase( repository, reportGroup );
159 String layoutProperty = getRepositoryLayout( repository.getLayout() );
160 ArtifactDiscoverer discoverer = (ArtifactDiscoverer) artifactDiscoverers.get( layoutProperty );
162 // Save some memory by not tracking paths we won't use
163 // TODO: Plexus CDC should be able to inject this configuration
164 discoverer.setTrackOmittedPaths( false );
166 List artifacts = discoverer.discoverArtifacts( repository, blacklistedPatterns, filter );
168 if ( !artifacts.isEmpty() )
170 getLogger().info( "Discovered " + artifacts.size() + " artifacts" );
172 // Work through these in batches, then flush the project cache.
173 for ( int j = 0; j < artifacts.size(); j += ARTIFACT_BUFFER_SIZE )
175 int end = j + ARTIFACT_BUFFER_SIZE;
176 List currentArtifacts = artifacts.subList( j, end > artifacts.size() ? artifacts.size() : end );
178 // TODO: proper queueing of this in case it was triggered externally (not harmful to do so at present, but not optimal)
181 runArtifactReports( reportGroup, currentArtifacts, repository );
183 // MNG-142 - the project builder retains a lot of objects in its inflexible cache. This is a hack
184 // around that. TODO: remove when it is configurable
185 flushProjectBuilderCacheHack();
189 MetadataDiscoverer metadataDiscoverer = (MetadataDiscoverer) metadataDiscoverers.get( layoutProperty );
191 metadataDiscoverer.discoverMetadata( repository, blacklistedPatterns, new AcceptAllMetadataFilter() );
193 if ( !metadata.isEmpty() )
195 getLogger().info( "Discovered " + metadata.size() + " metadata files" );
198 runMetadataReports( reportGroup, metadata, repository );
202 private String getRepositoryLayout( ArtifactRepositoryLayout layout )
204 // gross limitation that there is no reverse lookup of the hint for the layout.
205 if ( layout.getClass().equals( DefaultRepositoryLayout.class ) )
209 else if ( layout.getClass().equals( LegacyRepositoryLayout.class ) )
215 throw new IllegalArgumentException( "Unknown layout: " + layout );
219 private void flushProjectBuilderCacheHack()
223 if ( projectBuilder != null )
225 java.lang.reflect.Field f = projectBuilder.getClass().getDeclaredField( "rawProjectCache" );
226 f.setAccessible( true );
227 Map cache = (Map) f.get( projectBuilder );
230 f = projectBuilder.getClass().getDeclaredField( "processedProjectCache" );
231 f.setAccessible( true );
232 cache = (Map) f.get( projectBuilder );
236 catch ( NoSuchFieldException e )
238 throw new RuntimeException( e );
240 catch ( IllegalAccessException e )
242 throw new RuntimeException( e );