001/* 002 * Copyright 2012-2016 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.cli.compiler.autoconfigure; 018 019import groovy.lang.GroovyClassLoader; 020import org.codehaus.groovy.ast.AnnotationNode; 021import org.codehaus.groovy.ast.ClassHelper; 022import org.codehaus.groovy.ast.ClassNode; 023import org.codehaus.groovy.classgen.GeneratorContext; 024import org.codehaus.groovy.control.CompilationFailedException; 025import org.codehaus.groovy.control.SourceUnit; 026import org.codehaus.groovy.control.customizers.ImportCustomizer; 027 028import org.springframework.boot.cli.compiler.CompilerAutoConfiguration; 029import org.springframework.boot.cli.compiler.DependencyCustomizer; 030import org.springframework.boot.cli.compiler.GroovyCompilerConfiguration; 031 032/** 033 * {@link CompilerAutoConfiguration} for Spring. 034 * 035 * @author Dave Syer 036 * @author Phillip Webb 037 */ 038public class SpringBootCompilerAutoConfiguration extends CompilerAutoConfiguration { 039 040 @Override 041 public void applyDependencies(DependencyCustomizer dependencies) { 042 dependencies.ifAnyMissingClasses("org.springframework.boot.SpringApplication") 043 .add("spring-boot-starter"); 044 } 045 046 @Override 047 public void applyImports(ImportCustomizer imports) { 048 imports.addImports("javax.annotation.PostConstruct", 049 "javax.annotation.PreDestroy", "groovy.util.logging.Log", 050 "org.springframework.stereotype.Controller", 051 "org.springframework.stereotype.Service", 052 "org.springframework.stereotype.Component", 053 "org.springframework.beans.factory.annotation.Autowired", 054 "org.springframework.beans.factory.annotation.Value", 055 "org.springframework.context.annotation.Import", 056 "org.springframework.context.annotation.ImportResource", 057 "org.springframework.context.annotation.Profile", 058 "org.springframework.context.annotation.Scope", 059 "org.springframework.context.annotation.Configuration", 060 "org.springframework.context.annotation.ComponentScan", 061 "org.springframework.context.annotation.Bean", 062 "org.springframework.context.ApplicationContext", 063 "org.springframework.context.MessageSource", 064 "org.springframework.core.annotation.Order", 065 "org.springframework.core.io.ResourceLoader", 066 "org.springframework.boot.ApplicationRunner", 067 "org.springframework.boot.ApplicationArguments", 068 "org.springframework.boot.CommandLineRunner", 069 "org.springframework.boot.context.properties.ConfigurationProperties", 070 "org.springframework.boot.context.properties.EnableConfigurationProperties", 071 "org.springframework.boot.autoconfigure.EnableAutoConfiguration", 072 "org.springframework.boot.autoconfigure.SpringBootApplication", 073 "org.springframework.boot.context.properties.ConfigurationProperties", 074 "org.springframework.boot.context.properties.EnableConfigurationProperties"); 075 imports.addStarImports("org.springframework.stereotype", 076 "org.springframework.scheduling.annotation"); 077 } 078 079 @Override 080 public void applyToMainClass(GroovyClassLoader loader, 081 GroovyCompilerConfiguration configuration, GeneratorContext generatorContext, 082 SourceUnit source, ClassNode classNode) throws CompilationFailedException { 083 addEnableAutoConfigurationAnnotation(source, classNode); 084 } 085 086 private void addEnableAutoConfigurationAnnotation(SourceUnit source, 087 ClassNode classNode) { 088 if (!hasEnableAutoConfigureAnnotation(classNode)) { 089 AnnotationNode annotationNode = new AnnotationNode( 090 ClassHelper.make("EnableAutoConfiguration")); 091 classNode.addAnnotation(annotationNode); 092 } 093 } 094 095 private boolean hasEnableAutoConfigureAnnotation(ClassNode classNode) { 096 for (AnnotationNode node : classNode.getAnnotations()) { 097 String name = node.getClassNode().getNameWithoutPackage(); 098 if ("EnableAutoConfiguration".equals(name) 099 || "SpringBootApplication".equals(name)) { 100 return true; 101 } 102 } 103 return false; 104 } 105 106}