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;
018
019import groovy.lang.GroovyClassLoader;
020import org.codehaus.groovy.ast.ASTNode;
021import org.codehaus.groovy.ast.ClassNode;
022import org.codehaus.groovy.ast.ModuleNode;
023import org.codehaus.groovy.control.SourceUnit;
024import org.codehaus.groovy.transform.ASTTransformation;
025
026import org.springframework.boot.cli.compiler.grape.DependencyResolutionContext;
027import org.springframework.core.annotation.Order;
028
029/**
030 * {@link ASTTransformation} to apply
031 * {@link CompilerAutoConfiguration#applyDependencies(DependencyCustomizer) dependency
032 * auto-configuration}.
033 *
034 * @author Phillip Webb
035 * @author Dave Syer
036 * @author Andy Wilkinson
037 */
038@Order(DependencyAutoConfigurationTransformation.ORDER)
039public class DependencyAutoConfigurationTransformation implements ASTTransformation {
040
041        /**
042         * The order of the transformation.
043         */
044        public static final int ORDER = DependencyManagementBomTransformation.ORDER + 100;
045
046        private final GroovyClassLoader loader;
047
048        private final DependencyResolutionContext dependencyResolutionContext;
049
050        private final Iterable<CompilerAutoConfiguration> compilerAutoConfigurations;
051
052        public DependencyAutoConfigurationTransformation(GroovyClassLoader loader,
053                        DependencyResolutionContext dependencyResolutionContext,
054                        Iterable<CompilerAutoConfiguration> compilerAutoConfigurations) {
055                this.loader = loader;
056                this.dependencyResolutionContext = dependencyResolutionContext;
057                this.compilerAutoConfigurations = compilerAutoConfigurations;
058
059        }
060
061        @Override
062        public void visit(ASTNode[] nodes, SourceUnit source) {
063                for (ASTNode astNode : nodes) {
064                        if (astNode instanceof ModuleNode) {
065                                visitModule((ModuleNode) astNode);
066                        }
067                }
068        }
069
070        private void visitModule(ModuleNode module) {
071                DependencyCustomizer dependencies = new DependencyCustomizer(this.loader, module,
072                                this.dependencyResolutionContext);
073                for (ClassNode classNode : module.getClasses()) {
074                        for (CompilerAutoConfiguration autoConfiguration : this.compilerAutoConfigurations) {
075                                if (autoConfiguration.matches(classNode)) {
076                                        autoConfiguration.applyDependencies(dependencies);
077                                }
078                        }
079                }
080        }
081
082}