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