]> source.dussan.org Git - archiva.git/blob
91851c891cabcefd7c1fac71f5fa67d7cb820d09
[archiva.git] /
1 package org.apache.archiva.metadata.repository;
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 org.apache.archiva.metadata.model.ArtifactMetadata;
23 import org.apache.archiva.metadata.model.Dependency;
24 import org.apache.archiva.metadata.model.ProjectMetadata;
25 import org.apache.archiva.metadata.model.ProjectVersionMetadata;
26 import org.apache.archiva.metadata.model.ProjectVersionReference;
27 import org.apache.archiva.metadata.repository.filter.ExcludesFilter;
28 import org.apache.archiva.metadata.repository.storage.RepositoryStorage;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import java.util.ArrayList;
33 import java.util.Collection;
34
35 /**
36  * @plexus.component role="org.apache.archiva.metadata.repository.MetadataResolver"
37  */
38 public class DefaultMetadataResolver
39     implements MetadataResolver
40 {
41     /**
42      * @plexus.requirement
43      */
44     private MetadataRepository metadataRepository;
45
46     /**
47      * FIXME: this needs to be configurable based on storage type - and could also be instantiated per repo. Change to a
48      * factory.
49      *
50      * TODO: Also need to accommodate availability of proxy module
51      * ... could be a different type since we need methods to modify the storage metadata, which would also allow more
52      * appropriate methods to pass in the already determined repository configuration, for example, instead of the ID
53      *
54      * @plexus.requirement role-hint="maven2"
55      */
56     private RepositoryStorage repositoryStorage;
57
58     private static final Logger log = LoggerFactory.getLogger( DefaultMetadataResolver.class );
59
60     public ProjectVersionMetadata resolveProjectVersion( String repoId, String namespace, String projectId,
61                                                          String projectVersion )
62         throws MetadataResolutionException
63     {
64         ProjectVersionMetadata metadata = metadataRepository.getProjectVersion( repoId, namespace, projectId,
65                                                                                 projectVersion );
66         // TODO: do we want to detect changes as well by comparing timestamps? isProjectVersionNewerThan(updated)
67         //       in such cases we might also remove/update stale metadata, including adjusting plugin-based facets
68         //       This would also be better than checking for completeness - we can then refresh only when fixed (though
69         //       sometimes this has an additional dependency - such as a parent - requesting the user to force an update
70         //       may then work here and be more efficient than always trying again)
71         if ( metadata == null || metadata.isIncomplete() )
72         {
73             metadata = repositoryStorage.readProjectVersionMetadata( repoId, namespace, projectId, projectVersion );
74             if ( metadata != null )
75             {
76                 if ( log.isDebugEnabled() )
77                 {
78                     log.debug( "Resolved project version metadata from storage: " + metadata );
79                 }
80                 // FIXME: make this a more generic post-processing that plugins can take advantage of
81                 //       eg. maven projects should be able to process parent here
82                 if ( !metadata.getDependencies().isEmpty() )
83                 {
84                     ProjectVersionReference ref = new ProjectVersionReference();
85                     ref.setNamespace( namespace );
86                     ref.setProjectId( projectId );
87                     ref.setProjectVersion( projectVersion );
88                     ref.setReferenceType( ProjectVersionReference.ReferenceType.DEPENDENCY );
89                     for ( Dependency dependency : metadata.getDependencies() )
90                     {
91                         try
92                         {
93                             metadataRepository.updateProjectReference( repoId, dependency.getGroupId(),
94                                                                        dependency.getArtifactId(),
95                                                                        dependency.getVersion(), ref );
96                         }
97                         catch ( MetadataRepositoryException e )
98                         {
99                             log.warn( "Unable to persist resolved information: " + e.getMessage(), e );
100                         }
101                     }
102                 }
103                 try
104                 {
105                     metadataRepository.updateProjectVersion( repoId, namespace, projectId, metadata );
106                 }
107                 catch ( MetadataRepositoryException e )
108                 {
109                     log.warn( "Unable to persist resolved information: " + e.getMessage(), e );
110                 }
111             }
112         }
113         return metadata;
114     }
115
116     public Collection<ProjectVersionReference> resolveProjectReferences( String repoId, String namespace,
117                                                                          String projectId, String projectVersion )
118         throws MetadataResolutionException
119     {
120         // TODO: is this assumption correct? could a storage mech. actually know all references in a non-Maven scenario?
121         // not passed to the storage mechanism as resolving references would require iterating all artifacts
122         return metadataRepository.getProjectReferences( repoId, namespace, projectId, projectVersion );
123     }
124
125     public Collection<String> resolveRootNamespaces( String repoId )
126         throws MetadataResolutionException
127     {
128         Collection<String> namespaces = metadataRepository.getRootNamespaces( repoId );
129         Collection<String> storageNamespaces = repositoryStorage.listRootNamespaces( repoId, new ExcludesFilter<String>(
130             namespaces ) );
131         if ( storageNamespaces != null && !storageNamespaces.isEmpty() )
132         {
133             if ( log.isDebugEnabled() )
134             {
135                 log.debug( "Resolved root namespaces from storage: " + storageNamespaces );
136             }
137             for ( String n : storageNamespaces )
138             {
139                 try
140                 {
141                     metadataRepository.updateNamespace( repoId, n );
142                 }
143                 catch ( MetadataRepositoryException e )
144                 {
145                     log.warn( "Unable to persist resolved information: " + e.getMessage(), e );
146                 }
147             }
148             namespaces = new ArrayList<String>( namespaces );
149             namespaces.addAll( storageNamespaces );
150         }
151         return namespaces;
152     }
153
154     public Collection<String> resolveNamespaces( String repoId, String namespace )
155         throws MetadataResolutionException
156     {
157         Collection<String> namespaces = metadataRepository.getNamespaces( repoId, namespace );
158         Collection<String> exclusions = new ArrayList<String>( namespaces );
159         exclusions.addAll( metadataRepository.getProjects( repoId, namespace ) );
160         Collection<String> storageNamespaces = repositoryStorage.listNamespaces( repoId, namespace,
161                                                                                  new ExcludesFilter<String>(
162                                                                                      exclusions ) );
163         if ( storageNamespaces != null && !storageNamespaces.isEmpty() )
164         {
165             if ( log.isDebugEnabled() )
166             {
167                 log.debug( "Resolved namespaces from storage: " + storageNamespaces );
168             }
169             for ( String n : storageNamespaces )
170             {
171                 try
172                 {
173                     metadataRepository.updateNamespace( repoId, namespace + "." + n );
174                 }
175                 catch ( MetadataRepositoryException e )
176                 {
177                     log.warn( "Unable to persist resolved information: " + e.getMessage(), e );
178                 }
179             }
180             namespaces = new ArrayList<String>( namespaces );
181             namespaces.addAll( storageNamespaces );
182         }
183         return namespaces;
184     }
185
186     public Collection<String> resolveProjects( String repoId, String namespace )
187         throws MetadataResolutionException
188     {
189         Collection<String> projects = metadataRepository.getProjects( repoId, namespace );
190         Collection<String> exclusions = new ArrayList<String>( projects );
191         exclusions.addAll( metadataRepository.getNamespaces( repoId, namespace ) );
192         Collection<String> storageProjects = repositoryStorage.listProjects( repoId, namespace,
193                                                                              new ExcludesFilter<String>( exclusions ) );
194         if ( storageProjects != null && !storageProjects.isEmpty() )
195         {
196             if ( log.isDebugEnabled() )
197             {
198                 log.debug( "Resolved projects from storage: " + storageProjects );
199             }
200             for ( String projectId : storageProjects )
201             {
202                 ProjectMetadata projectMetadata = repositoryStorage.readProjectMetadata( repoId, namespace, projectId );
203                 if ( projectMetadata != null )
204                 {
205                     try
206                     {
207                         metadataRepository.updateProject( repoId, projectMetadata );
208                     }
209                     catch ( MetadataRepositoryException e )
210                     {
211                         log.warn( "Unable to persist resolved information: " + e.getMessage(), e );
212                     }
213                 }
214             }
215             projects = new ArrayList<String>( projects );
216             projects.addAll( storageProjects );
217         }
218         return projects;
219     }
220
221     public Collection<String> resolveProjectVersions( String repoId, String namespace, String projectId )
222         throws MetadataResolutionException
223     {
224         Collection<String> projectVersions = metadataRepository.getProjectVersions( repoId, namespace, projectId );
225         Collection<String> storageProjectVersions = repositoryStorage.listProjectVersions( repoId, namespace, projectId,
226                                                                                            new ExcludesFilter<String>(
227                                                                                                projectVersions ) );
228         if ( storageProjectVersions != null && !storageProjectVersions.isEmpty() )
229         {
230             if ( log.isDebugEnabled() )
231             {
232                 log.debug( "Resolved project versions from storage: " + storageProjectVersions );
233             }
234             for ( String projectVersion : storageProjectVersions )
235             {
236                 try
237                 {
238                     ProjectVersionMetadata versionMetadata = repositoryStorage.readProjectVersionMetadata( repoId,
239                                                                                                            namespace,
240                                                                                                            projectId,
241                                                                                                            projectVersion );
242                     if ( versionMetadata != null )
243                     {
244                         metadataRepository.updateProjectVersion( repoId, namespace, projectId, versionMetadata );
245                     }
246                 }
247                 catch ( MetadataResolutionException e )
248                 {
249                     log.warn( "Not update project in metadata repository due to an error resolving it from storage: " +
250                                   e.getMessage() );
251                 }
252                 catch ( MetadataRepositoryException e )
253                 {
254                     log.warn( "Unable to persist resolved information: " + e.getMessage(), e );
255                 }
256             }
257             projectVersions = new ArrayList<String>( projectVersions );
258             projectVersions.addAll( storageProjectVersions );
259         }
260         return projectVersions;
261     }
262
263     public Collection<ArtifactMetadata> resolveArtifacts( String repoId, String namespace, String projectId,
264                                                           String projectVersion )
265         throws MetadataResolutionException
266     {
267         Collection<ArtifactMetadata> artifacts = metadataRepository.getArtifacts( repoId, namespace, projectId,
268                                                                                   projectVersion );
269         Collection<ArtifactMetadata> storageArtifacts = repositoryStorage.readArtifactsMetadata( repoId, namespace,
270                                                                                                  projectId,
271                                                                                                  projectVersion,
272                                                                                                  new ExcludesFilter<String>(
273                                                                                                      createArtifactIdList(
274                                                                                                          artifacts ) ) );
275         if ( storageArtifacts != null && !storageArtifacts.isEmpty() )
276         {
277             if ( log.isDebugEnabled() )
278             {
279                 log.debug( "Resolved artifacts from storage: " + storageArtifacts );
280             }
281             for ( ArtifactMetadata artifact : storageArtifacts )
282             {
283                 try
284                 {
285                     metadataRepository.updateArtifact( repoId, namespace, projectId, projectVersion, artifact );
286                 }
287                 catch ( MetadataRepositoryException e )
288                 {
289                     log.warn( "Unable to persist resolved information: " + e.getMessage(), e );
290                 }
291             }
292             artifacts = new ArrayList<ArtifactMetadata>( artifacts );
293             artifacts.addAll( storageArtifacts );
294         }
295         return artifacts;
296     }
297
298     private Collection<String> createArtifactIdList( Collection<ArtifactMetadata> artifacts )
299     {
300         Collection<String> artifactIds = new ArrayList<String>();
301         for ( ArtifactMetadata artifact : artifacts )
302         {
303             artifactIds.add( artifact.getId() );
304         }
305         return artifactIds;
306     }
307 }