diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java index aa00fdb180d..6856d67f142 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/AbstractDependencyFilterMojo.java @@ -33,10 +33,20 @@ import org.apache.maven.shared.artifact.filter.collection.FilterArtifacts; * A base mojo filtering the dependencies of the project. * * @author Stephane Nicoll + * @author David Turanski * @since 1.1 */ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { + /** + * Collection of artifact definitions to include. The {@link Include} element defines + * a {@code groupId} and {@code artifactId} mandatory properties and an optional + * {@code classifier} property. + * @since 1.2 + */ + @Parameter + private List includes; + /** * Collection of artifact definitions to exclude. The {@link Exclude} element defines * a {@code groupId} and {@code artifactId} mandatory properties and an optional @@ -64,6 +74,10 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { this.excludes = excludes; } + protected void setIncludes(List includes) { + this.includes = includes; + } + protected void setExcludeGroupIds(String excludeGroupIds) { this.excludeGroupIds = excludeGroupIds; } @@ -97,7 +111,10 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { cleanFilterConfig(this.excludeArtifactIds))); filters.addFilter(new MatchingGroupIdFilter( cleanFilterConfig(this.excludeGroupIds))); - if (this.excludes != null) { + if (this.includes != null && !this.includes.isEmpty()) { + filters.addFilter(new IncludeFilter(this.includes)); + } + if (this.excludes != null && !this.excludes.isEmpty()) { filters.addFilter(new ExcludeFilter(this.excludes)); } return filters; diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DependencyFilter.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DependencyFilter.java new file mode 100644 index 00000000000..cb67fc1ee4e --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/DependencyFilter.java @@ -0,0 +1,79 @@ +/* + * Copyright 2014 the original author or authors. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.maven; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactsFilter; +import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; + +/** + * Base class for {@link ArtifactsFilter} based on a {@link FilterableDependency} list. + * + * @author Stephane Nicol + * @author David Turanski + * @since 1.2 + */ +public abstract class DependencyFilter extends AbstractArtifactsFilter { + + private final List filters; + + /** + * Create a new instance with the list of {@link FilterableDependency} instance(s) to use. + */ + public DependencyFilter(List dependencies) { + this.filters = dependencies; + } + + @Override + @SuppressWarnings({ "rawtypes", "unchecked" }) + public Set filter(Set artifacts) throws ArtifactFilterException { + Set result = new HashSet(); + for (Object artifact : artifacts) { + if (!filter((Artifact) artifact)) { + result.add(artifact); + } + } + return result; + } + + protected abstract boolean filter(Artifact artifact); + + /** + * Check if the specified {@link org.apache.maven.artifact.Artifact} matches the + * specified {@link org.springframework.boot.maven.FilterableDependency}. Returns {@code true} + * if it should be excluded + */ + protected final boolean equals(Artifact artifact, FilterableDependency dependency) { + if (!dependency.getGroupId().equals(artifact.getGroupId())) { + return false; + } + if (!dependency.getArtifactId().equals(artifact.getArtifactId())) { + return false; + } + return (dependency.getClassifier() == null || artifact.getClassifier() != null + && dependency.getClassifier().equals(artifact.getClassifier())); + } + + protected final List getFilters() { + return this.filters; + } + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java index 374847188b0..c3c713e5dca 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Exclude.java @@ -16,55 +16,12 @@ package org.springframework.boot.maven; -import org.apache.maven.plugins.annotations.Parameter; - /** * A model for a dependency to exclude. * * @author Stephane Nicoll * @since 1.1 */ -public class Exclude { +public class Exclude extends FilterableDependency { - /** - * The groupId of the artifact to exclude. - */ - @Parameter(required = true) - private String groupId; - - /** - * The artifactId of the artifact to exclude. - */ - @Parameter(required = true) - private String artifactId; - - /** - * The classifier of the artifact to exclude - */ - @Parameter - private String classifier; - - public String getGroupId() { - return this.groupId; - } - - public void setGroupId(String groupId) { - this.groupId = groupId; - } - - public String getArtifactId() { - return this.artifactId; - } - - public void setArtifactId(String artifactId) { - this.artifactId = artifactId; - } - - public String getClassifier() { - return this.classifier; - } - - public void setClassifier(String classifier) { - this.classifier = classifier; - } } diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ExcludeFilter.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ExcludeFilter.java index 07ca965572f..9104159acf5 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ExcludeFilter.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ExcludeFilter.java @@ -16,73 +16,32 @@ package org.springframework.boot.maven; -import java.util.HashSet; import java.util.List; -import java.util.Set; import org.apache.maven.artifact.Artifact; -import org.apache.maven.shared.artifact.filter.collection.AbstractArtifactsFilter; -import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; /** - * An {@link org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter - * ArtifactsFilter} that filters out any artifact matching a configurable list of - * {@link Exclude} instances. + * An {@ArtifactsFilter} that filters out any artifact matching an + * {@link Exclude}. * * @author Stephane Nicoll + * @author David Turanski * @since 1.1 */ -public class ExcludeFilter extends AbstractArtifactsFilter { +public class ExcludeFilter extends DependencyFilter { - private final List excludes; - - /** - * Create a new instance with the list of {@link Exclude} instance(s) to use. - */ public ExcludeFilter(List excludes) { - this.excludes = excludes; + super(excludes); } @Override - @SuppressWarnings("rawtypes") - public Set filter(Set artifacts) throws ArtifactFilterException { - Set result = new HashSet(); - for (Object a : artifacts) { - Artifact artifact = (Artifact) a; - if (!matchExclude(artifact)) { - result.add(artifact); - } - } - return result; - } - - /** - * Check if the specified {@link Artifact} matches one of the known excludes. Returns - * {@code true} if it should be excluded - */ - private boolean matchExclude(Artifact artifact) { - for (Exclude exclude : this.excludes) { - if (match(artifact, exclude)) { + protected boolean filter(Artifact artifact) { + for (FilterableDependency dependency : getFilters()) { + if (equals(artifact, dependency)) { return true; } } return false; } - /** - * Check if the specified {@link Artifact} matches the specified {@link Exclude}. - * Returns {@code true} if it should be excluded - */ - private boolean match(Artifact artifact, Exclude exclude) { - if (!exclude.getGroupId().equals(artifact.getGroupId())) { - return false; - } - if (!exclude.getArtifactId().equals(artifact.getArtifactId())) { - return false; - } - return (exclude.getClassifier() == null || artifact.getClassifier() != null - && exclude.getClassifier().equals(artifact.getClassifier())); - - } - } diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java new file mode 100644 index 00000000000..a8a69a1b7e9 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/FilterableDependency.java @@ -0,0 +1,72 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.maven; + +import org.apache.maven.plugins.annotations.Parameter; + +/** + * A model for a dependency to include or exclude. + * + * @author Stephane Nicoll + * @author David Turanski + * @since 1.2 + */ +abstract class FilterableDependency { + + /** + * The groupId of the artifact to exclude. + */ + @Parameter(required = true) + private String groupId; + + /** + * The artifactId of the artifact to exclude. + */ + @Parameter(required = true) + private String artifactId; + + /** + * The classifier of the artifact to exclude + */ + @Parameter + private String classifier; + + public String getGroupId() { + return this.groupId; + } + + public void setGroupId(String groupId) { + this.groupId = groupId; + } + + public String getArtifactId() { + return this.artifactId; + } + + public void setArtifactId(String artifactId) { + this.artifactId = artifactId; + } + + public String getClassifier() { + return this.classifier; + } + + public void setClassifier(String classifier) { + this.classifier = classifier; + } + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Include.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Include.java new file mode 100644 index 00000000000..40f6203e75b --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/Include.java @@ -0,0 +1,27 @@ +/* + * Copyright 2012-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.maven; + +/** + * A model for a dependency to include. + * + * @author David Turanski + * @since 1.2 + */ +public class Include extends FilterableDependency { + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/IncludeFilter.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/IncludeFilter.java new file mode 100644 index 00000000000..70fccc24a05 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/IncludeFilter.java @@ -0,0 +1,46 @@ +/* + * Copyright 2014 the original author or authors. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.maven; + +import java.util.List; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.artifact.filter.collection.ArtifactsFilter; + +/** + * An {@link ArtifactsFilter} that filters out any artifact not matching an + * {@link Include}. + * + * @author David Turanski + * @since 1.2 + */ +public class IncludeFilter extends DependencyFilter { + + public IncludeFilter(List includes) { + super(includes); + } + + @Override + protected boolean filter(Artifact artifact) { + for (FilterableDependency dependency : getFilters()) { + if (equals(artifact, dependency)) { + return false; + } + } + return true; + } + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ExcludeFilterTests.java b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ExcludeFilterTests.java index 2114d9ff680..9330379acf3 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ExcludeFilterTests.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ExcludeFilterTests.java @@ -34,6 +34,7 @@ import static org.mockito.Mockito.mock; * Tests for {@link ExcludeFilter}. * * @author Stephane Nicoll + * @author David Turanski */ @SuppressWarnings("rawtypes") public class ExcludeFilterTests { @@ -111,20 +112,20 @@ public class ExcludeFilterTests { assertSame(anotherAcme, result.iterator().next()); } - private Exclude createExclude(String groupId, String artifactId, String classifier) { - Exclude e = new Exclude(); - e.setGroupId(groupId); - e.setArtifactId(artifactId); - if (classifier != null) { - e.setClassifier(classifier); - } - return e; - } - private Exclude createExclude(String groupId, String artifactId) { return createExclude(groupId, artifactId, null); } + private Exclude createExclude(String groupId, String artifactId, String classifier) { + Exclude exclude = new Exclude(); + exclude.setGroupId(groupId); + exclude.setArtifactId(artifactId); + if (classifier != null) { + exclude.setClassifier(classifier); + } + return exclude; + } + private Artifact createArtifact(String groupId, String artifactId, String classifier) { Artifact a = mock(Artifact.class); given(a.getGroupId()).willReturn(groupId); @@ -136,4 +137,5 @@ public class ExcludeFilterTests { private Artifact createArtifact(String groupId, String artifactId) { return createArtifact(groupId, artifactId, null); } + } diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/IncludeFilterTests.java b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/IncludeFilterTests.java new file mode 100644 index 00000000000..fe002342e01 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/IncludeFilterTests.java @@ -0,0 +1,136 @@ +/* + * Copyright 2014 the original author or authors. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.boot.maven; + +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.shared.artifact.filter.collection.ArtifactFilterException; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertSame; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link org.springframework.boot.maven.IncludeFilter}. + * + * @author David Turanski + */ +@SuppressWarnings("rawtypes") +public class IncludeFilterTests { + + @Test + public void includeSimple() throws ArtifactFilterException { + IncludeFilter filter = new IncludeFilter(Arrays.asList(createInclude("com.foo", + "bar"))); + Artifact artifact = createArtifact("com.foo", "bar"); + Set result = filter.filter(Collections.singleton(artifact)); + assertEquals("Should not have been filtered", 1, result.size()); + assertSame(artifact, result.iterator().next()); + } + + @Test + public void includeGroupIdNoMatch() throws ArtifactFilterException { + IncludeFilter filter = new IncludeFilter(Arrays.asList(createInclude("com.foo", + "bar"))); + Artifact artifact = createArtifact("com.baz", "bar"); + Set result = filter.filter(Collections.singleton(artifact)); + assertEquals("Should have been filtered", 0, result.size()); + } + + @Test + public void includeArtifactIdNoMatch() throws ArtifactFilterException { + IncludeFilter filter = new IncludeFilter(Arrays.asList(createInclude("com.foo", + "bar"))); + Artifact artifact = createArtifact("com.foo", "biz"); + Set result = filter.filter(Collections.singleton(artifact)); + assertEquals("Should have been filtered", 0, result.size()); + } + + @Test + public void includeClassifier() throws ArtifactFilterException { + IncludeFilter filter = new IncludeFilter(Arrays.asList(createInclude("com.foo", + "bar", "jdk5"))); + Artifact artifact = createArtifact("com.foo", "bar", "jdk5"); + Set result = filter.filter(Collections.singleton(artifact)); + assertEquals("Should not have been filtered", 1, result.size()); + assertSame(artifact, result.iterator().next()); + } + + @Test + public void includeClassifierNoTargetClassifier() throws ArtifactFilterException { + IncludeFilter filter = new IncludeFilter(Arrays.asList(createInclude("com.foo", + "bar", "jdk5"))); + Artifact artifact = createArtifact("com.foo", "bar"); + Set result = filter.filter(Collections.singleton(artifact)); + assertEquals("Should have been filtered", 0, result.size()); + } + + @Test + public void includeClassifierNoMatch() throws ArtifactFilterException { + IncludeFilter filter = new IncludeFilter(Arrays.asList(createInclude("com.foo", + "bar", "jdk5"))); + Artifact artifact = createArtifact("com.foo", "bar", "jdk6"); + Set result = filter.filter(Collections.singleton(artifact)); + assertEquals("Should have been filtered", 0, result.size()); + } + + @Test + public void includeMulti() throws ArtifactFilterException { + IncludeFilter filter = new IncludeFilter(Arrays.asList( + createInclude("com.foo", "bar"), createInclude("com.foo", "bar2"), + createInclude("org.acme", "app"))); + Set artifacts = new HashSet(); + artifacts.add(createArtifact("com.foo", "bar")); + artifacts.add(createArtifact("com.foo", "bar")); + Artifact anotherAcme = createArtifact("org.acme", "another-app"); + artifacts.add(anotherAcme); + Set result = filter.filter(artifacts); + assertEquals("One dependency should have been filtered", 2, result.size()); + } + + private Include createInclude(String groupId, String artifactId) { + return createInclude(groupId, artifactId, null); + } + + private Include createInclude(String groupId, String artifactId, String classifier) { + Include include = new Include(); + include.setGroupId(groupId); + include.setArtifactId(artifactId); + if (classifier != null) { + include.setClassifier(classifier); + } + return include; + } + + private Artifact createArtifact(String groupId, String artifactId, String classifier) { + Artifact a = mock(Artifact.class); + given(a.getGroupId()).willReturn(groupId); + given(a.getArtifactId()).willReturn(artifactId); + given(a.getClassifier()).willReturn(classifier); + return a; + } + + private Artifact createArtifact(String groupId, String artifactId) { + return createArtifact(groupId, artifactId, null); + } + +}