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