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