org.grails.cli.boot.GrailsApplicationCompilerAutoConfiguration Maven / Gradle / Ivy
/*
* Copyright 2014 original 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.grails.cli.boot;
import grails.util.Environment;
import groovy.lang.Grab;
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.Parameter;
import org.codehaus.groovy.ast.expr.ClassExpression;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.customizers.ImportCustomizer;
import org.grails.cli.compiler.AstUtils;
import org.grails.cli.compiler.CompilerAutoConfiguration;
import org.grails.cli.compiler.DependencyCustomizer;
import org.grails.cli.compiler.GroovyCompilerConfiguration;
import org.grails.cli.compiler.autoconfigure.SpringMvcCompilerAutoConfiguration;
import org.grails.cli.compiler.dependencies.Dependency;
import org.grails.cli.compiler.dependencies.DependencyManagement;
import org.grails.cli.compiler.grape.DependencyResolutionContext;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* A {@link CompilerAutoConfiguration} for Grails Micro Service applications
*
* @author Graeme Rocher
* @since 3.0
*/
public class GrailsApplicationCompilerAutoConfiguration extends CompilerAutoConfiguration {
public static final String[] DEFAULT_IMPORTS = new String[]{
"grails.persistence",
"grails.gorm",
"grails.rest",
"grails.artefact",
"grails.web",
"grails.boot.config" };
public static final String ENABLE_AUTO_CONFIGURATION = "org.springframework.boot.autoconfigure.EnableAutoConfiguration";
public static final ClassNode ENABLE_AUTO_CONFIGURATION_CLASS_NODE = ClassHelper.make(ENABLE_AUTO_CONFIGURATION);
ClassNode lastMatch = null;
@Override
public boolean matches(ClassNode classNode) {
boolean matches = AstUtils.hasAtLeastOneAnnotation(classNode, "grails.persistence.Entity", "grails.rest.Resource", "Resource", "grails.artefact.Artefact", "grails.web.Controller");
if(matches) lastMatch = classNode;
return matches;
}
@Override
public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException {
addManagedDependencies(dependencies);
if(lastMatch != null) {
lastMatch.addAnnotation(createGrabAnnotation("org.grails", "grails-dependencies", Environment.class.getPackage().getImplementationVersion(), null, "pom", true));
lastMatch.addAnnotation(createGrabAnnotation("org.grails", "grails-web-boot", Environment.class.getPackage().getImplementationVersion(), null, null, true));
}
new SpringMvcCompilerAutoConfiguration().applyDependencies(dependencies);
}
private void addManagedDependencies(DependencyCustomizer dependencies) {
final List current = dependencies
.getDependencyResolutionContext().getManagedDependencies();
final DependencyResolutionContext resolutionContext = dependencies.getDependencyResolutionContext();
resolutionContext.addDependencyManagement(new GrailsDependencies(current));
resolutionContext.addDependencyManagement(getAdditionalDependencies());
}
protected DependencyManagement getAdditionalDependencies() {
return new GrailsDependencyVersions();
}
public static AnnotationNode createGrabAnnotation(String group, String module,
String version, String classifier, String type, boolean transitive) {
AnnotationNode annotationNode = new AnnotationNode(new ClassNode(Grab.class));
annotationNode.addMember("group", new ConstantExpression(group));
annotationNode.addMember("module", new ConstantExpression(module));
annotationNode.addMember("version", new ConstantExpression(version));
if (classifier != null) {
annotationNode.addMember("classifier", new ConstantExpression(classifier));
}
if (type != null) {
annotationNode.addMember("type", new ConstantExpression(type));
}
annotationNode.addMember("transitive", new ConstantExpression(transitive));
annotationNode.addMember("initClass", new ConstantExpression(false));
return annotationNode;
}
@Override
public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
imports.addStarImports(DEFAULT_IMPORTS);
new SpringMvcCompilerAutoConfiguration().applyImports(imports);
}
@Override
public void applyToMainClass(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) throws CompilationFailedException {
// if we arrive here then there is no 'Application' class and we need to add one automatically
ClassNode applicationClassNode = new ClassNode("Application", Modifier.PUBLIC, ClassHelper.make("grails.boot.config.GrailsAutoConfiguration"));
AnnotationNode enableAutoAnnotation = new AnnotationNode(ENABLE_AUTO_CONFIGURATION_CLASS_NODE);
try {
enableAutoAnnotation.addMember("exclude", new ClassExpression( ClassHelper.make("org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration")) );
} catch (Throwable e) {
// ignore
}
applicationClassNode.addAnnotation(enableAutoAnnotation);
applicationClassNode.setModule(source.getAST());
applicationClassNode.addMethod("shouldScanDefaultPackage", Modifier.PUBLIC, ClassHelper.Boolean_TYPE, new Parameter[0], null, new ReturnStatement(new ConstantExpression(Boolean.TRUE)));
source.getAST().getClasses().add(0, applicationClassNode);
classNode.addAnnotation(new AnnotationNode(ClassHelper.make("org.grails.boot.internal.EnableAutoConfiguration")));
}
class GrailsDependencies implements DependencyManagement {
private Map groupAndArtifactToDependency = new HashMap();
private Map artifactToGroupAndArtifact = new HashMap();
private List dependencies = new ArrayList();
public GrailsDependencies(List dependencies) {
for (org.eclipse.aether.graph.Dependency dependency : dependencies) {
String groupId = dependency.getArtifact().getGroupId();
String artifactId = dependency.getArtifact().getArtifactId();
String version = dependency.getArtifact().getVersion();
List exclusions = new ArrayList();
Dependency value = new Dependency(groupId, artifactId, version, exclusions);
this.dependencies.add(value);
groupAndArtifactToDependency.put(groupId + ":" + artifactId, value);
artifactToGroupAndArtifact.put(artifactId, groupId + ":" + artifactId);
}
}
// @Override
// public Dependency find(String groupId, String artifactId) {
// return groupAndArtifactToDependency.get(groupId + ":" + artifactId);
// }
@Override
public List getDependencies() {
return dependencies;
}
@Override
public String getSpringBootVersion() {
return find("spring-boot").getVersion();
}
@Override
public Dependency find(String artifactId) {
String groupAndArtifact = artifactToGroupAndArtifact.get(artifactId);
if (groupAndArtifact==null) {
return null;
}
return groupAndArtifactToDependency.get(groupAndArtifact);
}
// @Override
// public Iterator iterator() {
// return groupAndArtifactToDependency.values().iterator();
// }
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy