View Javadoc
1   package org.apache.maven.plugins.enforcer;
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.HashSet;
23  import java.util.List;
24  import java.util.Set;
25  
26  import org.apache.maven.artifact.Artifact;
27  import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
28  import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
29  import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
30  import org.apache.maven.plugin.logging.Log;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.shared.artifact.filter.StrictPatternExcludesArtifactFilter;
33  import org.apache.maven.shared.artifact.filter.StrictPatternIncludesArtifactFilter;
34  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
35  
36  /**
37   * This rule checks that no snapshots are included.
38   *
39   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
40   */
41  public class RequireReleaseDeps
42      extends AbstractBanDependencies
43  {
44  
45      /**
46       * Allows this rule to execute only when this project is a release.
47       *
48       * @parameter
49       * 
50       * @see {@link #setOnlyWhenRelease(boolean)}
51       * @see {@link #isOnlyWhenRelease()}
52  
53       */
54      private boolean onlyWhenRelease = false;
55  
56      /**
57       * Allows this rule to fail when the parent is defined as a snapshot.
58       *
59       * @parameter
60       * 
61       * @see {@link #setFailWhenParentIsSnapshot(boolean)}
62       * @see {@link #isFailWhenParentIsSnapshot()}
63       */
64      private boolean failWhenParentIsSnapshot = true;
65  
66      /**
67       * Dependencies to ignore when checking for release versions.  For example, inter-module dependencies 
68       * can be excluded from the check and therefore allowed to contain snapshot versions.
69       * 
70       * @see {@link #setExcludes(List)}
71       * @see {@link #getExcludes()}
72       */
73      private List<String> excludes = null;
74  
75      /**
76       * Dependencies to include when checking for release versions.  If any of the included dependencies
77       * have snapshot versions, the rule will fail.
78       * 
79       * @see {@link #setIncludes(List)}
80       * @see {@link #getIncludes()}
81       */
82      private List<String> includes = null;
83  
84      // Override parent to allow optional ignore of this rule.
85      @Override
86      public void execute( EnforcerRuleHelper helper )
87          throws EnforcerRuleException
88      {
89          boolean callSuper;
90          MavenProject project = null;
91          if ( onlyWhenRelease )
92          {
93              // get the project
94              project = getProject( helper );
95  
96              // only call super if this project is a release
97              callSuper = !project.getArtifact().isSnapshot();
98          }
99          else
100         {
101             callSuper = true;
102         }
103         if ( callSuper )
104         {
105             super.execute( helper );
106             if ( failWhenParentIsSnapshot )
107             {
108                 if ( project == null )
109                 {
110                     project = getProject( helper );
111                 }
112                 Artifact parentArtifact = project.getParentArtifact();
113                 if ( parentArtifact != null && parentArtifact.isSnapshot() )
114                 {
115                     throw new EnforcerRuleException( "Parent Cannot be a snapshot: " + parentArtifact.getId() );
116                 }
117             }
118         }
119     }
120 
121     /**
122      * @param helper
123      * @return The evaluated {@link MavenProject}.
124      * @throws EnforcerRuleException
125      */
126     private MavenProject getProject( EnforcerRuleHelper helper )
127         throws EnforcerRuleException
128     {
129         try
130         {
131             return (MavenProject) helper.evaluate( "${project}" );
132         }
133         catch ( ExpressionEvaluationException eee )
134         {
135             throw new EnforcerRuleException( "Unable to retrieve the MavenProject: ", eee );
136         }
137     }
138 
139     @Override
140     protected Set<Artifact> checkDependencies( Set<Artifact> dependencies, Log log )
141         throws EnforcerRuleException
142     {
143         Set<Artifact> foundSnapshots = new HashSet<Artifact>();
144 
145         Set<Artifact> filteredDependencies = filterArtifacts( dependencies );
146         
147         for ( Artifact artifact : filteredDependencies )
148         {
149             if ( artifact.isSnapshot() )
150             {
151                 foundSnapshots.add( artifact );
152             }
153         }
154 
155         return foundSnapshots;
156     }
157     
158     /*
159      * Filter the dependency artifacts according to the includes and excludes
160      * If includes and excludes are both null, the original set is returned.
161      * 
162      * @param dependencies the list of dependencies to filter
163      * @return the resulting set of dependencies
164      */
165     public Set<Artifact> filterArtifacts( Set<Artifact> dependencies )
166     {
167         if ( includes == null && excludes == null )
168         {
169             return dependencies;
170         }
171         
172         AndArtifactFilter filter = new AndArtifactFilter( );
173         if ( includes != null )
174         {
175             filter.add( new StrictPatternIncludesArtifactFilter( includes ) );
176         }
177         if ( excludes != null )
178         {
179             filter.add( new StrictPatternExcludesArtifactFilter( excludes ) );
180         }
181         
182         Set<Artifact> result = new HashSet<Artifact>();
183         for ( Artifact artifact : dependencies )
184         {
185             if ( filter.include( artifact ) )
186             {
187                 result.add( artifact );
188             }
189         }
190         return result;
191     }
192 
193     public final boolean isOnlyWhenRelease()
194     {
195         return onlyWhenRelease;
196     }
197 
198     public final void setOnlyWhenRelease( boolean onlyWhenRelease )
199     {
200         this.onlyWhenRelease = onlyWhenRelease;
201     }
202 
203     public final boolean isFailWhenParentIsSnapshot()
204     {
205         return failWhenParentIsSnapshot;
206     }
207 
208     public final void setFailWhenParentIsSnapshot( boolean failWhenParentIsSnapshot )
209     {
210         this.failWhenParentIsSnapshot = failWhenParentIsSnapshot;
211     }
212     
213     public final void setExcludes( List<String> excludes )
214     {
215         this.excludes = excludes;
216     }
217     
218     public final List<String> getExcludes()
219     {
220         return excludes;
221     }
222     
223     public void setIncludes( List<String> includes )
224     {
225         this.includes = includes;
226     }
227     
228     public List<String> getIncludes()
229     {
230         return includes;
231     }
232 }