1 package org.apache.maven.shared.artifact.filter.collection;
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.Arrays;
23 import java.util.LinkedHashSet;
24 import java.util.List;
25 import java.util.Objects;
26 import java.util.Set;
27
28 import org.apache.maven.artifact.Artifact;
29 import org.apache.maven.shared.utils.StringUtils;
30
31 /**
32 * This is the common base class of ClassifierFilter and TypeFilter
33 *
34 * @author <a href="richardv@mxtelecom.com">Richard van der Hoff</a>
35 */
36 public abstract class AbstractArtifactFeatureFilter
37 extends AbstractArtifactsFilter
38 {
39 /** The list of types or classifiers to include */
40 private List<String> includes;
41
42 /**
43 * The list of types or classifiers to exclude (ignored if includes != null)
44 */
45 private List<String> excludes;
46
47 /**
48 * <p>Constructor for AbstractArtifactFeatureFilter.</p>
49 *
50 * @param include comma separated list with includes.
51 * @param exclude comma separated list with excludes.
52 */
53 public AbstractArtifactFeatureFilter( String include, String exclude )
54 {
55 setExcludes( exclude );
56 setIncludes( include );
57 }
58
59 /**
60 * {@inheritDoc}
61 *
62 * This function determines if filtering needs to be performed. Includes are processed before Excludes.
63 */
64 public Set<Artifact> filter( Set<Artifact> artifacts )
65 {
66 Set<Artifact> results = artifacts;
67
68 if ( this.includes != null && !this.includes.isEmpty() )
69 {
70 results = filterIncludes( results, this.includes );
71 }
72
73 if ( this.excludes != null && !this.excludes.isEmpty() )
74 {
75 results = filterExcludes( results, this.excludes );
76 }
77
78 return results;
79 }
80
81 /**
82 * Processes the dependencies list and includes the dependencies that match a filter in the list.
83 *
84 * @param artifacts List of dependencies.
85 * @param theIncludes List of types or classifiers to include.
86 * @return a set of filtered artifacts.
87 */
88 private Set<Artifact> filterIncludes( Set<Artifact> artifacts, List<String> theIncludes )
89 {
90 Set<Artifact> result = new LinkedHashSet<>();
91
92 for ( String include : theIncludes )
93 {
94 for ( Artifact artifact : artifacts )
95 {
96 // if the classifier or type of the artifact
97 // matches the feature
98 // to include, add to the
99 // results
100 if ( compareFeatures( getArtifactFeature( artifact ), include ) )
101 {
102 result.add( artifact );
103 }
104 }
105 }
106 return result;
107 }
108
109 /**
110 * Processes the dependencies list and excludes the dependencies that match a filter in the list.
111 *
112 * @param artifacts List of dependencies.
113 * @param theExcludes List of types or classifiers to exclude.
114 * @return a set of filtered artifacts.
115 */
116 private Set<Artifact> filterExcludes( Set<Artifact> artifacts, List<String> theExcludes )
117 {
118 Set<Artifact> result = new LinkedHashSet<>();
119
120 for ( Artifact artifact : artifacts )
121 {
122 boolean exclude = false;
123 String artifactFeature = getArtifactFeature( artifact );
124
125 // look through all types or classifiers. If no
126 // matches are found
127 // then it can be added to the results.
128 for ( String excludeFeature : theExcludes )
129 {
130 if ( compareFeatures( artifactFeature, excludeFeature ) )
131 {
132 exclude = true;
133 break;
134 }
135 }
136
137 if ( !exclude )
138 {
139 result.add( artifact );
140 }
141 }
142
143 return result;
144 }
145
146 /**
147 * Should return the type or classifier of the given artifact, so that we can filter it
148 *
149 * @param artifact artifact to return type or classifier of
150 * @return type or classifier
151 */
152 protected abstract String getArtifactFeature( Artifact artifact );
153
154 /**
155 * <p>Setter for the field <code>excludes</code>.</p>
156 *
157 * @param excludeString comma separated list with excludes.
158 */
159 public void setExcludes( String excludeString )
160 {
161 if ( StringUtils.isNotEmpty( excludeString ) )
162 {
163 this.excludes = Arrays.asList( StringUtils.split( excludeString, "," ) );
164 }
165 }
166
167 /**
168 * <p>Setter for the field <code>includes</code>.</p>
169 *
170 * @param includeString comma separated list with includes.
171 */
172 public void setIncludes( String includeString )
173 {
174 if ( StringUtils.isNotEmpty( includeString ) )
175 {
176 this.includes = Arrays.asList( StringUtils.split( includeString, "," ) );
177 }
178 }
179
180 /**
181 * <p>Getter for the field <code>excludes</code>.</p>
182 *
183 * @return Returns the excludes.
184 */
185 public List<String> getExcludes()
186 {
187 return this.excludes;
188 }
189
190 /**
191 * <p>Getter for the field <code>includes</code>.</p>
192 *
193 * @return Returns the includes.
194 */
195 public List<String> getIncludes()
196 {
197 return this.includes;
198 }
199
200 /**
201 * Allows Feature comparison to be customized
202 *
203 * @param lhs String artifact's feature
204 * @param rhs String feature from exclude or include list
205 * @return boolean true if features match
206 */
207 protected boolean compareFeatures( String lhs, String rhs )
208 {
209 return ( Objects.equals( lhs, rhs ) );
210 }
211 }