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.factory.ArtifactFactory;
25 import org.apache.maven.artifact.repository.ArtifactRepository;
26 import org.apache.maven.artifact.repository.layout.ArtifactRepositoryLayout;
27 import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
28 import org.apache.maven.artifact.repository.layout.LegacyRepositoryLayout;
29 import org.apache.maven.artifact.repository.metadata.RepositoryMetadata;
30 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
31 import org.apache.maven.model.Model;
32 import org.apache.maven.project.MavenProject;
33 import org.apache.maven.project.MavenProjectBuilder;
34 import org.apache.maven.project.ProjectBuildingException;
35 import org.codehaus.plexus.logging.AbstractLogEnabled;
38 import java.util.Collections;
39 import java.util.Iterator;
40 import java.util.List;
44 * Report executor implementation.
46 * @todo should the report set be limitable by configuration?
49 public class DefaultReportExecutor
50 extends AbstractLogEnabled
51 implements ReportExecutor
56 private MavenProjectBuilder projectBuilder;
61 private ReportingStore reportingStore;
66 private ArtifactFactory artifactFactory;
69 * @plexus.requirement role="org.apache.maven.archiva.discoverer.ArtifactDiscoverer"
71 private Map artifactDiscoverers;
74 * @plexus.requirement role="org.apache.maven.archiva.discoverer.MetadataDiscoverer"
76 private Map metadataDiscoverers;
78 private static final int ARTIFACT_BUFFER_SIZE = 1000;
80 public void runMetadataReports( ReportGroup reportGroup, List metadata, ArtifactRepository repository )
81 throws ReportingStoreException
83 ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
85 for ( Iterator i = metadata.iterator(); i.hasNext(); )
87 RepositoryMetadata repositoryMetadata = (RepositoryMetadata) i.next();
90 new File( repository.getBasedir(), repository.pathOfRemoteRepositoryMetadata( repositoryMetadata ) );
91 reporter.cleanMetadata( repositoryMetadata, file.lastModified() );
93 reportGroup.processMetadata( repositoryMetadata, repository, reporter );
96 reportingStore.storeReports( reporter, repository );
99 public void runArtifactReports( ReportGroup reportGroup, List artifacts, ArtifactRepository repository )
100 throws ReportingStoreException
102 ReportingDatabase reporter = getReportDatabase( repository, reportGroup );
104 for ( Iterator i = artifacts.iterator(); i.hasNext(); )
106 Artifact artifact = (Artifact) i.next();
111 Artifact pomArtifact = artifactFactory.createProjectArtifact( artifact.getGroupId(),
112 artifact.getArtifactId(),
113 artifact.getVersion() );
114 MavenProject project =
115 projectBuilder.buildFromRepository( pomArtifact, Collections.EMPTY_LIST, repository );
117 model = project.getModel();
119 catch ( ProjectBuildingException e )
121 reporter.addWarning( artifact, "Error reading project model: " + e );
124 reporter.removeArtifact( artifact );
126 reportGroup.processArtifact( artifact, model, reporter );
129 reportingStore.storeReports( reporter, repository );
132 public ReportingDatabase getReportDatabase( ArtifactRepository repository, ReportGroup reportGroup )
133 throws ReportingStoreException
136 "Reading previous report database " + reportGroup.getName() + " from repository " + repository.getId() );
137 return reportingStore.getReportsFromStore( repository, reportGroup );
140 public void runReports( ReportGroup reportGroup, ArtifactRepository repository, List blacklistedPatterns,
141 ArtifactFilter filter )
142 throws DiscovererException, ReportingStoreException
144 // Flush (as in toilet, not store) the report database
145 ReportingDatabase database = getReportDatabase( repository, reportGroup );
149 String layoutProperty = getRepositoryLayout( repository.getLayout() );
150 ArtifactDiscoverer discoverer = (ArtifactDiscoverer) artifactDiscoverers.get( layoutProperty );
152 // Save some memory by not tracking paths we won't use
153 // TODO: Plexus CDC should be able to inject this configuration
154 discoverer.setTrackOmittedPaths( false );
156 List artifacts = discoverer.discoverArtifacts( repository, blacklistedPatterns, filter );
158 if ( !artifacts.isEmpty() )
160 getLogger().info( "Discovered " + artifacts.size() + " artifacts" );
162 // Work through these in batches, then flush the project cache.
163 for ( int j = 0; j < artifacts.size(); j += ARTIFACT_BUFFER_SIZE )
165 int end = j + ARTIFACT_BUFFER_SIZE;
166 List currentArtifacts = artifacts.subList( j, end > artifacts.size() ? artifacts.size() : end );
168 // TODO: proper queueing of this in case it was triggered externally (not harmful to do so at present, but not optimal)
171 runArtifactReports( reportGroup, currentArtifacts, repository );
173 // MNG-142 - the project builder retains a lot of objects in its inflexible cache. This is a hack
174 // around that. TODO: remove when it is configurable
175 flushProjectBuilderCacheHack();
179 MetadataDiscoverer metadataDiscoverer = (MetadataDiscoverer) metadataDiscoverers.get( layoutProperty );
181 metadataDiscoverer.discoverMetadata( repository, blacklistedPatterns, new AcceptAllMetadataFilter() );
183 if ( !metadata.isEmpty() )
185 getLogger().info( "Discovered " + metadata.size() + " metadata files" );
188 runMetadataReports( reportGroup, metadata, repository );
192 private String getRepositoryLayout( ArtifactRepositoryLayout layout )
194 // gross limitation that there is no reverse lookup of the hint for the layout.
195 if ( layout.getClass().equals( DefaultRepositoryLayout.class ) )
199 else if ( layout.getClass().equals( LegacyRepositoryLayout.class ) )
205 throw new IllegalArgumentException( "Unknown layout: " + layout );
209 private void flushProjectBuilderCacheHack()
213 if ( projectBuilder != null )
215 java.lang.reflect.Field f = projectBuilder.getClass().getDeclaredField( "rawProjectCache" );
216 f.setAccessible( true );
217 Map cache = (Map) f.get( projectBuilder );
220 f = projectBuilder.getClass().getDeclaredField( "processedProjectCache" );
221 f.setAccessible( true );
222 cache = (Map) f.get( projectBuilder );
226 catch ( NoSuchFieldException e )
228 throw new RuntimeException( e );
230 catch ( IllegalAccessException e )
232 throw new RuntimeException( e );