Add support for customizing layers in Maven
This commit adds an additional 'layers/configuration' property that can be used to refer to a separate layers configuration file. This separate file defines: * The layers and their order of precedence, * How libraries are handled using filters that match against the coordinates of each library, and * How classes are handled using filters that match against the location of the entry An XSD to validate the XML configuration file is available. Closes gh-20295 Co-authored-by: Stephane Nicoll <snicoll@pivotal.io>
This commit is contained in:
committed by
Stephane Nicoll
parent
896d2c8579
commit
e49e62df5c
@@ -25,6 +25,7 @@ import java.io.InputStream;
|
||||
* Encapsulates information about a single library that may be packed into the archive.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Scott Frederick
|
||||
* @since 1.1.2
|
||||
* @see Libraries
|
||||
*/
|
||||
@@ -38,6 +39,8 @@ public class Library {
|
||||
|
||||
private final boolean unpackRequired;
|
||||
|
||||
private final LibraryCoordinates coordinates;
|
||||
|
||||
/**
|
||||
* Create a new {@link Library}.
|
||||
* @param file the source file
|
||||
@@ -66,10 +69,15 @@ public class Library {
|
||||
* @param unpackRequired if the library needs to be unpacked before it can be used
|
||||
*/
|
||||
public Library(String name, File file, LibraryScope scope, boolean unpackRequired) {
|
||||
this(name, file, scope, unpackRequired, null);
|
||||
}
|
||||
|
||||
public Library(String name, File file, LibraryScope scope, boolean unpackRequired, LibraryCoordinates coordinates) {
|
||||
this.name = (name != null) ? name : file.getName();
|
||||
this.file = file;
|
||||
this.scope = scope;
|
||||
this.unpackRequired = unpackRequired;
|
||||
this.coordinates = coordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,6 +122,14 @@ public class Library {
|
||||
return this.unpackRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@linkplain LibraryCoordinates coordinates} of the library.
|
||||
* @return the coordinates
|
||||
*/
|
||||
public LibraryCoordinates getCoordinates() {
|
||||
return this.coordinates;
|
||||
}
|
||||
|
||||
long getLastModified() {
|
||||
return this.file.lastModified();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Encapsulates information about the Maven artifact coordinates of a library.
|
||||
*
|
||||
* @author Scott Frederick
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public final class LibraryCoordinates {
|
||||
|
||||
private final String groupId;
|
||||
|
||||
private final String artifactId;
|
||||
|
||||
private final String version;
|
||||
|
||||
/**
|
||||
* Create a new instance from discrete elements.
|
||||
* @param groupId the group ID
|
||||
* @param artifactId the artifact ID
|
||||
* @param version the version
|
||||
*/
|
||||
public LibraryCoordinates(String groupId, String artifactId, String version) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance from a String value in the form
|
||||
* {@code groupId:artifactId:version} where the version is optional.
|
||||
* @param coordinates the coordinates
|
||||
*/
|
||||
public LibraryCoordinates(String coordinates) {
|
||||
String[] elements = coordinates.split(":");
|
||||
Assert.isTrue(elements.length >= 2, "Coordinates must contain at least 'groupId:artifactId'");
|
||||
this.groupId = elements[0];
|
||||
this.artifactId = elements[1];
|
||||
if (elements.length > 2) {
|
||||
this.version = elements[2];
|
||||
}
|
||||
else {
|
||||
this.version = null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return this.groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return this.artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.loader.tools.Layer;
|
||||
import org.springframework.boot.loader.tools.Layers;
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
import org.springframework.boot.loader.tools.layer.classes.ResourceStrategy;
|
||||
import org.springframework.boot.loader.tools.layer.library.LibraryStrategy;
|
||||
|
||||
/**
|
||||
* Implementation of {@link Layers} representing user-provided layers.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class CustomLayers implements Layers {
|
||||
|
||||
private final List<Layer> layers;
|
||||
|
||||
private final List<ResourceStrategy> resourceStrategies;
|
||||
|
||||
private final List<LibraryStrategy> libraryStrategies;
|
||||
|
||||
public CustomLayers(List<Layer> layers, List<ResourceStrategy> resourceStrategies,
|
||||
List<LibraryStrategy> libraryStrategies) {
|
||||
this.layers = new ArrayList<>(layers);
|
||||
this.resourceStrategies = new ArrayList<>(resourceStrategies);
|
||||
this.libraryStrategies = new ArrayList<>(libraryStrategies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Layer> iterator() {
|
||||
return this.layers.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layer getLayer(String resourceName) {
|
||||
for (ResourceStrategy strategy : this.resourceStrategies) {
|
||||
Layer matchingLayer = strategy.getMatchingLayer(resourceName);
|
||||
if (matchingLayer != null) {
|
||||
return matchingLayer;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Resource '" + resourceName + "' did not match any layer.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layer getLayer(Library library) {
|
||||
for (LibraryStrategy strategy : this.libraryStrategies) {
|
||||
Layer matchingLayer = strategy.getMatchingLayer(library);
|
||||
if (matchingLayer != null) {
|
||||
return matchingLayer;
|
||||
}
|
||||
}
|
||||
throw new IllegalStateException("Library '" + library.getName() + "' did not match any layer.");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.classes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract base class for {@link ResourceFilter} implementations.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public abstract class AbstractResourceFilter implements ResourceFilter {
|
||||
|
||||
private final List<String> includes = new ArrayList<>();
|
||||
|
||||
private final List<String> excludes = new ArrayList<>();
|
||||
|
||||
public AbstractResourceFilter(List<String> includes, List<String> excludes) {
|
||||
this.includes.addAll(includes);
|
||||
this.excludes.addAll(excludes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResourceIncluded(String resourceName) {
|
||||
return isMatch(resourceName, this.includes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResourceExcluded(String resourceName) {
|
||||
return isMatch(resourceName, this.excludes);
|
||||
}
|
||||
|
||||
protected abstract boolean isMatch(String resourceName, List<String> toMatch);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.classes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.loader.tools.Layer;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link ResourceStrategy} with custom filters.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class FilteredResourceStrategy implements ResourceStrategy {
|
||||
|
||||
private final Layer layer;
|
||||
|
||||
private final List<ResourceFilter> filters = new ArrayList<>();
|
||||
|
||||
public FilteredResourceStrategy(String layer, List<ResourceFilter> filters) {
|
||||
Assert.notEmpty(filters, "Filters should not be empty for custom strategy.");
|
||||
this.layer = new Layer(layer);
|
||||
this.filters.addAll(filters);
|
||||
}
|
||||
|
||||
public Layer getLayer() {
|
||||
return this.layer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layer getMatchingLayer(String resourceName) {
|
||||
boolean isIncluded = false;
|
||||
for (ResourceFilter filter : this.filters) {
|
||||
if (filter.isResourceExcluded(resourceName)) {
|
||||
return null;
|
||||
}
|
||||
if (!isIncluded && filter.isResourceIncluded(resourceName)) {
|
||||
isIncluded = true;
|
||||
}
|
||||
}
|
||||
return (isIncluded) ? this.layer : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.classes;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
|
||||
/**
|
||||
* An implementation of {@link ResourceFilter} based on the resource location.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class LocationFilter extends AbstractResourceFilter {
|
||||
|
||||
private static final AntPathMatcher MATCHER = new AntPathMatcher();
|
||||
|
||||
public LocationFilter(List<String> includes, List<String> excludes) {
|
||||
super(includes, excludes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isMatch(String resourceName, List<String> toMatch) {
|
||||
return toMatch.stream().anyMatch((pattern) -> MATCHER.match(pattern, resourceName));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.classes;
|
||||
|
||||
/**
|
||||
* A filter that can tell if a resource has been included or excluded.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public interface ResourceFilter {
|
||||
|
||||
/**
|
||||
* Return true if the resource is included by the filter.
|
||||
* @param resourceName the resource name
|
||||
* @return true if the resource is included
|
||||
*/
|
||||
boolean isResourceIncluded(String resourceName);
|
||||
|
||||
/**
|
||||
* Return true if the resource is included by the filter.
|
||||
* @param resourceName the resource name
|
||||
* @return true if the resource is excluded
|
||||
*/
|
||||
boolean isResourceExcluded(String resourceName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.classes;
|
||||
|
||||
import org.springframework.boot.loader.tools.Layer;
|
||||
|
||||
/**
|
||||
* A strategy used to match a resource to a layer.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public interface ResourceStrategy {
|
||||
|
||||
/**
|
||||
* Return a {@link Layer} for the given resource. If no matching layer is found,
|
||||
* {@code null} is returned.
|
||||
* @param resourceName the name of the resource
|
||||
* @return the matching layer or {@code null}
|
||||
*/
|
||||
Layer getMatchingLayer(String resourceName);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.library;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
import org.springframework.boot.loader.tools.LibraryCoordinates;
|
||||
|
||||
/**
|
||||
* An implementation of {@link LibraryFilter} based on the library's coordinates.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class CoordinateFilter implements LibraryFilter {
|
||||
|
||||
private final List<String> includes = new ArrayList<>();
|
||||
|
||||
private final List<String> excludes = new ArrayList<>();
|
||||
|
||||
public CoordinateFilter(List<String> includes, List<String> excludes) {
|
||||
this.includes.addAll(includes);
|
||||
this.excludes.addAll(excludes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLibraryIncluded(Library library) {
|
||||
return isMatch(library, this.includes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLibraryExcluded(Library library) {
|
||||
return isMatch(library, this.excludes);
|
||||
}
|
||||
|
||||
private boolean isMatch(Library library, List<String> toMatch) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
LibraryCoordinates coordinates = library.getCoordinates();
|
||||
if (coordinates != null) {
|
||||
if (coordinates.getGroupId() != null) {
|
||||
builder.append(coordinates.getGroupId());
|
||||
}
|
||||
builder.append(":");
|
||||
if (coordinates.getArtifactId() != null) {
|
||||
builder.append(coordinates.getArtifactId());
|
||||
}
|
||||
builder.append(":");
|
||||
if (coordinates.getVersion() != null) {
|
||||
builder.append(coordinates.getVersion());
|
||||
}
|
||||
}
|
||||
else {
|
||||
builder.append("::");
|
||||
}
|
||||
String input = builder.toString();
|
||||
for (String patternString : toMatch) {
|
||||
Pattern pattern = buildPatternForString(patternString);
|
||||
if (pattern.matcher(input).matches()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private Pattern buildPatternForString(String pattern) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < pattern.length(); i++) {
|
||||
char c = pattern.charAt(i);
|
||||
if (c == '.') {
|
||||
builder.append("\\.");
|
||||
}
|
||||
else if (c == '*') {
|
||||
builder.append(".*");
|
||||
}
|
||||
else {
|
||||
builder.append(c);
|
||||
}
|
||||
}
|
||||
return Pattern.compile(builder.toString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.library;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.loader.tools.Layer;
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link LibraryStrategy} with custom filters.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public class FilteredLibraryStrategy implements LibraryStrategy {
|
||||
|
||||
private final Layer layer;
|
||||
|
||||
private final List<LibraryFilter> filters = new ArrayList<>();
|
||||
|
||||
public FilteredLibraryStrategy(String layer, List<LibraryFilter> filters) {
|
||||
Assert.notEmpty(filters, "Filters should not be empty for custom strategy.");
|
||||
this.layer = new Layer(layer);
|
||||
this.filters.addAll(filters);
|
||||
}
|
||||
|
||||
public Layer getLayer() {
|
||||
return this.layer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Layer getMatchingLayer(Library library) {
|
||||
boolean isIncluded = false;
|
||||
for (LibraryFilter filter : this.filters) {
|
||||
if (filter.isLibraryExcluded(library)) {
|
||||
return null;
|
||||
}
|
||||
if (!isIncluded && filter.isLibraryIncluded(library)) {
|
||||
isIncluded = true;
|
||||
}
|
||||
}
|
||||
return (isIncluded) ? this.layer : null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.library;
|
||||
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
|
||||
/**
|
||||
* A filter that can tell if a {@link Library} has been included or excluded.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public interface LibraryFilter {
|
||||
|
||||
/**
|
||||
* Return true if the {@link Library} is included by the filter.
|
||||
* @param library the library
|
||||
* @return true if the library is included
|
||||
*/
|
||||
boolean isLibraryIncluded(Library library);
|
||||
|
||||
/**
|
||||
* Return true if the {@link Library} is excluded by the filter.
|
||||
* @param library the library
|
||||
* @return true if the library is excluded
|
||||
*/
|
||||
boolean isLibraryExcluded(Library library);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.library;
|
||||
|
||||
import org.springframework.boot.loader.tools.Layer;
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
|
||||
/**
|
||||
* A strategy used to match a library to a layer.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @since 2.3.0
|
||||
*/
|
||||
public interface LibraryStrategy {
|
||||
|
||||
/**
|
||||
* Return a {@link Layer} for the given {@link Library}. If no matching layer is
|
||||
* found, {@code null} is returned.
|
||||
* @param library the library
|
||||
* @return the matching layer or {@code null}
|
||||
*/
|
||||
Layer getMatchingLayer(Library library);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link LibraryCoordinates}.
|
||||
*
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class LibraryCoordinatesTests {
|
||||
|
||||
@Test
|
||||
void parseCoordinatesWithAllElements() {
|
||||
LibraryCoordinates coordinates = new LibraryCoordinates("com.acme:my-library:1.0.0");
|
||||
assertThat(coordinates.getGroupId()).isEqualTo("com.acme");
|
||||
assertThat(coordinates.getArtifactId()).isEqualTo("my-library");
|
||||
assertThat(coordinates.getVersion()).isEqualTo("1.0.0");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCoordinatesWithoutVersion() {
|
||||
LibraryCoordinates coordinates = new LibraryCoordinates("com.acme:my-library");
|
||||
assertThat(coordinates.getGroupId()).isEqualTo("com.acme");
|
||||
assertThat(coordinates.getArtifactId()).isEqualTo("my-library");
|
||||
assertThat(coordinates.getVersion()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCoordinatesWithEmptyElements() {
|
||||
LibraryCoordinates coordinates = new LibraryCoordinates(":my-library:");
|
||||
assertThat(coordinates.getGroupId()).isEqualTo("");
|
||||
assertThat(coordinates.getArtifactId()).isEqualTo("my-library");
|
||||
assertThat(coordinates.getVersion()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCoordinatesWithExtraElements() {
|
||||
LibraryCoordinates coordinates = new LibraryCoordinates("com.acme:my-library:1.0.0.BUILD-SNAPSHOT:11111");
|
||||
assertThat(coordinates.getGroupId()).isEqualTo("com.acme");
|
||||
assertThat(coordinates.getArtifactId()).isEqualTo("my-library");
|
||||
assertThat(coordinates.getVersion()).isEqualTo("1.0.0.BUILD-SNAPSHOT");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseCoordinatesWithoutMinimumElements() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new LibraryCoordinates("com.acme"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.loader.tools.Layer;
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
import org.springframework.boot.loader.tools.LibraryCoordinates;
|
||||
import org.springframework.boot.loader.tools.layer.classes.FilteredResourceStrategy;
|
||||
import org.springframework.boot.loader.tools.layer.classes.LocationFilter;
|
||||
import org.springframework.boot.loader.tools.layer.library.CoordinateFilter;
|
||||
import org.springframework.boot.loader.tools.layer.library.FilteredLibraryStrategy;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CustomLayers}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class CustomLayersTests {
|
||||
|
||||
@Test
|
||||
void customLayersAreAvailable() {
|
||||
Layer first = new Layer("first");
|
||||
Layer second = new Layer("second");
|
||||
CustomLayers customLayers = new CustomLayers(Arrays.asList(first, second), Collections.emptyList(),
|
||||
Collections.emptyList());
|
||||
List<Layer> actualLayers = new ArrayList<>();
|
||||
customLayers.iterator().forEachRemaining(actualLayers::add);
|
||||
assertThat(actualLayers).containsExactly(first, second);
|
||||
}
|
||||
|
||||
@Test
|
||||
void layerForResourceIsFound() {
|
||||
FilteredResourceStrategy resourceStrategy = new FilteredResourceStrategy("test", Collections
|
||||
.singletonList(new LocationFilter(Collections.singletonList("META-INF/**"), Collections.emptyList())));
|
||||
Layer targetLayer = new Layer("test");
|
||||
CustomLayers customLayers = new CustomLayers(Collections.singletonList(targetLayer),
|
||||
Collections.singletonList(resourceStrategy), Collections.emptyList());
|
||||
assertThat(customLayers.getLayer("META-INF/manifest.mf")).isNotNull().isEqualTo(targetLayer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void layerForResourceIsNotFound() {
|
||||
FilteredResourceStrategy resourceStrategy = new FilteredResourceStrategy("test", Collections
|
||||
.singletonList(new LocationFilter(Collections.singletonList("META-INF/**"), Collections.emptyList())));
|
||||
CustomLayers customLayers = new CustomLayers(Collections.singletonList(new Layer("test")),
|
||||
Collections.singletonList(resourceStrategy), Collections.emptyList());
|
||||
assertThatIllegalStateException().isThrownBy(() -> customLayers.getLayer("com/acme"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void layerForLibraryIsFound() {
|
||||
FilteredLibraryStrategy libraryStrategy = new FilteredLibraryStrategy("test", Collections
|
||||
.singletonList(new CoordinateFilter(Collections.singletonList("com.acme:*"), Collections.emptyList())));
|
||||
Layer targetLayer = new Layer("test");
|
||||
CustomLayers customLayers = new CustomLayers(Collections.singletonList(targetLayer), Collections.emptyList(),
|
||||
Collections.singletonList(libraryStrategy));
|
||||
assertThat(customLayers.getLayer(mockLibrary("com.acme:test"))).isNotNull().isEqualTo(targetLayer);
|
||||
}
|
||||
|
||||
@Test
|
||||
void layerForLibraryIsNotFound() {
|
||||
FilteredLibraryStrategy libraryStrategy = new FilteredLibraryStrategy("test", Collections
|
||||
.singletonList(new CoordinateFilter(Collections.singletonList("com.acme:*"), Collections.emptyList())));
|
||||
CustomLayers customLayers = new CustomLayers(Collections.singletonList(new Layer("test")),
|
||||
Collections.emptyList(), Collections.singletonList(libraryStrategy));
|
||||
assertThatIllegalStateException().isThrownBy(() -> customLayers.getLayer(mockLibrary("org.another:test")));
|
||||
}
|
||||
|
||||
private Library mockLibrary(String coordinates) {
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates(coordinates));
|
||||
return library;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.classes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link FilteredResourceStrategy}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class FilteredResourceStrategyTests {
|
||||
|
||||
@Test
|
||||
void createWhenFiltersNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new FilteredResourceStrategy("custom", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenFiltersEmptyShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new FilteredResourceStrategy("custom", Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLayerShouldReturnLayerName() {
|
||||
FilteredResourceStrategy strategy = new FilteredResourceStrategy("custom",
|
||||
Collections.singletonList(new TestFilter1()));
|
||||
assertThat(strategy.getLayer().toString()).isEqualTo("custom");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMatchingLayerWhenFilterMatchesIncludes() {
|
||||
FilteredResourceStrategy strategy = new FilteredResourceStrategy("custom",
|
||||
Collections.singletonList(new TestFilter1()));
|
||||
assertThat(strategy.getMatchingLayer("ABCD").toString()).isEqualTo("custom");
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesWhenFilterMatchesIncludesAndExcludesFromSameFilter() {
|
||||
FilteredResourceStrategy strategy = new FilteredResourceStrategy("custom",
|
||||
Collections.singletonList(new TestFilter1()));
|
||||
assertThat(strategy.getMatchingLayer("AZ")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesWhenFilterMatchesIncludesAndExcludesFromAnotherFilter() {
|
||||
List<ResourceFilter> filters = new ArrayList<>();
|
||||
filters.add(new TestFilter1());
|
||||
filters.add(new TestFilter2());
|
||||
FilteredResourceStrategy strategy = new FilteredResourceStrategy("custom", filters);
|
||||
assertThat(strategy.getMatchingLayer("AY")).isNull();
|
||||
}
|
||||
|
||||
private static class TestFilter1 implements ResourceFilter {
|
||||
|
||||
@Override
|
||||
public boolean isResourceIncluded(String resourceName) {
|
||||
return resourceName.startsWith("A");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResourceExcluded(String resourceName) {
|
||||
return resourceName.endsWith("Z");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestFilter2 implements ResourceFilter {
|
||||
|
||||
@Override
|
||||
public boolean isResourceIncluded(String resourceName) {
|
||||
return resourceName.startsWith("B");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isResourceExcluded(String resourceName) {
|
||||
return resourceName.endsWith("Y");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.classes;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link LocationFilter}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class LocationFilterTests {
|
||||
|
||||
@Test
|
||||
void isResourceIncludedWhenPatternMatchesWithWildcard() {
|
||||
LocationFilter filter = new LocationFilter(Collections.singletonList("META-INF/**"), Collections.emptyList());
|
||||
assertThat(filter.isResourceIncluded("META-INF/resources/application.yml")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isResourceIncludedWhenPatternDoesNotMatch() {
|
||||
LocationFilter filter = new LocationFilter(Collections.singletonList("META-INF/**"), Collections.emptyList());
|
||||
assertThat(filter.isResourceIncluded("src/main/resources/application.yml")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isResourceExcludedWhenPatternMatchesWithWildcard() {
|
||||
LocationFilter filter = new LocationFilter(Collections.emptyList(), Collections.singletonList("META-INF/**"));
|
||||
assertThat(filter.isResourceExcluded("META-INF/resources/application.yml")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isResourceExcludedWhenPatternDoesNotMatch() {
|
||||
LocationFilter filter = new LocationFilter(Collections.emptyList(), Collections.singletonList("META-INF/**"));
|
||||
assertThat(filter.isResourceExcluded("src/main/resources/application.yml")).isFalse();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.library;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
import org.springframework.boot.loader.tools.LibraryCoordinates;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link CoordinateFilter}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
* @author Scott Frederick
|
||||
*/
|
||||
class CoordinateFilterTests {
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenGroupIdIsNullAndToMatchHasWildcard() {
|
||||
List<String> includes = Collections.singletonList("*:*");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates(null, null, null));
|
||||
assertThat(filter.isLibraryIncluded(library)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenArtifactIdIsNullAndToMatchHasWildcard() {
|
||||
List<String> includes = Collections.singletonList("org.acme:*");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates("org.acme", null, null));
|
||||
assertThat(filter.isLibraryIncluded(library)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenVersionIsNullAndToMatchHasWildcard() {
|
||||
List<String> includes = Collections.singletonList("org.acme:something:*");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates("org.acme", "something", null));
|
||||
assertThat(filter.isLibraryIncluded(library)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenGroupIdDoesNotMatch() {
|
||||
List<String> includes = Collections.singletonList("org.acme:*");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates("other.foo", null, null));
|
||||
assertThat(filter.isLibraryIncluded(library)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenArtifactIdDoesNotMatch() {
|
||||
List<String> includes = Collections.singletonList("org.acme:test:*");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates("org.acme", "other", null));
|
||||
assertThat(filter.isLibraryIncluded(library)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenArtifactIdMatches() {
|
||||
List<String> includes = Collections.singletonList("org.acme:test:*");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates("org.acme", "test", null));
|
||||
assertThat(filter.isLibraryIncluded(library)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenVersionDoesNotMatch() {
|
||||
List<String> includes = Collections.singletonList("org.acme:test:*SNAPSHOT");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates("org.acme", "test", "1.0.0"));
|
||||
assertThat(filter.isLibraryIncluded(library)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isLibraryIncludedWhenVersionMatches() {
|
||||
List<String> includes = Collections.singletonList("org.acme:test:*SNAPSHOT");
|
||||
CoordinateFilter filter = new CoordinateFilter(includes, Collections.emptyList());
|
||||
Library library = mock(Library.class);
|
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates("org.acme", "test", "1.0.0-SNAPSHOT"));
|
||||
assertThat(filter.isLibraryIncluded(library)).isTrue();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2012-2020 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
|
||||
*
|
||||
* https://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.loader.tools.layer.library;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.loader.tools.Library;
|
||||
import org.springframework.boot.loader.tools.LibraryScope;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link FilteredLibraryStrategy}.
|
||||
*
|
||||
* @author Madhura Bhave
|
||||
*/
|
||||
class FilteredLibraryStrategyTests {
|
||||
|
||||
@Test
|
||||
void createWhenFiltersNullShouldThrowException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new FilteredLibraryStrategy("custom", null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenFiltersEmptyShouldThrowException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new FilteredLibraryStrategy("custom", Collections.emptyList()));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLayerShouldReturnLayerName() {
|
||||
FilteredLibraryStrategy strategy = new FilteredLibraryStrategy("custom",
|
||||
Collections.singletonList(new TestFilter1Library()));
|
||||
assertThat(strategy.getLayer().toString()).isEqualTo("custom");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getMatchingLayerWhenFilterMatchesIncludes() {
|
||||
FilteredLibraryStrategy strategy = new FilteredLibraryStrategy("custom",
|
||||
Collections.singletonList(new TestFilter1Library()));
|
||||
Library library = mockLibrary("A-Compile", LibraryScope.COMPILE);
|
||||
assertThat(strategy.getMatchingLayer(library).toString()).isEqualTo("custom");
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesWhenFilterMatchesIncludesAndExcludesFromSameFilter() {
|
||||
FilteredLibraryStrategy strategy = new FilteredLibraryStrategy("custom",
|
||||
Collections.singletonList(new TestFilter1Library()));
|
||||
Library library = mockLibrary("A-Runtime", LibraryScope.RUNTIME);
|
||||
assertThat(strategy.getMatchingLayer(library)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void matchesWhenFilterMatchesIncludesAndExcludesFromAnotherFilter() {
|
||||
List<LibraryFilter> filters = new ArrayList<>();
|
||||
filters.add(new TestFilter1Library());
|
||||
filters.add(new TestFilter2Library());
|
||||
FilteredLibraryStrategy strategy = new FilteredLibraryStrategy("custom", filters);
|
||||
Library library = mockLibrary("A-Provided", LibraryScope.PROVIDED);
|
||||
assertThat(strategy.getMatchingLayer(library)).isNull();
|
||||
}
|
||||
|
||||
private Library mockLibrary(String name, LibraryScope runtime) {
|
||||
Library library = mock(Library.class);
|
||||
given(library.getName()).willReturn(name);
|
||||
given(library.getScope()).willReturn(runtime);
|
||||
return library;
|
||||
}
|
||||
|
||||
private static class TestFilter1Library implements LibraryFilter {
|
||||
|
||||
@Override
|
||||
public boolean isLibraryIncluded(Library library) {
|
||||
return library.getName().contains("A");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLibraryExcluded(Library library) {
|
||||
return library.getScope().equals(LibraryScope.RUNTIME);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestFilter2Library implements LibraryFilter {
|
||||
|
||||
@Override
|
||||
public boolean isLibraryIncluded(Library library) {
|
||||
return library.getName().contains("B");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLibraryExcluded(Library library) {
|
||||
return library.getScope().equals(LibraryScope.PROVIDED);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user