Support bom-based dependency management in the CLI

Previously, the CLI’s dependency management used proprietary Properties
file-based metadata to configure its dependency management. Since
spring-boot-gradle-plugin’s move to using the separate dependency
management plugin the CLI was the only user of this format.

This commit updates the CLI to use Maven boms to configure its
dependency management. By default it uses the spring-boot-dependencies
bom. This configuration can be augmented and overridden using the new
@DependencyManagementBom annotation which replaces @GrabMetadata.

Closes gh-2688
Closes gh-2439
pull/2928/head
Andy Wilkinson 10 years ago
parent 390e6fa690
commit 51c49b69c5

@ -80,7 +80,6 @@
<modules>
<module>spring-boot-dependencies</module>
<module>spring-boot-parent</module>
<module>spring-boot-versions</module>
<module>spring-boot-tools</module>
<module>spring-boot</module>
<module>spring-boot-autoconfigure</module>
@ -110,7 +109,6 @@
<modules>
<module>spring-boot-dependencies</module>
<module>spring-boot-parent</module>
<module>spring-boot-versions</module>
<module>spring-boot-tools</module>
</modules>
<build>

@ -19,6 +19,7 @@
<main.basedir>${basedir}/..</main.basedir>
<start-class>org.springframework.boot.cli.SpringCli</start-class>
<spring.profiles.active>default</spring.profiles.active>
<generated.pom.dir>${project.build.directory}/generated-resources/org/springframework/boot/cli/compiler/dependencies</generated.pom.dir>
</properties>
<profiles>
<profile>
@ -33,10 +34,6 @@
</profiles>
<dependencies>
<!-- Compile -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependency-tools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader-tools</artifactId>
@ -132,6 +129,14 @@
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@ -155,6 +160,26 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-effective-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${project.version}</version>
<type>effective-pom</type>
<overWrite>true</overWrite>
<outputDirectory>${generated.pom.dir}</outputDirectory>
<destFileName>effective-pom.xml</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
<execution>
<id>unpack</id>
<phase>prepare-package</phase>

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -17,6 +17,7 @@
package org.springframework.boot.cli.compiler;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -42,12 +43,16 @@ public abstract class AnnotatedNodeASTTransformation implements ASTTransformatio
private final Set<String> interestingAnnotationNames;
private final boolean removeAnnotations;
private List<AnnotationNode> annotationNodes = new ArrayList<AnnotationNode>();
private SourceUnit sourceUnit;
protected AnnotatedNodeASTTransformation(Set<String> interestingAnnotationNames) {
protected AnnotatedNodeASTTransformation(Set<String> interestingAnnotationNames,
boolean removeAnnotations) {
this.interestingAnnotationNames = interestingAnnotationNames;
this.removeAnnotations = removeAnnotations;
}
@Override
@ -94,10 +99,16 @@ public abstract class AnnotatedNodeASTTransformation implements ASTTransformatio
private void visitAnnotatedNode(AnnotatedNode annotatedNode) {
if (annotatedNode != null) {
for (AnnotationNode annotationNode : annotatedNode.getAnnotations()) {
Iterator<AnnotationNode> annotationNodes = annotatedNode.getAnnotations()
.iterator();
while (annotationNodes.hasNext()) {
AnnotationNode annotationNode = annotationNodes.next();
if (this.interestingAnnotationNames.contains(annotationNode
.getClassNode().getName())) {
this.annotationNodes.add(annotationNode);
if (this.removeAnnotations) {
annotationNodes.remove();
}
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -38,7 +38,7 @@ import org.springframework.core.annotation.Order;
@Order(DependencyAutoConfigurationTransformation.ORDER)
public class DependencyAutoConfigurationTransformation implements ASTTransformation {
public static final int ORDER = GrabMetadataTransformation.ORDER + 100;
public static final int ORDER = DependencyManagementBomTransformation.ORDER + 100;
private final GroovyClassLoader loader;

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -18,7 +18,7 @@ package org.springframework.boot.cli.compiler;
import groovy.grape.Grape;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Arrays;
@ -29,6 +29,16 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.apache.maven.model.Model;
import org.apache.maven.model.Repository;
import org.apache.maven.model.building.DefaultModelBuilder;
import org.apache.maven.model.building.DefaultModelBuilderFactory;
import org.apache.maven.model.building.DefaultModelBuildingRequest;
import org.apache.maven.model.building.ModelSource;
import org.apache.maven.model.building.UrlModelSource;
import org.apache.maven.model.resolution.InvalidRepositoryException;
import org.apache.maven.model.resolution.ModelResolver;
import org.apache.maven.model.resolution.UnresolvableModelException;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.expr.ConstantExpression;
@ -38,33 +48,33 @@ import org.codehaus.groovy.control.messages.Message;
import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
import org.codehaus.groovy.syntax.SyntaxException;
import org.codehaus.groovy.transform.ASTTransformation;
import org.springframework.boot.cli.compiler.dependencies.MavenModelDependencyManagement;
import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext;
import org.springframework.boot.dependency.tools.Dependencies;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.dependency.tools.PropertiesFileDependencies;
import org.springframework.boot.groovy.GrabMetadata;
import org.springframework.boot.groovy.DependencyManagementBom;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
/**
* {@link ASTTransformation} for processing {@link GrabMetadata @GrabMetadata}
* {@link ASTTransformation} for processing {@link DependencyManagementBom} annotations
*
* @author Andy Wilkinson
* @since 1.1.0
* @since 1.3.0
*/
@Order(GrabMetadataTransformation.ORDER)
public class GrabMetadataTransformation extends AnnotatedNodeASTTransformation {
@Order(DependencyManagementBomTransformation.ORDER)
public class DependencyManagementBomTransformation extends AnnotatedNodeASTTransformation {
public static final int ORDER = Ordered.HIGHEST_PRECEDENCE;
private static final Set<String> GRAB_METADATA_ANNOTATION_NAMES = Collections
private static final Set<String> DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES = Collections
.unmodifiableSet(new HashSet<String>(Arrays.asList(
GrabMetadata.class.getName(), GrabMetadata.class.getSimpleName())));
DependencyManagementBom.class.getName(),
DependencyManagementBom.class.getSimpleName())));
private final DependencyResolutionContext resolutionContext;
public GrabMetadataTransformation(DependencyResolutionContext resolutionContext) {
super(GRAB_METADATA_ANNOTATION_NAMES);
public DependencyManagementBomTransformation(
DependencyResolutionContext resolutionContext) {
super(DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES, true);
this.resolutionContext = resolutionContext;
}
@ -73,19 +83,19 @@ public class GrabMetadataTransformation extends AnnotatedNodeASTTransformation {
if (!annotationNodes.isEmpty()) {
if (annotationNodes.size() > 1) {
for (AnnotationNode annotationNode : annotationNodes) {
handleDuplicateGrabMetadataAnnotation(annotationNode);
handleDuplicateDependencyManagementBomAnnotation(annotationNode);
}
}
else {
processGrabMetadataAnnotation(annotationNodes.get(0));
processDependencyManagementBomAnnotation(annotationNodes.get(0));
}
}
}
private void processGrabMetadataAnnotation(AnnotationNode annotationNode) {
private void processDependencyManagementBomAnnotation(AnnotationNode annotationNode) {
Expression valueExpression = annotationNode.getMember("value");
List<Map<String, String>> metadataDependencies = createDependencyMaps(valueExpression);
updateArtifactCoordinatesResolver(metadataDependencies);
List<Map<String, String>> bomDependencies = createDependencyMaps(valueExpression);
updateDependencyResolutionContext(bomDependencies);
}
private List<Map<String, String>> createDependencyMaps(Expression valueExpression) {
@ -104,7 +114,7 @@ public class GrabMetadataTransformation extends AnnotatedNodeASTTransformation {
dependency.put("group", components[0]);
dependency.put("module", components[1]);
dependency.put("version", components[2]);
dependency.put("type", "properties");
dependency.put("type", "pom");
dependencies.add(dependency);
}
else {
@ -126,7 +136,7 @@ public class GrabMetadataTransformation extends AnnotatedNodeASTTransformation {
return Arrays.asList((ConstantExpression) valueExpression);
}
reportError("@GrabMetadata requires an inline constant that is a "
reportError("@DependencyManagementBom requires an inline constant that is a "
+ "string or a string array", valueExpression);
return Collections.emptyList();
}
@ -152,29 +162,34 @@ public class GrabMetadataTransformation extends AnnotatedNodeASTTransformation {
getSourceUnit().getErrorCollector().addErrorAndContinue(message);
}
private void updateArtifactCoordinatesResolver(
List<Map<String, String>> metadataDependencies) {
private void updateDependencyResolutionContext(
List<Map<String, String>> bomDependencies) {
URI[] uris = Grape.getInstance().resolve(null,
metadataDependencies.toArray(new Map[metadataDependencies.size()]));
List<Dependencies> managedDependencies = new ArrayList<Dependencies>(uris.length);
bomDependencies.toArray(new Map[bomDependencies.size()]));
DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance();
for (URI uri : uris) {
try {
managedDependencies.add(new PropertiesFileDependencies(uri.toURL()
.openStream()));
DefaultModelBuildingRequest request = new DefaultModelBuildingRequest();
request.setModelResolver(new GrapeModelResolver());
request.setModelSource(new UrlModelSource(uri.toURL()));
Model model = modelBuilder.build(request).getEffectiveModel();
this.resolutionContext
.addDependencyManagement(new MavenModelDependencyManagement(model));
}
catch (IOException ex) {
throw new IllegalStateException("Failed to parse '" + uris[0]
+ "'. Is it a valid properties file?");
catch (Exception ex) {
throw new IllegalStateException("Failed to build model for '" + uri
+ "'. Is it a valid Maven bom?", ex);
}
}
this.resolutionContext.setManagedDependencies(ManagedDependencies
.get(managedDependencies));
}
private void handleDuplicateGrabMetadataAnnotation(AnnotationNode annotationNode) {
private void handleDuplicateDependencyManagementBomAnnotation(
AnnotationNode annotationNode) {
Message message = createSyntaxErrorMessage(
"Duplicate @GrabMetadata annotation. It must be declared at most once.",
"Duplicate @DependencyManagementBom annotation. It must be declared at most once.",
annotationNode);
getSourceUnit().getErrorCollector().addErrorAndContinue(message);
}
@ -189,4 +204,36 @@ public class GrabMetadataTransformation extends AnnotatedNodeASTTransformation {
node.getColumnNumber(), node.getLastLineNumber(),
node.getLastColumnNumber()), getSourceUnit());
}
private static class GrapeModelResolver implements ModelResolver {
@Override
public ModelSource resolveModel(String groupId, String artifactId, String version)
throws UnresolvableModelException {
Map<String, String> dependency = new HashMap<String, String>();
dependency.put("group", groupId);
dependency.put("module", artifactId);
dependency.put("version", version);
dependency.put("type", "pom");
try {
return new UrlModelSource(
Grape.getInstance().resolve(null, dependency)[0].toURL());
}
catch (MalformedURLException e) {
throw new UnresolvableModelException(e.getMessage(), groupId, artifactId,
version);
}
}
@Override
public void addRepository(Repository repository)
throws InvalidRepositoryException {
}
@Override
public ModelResolver newCopy() {
return this;
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -42,7 +42,7 @@ import org.springframework.core.annotation.Order;
@Order(GroovyBeansTransformation.ORDER)
public class GroovyBeansTransformation implements ASTTransformation {
public static final int ORDER = GrabMetadataTransformation.ORDER + 200;
public static final int ORDER = DependencyManagementBomTransformation.ORDER + 200;
@Override
public void visit(ASTNode[] nodes, SourceUnit source) {

@ -105,7 +105,7 @@ public class GroovyCompiler {
}
this.transformations = new ArrayList<ASTTransformation>();
this.transformations.add(new GrabMetadataTransformation(resolutionContext));
this.transformations.add(new DependencyManagementBomTransformation(resolutionContext));
this.transformations.add(new DependencyAutoConfigurationTransformation(
this.loader, resolutionContext, this.compilerAutoConfigurations));
this.transformations.add(new GroovyBeansTransformation());

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -41,7 +41,7 @@ import org.springframework.core.annotation.Order;
public class ResolveDependencyCoordinatesTransformation extends
AnnotatedNodeASTTransformation {
public static final int ORDER = GrabMetadataTransformation.ORDER + 300;
public static final int ORDER = DependencyManagementBomTransformation.ORDER + 300;
private static final Set<String> GRAB_ANNOTATION_NAMES = Collections
.unmodifiableSet(new HashSet<String>(Arrays.asList(Grab.class.getName(),
@ -51,7 +51,7 @@ public class ResolveDependencyCoordinatesTransformation extends
public ResolveDependencyCoordinatesTransformation(
DependencyResolutionContext resolutionContext) {
super(GRAB_ANNOTATION_NAMES);
super(GRAB_ANNOTATION_NAMES, false);
this.resolutionContext = resolutionContext;
}

@ -70,8 +70,7 @@ public class SpringBootCompilerAutoConfiguration extends CompilerAutoConfigurati
"org.springframework.boot.context.properties.EnableConfigurationProperties",
"org.springframework.boot.autoconfigure.EnableAutoConfiguration",
"org.springframework.boot.context.properties.ConfigurationProperties",
"org.springframework.boot.context.properties.EnableConfigurationProperties",
"org.springframework.boot.groovy.GrabMetadata");
"org.springframework.boot.context.properties.EnableConfigurationProperties");
imports.addStarImports("org.springframework.stereotype",
"org.springframework.scheduling.annotation");
}

@ -0,0 +1,70 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* {@link DependencyManagement} that delegates to one or more {@link DependencyManagement}
* instances
*
* @author Andy Wilkinson
* @since 1.3.0
*/
public class CompositeDependencyManagement implements DependencyManagement {
private final List<DependencyManagement> delegates;
private final List<Dependency> dependencies = new ArrayList<Dependency>();
public CompositeDependencyManagement(DependencyManagement... delegates) {
this.delegates = Arrays.asList(delegates);
for (DependencyManagement delegate : delegates) {
this.dependencies.addAll(delegate.getDependencies());
}
}
@Override
public List<Dependency> getDependencies() {
return this.dependencies;
}
@Override
public String getSpringBootVersion() {
for (DependencyManagement delegate : this.delegates) {
String version = delegate.getSpringBootVersion();
if (version != null) {
return version;
}
}
return null;
}
@Override
public Dependency find(String artifactId) {
for (DependencyManagement delegate : this.delegates) {
Dependency found = delegate.find(artifactId);
if (found != null) {
return found;
}
}
return null;
}
}

@ -14,16 +14,18 @@
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
package org.springframework.boot.cli.compiler.dependencies;
import java.util.Collections;
import java.util.List;
import org.springframework.util.Assert;
/**
* A single dependency.
*
* @author Phillip Webb
* @see Dependencies
* @since 1.3.0
*/
public final class Dependency {

@ -0,0 +1,50 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import java.util.List;
/**
* An encapsulation of dependency management information
*
* @author Andy Wilkinson
* @since 1.3.0
*/
public interface DependencyManagement {
/**
* Returns the managed dependencies.
*
* @return the managed dependencies
*/
List<Dependency> getDependencies();
/**
* Returns the managed version of Spring Boot. May be {@code null}.
*
* @return the Spring Boot version, or {@code null}
*/
String getSpringBootVersion();
/**
* Finds the managed dependency with the given {@code artifactId}.
*
* @param artifactId The artifact ID of the dependency to find
* @return the dependency, or {@code null}
*/
Dependency find(String artifactId);
}

@ -0,0 +1,73 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import org.springframework.util.StringUtils;
/**
* {@link ArtifactCoordinatesResolver} backed by {@link SpringBootDependenciesDependencyManagement}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class DependencyManagementArtifactCoordinatesResolver implements
ArtifactCoordinatesResolver {
private final DependencyManagement dependencyManagement;
public DependencyManagementArtifactCoordinatesResolver() {
this(new SpringBootDependenciesDependencyManagement());
}
public DependencyManagementArtifactCoordinatesResolver(
DependencyManagement dependencyManagement) {
this.dependencyManagement = dependencyManagement;
}
@Override
public String getGroupId(String artifactId) {
Dependency dependency = find(artifactId);
return (dependency == null ? null : dependency.getGroupId());
}
@Override
public String getArtifactId(String id) {
Dependency dependency = find(id);
return dependency == null ? null : dependency.getArtifactId();
}
private Dependency find(String id) {
if (StringUtils.countOccurrencesOf(id, ":") == 2) {
String[] tokens = id.split(":");
return new Dependency(tokens[0], tokens[1], tokens[2]);
}
if (id != null) {
if (id.startsWith("spring-boot")) {
return new Dependency("org.springframework.boot", id,
this.dependencyManagement.getSpringBootVersion());
}
return this.dependencyManagement.find(id);
}
return null;
}
@Override
public String getVersion(String module) {
Dependency dependency = find(module);
return dependency == null ? null : dependency.getVersion();
}
}

@ -1,74 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import org.springframework.boot.dependency.tools.Dependencies;
import org.springframework.boot.dependency.tools.Dependency;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.util.StringUtils;
/**
* {@link ArtifactCoordinatesResolver} backed by {@link Dependencies}.
*
* @author Phillip Webb
*/
public class ManagedDependenciesArtifactCoordinatesResolver implements
ArtifactCoordinatesResolver {
private final ManagedDependencies dependencies;
public ManagedDependenciesArtifactCoordinatesResolver() {
this(ManagedDependencies.get());
}
public ManagedDependenciesArtifactCoordinatesResolver(ManagedDependencies dependencies) {
this.dependencies = dependencies;
}
@Override
public String getGroupId(String artifactId) {
Dependency dependency = find(artifactId);
return (dependency == null ? null : dependency.getGroupId());
}
@Override
public String getVersion(String artifactId) {
Dependency dependency = find(artifactId);
return (dependency == null ? null : dependency.getVersion());
}
@Override
public String getArtifactId(String artifactId) {
Dependency dependency = find(artifactId);
return (dependency == null ? null : dependency.getArtifactId());
}
private Dependency find(String artifactId) {
if (StringUtils.countOccurrencesOf(artifactId, ":") == 2) {
String[] tokens = artifactId.split(":");
return new Dependency(tokens[0], tokens[1], tokens[2]);
}
if (artifactId != null) {
if (artifactId.startsWith("spring-boot")) {
return new Dependency("org.springframework.boot", artifactId,
this.dependencies.getSpringBootVersion());
}
return this.dependencies.find(artifactId);
}
return null;
}
}

@ -0,0 +1,78 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.maven.model.Model;
import org.springframework.boot.cli.compiler.dependencies.Dependency.Exclusion;
/**
* {@link DependencyManagement} derived from a Maven {@link Model}
*
* @author Andy Wilkinson
* @since 1.3.0
*/
public class MavenModelDependencyManagement implements DependencyManagement {
private final List<Dependency> dependencies;
private final Map<String, Dependency> byArtifactId = new LinkedHashMap<String, Dependency>();
public MavenModelDependencyManagement(Model model) {
this.dependencies = extractDependenciesFromModel(model);
for (Dependency dependency : this.dependencies) {
this.byArtifactId.put(dependency.getArtifactId(), dependency);
}
}
private static List<Dependency> extractDependenciesFromModel(Model model) {
List<Dependency> dependencies = new ArrayList<Dependency>();
for (org.apache.maven.model.Dependency mavenDependency : model
.getDependencyManagement().getDependencies()) {
List<Exclusion> exclusions = new ArrayList<Exclusion>();
for (org.apache.maven.model.Exclusion mavenExclusion : mavenDependency
.getExclusions()) {
exclusions.add(new Exclusion(mavenExclusion.getGroupId(), mavenExclusion
.getArtifactId()));
}
Dependency dependency = new Dependency(mavenDependency.getGroupId(),
mavenDependency.getArtifactId(), mavenDependency.getVersion(),
exclusions);
dependencies.add(dependency);
}
return dependencies;
}
@Override
public List<Dependency> getDependencies() {
return this.dependencies;
}
@Override
public String getSpringBootVersion() {
return find("spring-boot").getVersion();
}
@Override
public Dependency find(String artifactId) {
return this.byArtifactId.get(artifactId);
}
}

@ -0,0 +1,54 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import java.io.IOException;
import org.apache.maven.model.Model;
import org.apache.maven.model.building.DefaultModelProcessor;
import org.apache.maven.model.io.DefaultModelReader;
import org.apache.maven.model.locator.DefaultModelLocator;
/**
* {@link DependencyManagement} derived from the effective pom of spring-boot-dependencies
*
* @author Andy Wilkinson
* @since 1.3.0
*/
public class SpringBootDependenciesDependencyManagement extends
MavenModelDependencyManagement {
public SpringBootDependenciesDependencyManagement() {
super(readModel());
}
private static Model readModel() {
DefaultModelProcessor modelProcessor = new DefaultModelProcessor();
modelProcessor.setModelLocator(new DefaultModelLocator());
modelProcessor.setModelReader(new DefaultModelReader());
try {
return modelProcessor.read(SpringBootDependenciesDependencyManagement.class
.getResourceAsStream("effective-pom.xml"), null);
}
catch (IOException ex) {
throw new IllegalStateException("Failed to build model from effective pom",
ex);
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -167,6 +167,9 @@ public class AetherGrapeEngine implements GrapeEngine {
String group = (String) dependencyMap.get("group");
String module = (String) dependencyMap.get("module");
String version = (String) dependencyMap.get("version");
if (version == null) {
version = this.resolutionContext.getManagedVersion(group, module);
}
String classifier = (String) dependencyMap.get("classifier");
String type = determineType(dependencyMap);
return new DefaultArtifact(group, module, classifier, type, version);
@ -324,7 +327,7 @@ public class AetherGrapeEngine implements GrapeEngine {
}
private void addManagedDependencies(DependencyResult result) {
this.resolutionContext.getManagedDependencies().addAll(getDependencies(result));
this.resolutionContext.addManagedDependencies(getDependencies(result));
}
@Override

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -17,12 +17,20 @@
package org.springframework.boot.cli.compiler.grape;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.graph.Exclusion;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.springframework.boot.cli.compiler.dependencies.ArtifactCoordinatesResolver;
import org.springframework.boot.cli.compiler.dependencies.ManagedDependenciesArtifactCoordinatesResolver;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.cli.compiler.dependencies.CompositeDependencyManagement;
import org.springframework.boot.cli.compiler.dependencies.DependencyManagement;
import org.springframework.boot.cli.compiler.dependencies.DependencyManagementArtifactCoordinatesResolver;
import org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement;
/**
* Context used when resolving dependencies.
@ -32,34 +40,77 @@ import org.springframework.boot.dependency.tools.ManagedDependencies;
*/
public class DependencyResolutionContext {
private ArtifactCoordinatesResolver artifactCoordinatesResolver;
private final Map<String, Dependency> managedDependencyByGroupAndArtifact = new HashMap<String, Dependency>();
private List<Dependency> managedDependencies = new ArrayList<Dependency>();
private final List<Dependency> managedDependencies = new ArrayList<Dependency>();
private DependencyManagement dependencyManagement = new SpringBootDependenciesDependencyManagement();
private ArtifactCoordinatesResolver artifactCoordinatesResolver = new DependencyManagementArtifactCoordinatesResolver(
this.dependencyManagement);
public DependencyResolutionContext() {
this(new ManagedDependenciesArtifactCoordinatesResolver());
addDependencyManagement(this.dependencyManagement);
}
public DependencyResolutionContext(
ArtifactCoordinatesResolver artifactCoordinatesResolver) {
this.artifactCoordinatesResolver = artifactCoordinatesResolver;
this.managedDependencies = new ManagedDependenciesFactory()
.getManagedDependencies();
private String getIdentifier(Dependency dependency) {
return getIdentifier(dependency.getArtifact().getGroupId(), dependency
.getArtifact().getArtifactId());
}
public void setManagedDependencies(ManagedDependencies managedDependencies) {
this.artifactCoordinatesResolver = new ManagedDependenciesArtifactCoordinatesResolver(
managedDependencies);
this.managedDependencies = new ArrayList<Dependency>(
new ManagedDependenciesFactory(managedDependencies)
.getManagedDependencies());
private String getIdentifier(String groupId, String artifactId) {
return groupId + ":" + artifactId;
}
public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() {
return this.artifactCoordinatesResolver;
}
public String getManagedVersion(String groupId, String artifactId) {
Dependency dependency = getManagedDependency(groupId, artifactId);
if (dependency == null) {
dependency = this.managedDependencyByGroupAndArtifact.get(getIdentifier(
groupId, artifactId));
}
return dependency != null ? dependency.getArtifact().getVersion() : null;
}
public List<Dependency> getManagedDependencies() {
return this.managedDependencies;
return Collections.unmodifiableList(this.managedDependencies);
}
private Dependency getManagedDependency(String group, String artifact) {
return this.managedDependencyByGroupAndArtifact
.get(getIdentifier(group, artifact));
}
void addManagedDependencies(List<Dependency> dependencies) {
this.managedDependencies.addAll(dependencies);
for (Dependency dependency : dependencies) {
this.managedDependencyByGroupAndArtifact.put(getIdentifier(dependency),
dependency);
}
}
public void addDependencyManagement(DependencyManagement dependencyManagement) {
for (org.springframework.boot.cli.compiler.dependencies.Dependency dependency : dependencyManagement
.getDependencies()) {
List<Exclusion> aetherExclusions = new ArrayList<Exclusion>();
for (org.springframework.boot.cli.compiler.dependencies.Dependency.Exclusion exclusion : dependency
.getExclusions()) {
aetherExclusions.add(new Exclusion(exclusion.getGroupId(), exclusion
.getArtifactId(), "*", "*"));
}
Dependency aetherDependency = new Dependency(new DefaultArtifact(
dependency.getGroupId(), dependency.getArtifactId(), "jar",
dependency.getVersion()), JavaScopes.COMPILE, false, aetherExclusions);
this.managedDependencies.add(0, aetherDependency);
this.managedDependencyByGroupAndArtifact.put(getIdentifier(aetherDependency),
aetherDependency);
}
this.artifactCoordinatesResolver = new DependencyManagementArtifactCoordinatesResolver(
new CompositeDependencyManagement(dependencyManagement,
this.dependencyManagement));
}
}

@ -1,64 +0,0 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.grape;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.artifact.DefaultArtifact;
import org.eclipse.aether.graph.Dependency;
import org.eclipse.aether.util.artifact.JavaScopes;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.dependency.tools.PomDependencies;
/**
* Factory to create Maven {@link Dependency} objects from Boot {@link PomDependencies}.
*
* @author Phillip Webb
*/
public class ManagedDependenciesFactory {
private final ManagedDependencies dependencies;
ManagedDependenciesFactory() {
this(ManagedDependencies.get());
}
public ManagedDependenciesFactory(ManagedDependencies dependencies) {
this.dependencies = dependencies;
}
/**
* Return a list of the managed dependencies.
* @return the managed dependencies
*/
public List<Dependency> getManagedDependencies() {
List<Dependency> result = new ArrayList<Dependency>();
for (org.springframework.boot.dependency.tools.Dependency dependency : this.dependencies) {
Artifact artifact = asArtifact(dependency);
result.add(new Dependency(artifact, JavaScopes.COMPILE));
}
return result;
}
private Artifact asArtifact(
org.springframework.boot.dependency.tools.Dependency dependency) {
return new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(),
"jar", dependency.getVersion());
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -22,21 +22,21 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Used to provide an alternative source of dependency metadata that is used to deduce
* groups and versions when processing {@code @Grab} dependencies.
* Provides one or more additional sources of dependency management that is used when
* resolving {@code @Grab} dependencies.
*
* @author Andy Wilkinson
* @since 1.1.0
* @since 1.3.0
*/
@Target({ ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE,
ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE })
@Retention(RetentionPolicy.SOURCE)
public @interface GrabMetadata {
public @interface DependencyManagementBom {
/**
* One or more sets of colon-separated coordinates ({@code group:module:version}) of a
* properties file that contains dependency metadata that will add to and override the
* default metadata.
* Maven bom that contains dependency management that will add to and override the
* default dependency management.
*/
String[] value();

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -17,8 +17,6 @@
package org.springframework.boot.cli;
import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import org.junit.After;
import org.junit.Before;
@ -65,31 +63,25 @@ public class GrabCommandIntegrationTests {
}
@Test
public void duplicateGrabMetadataAnnotationsProducesAnError() throws Exception {
public void duplicateDependencyManagementBomAnnotationsProducesAnError()
throws Exception {
try {
this.cli.grab("duplicateGrabMetadata.groovy");
this.cli.grab("duplicateDependencyManagementBom.groovy");
fail();
}
catch (Exception ex) {
assertThat(ex.getMessage(),
containsString("Duplicate @GrabMetadata annotation"));
containsString("Duplicate @DependencyManagementBom annotation"));
}
}
@Test
public void customMetadata() throws Exception {
System.setProperty("grape.root", "target");
File testArtifactDir = new File("target/repository/test/test/1.0.0");
testArtifactDir.mkdirs();
File testArtifact = new File(testArtifactDir, "test-1.0.0.properties");
testArtifact.createNewFile();
PrintWriter writer = new PrintWriter(new FileWriter(testArtifact));
writer.println("javax.ejb\\:ejb-api=3.0");
writer.close();
this.cli.grab("customGrabMetadata.groovy", "--autoconfigure=false");
FileSystemUtils.copyRecursively(new File(
"src/test/resources/grab-samples/repository"), new File(
"target/repository"));
this.cli.grab("customDependencyManagement.groovy", "--autoconfigure=false");
assertTrue(new File("target/repository/javax/ejb/ejb-api/3.0").isDirectory());
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -60,12 +60,17 @@ public class DependencyCustomizerTests {
"org.springframework.boot");
given(this.resolver.getArtifactId("spring-boot-starter-logging")).willReturn(
"spring-boot-starter-logging");
given(this.resolver.getVersion("spring-boot-starter-logging"))
.willReturn("1.2.3");
this.moduleNode.addClass(this.classNode);
this.dependencyCustomizer = new DependencyCustomizer(new GroovyClassLoader(
getClass().getClassLoader()), this.moduleNode,
new DependencyResolutionContext(this.resolver));
new DependencyResolutionContext() {
@Override
public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() {
return DependencyCustomizerTests.this.resolver;
}
});
}
@Test
@ -149,7 +154,6 @@ public class DependencyCustomizerTests {
boolean transitive) {
assertEquals(group, getMemberValue(annotationNode, "group"));
assertEquals(module, getMemberValue(annotationNode, "module"));
assertEquals(version, getMemberValue(annotationNode, "version"));
if (type == null) {
assertNull(annotationNode.getMember("type"));
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -65,8 +65,14 @@ public final class ResolveDependencyCoordinatesTransformationTests {
private final ArtifactCoordinatesResolver coordinatesResolver = mock(ArtifactCoordinatesResolver.class);
private final DependencyResolutionContext resolutionContext = new DependencyResolutionContext(
this.coordinatesResolver);
private final DependencyResolutionContext resolutionContext = new DependencyResolutionContext() {
@Override
public ArtifactCoordinatesResolver getArtifactCoordinatesResolver() {
return ResolveDependencyCoordinatesTransformationTests.this.coordinatesResolver;
}
};
private final ASTTransformation transformation = new ResolveDependencyCoordinatesTransformation(
this.resolutionContext);
@ -75,13 +81,12 @@ public final class ResolveDependencyCoordinatesTransformationTests {
public void setupExpectations() {
given(this.coordinatesResolver.getGroupId("spring-core")).willReturn(
"org.springframework");
given(this.coordinatesResolver.getVersion("spring-core")).willReturn("4.0.0.RC1");
}
@Test
public void transformationOfAnnotationOnImport() {
this.moduleNode.addImport(null, null, Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -89,7 +94,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
this.moduleNode.addStarImport("org.springframework.util",
Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -97,7 +102,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
this.moduleNode.addStaticImport(null, null, null,
Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -105,7 +110,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
this.moduleNode.addStaticStarImport(null, null,
Arrays.asList(this.grabAnnotation));
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -114,7 +119,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
packageNode.addAnnotation(this.grabAnnotation);
this.moduleNode.setPackage(packageNode);
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -123,7 +128,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
classNode.addAnnotation(this.grabAnnotation);
this.moduleNode.addClass(classNode);
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -141,7 +146,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
fieldNode.addAnnotation(this.grabAnnotation);
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -153,7 +158,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
constructorNode.addAnnotation(this.grabAnnotation);
classNode.addMethod(constructorNode);
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -166,7 +171,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
methodNode.addAnnotation(this.grabAnnotation);
classNode.addMethod(methodNode);
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -181,7 +186,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
new Parameter[] { parameter }, new ClassNode[0], null);
classNode.addMethod(methodNode);
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
@Test
@ -202,7 +207,7 @@ public final class ResolveDependencyCoordinatesTransformationTests {
classNode.addMethod(methodNode);
assertGrabAnnotationHasBeenTransformation();
assertGrabAnnotationHasBeenTransformed();
}
private AnnotationNode createGrabAnnotation() {
@ -212,12 +217,11 @@ public final class ResolveDependencyCoordinatesTransformationTests {
return annotationNode;
}
private void assertGrabAnnotationHasBeenTransformation() {
private void assertGrabAnnotationHasBeenTransformed() {
this.transformation.visit(new ASTNode[] { this.moduleNode }, this.sourceUnit);
assertEquals("org.springframework", getGrabAnnotationMemberAsString("group"));
assertEquals("spring-core", getGrabAnnotationMemberAsString("module"));
assertEquals("4.0.0.RC1", getGrabAnnotationMemberAsString("version"));
}
private Object getGrabAnnotationMemberAsString(String memberName) {

@ -0,0 +1,98 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import java.util.Arrays;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
/**
* Tests for {@link CompositeDependencyManagement}
*
* @author Andy Wilkinson
*/
@RunWith(MockitoJUnitRunner.class)
public class CompositeDependencyManagementTests {
@Mock
private DependencyManagement dependencyManagement1;
@Mock
private DependencyManagement dependencyManagement2;
@Test
public void unknownSpringBootVersion() {
given(this.dependencyManagement1.getSpringBootVersion()).willReturn(null);
given(this.dependencyManagement2.getSpringBootVersion()).willReturn(null);
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).getSpringBootVersion(), is(nullValue()));
}
@Test
public void knownSpringBootVersion() {
given(this.dependencyManagement1.getSpringBootVersion()).willReturn("1.2.3");
given(this.dependencyManagement2.getSpringBootVersion()).willReturn("1.2.4");
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).getSpringBootVersion(), is("1.2.3"));
}
@Test
public void unknownDependency() {
given(this.dependencyManagement1.find("artifact")).willReturn(null);
given(this.dependencyManagement2.find("artifact")).willReturn(null);
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).find("artifact"), is(nullValue()));
}
@Test
public void knownDependency() {
given(this.dependencyManagement1.find("artifact")).willReturn(
new Dependency("test", "artifact", "1.2.3"));
given(this.dependencyManagement2.find("artifact")).willReturn(
new Dependency("test", "artifact", "1.2.4"));
assertThat(new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).find("artifact"), is(new Dependency("test",
"artifact", "1.2.3")));
}
@Test
public void getDependencies() {
given(this.dependencyManagement1.getDependencies()).willReturn(
Arrays.asList(new Dependency("test", "artifact", "1.2.3")));
given(this.dependencyManagement2.getDependencies()).willReturn(
Arrays.asList(new Dependency("test", "artifact", "1.2.4")));
assertThat(
new CompositeDependencyManagement(this.dependencyManagement1,
this.dependencyManagement2).getDependencies(),
contains(new Dependency("test", "artifact", "1.2.3"), new Dependency(
"test", "artifact", "1.2.4")));
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -18,8 +18,6 @@ package org.springframework.boot.cli.compiler.dependencies;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.dependency.tools.Dependency;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
@ -31,30 +29,32 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link ManagedDependenciesArtifactCoordinatesResolver}.
* Tests for {@link DependencyManagementArtifactCoordinatesResolver}.
*
* @author Phillip Webb
* @author Andy Wilkinson
*/
public class ManagedDependenciesArtifactCoordinatesResolverTests {
public class DependencyManagementArtifactCoordinatesResolverTests {
private ManagedDependencies dependencies;
private DependencyManagement dependencyManagement;
private ManagedDependenciesArtifactCoordinatesResolver resolver;
private DependencyManagementArtifactCoordinatesResolver resolver;
@Before
public void setup() {
this.dependencies = mock(ManagedDependencies.class);
given(this.dependencies.find("a1")).willReturn(new Dependency("g1", "a1", "0"));
given(this.dependencies.getSpringBootVersion()).willReturn("1");
this.resolver = new ManagedDependenciesArtifactCoordinatesResolver(
this.dependencies);
this.dependencyManagement = mock(DependencyManagement.class);
given(this.dependencyManagement.find("a1")).willReturn(
new Dependency("g1", "a1", "0"));
given(this.dependencyManagement.getSpringBootVersion()).willReturn("1");
this.resolver = new DependencyManagementArtifactCoordinatesResolver(
this.dependencyManagement);
}
@Test
public void getGroupIdForBootArtifact() throws Exception {
assertThat(this.resolver.getGroupId("spring-boot-something"),
equalTo("org.springframework.boot"));
verify(this.dependencies, never()).find(anyString());
verify(this.dependencyManagement, never()).find(anyString());
}
@Test
@ -67,20 +67,4 @@ public class ManagedDependenciesArtifactCoordinatesResolverTests {
assertThat(this.resolver.getGroupId("a2"), nullValue());
}
@Test
public void getVersionForBootArtifact() throws Exception {
assertThat(this.resolver.getVersion("spring-boot-something"), equalTo("1"));
verify(this.dependencies, never()).find(anyString());
}
@Test
public void getVersionFound() throws Exception {
assertThat(this.resolver.getVersion("a1"), equalTo("0"));
}
@Test
public void getVersionNotFound() throws Exception {
assertThat(this.resolver.getVersion("a2"), nullValue());
}
}

@ -0,0 +1,55 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.dependencies;
import org.junit.Test;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link SpringBootDependenciesDependencyManagement}
*
* @author Andy Wilkinson
*/
public class SpringBootDependenciesDependencyManagementTests {
private final DependencyManagement dependencyManagement = new SpringBootDependenciesDependencyManagement();
@Test
public void springBootVersion() {
assertThat(this.dependencyManagement.getSpringBootVersion(), is(notNullValue()));
}
@Test
public void find() {
Dependency dependency = this.dependencyManagement.find("spring-boot");
assertThat(dependency, is(notNullValue()));
assertThat(dependency.getGroupId(), is(equalTo("org.springframework.boot")));
assertThat(dependency.getArtifactId(), is(equalTo("spring-boot")));
}
@Test
public void getDependencies() {
assertThat(this.dependencyManagement.getDependencies(), is(not(empty())));
}
}

@ -1,53 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.cli.compiler.grape;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.springframework.boot.dependency.tools.Dependency;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Tests for {@link ManagedDependenciesFactory}.
*
* @author Phillip Webb
*/
public class ManagedDependenciesFactoryTests {
@Test
public void getManagedDependencies() {
List<Dependency> dependencyList = new ArrayList<Dependency>();
dependencyList.add(new Dependency("g1", "a1", "1"));
dependencyList.add(new Dependency("g1", "a2", "1"));
ManagedDependencies dependencies = mock(ManagedDependencies.class);
given(dependencies.iterator()).willReturn(dependencyList.iterator());
ManagedDependenciesFactory factory = new ManagedDependenciesFactory(dependencies);
List<org.eclipse.aether.graph.Dependency> result = factory
.getManagedDependencies();
assertThat(result.size(), equalTo(2));
assertThat(result.get(0).toString(), equalTo("g1:a1:jar:1 (compile)"));
assertThat(result.get(1).toString(), equalTo("g1:a2:jar:1 (compile)"));
}
}

@ -0,0 +1,5 @@
@DependencyManagementBom('test:child:1.0.0')
@Grab('ejb-api')
class CustomDependencyManagement {
}

@ -1,5 +0,0 @@
@org.springframework.boot.groovy.GrabMetadata('test:test:1.0.0')
@Grab('ejb-api')
class CustomGrabMetadata {
}

@ -0,0 +1,5 @@
@DependencyManagementBom("foo:bar:1.0")
@DependencyManagementBom("alpha:bravo:2.0")
class DuplicateDependencyManagement {
}

@ -1,5 +0,0 @@
@GrabMetadata("foo:bar:1.0")
@GrabMetadata("alpha:bravo:2.0")
class DuplicateGrabMetadata {
}

@ -0,0 +1,13 @@
<project>
<parent>
<groupId>test</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>child</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modelVersion>4.0.0</modelVersion>
</project>

@ -0,0 +1,18 @@
<project>
<groupId>test</groupId>
<artifactId>parent</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modelVersion>4.0.0</modelVersion>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>javax.ejb</groupId>
<artifactId>ejb-api</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

@ -181,11 +181,6 @@
<artifactId>spring-boot-configuration-processor</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependency-tools</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader</artifactId>
@ -1739,6 +1734,68 @@
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-help-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>generate-effective-dependencies-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>effective-pom</goal>
</goals>
<configuration>
<output>${project.build.directory}/effective-pom/spring-boot-dependencies.xml</output>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0</version>
<inherited>false</inherited>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/effective-pom</dir>
<stylesheet>src/main/xslt/single-project.xsl</stylesheet>
<outputDir>${project.build.directory}/effective-pom</outputDir>
</transformationSet>
</transformationSets>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<inherited>false</inherited>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/effective-pom/spring-boot-dependencies.xml</file>
<type>effective-pom</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<profiles>
<profile>

@ -0,0 +1,6 @@
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<xsl:template match="/">
<xsl:copy-of select="projects/*[1]" />
<xsl:copy-of select="*[local-name()='project']" />
</xsl:template>
</xsl:stylesheet>

@ -392,7 +392,7 @@
<artifactItems>
<artifactItem>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-versions</artifactId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${project.version}</version>
<type>effective-pom</type>
<overWrite>true</overWrite>

@ -213,40 +213,42 @@ Unlike the equivalent Java application, you do not need to include a
[[cli-default-grab-deduced-coordinates-custom-metadata]]
==== Custom "`grab`" metadata
Spring Boot provides a new `@GrabMetadata` annotation that can be used to provide custom
dependency metadata that overrides Spring Boot's defaults. This metadata is specified by
using the annotation to provide coordinates of one or more properties files (deployed
to a Maven repository with a "`type`" identifier of `properties`). Each entry in each
properties file must be in the form `group:module=version`.
[[cli-default-grab-deduced-coordinates-custom-dependency-management]]
==== Custom dependency management
By default, the CLI uses the dependency management declared in `spring-boot-dependencies`
when resolving `@Grab` dependencies. Additional dependency management, that will override
the default dependency management, can be configured using the `@DependencyManagementBom`
annotation. The annotation's value should specify the coordinates
(`groupId:artifactId:version`) of one or more Maven boms.
For example, the following declaration:
[source,java,indent=0]
[source,groovy,indent=0]
----
`@GrabMetadata("com.example.custom-versions:1.0.0")`
`@DependencyManagementBom("com.example.custom-bom:1.0.0")`
----
Will pick up `custom-versions-1.0.0.properties` in a Maven repository under
Will pick up `custom-bom-1.0.0.pom` in a Maven repository under
`com/example/custom-versions/1.0.0/`.
Multiple properties files can be specified from the annotation, they will be applied in
the order that they're declared. For example:
When multiple boms are specified they are applied in the order that they're declared.
For example:
[source,java,indent=0]
----
`@GrabMetadata(["com.example.custom-versions:1.0.0",
"com.example.more-versions:1.0.0"])`
`@DependencyManagementBom(["com.example.custom-bom:1.0.0",
"com.example.another-bom:1.0.0"])`
----
indicates that properties in `more-versions` will override properties in `custom-versions`.
indicates that dependency management in `another-bom` will override the dependency
management in `custom-bom`.
You can use `@GrabMetadata` anywhere that you can use `@Grab`, however, to ensure
consistent ordering of the metadata, you can only use `@GrabMetadata` at most once in your
application. A useful source of dependency metadata (a superset of Spring Boot) is the
You can use `@DependencyManagementBom` anywhere that you can use `@Grab`, however, to
ensure consistent ordering of the dependency management, you can only use
`@DependencyManagementBom` at most once in your application. A useful source of
dependency management (that is a superset of Spring Boot's dependency management) is the
http://platform.spring.io/[Spring IO Platform], e.g.
`@GrabMetadata('io.spring.platform:platform-versions:1.0.4.RELEASE')`.
`@DepenedencyManagementBom('io.spring.platform:platform-bom:1.1.2.RELEASE')`.

@ -45,7 +45,6 @@
</developers>
<modules>
<module>../</module>
<module>../spring-boot-versions</module>
<module>../spring-boot-dependencies</module>
<module>../spring-boot-parent</module>
<module>../spring-boot-tools</module>

@ -27,15 +27,46 @@
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependency-tools</artifactId>
<artifactId>spring-boot</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<groupId>org.apache.maven</groupId>
<artifactId>maven-model-builder</artifactId>
<version>3.2.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-effective-pom</id>
<phase>generate-test-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${project.version}</version>
<type>effective-pom</type>
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}</outputDirectory>
<destFileName>dependencies-pom.xml</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>gradle</id>

@ -22,7 +22,6 @@ import org.gradle.tooling.ProjectConnection;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.test.OutputCapture;
import static org.hamcrest.Matchers.containsString;
@ -35,8 +34,7 @@ import static org.junit.Assert.assertThat;
*/
public class BootRunResourceTests {
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
private static ProjectConnection project;

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -20,7 +20,6 @@ import java.util.jar.JarFile;
import org.gradle.tooling.ProjectConnection;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import static org.junit.Assert.assertNotNull;
@ -33,8 +32,7 @@ public class ClassifierTests {
private ProjectConnection project;
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
@Test
public void classifierInBootTask() throws Exception {

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -21,7 +21,6 @@ import java.io.File;
import org.gradle.tooling.ProjectConnection;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.FileSystemUtils;
@ -36,8 +35,7 @@ public class FlatdirTests {
private File libs = new File("target/flatdir/lib");
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
@Before
public void init() {

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -18,7 +18,6 @@ package org.springframework.boot.gradle;
import org.gradle.tooling.ProjectConnection;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
/**
* Tests for using the Gradle plugin's support for installing artifacts
@ -29,8 +28,7 @@ public class InstallTests {
private ProjectConnection project;
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
@Test
public void cleanInstall() throws Exception {

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -21,7 +21,6 @@ import java.io.IOException;
import org.gradle.tooling.ProjectConnection;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
/**
* Tests for using the Gradle plugin's support for installing artifacts
@ -32,8 +31,7 @@ public class MainClassTests {
private static ProjectConnection project;
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
@BeforeClass
public static void createProject() throws IOException {

@ -21,7 +21,6 @@ import java.util.jar.JarFile;
import org.gradle.tooling.ProjectConnection;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;
@ -33,8 +32,7 @@ import static org.junit.Assert.assertThat;
*/
public class MultiProjectRepackagingTests {
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
@Test
public void repackageWithTransitiveFileDependency() throws Exception {

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -20,7 +20,6 @@ import java.io.File;
import org.gradle.tooling.ProjectConnection;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import static org.junit.Assert.assertFalse;
@ -33,8 +32,7 @@ public class NoJarTests {
private ProjectConnection project;
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
@Test
public void nojar() throws Exception {

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -23,7 +23,6 @@ import java.util.jar.JarFile;
import org.gradle.tooling.ProjectConnection;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.util.FileCopyUtils;
import static org.hamcrest.Matchers.notNullValue;
@ -38,8 +37,7 @@ import static org.junit.Assert.assertTrue;
*/
public class RepackagingTests {
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
private static ProjectConnection project;

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -25,7 +25,6 @@ import java.util.List;
import org.gradle.tooling.ProjectConnection;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import static org.junit.Assert.fail;
@ -36,11 +35,9 @@ import static org.junit.Assert.fail;
*/
public class SpringLoadedTests {
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
private static final String SPRING_LOADED_VERSION = ManagedDependencies.get()
.find("springloaded").getVersion();
private static final String SPRING_LOADED_VERSION = Versions.getSpringLoadedVersion();
@Test
public void defaultJvmArgsArePreservedWhenLoadedAgentIsConfigured()

@ -0,0 +1,60 @@
/*
* Copyright 2012-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.gradle;
import java.io.FileReader;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.xml.sax.InputSource;
/**
* @author Andy Wilkinson
*/
public class Versions {
public static String getBootVersion() {
return evaluateExpression("/*[local-name()='project']/*[local-name()='version']"
+ "/text()");
}
public static String getSpringLoadedVersion() {
return evaluateExpression("/*[local-name()='project']/*[local-name()='properties']"
+ "/*[local-name()='spring-loaded.version']/text()");
}
public static String getSpringVersion() {
return evaluateExpression("/*[local-name()='project']/*[local-name()='properties']"
+ "/*[local-name()='spring.version']/text()");
}
private static String evaluateExpression(String expression) {
try {
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile(expression);
String version = expr.evaluate(new InputSource(new FileReader(
"target/dependencies-pom.xml")));
return version;
}
catch (Exception ex) {
throw new IllegalStateException("Failed to evaluate expression", ex);
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -29,7 +29,6 @@ import java.util.jar.JarFile;
import org.gradle.tooling.ProjectConnection;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@ -62,8 +61,7 @@ public class WarPackagingTests {
"websocket-server-", "jetty-jndi-", "jetty-xml-",
"websocket-servlet-"));
private static final String BOOT_VERSION = ManagedDependencies.get()
.find("spring-boot").getVersion();
private static final String BOOT_VERSION = Versions.getBootVersion();
private static ProjectConnection project;

@ -1,5 +1,5 @@
/*
* Copyright 2012-2014 the original author or authors.
* Copyright 2012-2015 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.
@ -30,8 +30,8 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.boot.dependency.tools.ManagedDependencies;
import org.springframework.boot.gradle.ProjectCreator;
import org.springframework.boot.gradle.Versions;
import static org.junit.Assert.fail;
@ -79,8 +79,8 @@ public class StarterDependenciesIntegrationTests {
@BeforeClass
public static void determineVersions() throws Exception {
springVersion = ManagedDependencies.get().find("spring-core").getVersion();
bootVersion = ManagedDependencies.get().find("spring-boot").getVersion();
springVersion = Versions.getSpringVersion();
bootVersion = Versions.getBootVersion();
}
@AfterClass

@ -19,7 +19,7 @@
<properties>
<main.basedir>..</main.basedir>
<java.version>1.6</java.version>
<aether.version>0.9.1.v20140329</aether.version>
<aether.version>1.0.2.v20150114</aether.version>
<json.version>20140107</json.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>

@ -21,7 +21,6 @@
</properties>
<modules>
<module>spring-boot-configuration-processor</module>
<module>spring-boot-dependency-tools</module>
<module>spring-boot-loader</module>
<module>spring-boot-loader-tools</module>
<module>spring-boot-maven-plugin</module>

@ -1,56 +0,0 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-tools</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-boot-dependency-tools</artifactId>
<name>Spring Boot Dependency Tools</name>
<description>Spring Boot Dependency Tools</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
<generated.pom.dir>${project.build.directory}/generated-resources/org/springframework/boot/dependency/tools</generated.pom.dir>
</properties>
<build>
<resources>
<resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-effective-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-versions</artifactId>
<version>${project.version}</version>
<type>effective-pom</type>
<overWrite>true</overWrite>
<outputDirectory>${generated.pom.dir}</outputDirectory>
<destFileName>effective-pom.xml</destFileName>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,128 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.springframework.boot.dependency.tools.Dependency.Exclusion;
/**
* Abstract base implementation for {@link Dependencies}.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.1.0
*/
abstract class AbstractDependencies implements Dependencies {
private final Map<ArtifactAndGroupId, Dependency> byArtifactAndGroupId;
private final Map<String, Dependency> byArtifactId;
public AbstractDependencies() {
this.byArtifactAndGroupId = new LinkedHashMap<ArtifactAndGroupId, Dependency>();
this.byArtifactId = new LinkedHashMap<String, Dependency>();
}
@Override
public Dependency find(String groupId, String artifactId) {
return this.byArtifactAndGroupId.get(new ArtifactAndGroupId(groupId, artifactId));
}
@Override
public Dependency find(String artifactId) {
return this.byArtifactId.get(artifactId);
}
@Override
public Iterator<Dependency> iterator() {
return this.byArtifactAndGroupId.values().iterator();
}
protected void add(ArtifactAndGroupId artifactAndGroupId, Dependency dependency) {
Dependency existing = this.byArtifactAndGroupId.get(artifactAndGroupId);
if (existing != null) {
dependency = mergeDependencies(existing, dependency);
}
this.byArtifactAndGroupId.put(artifactAndGroupId, dependency);
this.byArtifactId.put(dependency.getArtifactId(), dependency);
}
private Dependency mergeDependencies(Dependency existingDependency,
Dependency newDependency) {
Set<Exclusion> combinedExclusions = new LinkedHashSet<Exclusion>();
combinedExclusions.addAll(existingDependency.getExclusions());
combinedExclusions.addAll(newDependency.getExclusions());
return new Dependency(newDependency.getGroupId(), newDependency.getArtifactId(),
newDependency.getVersion(), new ArrayList<Exclusion>(combinedExclusions));
}
/**
* Simple holder for an artifact+group ID.
*/
protected static class ArtifactAndGroupId {
private final String groupId;
private final String artifactId;
public ArtifactAndGroupId(Dependency dependency) {
this(dependency.getGroupId(), dependency.getArtifactId());
}
public ArtifactAndGroupId(String groupId, String artifactId) {
Assert.notNull(groupId, "GroupId must not be null");
Assert.notNull(artifactId, "ArtifactId must not be null");
this.groupId = groupId;
this.artifactId = artifactId;
}
public Dependency newDependency(String version) {
return new Dependency(this.groupId, this.artifactId, version);
}
@Override
public int hashCode() {
return this.groupId.hashCode() * 31 + this.artifactId.hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() == obj.getClass()) {
ArtifactAndGroupId other = (ArtifactAndGroupId) obj;
boolean result = true;
result &= this.groupId.equals(other.groupId);
result &= this.artifactId.equals(other.artifactId);
return result;
}
return false;
}
}
}

@ -1,32 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
/**
* Simple subset of the Spring Assert utility.
*
* @author Phillip Webb
*/
class Assert {
public static void notNull(Object object, String message) {
if (object == null) {
throw new IllegalArgumentException(message);
}
}
}

@ -1,51 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.util.Iterator;
/**
* Interface for accessing a known set of dependencies.
*
* @author Phillip Webb
* @see Dependency
* @since 1.1.0
*/
public interface Dependencies extends Iterable<Dependency> {
/**
* Find a single dependency for the given group and artifact IDs.
* @param groupId the group ID
* @param artifactId the artifact ID
* @return a {@link Dependency} or {@code null}
*/
public Dependency find(String groupId, String artifactId);
/**
* Find a single dependency for the artifact IDs.
* @param artifactId the artifact ID
* @return a {@link Dependency} or {@code null}
*/
public Dependency find(String artifactId);
/**
* Provide an {@link Iterator} over all managed {@link Dependency Dependencies}.
*/
@Override
public Iterator<Dependency> iterator();
}

@ -1,113 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
/**
* {@link Dependencies} used by various spring boot tools. Provides programmatic access to
* 'spring-boot-dependencies' and can also support user defined version managed
* dependencies.
*
* @author Phillip Webb
* @see Dependency
*/
public abstract class ManagedDependencies implements Dependencies {
// NOTE: Take care if changing the API of this class, it is used by the third-party
// Gretty tool (https://github.com/akhikhl/gretty)
private final Dependencies delegate;
ManagedDependencies(Dependencies delegate) {
this.delegate = delegate;
}
/**
* Return the 'spring-boot-dependencies' POM version.
* @return the version
* @deprecated since 1.1.0 in favor of {@link #getSpringBootVersion()}
*/
@Deprecated
public String getVersion() {
return getSpringBootVersion();
}
/**
* Return the 'spring-boot-dependencies' POM version.
* @return the spring boot version
*/
public String getSpringBootVersion() {
Dependency dependency = find("org.springframework.boot", "spring-boot");
return (dependency == null ? null : dependency.getVersion());
}
/**
* Find a single dependency for the given group and artifact IDs.
* @param groupId the group ID
* @param artifactId the artifact ID
* @return a {@link Dependency} or {@code null}
*/
@Override
public Dependency find(String groupId, String artifactId) {
return this.delegate.find(groupId, artifactId);
}
/**
* Find a single dependency for the artifact IDs.
* @param artifactId the artifact ID
* @return a {@link Dependency} or {@code null}
*/
@Override
public Dependency find(String artifactId) {
return this.delegate.find(artifactId);
}
/**
* Provide an {@link Iterator} over all managed {@link Dependency Dependencies}.
*/
@Override
public Iterator<Dependency> iterator() {
return this.delegate.iterator();
}
/**
* Return spring-boot managed dependencies.
* @return The dependencies.
* @see #get(Collection)
*/
public static ManagedDependencies get() {
return get(Collections.<Dependencies> emptySet());
}
/**
* Return spring-boot managed dependencies with optional version managed dependencies.
* @param versionManagedDependencies a collection of {@link Dependencies} that take
* precedence over the {@literal spring-boot-dependencies}.
* @return the dependencies
* @since 1.1.0
*/
public static ManagedDependencies get(
Collection<Dependencies> versionManagedDependencies) {
return new ManagedDependencies(new ManagedDependenciesDelegate(
versionManagedDependencies)) {
};
}
}

@ -1,72 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.io.InputStream;
import java.util.Collection;
/**
* {@link Dependencies} delegate used internally by {@link ManagedDependencies}.
*
* @author Phillip Webb
* @since 1.1.0
*/
class ManagedDependenciesDelegate extends AbstractDependencies {
private static Dependencies springBootDependencies;
/**
* Create a new {@link ManagedDependenciesDelegate} instance with optional version
* managed dependencies.
* @param versionManagedDependencies a collection of {@link Dependencies} that take
* precedence over the `spring-boot-dependencies`.
*/
public ManagedDependenciesDelegate(Collection<Dependencies> versionManagedDependencies) {
this(getSpringBootDependencies(), versionManagedDependencies);
}
ManagedDependenciesDelegate(Dependencies rootDependencies,
Collection<Dependencies> versionManagedDependencies) {
addAll(rootDependencies);
if (versionManagedDependencies != null) {
for (Dependencies managedDependencies : versionManagedDependencies) {
addAll(managedDependencies);
}
}
}
private void addAll(Dependencies dependencies) {
for (Dependency dependency : dependencies) {
add(new ArtifactAndGroupId(dependency), dependency);
}
}
private static Dependencies getSpringBootDependencies() {
if (springBootDependencies == null) {
springBootDependencies = new PomDependencies(getResource("effective-pom.xml"));
}
return springBootDependencies;
}
private static InputStream getResource(String name) {
InputStream inputStream = ManagedDependenciesDelegate.class
.getResourceAsStream(name);
Assert.notNull(inputStream, "Unable to load " + name);
return inputStream;
}
}

@ -1,128 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.springframework.boot.dependency.tools.Dependency.Exclusion;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
/**
* {@link Dependencies} implementation backed a maven POM.
*
* @author Phillip Webb
* @author Andy Wilkinson
* @since 1.1.0
*/
public class PomDependencies extends AbstractDependencies {
/**
* Create a new {@link PomDependencies} instance.
* @param effectivePomInputStream the effective POM containing resolved versions. The
* input stream will be closed once content has been loaded.
*/
public PomDependencies(InputStream effectivePomInputStream) {
try {
Document effectivePom = readDocument(effectivePomInputStream);
for (Dependency dependency : readDependencies(effectivePom)) {
add(new ArtifactAndGroupId(dependency), dependency);
}
}
catch (Exception ex) {
throw new IllegalStateException(ex);
}
}
private Document readDocument(InputStream inputStream) throws Exception {
if (inputStream == null) {
return null;
}
try {
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document document = builder.parse(inputStream);
document.getDocumentElement().normalize();
return document;
}
finally {
inputStream.close();
}
}
private List<Dependency> readDependencies(Document document) throws Exception {
Element element = (Element) document.getElementsByTagName("project").item(0);
element = (Element) element.getElementsByTagName("dependencyManagement").item(0);
element = (Element) element.getElementsByTagName("dependencies").item(0);
NodeList nodes = element.getChildNodes();
List<Dependency> dependencies = new ArrayList<Dependency>();
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node instanceof Element) {
dependencies.add(createDependency((Element) node));
}
}
return dependencies;
}
private Dependency createDependency(Element element) throws Exception {
String groupId = getTextContent(element, "groupId");
String artifactId = getTextContent(element, "artifactId");
String version = getTextContent(element, "version");
List<Exclusion> exclusions = createExclusions(element
.getElementsByTagName("exclusions"));
return new Dependency(groupId, artifactId, version, exclusions);
}
private List<Exclusion> createExclusions(NodeList exclusion) {
if (exclusion == null || exclusion.getLength() == 0) {
return Collections.emptyList();
}
return createExclusions(exclusion.item(0));
}
private List<Exclusion> createExclusions(Node item) {
List<Exclusion> exclusions = new ArrayList<Dependency.Exclusion>();
NodeList children = item.getChildNodes();
for (int i = 0; i < children.getLength(); i++) {
Node child = children.item(i);
if (child instanceof Element) {
exclusions.add(createExclusion((Element) child));
}
}
return exclusions;
}
private Exclusion createExclusion(Element element) {
String groupId = getTextContent(element, "groupId");
String artifactId = getTextContent(element, "artifactId");
return new Exclusion(groupId, artifactId);
}
private String getTextContent(Element element, String tagName) {
return element.getElementsByTagName(tagName).item(0).getTextContent();
}
}

@ -1,73 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
import java.util.Properties;
import java.util.TreeMap;
/**
* {@link Dependencies} backed by an external properties file (of the form created by the
* Spring IO platform). The property key should be the groupId and artifactId (in the form
* {@literal groupId:artifactId}) and the value should be the version.
*
* @author Phillip Webb
* @since 1.1.0
*/
public class PropertiesFileDependencies extends AbstractDependencies {
/**
* Create a new {@link PropertiesFileDependencies} instance from the specified input
* stream.
* @param inputStream source input stream (will be closed when properties have been
* loaded)
* @throws IOException
*/
public PropertiesFileDependencies(InputStream inputStream) throws IOException {
try {
Properties properties = new Properties();
properties.load(inputStream);
initialize(properties);
}
finally {
inputStream.close();
}
}
private void initialize(Properties properties) {
Map<String, String> sortedMap = new TreeMap<String, String>();
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
sortedMap.put(entry.getKey().toString(), entry.getValue().toString());
}
for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
ArtifactAndGroupId artifactAndGroupId = parse(entry.getKey());
Dependency dependency = artifactAndGroupId.newDependency(entry.getValue());
add(artifactAndGroupId, dependency);
}
}
private ArtifactAndGroupId parse(String value) {
String[] parts = value.split("\\:");
if (parts.length != 2) {
throw new IllegalStateException("Unable to parse " + value);
}
return new ArtifactAndGroupId(parts[0], parts[1]);
}
}

@ -1,24 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Utilities for working with the managed dependencies declared in the
* {@literal spring-boot-dependencies} project.
*
* @see org.springframework.boot.dependency.tools.ManagedDependencies
*/
package org.springframework.boot.dependency.tools;

@ -1,70 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.util.Collections;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link ManagedDependenciesDelegate}.
*
* @author Phillip Webb
*/
public class ManagedDependenciesDelegateTests {
private ManagedDependenciesDelegate dependencies;
@Before
public void setup() throws Exception {
PropertiesFileDependencies root = new PropertiesFileDependencies(getClass()
.getResourceAsStream("external.properties"));
PropertiesFileDependencies extra = new PropertiesFileDependencies(getClass()
.getResourceAsStream("additional-external.properties"));
this.dependencies = new ManagedDependenciesDelegate(root,
Collections.<Dependencies> singleton(extra));
}
@Test
public void extra() throws Exception {
assertThat(this.dependencies.find("org.sample", "sample03").toString(),
equalTo("org.sample:sample03:2.0.0"));
}
@Test
public void override() throws Exception {
assertThat(this.dependencies.find("org.sample", "sample02").toString(),
equalTo("org.sample:sample02:2.0.0"));
}
@Test
public void iterator() throws Exception {
Iterator<Dependency> iterator = this.dependencies.iterator();
assertThat(iterator.next().toString(), equalTo("org.sample:sample01:1.0.0"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample02:2.0.0"));
assertThat(iterator.next().toString(),
equalTo("org.springframework.boot:spring-boot:1.0.0.BUILD-SNAPSHOT"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample03:2.0.0"));
assertThat(iterator.hasNext(), equalTo(false));
}
}

@ -1,74 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import org.junit.Before;
import org.junit.Test;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
/**
* Tests for {@link ManagedDependencies}.
*
* @author Phillip Webb
*/
public class ManagedDependenciesTests {
private ManagedDependencies managedDependencies;
private Dependencies delegate;
@Before
public void setup() {
this.delegate = mock(Dependencies.class);
this.managedDependencies = new ManagedDependencies(this.delegate) {
};
}
@Test
@Deprecated
public void getVersion() throws Exception {
this.managedDependencies.getVersion();
verify(this.delegate).find("org.springframework.boot", "spring-boot");
}
@Test
public void getSpringBootVersion() throws Exception {
this.managedDependencies.getSpringBootVersion();
verify(this.delegate).find("org.springframework.boot", "spring-boot");
}
@Test
public void findGroupIdArtifactId() throws Exception {
this.managedDependencies.find("groupId", "artifactId");
verify(this.delegate).find("groupId", "artifactId");
}
@Test
public void findArtifactId() throws Exception {
this.managedDependencies.find("artifactId");
verify(this.delegate).find("artifactId");
}
@Test
public void iterator() throws Exception {
this.managedDependencies.iterator();
verify(this.delegate).iterator();
}
}

@ -1,90 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.io.InputStream;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link PomDependencies}.
*
* @author Phillip Webb
*/
public class PomDependenciesTests {
private PomDependencies dependencies;
@Before
public void setup() {
InputStream x = getResource("test-effective-pom.xml");
this.dependencies = new PomDependencies(x);
}
private InputStream getResource(String name) {
InputStream inputStream = getClass().getResourceAsStream(name);
assertNotNull("Unable to read " + name, inputStream);
return inputStream;
}
@Test
public void iterate() throws Exception {
Iterator<Dependency> iterator = this.dependencies.iterator();
assertThat(iterator.next().toString(), equalTo("org.sample:sample01:1.0.0"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample02:1.0.0"));
assertThat(iterator.next().toString(),
equalTo("org.springframework.boot:spring-boot:1.0.0.BUILD-SNAPSHOT"));
assertThat(iterator.hasNext(), equalTo(false));
}
@Test
public void findByArtifactAndGroupId() throws Exception {
assertThat(this.dependencies.find("org.sample", "sample02").toString(),
equalTo("org.sample:sample02:1.0.0"));
}
@Test
public void findByArtifactAndGroupIdMissing() throws Exception {
assertThat(this.dependencies.find("org.sample", "missing"), nullValue());
}
@Test
public void findByArtifactId() throws Exception {
assertThat(this.dependencies.find("sample02").toString(),
equalTo("org.sample:sample02:1.0.0"));
}
@Test
public void findByArtifactIdMissing() throws Exception {
assertThat(this.dependencies.find("missing"), nullValue());
}
@Test
public void exludes() throws Exception {
Dependency dependency = this.dependencies.find("org.sample", "sample01");
assertThat(dependency.getExclusions().toString(),
equalTo("[org.exclude:exclude01]"));
}
}

@ -1,87 +0,0 @@
/*
* Copyright 2012-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.boot.dependency.tools;
import java.util.Iterator;
import org.junit.Before;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
/**
* Tests for {@link PropertiesFileDependencies}.
*
* @author Phillip Webb
*/
public class PropertiesFileDependenciesTests {
private PropertiesFileDependencies dependencies;
@Before
public void setup() throws Exception {
this.dependencies = new PropertiesFileDependencies(getClass()
.getResourceAsStream("external.properties"));
}
@Test
public void iterate() throws Exception {
Iterator<Dependency> iterator = this.dependencies.iterator();
assertThat(iterator.next().toString(), equalTo("org.sample:sample01:1.0.0"));
assertThat(iterator.next().toString(), equalTo("org.sample:sample02:1.0.0"));
assertThat(iterator.next().toString(),
equalTo("org.springframework.boot:spring-boot:1.0.0.BUILD-SNAPSHOT"));
assertThat(iterator.hasNext(), equalTo(false));
}
@Test
public void findByArtifactAndGroupId() throws Exception {
assertThat(this.dependencies.find("org.sample", "sample02").toString(),
equalTo("org.sample:sample02:1.0.0"));
}
@Test
public void findByArtifactAndGroupIdMissing() throws Exception {
assertThat(this.dependencies.find("org.sample", "missing"), nullValue());
}
@Test
public void findByArtifactAndGroupIdOnlyInEffectivePom() throws Exception {
assertThat(this.dependencies.find("org.extra", "extra01"), nullValue());
}
@Test
public void findByArtifactId() throws Exception {
assertThat(this.dependencies.find("sample02").toString(),
equalTo("org.sample:sample02:1.0.0"));
}
@Test
public void findByArtifactIdMissing() throws Exception {
assertThat(this.dependencies.find("missing"), nullValue());
}
@Test
public void exludes() throws Exception {
// No Support for exclusion
Dependency dependency = this.dependencies.find("org.sample", "sample01");
assertThat(dependency.getExclusions().size(), equalTo(0));
}
}

@ -1,3 +0,0 @@
org.sample\:sample01=1.0.0
org.sample\:sample02=1.0.0
org.springframework.boot\:spring-boot=1.0.0.BUILD-SNAPSHOT

@ -1,34 +0,0 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<version>1.0.0.BUILD-SNAPSHOT</version>
<properties>
<sample.version>1.0.0</sample.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.sample</groupId>
<artifactId>sample01</artifactId>
<version>1.0.0</version>
<exclusions>
<exclusion>
<groupId>org.exclude</groupId>
<artifactId>exclude01</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.sample</groupId>
<artifactId>sample02</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

@ -23,10 +23,6 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-loader-tools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependency-tools</artifactId>
</dependency>
<dependency>
<groupId>io.spring.gradle</groupId>
<artifactId>dependency-management-plugin</artifactId>

@ -1,97 +0,0 @@
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.0.BUILD-SNAPSHOT</version>
<relativePath>../spring-boot-dependencies</relativePath>
</parent>
<artifactId>spring-boot-versions</artifactId>
<packaging>pom</packaging>
<name>Spring Boot Versions</name>
<description>Spring Boot Versions Property File</description>
<url>http://projects.spring.io/spring-boot/</url>
<organization>
<name>Pivotal Software, Inc.</name>
<url>http://www.spring.io</url>
</organization>
<properties>
<main.basedir>${basedir}/../..</main.basedir>
</properties>
<build>
<resources>
<resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-help-plugin</artifactId>
<executions>
<execution>
<id>generate-effective-dependencies-pom</id>
<phase>generate-resources</phase>
<goals>
<goal>effective-pom</goal>
</goals>
<configuration>
<output>${project.build.directory}/effective-pom/spring-boot-versions.xml</output>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>${project.build.directory}/effective-pom</dir>
<stylesheet>src/main/xslt/dependency-management-to-versions.xsl</stylesheet>
<fileMappers>
<fileMapper implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
<targetExtension>.properties</targetExtension>
</fileMapper>
</fileMappers>
<outputDir>${project.build.directory}/generated-resources</outputDir>
</transformationSet>
</transformationSets>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/generated-resources/spring-boot-versions.properties</file>
<type>properties</type>
</artifact>
<artifact>
<file>${project.build.directory}/effective-pom/spring-boot-versions.xml</file>
<type>effective-pom</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -1,35 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<profiles>
<profile>
<id>it-repo</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<repositories>
<repository>
<id>local.central</id>
<url>@localRepositoryUrl@</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>local.central</id>
<url>@localRepositoryUrl@</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
</profiles>
</settings>

@ -1,21 +0,0 @@
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:mvn="http://maven.apache.org/POM/4.0.0"
version="1.0">
<xsl:output method="text" encoding="UTF-8" indent="no"/>
<xsl:template match="/">
<xsl:for-each select="//mvn:dependency">
<xsl:sort select="mvn:groupId"/>
<xsl:sort select="mvn:artifactId"/>
<xsl:copy-of select="mvn:groupId"/>
<xsl:text>\:</xsl:text>
<xsl:copy-of select="mvn:artifactId"/>
<xsl:text>=</xsl:text>
<xsl:copy-of select="mvn:version"/>
<xsl:text>&#xa;</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Loading…
Cancel
Save