View Javadoc

1   package org.alfresco.maven.plugin.amp.overlay;
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 java.util.ArrayList;
23  import java.util.Iterator;
24  import java.util.List;
25  import java.util.ListIterator;
26  import java.util.Set;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
30  import org.alfresco.maven.plugin.amp.Overlay;
31  import org.apache.maven.project.MavenProject;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  /***
35   * Manages the overlays.
36   *
37   * 
38   * @author Stephane Nicoll
39   */
40  public class OverlayManager
41  {
42      private final List overlays;
43  
44      private final MavenProject project;
45  
46      private final List artifactsOverlays;
47      
48      /***
49       * Creates a manager with the specified overlays.
50       * <p/>
51       * Note that the list is potentially updated by the
52       * manager so a new list is created based on the overlays.
53       *
54       * @param overlays        the overlays
55       * @param project         the maven project
56       * @param defaultIncludes the default includes to use
57       * @param defaultExcludes the default excludes to use
58       * @throws InvalidOverlayConfigurationException
59       *          if the config is invalid
60       */
61      public OverlayManager( List overlays, MavenProject project, String defaultIncludes, String defaultExcludes )
62          throws InvalidOverlayConfigurationException
63      {
64          this.overlays = new ArrayList();
65          if ( overlays != null )
66          {
67              this.overlays.addAll( overlays );
68          }
69          this.project = project;
70  
71          this.artifactsOverlays = getOverlaysAsArtifacts();
72          
73          // Initialize
74          initialize( defaultIncludes, defaultExcludes );
75          
76      }
77      
78  
79      /***
80       * Returns the resolved overlays.
81       *
82       * @return the overlays
83       */
84      public List getOverlays()
85      {
86          return overlays;
87      }
88  
89      /***
90       * Returns the id of the resolved overlays.
91       *
92       * @return the overlay ids
93       */
94      public List getOverlayIds()
95      {
96          final Iterator it = overlays.iterator();
97          final List result = new ArrayList();
98          while ( it.hasNext() )
99          {
100             Overlay overlay = (Overlay) it.next();
101             result.add( overlay.getId() );
102         }
103         return result;
104 
105     }
106 
107     /***
108      * Intializes the manager and validates the overlays configuration.
109      *
110      * @param defaultIncludes the default includes to use
111      * @param defaultExcludes the default excludes to use
112      * @throws InvalidOverlayConfigurationException
113      *          if the configuration is invalid
114      */
115     void initialize( String defaultIncludes, String defaultExcludes )
116         throws InvalidOverlayConfigurationException
117     {
118 
119         // Build the list of configured artifacts and makes sure that each overlay
120         // refer to a valid artifact
121         final List configuredWarArtifacts = new ArrayList();
122         final ListIterator it = overlays.listIterator();
123         while ( it.hasNext() )
124         {
125             Overlay overlay = (Overlay) it.next();
126             if ( overlay == null )
127             {
128                 throw new InvalidOverlayConfigurationException( "overlay could not be null." );
129             }
130             // If it's the current project, return the project instance
131             if ( overlay.isCurrentProject() )
132             {
133                 overlay = Overlay.currentProjectInstance();
134                 it.set( overlay );
135             }
136             // default includes/excludes - only if the overlay uses the default settings
137             if ( Overlay.DEFAULT_INCLUDES.equals( overlay.getIncludes() ) &&
138                 Overlay.DEFAULT_EXCLUDES.equals( overlay.getExcludes() ) )
139             {
140                 overlay.setIncludes( defaultIncludes );
141                 overlay.setExcludes( defaultExcludes );
142             }
143 
144             final Artifact artifact = getAssociatedArtifact( overlay );
145             if ( artifact != null )
146             {
147                 configuredWarArtifacts.add( artifact );
148                 overlay.setArtifact( artifact );
149             }
150         }
151 
152         // Build the list of missing overlays
153         final Iterator it2 = artifactsOverlays.iterator();
154         while ( it2.hasNext() )
155         {
156             Artifact artifact = (Artifact) it2.next();
157             if ( !configuredWarArtifacts.contains( artifact ) )
158             {
159                 // Add a default overlay for the given artifact which will be applied after
160                 // the ones that have been configured
161                 overlays.add( new DefaultOverlay( artifact, defaultIncludes, defaultExcludes ) );
162             }
163         }
164 
165         // Final validation, make sure that the current project is in there. Otherwise add it first
166         final Iterator it3 = overlays.iterator();
167         while ( it3.hasNext() )
168         {
169             Overlay overlay = (Overlay) it3.next();
170             if ( overlay.equals( Overlay.currentProjectInstance() ) )
171             {
172                 return;
173             }
174         }
175         overlays.add( 0, Overlay.currentProjectInstance() );
176     }
177 
178     /***
179      * Returns the Artifact associated to the specified overlay.
180      * <p/>
181      * If the overlay defines the current project, <tt>null</tt> is
182      * returned. If no artifact could not be found for the overlay
183      * a InvalidOverlayConfigurationException is thrown.
184      *
185      * @param overlay an overlay
186      * @return the artifact associated to the overlay
187      * @throws org.apache.maven.plugin.war.overlay.InvalidOverlayConfigurationException
188      *          if the overlay does not have an associated artifact
189      */
190     Artifact getAssociatedArtifact( final Overlay overlay )
191         throws InvalidOverlayConfigurationException
192     {
193         if ( overlay.isCurrentProject() )
194         {
195             return null;
196         }
197 
198         for ( Iterator iterator = artifactsOverlays.iterator(); iterator.hasNext(); )
199         {
200             // Handle classifier dependencies properly (clash management)
201             Artifact artifact = (Artifact) iterator.next();
202             if ( compareOverlayWithArtifact(overlay, artifact) )
203             {
204                 return artifact;
205             }
206         }
207         
208         // maybe its a project dependencies zip or an other type
209         Set projectArtifacts = this.project.getDependencyArtifacts();
210         if (projectArtifacts != null)
211         {
212             for( Iterator iterator = projectArtifacts.iterator();iterator.hasNext();)
213             {
214                 Artifact artifact = (Artifact) iterator.next();
215                 if ( compareOverlayWithArtifact(overlay, artifact) )
216                 {
217                     return artifact;
218                 }
219             }
220         }
221         throw new InvalidOverlayConfigurationException(
222             "overlay[" + overlay + "] is not a dependency of the project." );
223 
224     }
225     
226     private boolean compareOverlayWithArtifact(Overlay overlay, Artifact artifact)
227     {
228        return ( StringUtils.equals( overlay.getGroupId(), artifact.getGroupId() )
229             && StringUtils.equals( overlay.getArtifactId(), artifact.getArtifactId() )
230             && StringUtils.equals( overlay.getType(), artifact.getType() ) && ( overlay.getClassifier() == null || ( StringUtils
231             .equals( overlay.getClassifier(), artifact.getClassifier() ) ) ) );
232     }
233     
234     /***
235      * Returns a list of war {@link org.apache.maven.artifact.Artifact} describing
236      * the overlays of the current project.
237      *
238      * @return the overlays as artifacts objects
239      */    
240     private List getOverlaysAsArtifacts()
241     {
242         ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
243         final Set artifacts = project.getArtifacts();
244         final Iterator it = artifacts.iterator();
245 
246         final List result = new ArrayList();
247         while ( it.hasNext() )
248         {
249             Artifact artifact = (Artifact) it.next();
250             if ( !artifact.isOptional() && filter.include( artifact ) && ( "amp".equals( artifact.getType() ) ) )
251             {
252                 result.add( artifact );
253             }
254         }
255         return result;
256     }
257 }