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