]> source.dussan.org Git - archiva.git/blob
cb7768f3b1457a79e8bfa83a822d867b26aee915
[archiva.git] /
1 package org.apache.maven.archiva.repository.project.filters;
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.commons.collections.CollectionUtils;
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.maven.archiva.model.ArchivaModelCloner;
25 import org.apache.maven.archiva.model.ArchivaProjectModel;
26 import org.apache.maven.archiva.model.Dependency;
27 import org.apache.maven.archiva.model.VersionedReference;
28 import org.apache.maven.archiva.repository.project.ProjectModelException;
29 import org.apache.maven.archiva.repository.project.ProjectModelFilter;
30 import org.apache.maven.archiva.repository.project.ProjectModelMerge;
31 import org.apache.maven.archiva.repository.project.ProjectModelResolverFactory;
32 import org.codehaus.plexus.logging.AbstractLogEnabled;
33 import org.codehaus.plexus.logging.Logger;
34 import org.codehaus.plexus.logging.console.ConsoleLogger;
35
36 import java.util.HashMap;
37 import java.util.Iterator;
38 import java.util.List;
39 import java.util.Map;
40
41 /**
42  * Builder for the Effective Project Model.  
43  *
44  * @author <a href="mailto:joakime@apache.org">Joakim Erdfelt</a>
45  * @version $Id$
46  * @plexus.component role="org.apache.maven.archiva.repository.project.ProjectModelFilter" 
47  *                   role-hint="effective" 
48  */
49 public class EffectiveProjectModelFilter
50     extends AbstractLogEnabled
51     implements ProjectModelFilter
52 {
53     private ProjectModelFilter expressionFilter = new ProjectModelExpressionFilter();
54
55     /**
56      * @plexus.requirement
57      */
58     private ProjectModelResolverFactory resolverFactory;
59
60     /**
61      * Take the provided {@link ArchivaProjectModel} and build the effective {@link ArchivaProjectModel}.
62      * 
63      * Steps:
64      * 1) Expand any expressions / properties.
65      * 2) Walk the parent project references and merge.
66      * 3) Apply dependency management settings.
67      * 
68      * @param project the project to create the effective {@link ArchivaProjectModel} from.
69      * @return a the effective {@link ArchivaProjectModel}.
70      * @throws ProjectModelException if there was a problem building the effective pom.
71      */
72     public ArchivaProjectModel filter( final ArchivaProjectModel project )
73         throws ProjectModelException
74     {
75         if ( project == null )
76         {
77             return null;
78         }
79
80         if ( resolverFactory.getCurrentResolverStack().isEmpty() )
81         {
82             throw new IllegalStateException( "Unable to build effective pom with no project model resolvers defined." );
83         }
84
85         // Clone submitted project (so that we don't mess with it) 
86         ArchivaProjectModel effectiveProject = ArchivaModelCloner.clone( project );
87
88         // Setup Expression Evaluation pieces.
89         effectiveProject = expressionFilter.filter( effectiveProject );
90
91         getLogger().debug( "Starting build of effective with: " + effectiveProject );
92
93         // Merge in all the parent poms.
94         effectiveProject = mergeParent( effectiveProject );
95
96         // Resolve dependency versions from dependency management.
97         applyDependencyManagement( effectiveProject );
98
99         // Return what we got.
100         return effectiveProject;
101     }
102
103     private Logger logger;
104
105     protected Logger getLogger()
106     {
107         if ( logger == null )
108         {
109             logger = super.getLogger();
110             if ( logger == null )
111             {
112                 logger = new ConsoleLogger( ConsoleLogger.LEVEL_INFO, this.getClass().getName() );
113             }
114         }
115
116         return logger;
117     }
118
119     private void applyDependencyManagement( ArchivaProjectModel pom )
120     {
121         if ( CollectionUtils.isEmpty( pom.getDependencyManagement() )
122             || CollectionUtils.isEmpty( pom.getDependencies() ) )
123         {
124             // Nothing to do. All done!
125             return;
126         }
127
128         Map managedDependencies = createDependencyMap( pom.getDependencyManagement() );
129         Iterator it = pom.getDependencies().iterator();
130         while ( it.hasNext() )
131         {
132             Dependency dep = (Dependency) it.next();
133             String key = toVersionlessDependencyKey( dep );
134
135             // Do we need to do anything?
136             if ( managedDependencies.containsKey( key ) )
137             {
138                 Dependency mgmtDep = (Dependency) managedDependencies.get( key );
139
140                 dep.setVersion( mgmtDep.getVersion() );
141                 dep.setScope( mgmtDep.getScope() );
142                 dep.setExclusions( ProjectModelMerge.mergeExclusions( dep.getExclusions(), mgmtDep.getExclusions() ) );
143             }
144         }
145     }
146
147     private ArchivaProjectModel mergeParent( ArchivaProjectModel pom )
148         throws ProjectModelException
149     {
150         ArchivaProjectModel mixedProject;
151
152         getLogger().debug( "Parent: " + pom.getParentProject() );
153
154         if ( pom.getParentProject() != null )
155         {
156             // Use parent reference.
157             VersionedReference parentRef = pom.getParentProject();
158
159             getLogger().debug( "Has parent: " + parentRef );
160
161             // Find parent using resolvers.
162             ArchivaProjectModel parentProject = this.resolverFactory.getCurrentResolverStack().findProject( parentRef );
163
164             if ( parentProject != null )
165             {
166                 parentProject = expressionFilter.filter( parentProject );
167                 parentProject = mergeParent( parentProject );
168                 mixedProject = ProjectModelMerge.merge( pom, parentProject );
169             }
170             else
171             {
172                 // Shortcircuit due to missing parent pom.
173                 // TODO: Document this via monitor.
174                 mixedProject = mixinSuperPom( pom );
175             }
176         }
177         else
178         {
179             getLogger().debug( "No parent found" );
180
181             /* Mix in the super-pom.
182              * 
183              * Super POM from maven/components contains many things.
184              * However, for purposes of archiva, only the <repositories>
185              * and <pluginRepositories> sections are of any value.
186              */
187
188             mixedProject = mixinSuperPom( pom );
189         }
190
191         return mixedProject;
192     }
193
194     /**
195      * Super POM from maven/components contains many things.
196      * However, for purposes of archiva, only the <repositories>
197      * and <pluginRepositories> sections are of any value.
198      * 
199      * @param pom
200      * @return
201      */
202     private ArchivaProjectModel mixinSuperPom( ArchivaProjectModel pom )
203     {
204         // TODO: add super pom repositories.
205         getLogger().debug( "Mix in Super POM: " + pom );
206
207         return pom;
208     }
209
210     private static Map createDependencyMap( List dependencies )
211     {
212         Map ret = new HashMap();
213
214         Iterator it = dependencies.iterator();
215         while ( it.hasNext() )
216         {
217             Dependency dep = (Dependency) it.next();
218             String key = toVersionlessDependencyKey( dep );
219             ret.put( key, dep );
220         }
221
222         return ret;
223     }
224
225     private static String toVersionlessDependencyKey( Dependency dep )
226     {
227         StringBuffer key = new StringBuffer();
228
229         key.append( dep.getGroupId() ).append( ":" ).append( dep.getArtifactId() );
230         key.append( StringUtils.defaultString( dep.getClassifier() ) ).append( ":" );
231         key.append( dep.getType() );
232
233         return key.toString();
234     }
235 }