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.plugins.assembly.utils;
20  
21  import java.util.ArrayList;
22  import java.util.Arrays;
23  import java.util.Collection;
24  import java.util.Collections;
25  import java.util.HashSet;
26  import java.util.Iterator;
27  import java.util.LinkedHashSet;
28  import java.util.List;
29  import java.util.Set;
30  
31  import org.apache.maven.artifact.Artifact;
32  import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
33  import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
34  import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
37  import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
38  import org.apache.maven.shared.artifact.filter.StatisticsReportingArtifactFilter;
39  import org.apache.maven.shared.artifact.filter.resolve.ScopeFilter;
40  import org.slf4j.Logger;
41  
42  /**
43   *
44   */
45  public final class FilterUtils {
46  
47      private FilterUtils() {}
48  
49      public static Set<MavenProject> filterProjects(
50              final Set<MavenProject> projects,
51              final List<String> includes,
52              final List<String> excludes,
53              final boolean actTransitively,
54              final Logger logger) {
55          final List<PatternIncludesArtifactFilter> allFilters = new ArrayList<>();
56  
57          final AndArtifactFilter filter = new AndArtifactFilter();
58  
59          if (!includes.isEmpty()) {
60              final PatternIncludesArtifactFilter includeFilter =
61                      new PatternIncludesArtifactFilter(includes, actTransitively);
62  
63              filter.add(includeFilter);
64              allFilters.add(includeFilter);
65          }
66          if (!excludes.isEmpty()) {
67              final PatternExcludesArtifactFilter excludeFilter =
68                      new PatternExcludesArtifactFilter(excludes, actTransitively);
69  
70              filter.add(excludeFilter);
71              allFilters.add(excludeFilter);
72          }
73  
74          Set<MavenProject> result = new LinkedHashSet<>(projects.size());
75          for (MavenProject project : projects) {
76              final Artifact artifact = project.getArtifact();
77  
78              if (filter.include(artifact)) {
79                  result.add(project);
80              }
81          }
82  
83          for (final PatternIncludesArtifactFilter f : allFilters) {
84              if (f != null) {
85                  f.reportMissedCriteria(logger);
86              }
87          }
88          return result;
89      }
90  
91      public static void filterArtifacts(
92              final Set<Artifact> artifacts,
93              final List<String> includes,
94              final List<String> excludes,
95              final boolean strictFiltering,
96              final boolean actTransitively,
97              final Logger logger,
98              final ArtifactFilter... additionalFilters)
99              throws InvalidAssemblerConfigurationException {
100         final List<ArtifactFilter> allFilters = new ArrayList<>();
101 
102         final AndArtifactFilter filter = new AndArtifactFilter();
103 
104         if (additionalFilters != null) {
105             for (final ArtifactFilter additionalFilter : additionalFilters) {
106                 if (additionalFilter != null) {
107                     filter.add(additionalFilter);
108                 }
109             }
110         }
111 
112         if (!includes.isEmpty()) {
113             final ArtifactFilter includeFilter = new PatternIncludesArtifactFilter(includes, actTransitively);
114 
115             filter.add(includeFilter);
116 
117             allFilters.add(includeFilter);
118         }
119 
120         if (!excludes.isEmpty()) {
121             final ArtifactFilter excludeFilter = new PatternExcludesArtifactFilter(excludes, actTransitively);
122 
123             filter.add(excludeFilter);
124 
125             allFilters.add(excludeFilter);
126         }
127 
128         // FIXME: Why is this added twice??
129         // if ( additionalFilters != null && !additionalFilters.isEmpty() )
130         // {
131         // allFilters.addAll( additionalFilters );
132         // }
133 
134         for (final Iterator<Artifact> it = artifacts.iterator(); it.hasNext(); ) {
135             final Artifact artifact = it.next();
136 
137             if (!filter.include(artifact)) {
138                 it.remove();
139 
140                 if (logger.isDebugEnabled()) {
141                     logger.debug(artifact.getId() + " was removed by one or more filters.");
142                 }
143             }
144         }
145 
146         reportFilteringStatistics(allFilters, logger);
147 
148         for (final ArtifactFilter f : allFilters) {
149             if (f instanceof StatisticsReportingArtifactFilter) {
150                 final StatisticsReportingArtifactFilter sFilter = (StatisticsReportingArtifactFilter) f;
151 
152                 if (strictFiltering && sFilter.hasMissedCriteria()) {
153                     throw new InvalidAssemblerConfigurationException(
154                             "One or more filters had unmatched criteria. Check debug log for more information.");
155                 }
156             }
157         }
158     }
159 
160     public static void reportFilteringStatistics(final Collection<ArtifactFilter> filters, final Logger logger) {
161         for (final ArtifactFilter f : filters) {
162             if (f instanceof StatisticsReportingArtifactFilter) {
163                 final StatisticsReportingArtifactFilter sFilter = (StatisticsReportingArtifactFilter) f;
164 
165                 if (logger.isDebugEnabled()) {
166                     logger.debug("Statistics for " + sFilter + "\n");
167                 }
168 
169                 sFilter.reportMissedCriteria(logger);
170                 sFilter.reportFilteredArtifacts(logger);
171             }
172         }
173     }
174 
175     /**
176      * Results in a filter including the rootScope and its transitive scopes
177      *
178      * @param rootScope the root scope
179      * @return the filter
180      */
181     public static ScopeFilter newScopeFilter(final String rootScope) {
182         return newScopeFilter(Collections.singleton(rootScope));
183     }
184 
185     /**
186      * Results in a filter including all rootScopes and their transitive scopes
187      *
188      * @param rootScopes all root scopes
189      * @return the filter
190      */
191     public static ScopeFilter newScopeFilter(final Collection<String> rootScopes) {
192         Set<String> scopes = new HashSet<>();
193 
194         for (String rootScope : rootScopes) {
195             if (Artifact.SCOPE_COMPILE.equals(rootScope)) {
196                 scopes.addAll(Arrays.asList("compile", "provided", "system"));
197             }
198             if (Artifact.SCOPE_PROVIDED.equals(rootScope)) {
199                 scopes.add("provided");
200             }
201             if (Artifact.SCOPE_RUNTIME.equals(rootScope)) {
202                 scopes.addAll(Arrays.asList("compile", "runtime"));
203             }
204             if (Artifact.SCOPE_SYSTEM.equals(rootScope)) {
205                 scopes.add("system");
206             }
207             if (Artifact.SCOPE_TEST.equals(rootScope)) {
208                 scopes.addAll(Arrays.asList("compile", "provided", "runtime", "system", "test"));
209             }
210         }
211 
212         return ScopeFilter.including(scopes);
213     }
214 }