Browse Source
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>pull/20518/head
38 changed files with 2024 additions and 37 deletions
@ -0,0 +1,77 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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); |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<groupId>org.springframework.boot.maven.it</groupId> |
||||
<artifactId>jar-release</artifactId> |
||||
<version>0.0.1.RELEASE</version> |
||||
<packaging>jar</packaging> |
||||
<name>jar</name> |
||||
<description>Release Jar dependency</description> |
||||
</project> |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<groupId>org.springframework.boot.maven.it</groupId> |
||||
<artifactId>jar-snapshot</artifactId> |
||||
<version>0.0.1.BUILD-SNAPSHOT</version> |
||||
<packaging>jar</packaging> |
||||
<name>jar</name> |
||||
<description>Snapshot Jar dependency</description> |
||||
</project> |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<groupId>org.springframework.boot.maven.it</groupId> |
||||
<artifactId>jar-layered</artifactId> |
||||
<version>0.0.1.BUILD-SNAPSHOT</version> |
||||
<properties> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
<maven.compiler.source>@java.version@</maven.compiler.source> |
||||
<maven.compiler.target>@java.version@</maven.compiler.target> |
||||
</properties> |
||||
<build> |
||||
<plugins> |
||||
<plugin> |
||||
<groupId>@project.groupId@</groupId> |
||||
<artifactId>@project.artifactId@</artifactId> |
||||
<version>@project.version@</version> |
||||
<executions> |
||||
<execution> |
||||
<goals> |
||||
<goal>repackage</goal> |
||||
</goals> |
||||
<configuration> |
||||
<layers> |
||||
<enabled>true</enabled> |
||||
<configuration>${project.basedir}/src/layers.xml</configuration> |
||||
</layers> |
||||
</configuration> |
||||
</execution> |
||||
</executions> |
||||
</plugin> |
||||
</plugins> |
||||
</build> |
||||
<dependencies> |
||||
<dependency> |
||||
<groupId>org.springframework.boot.maven.it</groupId> |
||||
<artifactId>jar-snapshot</artifactId> |
||||
<version>0.0.1.BUILD-SNAPSHOT</version> |
||||
</dependency> |
||||
<dependency> |
||||
<groupId>org.springframework.boot.maven.it</groupId> |
||||
<artifactId>jar-release</artifactId> |
||||
<version>0.0.1.RELEASE</version> |
||||
</dependency> |
||||
</dependencies> |
||||
</project> |
||||
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
<layers-configuration xmlns="http://www.springframework.org/schema/boot/layers" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers |
||||
https://www.springframework.org/schema/layers/layers-configuration.xsd"> |
||||
<layers> |
||||
<layer>configuration</layer> |
||||
<layer>application</layer> |
||||
<layer>snapshot-dependencies</layer> |
||||
<layer>my-dependencies-name</layer> |
||||
</layers> |
||||
<libraries> |
||||
<layer-content layer="snapshot-dependencies"> |
||||
<coordinates> |
||||
<include>*:*:*-SNAPSHOT</include> |
||||
</coordinates> |
||||
</layer-content> |
||||
<layer-content layer="my-dependencies-name"> |
||||
<coordinates> |
||||
<include>*:*:*</include> |
||||
</coordinates> |
||||
</layer-content> |
||||
</libraries> |
||||
<classes> |
||||
<layer-content layer="configuration"> |
||||
<locations> |
||||
<include>**/application*.*</include> |
||||
</locations> |
||||
</layer-content> |
||||
<layer-content layer="application"> |
||||
<locations> |
||||
<include>**</include> |
||||
</locations> |
||||
</layer-content> |
||||
</classes> |
||||
</layers-configuration> |
||||
@ -0,0 +1,24 @@
@@ -0,0 +1,24 @@
|
||||
/* |
||||
* 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.test; |
||||
|
||||
public class SampleApplication { |
||||
|
||||
public static void main(String[] args) { |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?> |
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
<modelVersion>4.0.0</modelVersion> |
||||
<groupId>org.springframework.boot.maven.it</groupId> |
||||
<artifactId>aggregator</artifactId> |
||||
<version>0.0.1.BUILD-SNAPSHOT</version> |
||||
<packaging>pom</packaging> |
||||
<properties> |
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
<maven.compiler.source>@java.version@</maven.compiler.source> |
||||
<maven.compiler.target>@java.version@</maven.compiler.target> |
||||
</properties> |
||||
<modules> |
||||
<module>jar-snapshot</module> |
||||
<module>jar-release</module> |
||||
<module>jar</module> |
||||
</modules> |
||||
</project> |
||||
@ -0,0 +1,169 @@
@@ -0,0 +1,169 @@
|
||||
/* |
||||
* 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.maven; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.w3c.dom.Document; |
||||
import org.w3c.dom.Element; |
||||
import org.w3c.dom.Node; |
||||
import org.w3c.dom.NodeList; |
||||
|
||||
import org.springframework.boot.loader.tools.Layer; |
||||
import org.springframework.boot.loader.tools.layer.CustomLayers; |
||||
import org.springframework.boot.loader.tools.layer.classes.FilteredResourceStrategy; |
||||
import org.springframework.boot.loader.tools.layer.classes.ResourceFilter; |
||||
import org.springframework.boot.loader.tools.layer.classes.ResourceStrategy; |
||||
import org.springframework.boot.loader.tools.layer.library.CoordinateFilter; |
||||
import org.springframework.boot.loader.tools.layer.library.FilteredLibraryStrategy; |
||||
import org.springframework.boot.loader.tools.layer.library.LibraryFilter; |
||||
import org.springframework.boot.loader.tools.layer.library.LibraryStrategy; |
||||
|
||||
/** |
||||
* Produces a {@link CustomLayers} based on the given {@link Document}. |
||||
* |
||||
* @author Madhura Bhave |
||||
* @since 2.3.0 |
||||
*/ |
||||
public class CustomLayersProvider { |
||||
|
||||
public CustomLayers getLayers(Document document) { |
||||
Element root = document.getDocumentElement(); |
||||
NodeList nl = root.getChildNodes(); |
||||
List<Layer> layers = new ArrayList<>(); |
||||
List<LibraryStrategy> libraryStrategies = new ArrayList<>(); |
||||
List<ResourceStrategy> resourceStrategies = new ArrayList<>(); |
||||
for (int i = 0; i < nl.getLength(); i++) { |
||||
Node node = nl.item(i); |
||||
if (node instanceof Element) { |
||||
Element ele = (Element) node; |
||||
String nodeName = ele.getNodeName(); |
||||
if ("layers".equals(nodeName)) { |
||||
layers.addAll(getLayers(ele)); |
||||
} |
||||
if ("libraries".equals(nodeName)) { |
||||
libraryStrategies.addAll(getLibraryStrategies(ele.getChildNodes())); |
||||
} |
||||
if ("classes".equals(nodeName)) { |
||||
resourceStrategies.addAll(getResourceStrategies(ele.getChildNodes())); |
||||
} |
||||
} |
||||
} |
||||
return new CustomLayers(layers, resourceStrategies, libraryStrategies); |
||||
} |
||||
|
||||
private List<LibraryStrategy> getLibraryStrategies(NodeList nodes) { |
||||
List<LibraryStrategy> strategy = new ArrayList<>(); |
||||
for (int i = 0; i < nodes.getLength(); i++) { |
||||
Node item = nodes.item(i); |
||||
if (item instanceof Element) { |
||||
Element element = (Element) item; |
||||
String layer = element.getAttribute("layer"); |
||||
if ("layer-content".equals(element.getTagName())) { |
||||
List<LibraryFilter> filters = new ArrayList<>(); |
||||
NodeList filterList = item.getChildNodes(); |
||||
if (filterList.getLength() == 0) { |
||||
throw new IllegalArgumentException("Filters for layer-content must not be empty."); |
||||
} |
||||
for (int k = 0; k < filterList.getLength(); k++) { |
||||
Node filter = filterList.item(k); |
||||
if (filter instanceof Element) { |
||||
List<String> includeList = getPatterns((Element) filter, "include"); |
||||
List<String> excludeList = getPatterns((Element) filter, "exclude"); |
||||
addLibraryFilter(filters, filter, includeList, excludeList); |
||||
} |
||||
} |
||||
strategy.add(new FilteredLibraryStrategy(layer, filters)); |
||||
} |
||||
} |
||||
} |
||||
return strategy; |
||||
} |
||||
|
||||
private void addLibraryFilter(List<LibraryFilter> filters, Node filter, List<String> includeList, |
||||
List<String> excludeList) { |
||||
if ("coordinates".equals(filter.getNodeName())) { |
||||
filters.add(new CoordinateFilter(includeList, excludeList)); |
||||
} |
||||
} |
||||
|
||||
private List<ResourceStrategy> getResourceStrategies(NodeList strategies) { |
||||
List<ResourceStrategy> strategy = new ArrayList<>(); |
||||
for (int i = 0; i < strategies.getLength(); i++) { |
||||
Node item = strategies.item(i); |
||||
List<ResourceFilter> filters = new ArrayList<>(); |
||||
if (item instanceof Element) { |
||||
Element element = (Element) item; |
||||
String layer = element.getAttribute("layer"); |
||||
if ("layer-content".equals(element.getTagName())) { |
||||
NodeList filterList = item.getChildNodes(); |
||||
if (filterList.getLength() == 0) { |
||||
throw new IllegalArgumentException("Filters for layer-content must not be empty."); |
||||
} |
||||
for (int k = 0; k < filterList.getLength(); k++) { |
||||
Node filter = filterList.item(k); |
||||
if (filter instanceof Element) { |
||||
List<String> includeList = getPatterns((Element) filter, "include"); |
||||
List<String> excludeList = getPatterns((Element) filter, "exclude"); |
||||
addFilter(filters, filter, includeList, excludeList); |
||||
} |
||||
} |
||||
strategy.add(new FilteredResourceStrategy(layer, filters)); |
||||
} |
||||
} |
||||
} |
||||
return strategy; |
||||
} |
||||
|
||||
private void addFilter(List<ResourceFilter> filters, Node filter, List<String> includeList, |
||||
List<String> excludeList) { |
||||
if ("locations".equals(filter.getNodeName())) { |
||||
filters.add( |
||||
new org.springframework.boot.loader.tools.layer.classes.LocationFilter(includeList, excludeList)); |
||||
} |
||||
} |
||||
|
||||
private List<String> getPatterns(Element element, String key) { |
||||
NodeList patterns = element.getElementsByTagName(key); |
||||
List<String> values = new ArrayList<>(); |
||||
for (int j = 0; j < patterns.getLength(); j++) { |
||||
Node item = patterns.item(j); |
||||
if (item instanceof Element) { |
||||
values.add(item.getTextContent()); |
||||
} |
||||
} |
||||
return values; |
||||
} |
||||
|
||||
private List<Layer> getLayers(Element element) { |
||||
List<Layer> layers = new ArrayList<>(); |
||||
NodeList nl = element.getChildNodes(); |
||||
for (int i = 0; i < nl.getLength(); i++) { |
||||
Node node = nl.item(i); |
||||
if (node instanceof Element) { |
||||
Element ele = (Element) node; |
||||
String nodeName = ele.getNodeName(); |
||||
if ("layer".equals(nodeName)) { |
||||
layers.add(new Layer(ele.getTextContent())); |
||||
} |
||||
} |
||||
} |
||||
return layers; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,96 @@
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||
<xsd:schema elementFormDefault="qualified" |
||||
xmlns="http://www.springframework.org/schema/boot/layers" |
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema" |
||||
targetNamespace="http://www.springframework.org/schema/boot/layers"> |
||||
<xsd:element name="layers-configuration" type="layersConfigurationType"/> |
||||
<xsd:complexType name="layersConfigurationType"> |
||||
<xsd:sequence> |
||||
<xsd:element type="layersType" name="layers"/> |
||||
<xsd:element type="librariesType" name="libraries" minOccurs="0"/> |
||||
<xsd:element type="classesType" name="classes" minOccurs="0"/> |
||||
</xsd:sequence> |
||||
</xsd:complexType> |
||||
<xsd:complexType name="layersType"> |
||||
<xsd:sequence> |
||||
<xsd:element type="xsd:string" name="layer" maxOccurs="unbounded"> |
||||
<xsd:annotation> |
||||
<xsd:documentation><![CDATA[ |
||||
The name of a layer. Each layer in the configuration must be referenced once and the |
||||
order matches how the content is likely to change. Put layers that are frequently |
||||
updated first, layers that are more stable (such as non-snapshot dependencies) last. |
||||
]]></xsd:documentation> |
||||
</xsd:annotation> |
||||
</xsd:element> |
||||
</xsd:sequence> |
||||
</xsd:complexType> |
||||
<xsd:complexType name="librariesType"> |
||||
<xsd:annotation> |
||||
<xsd:documentation><![CDATA[ |
||||
Strategies that should be applied to libraries. If no strategies are defined, two |
||||
layers are created out-of-the-box. A "snapshot-dependencies" layer with SNAPSHOT |
||||
libraries and a "dependencies" layer with all the other libraries. |
||||
]]></xsd:documentation> |
||||
</xsd:annotation> |
||||
<xsd:choice maxOccurs="unbounded"> |
||||
<xsd:element type="librariesLayerContentType" name="layer-content"> |
||||
<xsd:annotation> |
||||
<xsd:documentation><![CDATA[ |
||||
Strategy to apply on libraries. |
||||
]]></xsd:documentation> |
||||
</xsd:annotation> |
||||
</xsd:element> |
||||
</xsd:choice> |
||||
</xsd:complexType> |
||||
<xsd:complexType name="librariesLayerContentType" mixed="true"> |
||||
<xsd:sequence> |
||||
<xsd:element type="filterType" name="coordinates" minOccurs="0"/> |
||||
</xsd:sequence> |
||||
<xsd:attribute type="xsd:string" name="layer" use="required"/> |
||||
</xsd:complexType> |
||||
<xsd:complexType name="classesType"> |
||||
<xsd:annotation> |
||||
<xsd:documentation><![CDATA[ |
||||
Strategies that should be applied to classes. If no strategies are defined, a single |
||||
"application" layer is created out-of-the-box. |
||||
]]></xsd:documentation> |
||||
</xsd:annotation> |
||||
<xsd:choice maxOccurs="unbounded"> |
||||
<xsd:element type="classesLayerContentType" name="layer-content" maxOccurs="unbounded" |
||||
minOccurs="0"> |
||||
<xsd:annotation> |
||||
<xsd:documentation><![CDATA[ |
||||
Strategy to apply on classes. |
||||
]]></xsd:documentation> |
||||
</xsd:annotation> |
||||
</xsd:element> |
||||
</xsd:choice> |
||||
</xsd:complexType> |
||||
<xsd:complexType name="classesLayerContentType" mixed="true"> |
||||
<xsd:sequence> |
||||
<xsd:element type="filterType" name="locations" minOccurs="0"/> |
||||
</xsd:sequence> |
||||
<xsd:attribute type="xsd:string" name="layer" use="required"/> |
||||
</xsd:complexType> |
||||
|
||||
<xsd:complexType name="filterType"> |
||||
<xsd:sequence> |
||||
<xsd:element type="xsd:string" name="exclude" minOccurs="0" maxOccurs="unbounded"> |
||||
<xsd:annotation> |
||||
<xsd:documentation><![CDATA[ |
||||
Pattern of the elements to exclude. An exclude pattern takes precedence over an |
||||
include pattern and must be declared first. |
||||
]]></xsd:documentation> |
||||
</xsd:annotation> |
||||
</xsd:element> |
||||
<xsd:element type="xsd:string" name="include" minOccurs="0" maxOccurs="unbounded"> |
||||
<xsd:annotation> |
||||
<xsd:documentation><![CDATA[ |
||||
Pattern of the elements to include. |
||||
]]></xsd:documentation> |
||||
</xsd:annotation> |
||||
</xsd:element> |
||||
</xsd:sequence> |
||||
</xsd:complexType> |
||||
|
||||
</xsd:schema> |
||||
@ -0,0 +1,97 @@
@@ -0,0 +1,97 @@
|
||||
/* |
||||
* 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.maven; |
||||
|
||||
import javax.xml.parsers.DocumentBuilder; |
||||
import javax.xml.parsers.DocumentBuilderFactory; |
||||
|
||||
import org.junit.jupiter.api.BeforeEach; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.w3c.dom.Document; |
||||
import org.xml.sax.InputSource; |
||||
|
||||
import org.springframework.boot.loader.tools.Library; |
||||
import org.springframework.boot.loader.tools.LibraryCoordinates; |
||||
import org.springframework.boot.loader.tools.layer.CustomLayers; |
||||
import org.springframework.core.io.ClassPathResource; |
||||
|
||||
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 CustomLayersProvider}. |
||||
* |
||||
* @author Madhura Bhave |
||||
* @author Scott Frederick |
||||
*/ |
||||
public class CustomLayersProviderTests { |
||||
|
||||
private CustomLayersProvider customLayersProvider; |
||||
|
||||
@BeforeEach |
||||
void setup() { |
||||
this.customLayersProvider = new CustomLayersProvider(); |
||||
} |
||||
|
||||
@Test |
||||
void getLayerResolverWhenDocumentValid() throws Exception { |
||||
CustomLayers layers = this.customLayersProvider.getLayers(getDocument("layers.xml")); |
||||
assertThat(layers).extracting("name").containsExactly("configuration", "application", "my-resources", |
||||
"snapshot-dependencies", "my-deps", "my-dependencies-name"); |
||||
Library snapshot = mockLibrary("test-SNAPSHOT.jar", "org.foo", "1.0.0-SNAPSHOT"); |
||||
Library groupId = mockLibrary("my-library", "com.acme", null); |
||||
Library otherDependency = mockLibrary("other-library", "org.foo", null); |
||||
assertThat(layers.getLayer(snapshot).toString()).isEqualTo("snapshot-dependencies"); |
||||
assertThat(layers.getLayer(groupId).toString()).isEqualTo("my-deps"); |
||||
assertThat(layers.getLayer(otherDependency).toString()).isEqualTo("my-dependencies-name"); |
||||
assertThat(layers.getLayer("META-INF/resources/test.css").toString()).isEqualTo("my-resources"); |
||||
assertThat(layers.getLayer("application.yml").toString()).isEqualTo("configuration"); |
||||
assertThat(layers.getLayer("test").toString()).isEqualTo("application"); |
||||
} |
||||
|
||||
private Library mockLibrary(String name, String groupId, String version) { |
||||
Library library = mock(Library.class); |
||||
given(library.getName()).willReturn(name); |
||||
given(library.getCoordinates()).willReturn(new LibraryCoordinates(groupId, null, version)); |
||||
return library; |
||||
} |
||||
|
||||
@Test |
||||
void getLayerResolverWhenDocumentContainsLibraryLayerWithNoFilters() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.customLayersProvider.getLayers(getDocument("library-layer-no-filter.xml"))) |
||||
.withMessage("Filters for layer-content must not be empty."); |
||||
} |
||||
|
||||
@Test |
||||
void getLayerResolverWhenDocumentContainsResourceLayerWithNoFilters() { |
||||
assertThatIllegalArgumentException() |
||||
.isThrownBy(() -> this.customLayersProvider.getLayers(getDocument("resource-layer-no-filter.xml"))) |
||||
.withMessage("Filters for layer-content must not be empty."); |
||||
} |
||||
|
||||
private Document getDocument(String resourceName) throws Exception { |
||||
ClassPathResource resource = new ClassPathResource(resourceName); |
||||
InputSource inputSource = new InputSource(resource.getInputStream()); |
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); |
||||
DocumentBuilder documentBuilder = factory.newDocumentBuilder(); |
||||
return documentBuilder.parse(inputSource); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
<layers-configuration xmlns="http://www.springframework.org/schema/boot/layers" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers |
||||
https://www.springframework.org/schema/boot/layers/layers-configuration.xsd"> |
||||
<layers> |
||||
<layer>configuration</layer> |
||||
<layer>application</layer> |
||||
<layer>my-resources</layer> |
||||
<layer>snapshot-dependencies</layer> |
||||
<layer>my-deps</layer> |
||||
<layer>my-dependencies-name</layer> |
||||
</layers> |
||||
<libraries> |
||||
<layer-content layer="snapshot-dependencies"> |
||||
<coordinates> |
||||
<include>*:*:*-SNAPSHOT</include> |
||||
</coordinates> |
||||
</layer-content> |
||||
<layer-content layer="my-deps"> |
||||
<coordinates> |
||||
<include>com.acme:*</include> |
||||
</coordinates> |
||||
</layer-content> |
||||
<layer-content layer="my-dependencies-name"> |
||||
<coordinates> |
||||
<include>*:*:*</include> |
||||
</coordinates> |
||||
</layer-content> |
||||
</libraries> |
||||
<classes> |
||||
<layer-content layer="my-resources"> |
||||
<locations> |
||||
<include>META-INF/resources/**</include> |
||||
</locations> |
||||
</layer-content> |
||||
<layer-content layer="configuration"> |
||||
<locations> |
||||
<include>**/application*.*</include> |
||||
</locations> |
||||
</layer-content> |
||||
<layer-content layer="application"> |
||||
<locations> |
||||
<include>**</include> |
||||
</locations> |
||||
</layer-content> |
||||
</classes> |
||||
</layers-configuration> |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
<layers-configuration xmlns="http://www.springframework.org/schema/boot/layers" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers |
||||
https://www.springframework.org/schema/boot/layers/layers-configuration.xsd"> |
||||
<layers> |
||||
<layer>my-deps</layer> |
||||
</layers> |
||||
<libraries> |
||||
<layer-content layer="my-deps"/> |
||||
</libraries> |
||||
</layers-configuration> |
||||
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
<layers-configuration xmlns="http://www.springframework.org/schema/boot/layers" |
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers |
||||
https://www.springframework.org/schema/boot/layers/layers-configuration.xsd"> |
||||
<layers> |
||||
<layer>my-layer</layer> |
||||
</layers> |
||||
<classes> |
||||
<layer-content layer="my-layer"/> |
||||
</classes> |
||||
</layers-configuration> |
||||
Loading…
Reference in new issue