View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.shared.artifact.filter;
20  
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.List;
24  
25  import org.apache.maven.artifact.Artifact;
26  import org.apache.maven.artifact.DefaultArtifact;
27  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
28  import org.codehaus.plexus.logging.Logger;
29  
30  /**
31   * {@link ArtifactFilter} implementation that selects artifacts based on their
32   * scopes.
33   * <br/>
34   * <b>NOTE:</b> None of the fine-grained scopes imply other scopes when enabled;
35   * when fine-grained scope control is used, each scope must be enabled separately,
36   * UNLESS the corresponding XXXWithImplications() method is used to enable that
37   * scope.
38   */
39  public class ScopeArtifactFilter
40      implements ArtifactFilter, StatisticsReportingArtifactFilter
41  {
42      private boolean includeCompileScope;
43  
44      private boolean includeRuntimeScope;
45  
46      private boolean includeTestScope;
47  
48      private boolean includeProvidedScope;
49  
50      private boolean includeSystemScope;
51      
52      private boolean includeNullScope = true;
53      
54      private boolean nullScopeHit = false;
55  
56      private boolean compileScopeHit = false;
57  
58      private boolean runtimeScopeHit = false;
59  
60      private boolean testScopeHit = false;
61  
62      private boolean providedScopeHit = false;
63  
64      private boolean systemScopeHit = false;
65  
66      private List filteredArtifactIds = new ArrayList();
67      
68      /**
69       * Constructor that is meant to be used with fine-grained manipulation to 
70       * enable/disable specific scopes using the associated mutator methods.
71       */
72      public ScopeArtifactFilter()
73      {
74          // don't enable anything by default.
75          this( null );
76      }
77  
78      /**
79       * Constructor that uses the implied nature of Maven scopes to determine which
80       * artifacts to include. For instance, 'test' scope implies compile, provided, and runtime,
81       * while 'runtime' scope implies only compile.
82       */
83      public ScopeArtifactFilter( String scope )
84      {
85          if ( DefaultArtifact.SCOPE_COMPILE.equals( scope ) )
86          {
87              setIncludeCompileScopeWithImplications( true );
88          }
89          else if ( DefaultArtifact.SCOPE_RUNTIME.equals( scope ) )
90          {
91              setIncludeRuntimeScopeWithImplications( true );
92          }
93          else if ( DefaultArtifact.SCOPE_TEST.equals( scope ) )
94          {
95              setIncludeTestScopeWithImplications( true );
96          }
97          else if ( DefaultArtifact.SCOPE_PROVIDED.equals( scope ) )
98          {
99              setIncludeProvidedScope( true );
100         }
101         else if ( DefaultArtifact.SCOPE_SYSTEM.equals( scope ) )
102         {
103             setIncludeSystemScope( true );
104         }
105     }
106 
107     public boolean include( Artifact artifact )
108     {
109         boolean result = true;
110         
111         if ( artifact.getScope() == null )
112         {
113             nullScopeHit = true;
114             result = includeNullScope;
115         }
116         else if ( Artifact.SCOPE_COMPILE.equals( artifact.getScope() ) )
117         {
118             compileScopeHit = true;
119             result = includeCompileScope;
120         }
121         else if ( Artifact.SCOPE_RUNTIME.equals( artifact.getScope() ) )
122         {
123             runtimeScopeHit = true;
124             result = includeRuntimeScope;
125         }
126         else if ( Artifact.SCOPE_TEST.equals( artifact.getScope() ) )
127         {
128             testScopeHit = true;
129             result = includeTestScope;
130         }
131         else if ( Artifact.SCOPE_PROVIDED.equals( artifact.getScope() ) )
132         {
133             providedScopeHit = true;
134             result = includeProvidedScope;
135         }
136         else if ( Artifact.SCOPE_SYSTEM.equals( artifact.getScope() ) )
137         {
138             systemScopeHit = true;
139             result = includeSystemScope;
140         }
141 
142         if ( !result )
143         {
144             // We have to be very careful with artifacts that have ranges, 
145             // because DefaultArtifact.getId() as of <= 2.1.0-M1 will throw a NPE 
146             // if a range is specified.
147             String id;
148             if ( artifact.getVersionRange() != null )
149             {
150                 id = artifact.getDependencyConflictId() + ":" + artifact.getVersionRange();
151             }
152             else
153             {
154                 id = artifact.getId();
155             }
156             
157             filteredArtifactIds.add( id );
158         }
159 
160         return result;
161     }
162 
163     public String toString()
164     {
165         return "Scope filter [null-scope=" + includeNullScope + ", compile=" + includeCompileScope + ", runtime=" + includeRuntimeScope + ", test=" + includeTestScope
166             + ", provided=" + includeProvidedScope + ", system=" + includeSystemScope + "]";
167     }
168 
169     public void reportFilteredArtifacts( Logger logger )
170     {
171         if ( !filteredArtifactIds.isEmpty() && logger.isDebugEnabled() )
172         {
173             StringBuffer buffer = new StringBuffer( "The following artifacts were removed by this filter: " );
174 
175             for ( Iterator it = filteredArtifactIds.iterator(); it.hasNext(); )
176             {
177                 String artifactId = (String) it.next();
178 
179                 buffer.append( '\n' ).append( artifactId );
180             }
181 
182             logger.debug( buffer.toString() );
183         }
184     }
185 
186     public void reportMissedCriteria( Logger logger )
187     {
188         if ( logger.isDebugEnabled() )
189         {
190             StringBuffer buffer = new StringBuffer();
191 
192             boolean report = false;
193             if ( !nullScopeHit )
194             {
195                 buffer.append( "\no [Null Scope]" );
196                 report = true;
197             }
198             if ( !compileScopeHit )
199             {
200                 buffer.append( "\no Compile" );
201                 report = true;
202             }
203             if ( !runtimeScopeHit )
204             {
205                 buffer.append( "\no Runtime" );
206                 report = true;
207             }
208             if ( !testScopeHit )
209             {
210                 buffer.append( "\no Test" );
211                 report = true;
212             }
213             if ( !providedScopeHit )
214             {
215                 buffer.append( "\no Provided" );
216                 report = true;
217             }
218             if ( !systemScopeHit )
219             {
220                 buffer.append( "\no System" );
221                 report = true;
222             }
223 
224             if ( report )
225             {
226                 logger.debug( "The following scope filters were not used: " + buffer.toString() );
227             }
228         }
229     }
230 
231     public boolean hasMissedCriteria()
232     {
233         boolean report = false;
234 
235         if ( !nullScopeHit )
236         {
237             report = true;
238         }
239         if ( !compileScopeHit )
240         {
241             report = true;
242         }
243         if ( !runtimeScopeHit )
244         {
245             report = true;
246         }
247         if ( !testScopeHit )
248         {
249             report = true;
250         }
251         if ( !providedScopeHit )
252         {
253             report = true;
254         }
255         if ( !systemScopeHit )
256         {
257             report = true;
258         }
259 
260         return report;
261     }
262     
263     public boolean isIncludeCompileScope()
264     {
265         return includeCompileScope;
266     }
267 
268     public ScopeArtifactFilter setIncludeCompileScope( boolean includeCompileScope )
269     {
270         this.includeCompileScope = includeCompileScope;
271         
272         return this;
273     }
274 
275     public boolean isIncludeRuntimeScope()
276     {
277         return includeRuntimeScope;
278     }
279 
280     public ScopeArtifactFilter setIncludeRuntimeScope( boolean includeRuntimeScope )
281     {
282         this.includeRuntimeScope = includeRuntimeScope;
283         
284         return this;
285     }
286 
287     public boolean isIncludeTestScope()
288     {
289         return includeTestScope;
290     }
291 
292     public ScopeArtifactFilter setIncludeTestScope( boolean includeTestScope )
293     {
294         this.includeTestScope = includeTestScope;
295         
296         return this;
297     }
298 
299     public boolean isIncludeProvidedScope()
300     {
301         return includeProvidedScope;
302     }
303 
304     public ScopeArtifactFilter setIncludeProvidedScope( boolean includeProvidedScope )
305     {
306         this.includeProvidedScope = includeProvidedScope;
307         
308         return this;
309     }
310 
311     public boolean isIncludeSystemScope()
312     {
313         return includeSystemScope;
314     }
315 
316     public ScopeArtifactFilter setIncludeSystemScope( boolean includeSystemScope )
317     {
318         this.includeSystemScope = includeSystemScope;
319         
320         return this;
321     }
322     
323     /**
324      * Manages the following scopes:
325      * 
326      * <ul>
327      *   <li>system</li>
328      *   <li>provided</li>
329      *   <li>compile</li>
330      * </ul>
331      */
332     public ScopeArtifactFilter setIncludeCompileScopeWithImplications( boolean enabled )
333     {
334         includeSystemScope = enabled;
335         includeProvidedScope = enabled;
336         includeCompileScope = enabled;
337         
338         return this;
339     }
340     
341     /**
342      * Manages the following scopes:
343      * 
344      * <ul>
345      *   <li>compile</li>
346      *   <li>runtime</li>
347      * </ul>
348      */
349     public ScopeArtifactFilter setIncludeRuntimeScopeWithImplications( boolean enabled )
350     {
351         includeCompileScope = enabled;
352         includeRuntimeScope = enabled;
353         
354         return this;
355     }
356 
357     /**
358      * Manages the following scopes:
359      * 
360      * <ul>
361      *   <li>system</li>
362      *   <li>provided</li>
363      *   <li>compile</li>
364      *   <li>runtime</li>
365      *   <li>test</li>
366      * </ul>
367      */
368     public ScopeArtifactFilter setIncludeTestScopeWithImplications( boolean enabled )
369     {
370         includeSystemScope = enabled;
371         includeProvidedScope = enabled;
372         includeCompileScope = enabled;
373         includeRuntimeScope = enabled;
374         includeTestScope = enabled;
375         
376         return this;
377     }
378     
379     /**
380      * Determine whether artifacts that have a null scope are included or excluded.
381      */
382     public ScopeArtifactFilter setIncludeNullScope( boolean enable )
383     {
384         includeNullScope = enable;
385         
386         return this;
387     }
388     
389     /**
390      * Reset hit counts and tracking of filtered artifacts, BUT NOT ENABLED SCOPES.
391      */
392     public ScopeArtifactFilter reset()
393     {
394         compileScopeHit = false;
395         runtimeScopeHit = false;
396         testScopeHit = false;
397         providedScopeHit = false;
398         systemScopeHit = false;
399         filteredArtifactIds.clear();
400         
401         return this;
402     }
403 }