1 package org.apache.maven.archiva.reporting;
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.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;
39 import java.util.Collections;
40 import java.util.Iterator;
41 import java.util.List;
45 * Report executor implementation.
47 * @todo should the report set be limitable by configuration?
50 public class DefaultReportExecutor
51 extends AbstractLogEnabled
52 implements ReportExecutor
57 private MavenProjectBuilder projectBuilder;
62 private ReportingStore reportingStore;
67 private ArtifactFactory artifactFactory;
70 * @plexus.requirement role="org.apache.maven.archiva.discoverer.ArtifactDiscoverer"
72 private Map artifactDiscoverers;
75 * @plexus.requirement role="org.apache.maven.archiva.discoverer.MetadataDiscoverer"
77 private Map metadataDiscoverers;
79 private static final int ARTIFACT_BUFFER_SIZE = 1000;
81 public void runMetadataReports( ReportGroup reportGroup, List metadata, ArtifactRepository repository )
82 throws ReportingStoreException
84 ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
86 for ( Iterator i = metadata.iterator(); i.hasNext(); )
88 RepositoryMetadata repositoryMetadata = (RepositoryMetadata) i.next();
91 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( repositoryMetadata ) );
92 reporter.cleanMetadata( repositoryMetadata, file.lastModified() );
94 reportGroup.processMetadata( repositoryMetadata, repository, reporter );
97 reportingStore.storeReports( reporter, repository );
100 public void runArtifactReports( ReportGroup reportGroup, List artifacts, ArtifactRepository repository )
101 throws ReportingStoreException
103 ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
105 for ( Iterator i = artifacts.iterator(); i.hasNext(); )
107 Artifact artifact = (Artifact) i.next();
112 Artifact pomArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(),
113 artifact.getArtifactId(),
114 artifact.getVersion() );
115 MavenProject project =
116 projectBuilder.buildFromRepository( pomArtifact, Collections.EMPTY_LIST, repository );
118 model = project.getModel();
120 catch ( InvalidArtifactRTException e )
122 reporter.addWarning( artifact, null, null, "Invalid artifact [" + artifact + "] : " + e );
124 catch ( ProjectBuildingException e )
126 reporter.addWarning( artifact, null, null, "Error reading project model: " + e );
129 reporter.removeArtifact( artifact );
131 reportGroup.processArtifact( artifact, model, reporter );
134 reportingStore.storeReports( reporter, repository );
137 public ReportingDatabase getReportDatabase( ArtifactRepository repository, ReportGroup reportGroup )
138 throws ReportingStoreException
141 "Reading previous report database " + reportGroup.getName() + " from repository " + repository.getId() );
142 return reportingStore.getReportsFromStore( repository, reportGroup );
145 public void runReports( ReportGroup reportGroup, ArtifactRepository repository, List blacklistedPatterns,
146 ArtifactFilter filter )
147 throws DiscovererException, ReportingStoreException
149 // Flush (as in toilet, not store) the report database
150 ReportingDatabase database = getReportDatabase( repository, reportGroup );
154 String layoutProperty = getRepositoryLayout( repository.getLayout() );
155 ArtifactDiscoverer discoverer = (ArtifactDiscoverer) artifactDiscoverers.get( layoutProperty );
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 );
161 List artifacts = discoverer.discoverArtifacts( repository, blacklistedPatterns, filter );
163 if ( !artifacts.isEmpty() )
165 getLogger().info( "Discovered " + artifacts.size() + " artifacts" );
167 // Work through these in batches, then flush the project cache.
168 for ( int j = 0; j < artifacts.size(); j += ARTIFACT_BUFFER_SIZE )
170 int end = j + ARTIFACT_BUFFER_SIZE;
171 List currentArtifacts = artifacts.subList( j, end > artifacts.size() ? artifacts.size() : end );
173 // TODO: proper queueing of this in case it was triggered externally (not harmful to do so at present, but not optimal)
176 runArtifactReports( reportGroup, currentArtifacts, repository );
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();
184 MetadataDiscoverer metadataDiscoverer = (MetadataDiscoverer) metadataDiscoverers.get( layoutProperty );
186 metadataDiscoverer.discoverMetadata( repository, blacklistedPatterns, new AcceptAllMetadataFilter() );
188 if ( !metadata.isEmpty() )
190 getLogger().info( "Discovered " + metadata.size() + " metadata files" );
193 runMetadataReports( reportGroup, metadata, repository );
197 private String getRepositoryLayout( ArtifactRepositoryLayout layout )
199 // gross limitation that there is no reverse lookup of the hint for the layout.
200 if ( layout.getClass().equals( DefaultRepositoryLayout.class ) )
204 else if ( layout.getClass().equals( LegacyRepositoryLayout.class ) )
210 throw new IllegalArgumentException( "Unknown layout: " + layout );
214 private void flushProjectBuilderCacheHack()
218 if ( projectBuilder != null )
220 java.lang.reflect.Field f = projectBuilder.getClass().getDeclaredField( "rawProjectCache" );
221 f.setAccessible( true );
222 Map cache = (Map) f.get( projectBuilder );
225 f = projectBuilder.getClass().getDeclaredField( "processedProjectCache" );
226 f.setAccessible( true );
227 cache = (Map) f.get( projectBuilder );
231 catch ( NoSuchFieldException e )
233 throw new RuntimeException( e );
235 catch ( IllegalAccessException e )
237 throw new RuntimeException( e );