diff --git a/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsApplicationCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsApplicationCompilerAutoConfiguration.java index ed70b6af89..cb852dc591 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsApplicationCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsApplicationCompilerAutoConfiguration.java @@ -35,7 +35,8 @@ import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.control.customizers.ImportCustomizer; -import org.grails.cli.compiler.dependencies.GrailsDependenciesDependencyManagement; +import grails.util.Environment; + import org.grails.cli.compiler.AstUtils; import org.grails.cli.compiler.CompilerAutoConfiguration; import org.grails.cli.compiler.DependencyCustomizer; @@ -43,10 +44,9 @@ 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.dependencies.GrailsDependenciesDependencyManagement; import org.grails.cli.compiler.grape.DependencyResolutionContext; -import grails.util.Environment; - /** * A {@link org.grails.cli.compiler.CompilerAutoConfiguration} for Grails Micro Service applications * diff --git a/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsTestCompilerAutoConfiguration.groovy b/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsTestCompilerAutoConfiguration.groovy index ce13bd92a4..cd6ac062ac 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsTestCompilerAutoConfiguration.groovy +++ b/grails-shell/src/main/groovy/org/grails/cli/boot/GrailsTestCompilerAutoConfiguration.groovy @@ -1,5 +1,5 @@ /* - * Copyright 2014-2022 the original author or authors. + * Copyright 2014-2023 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. @@ -19,12 +19,13 @@ import groovy.transform.CompileStatic import org.codehaus.groovy.ast.ClassNode import org.codehaus.groovy.control.CompilationFailedException import org.codehaus.groovy.control.customizers.ImportCustomizer + +import grails.util.Environment + import org.grails.cli.compiler.AstUtils import org.grails.cli.compiler.CompilerAutoConfiguration import org.grails.cli.compiler.DependencyCustomizer -import grails.util.Environment - /** * @author Graeme Rocher * @since 3.0 diff --git a/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationLauncher.java b/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationLauncher.java index f555bf9f62..df8d075239 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationLauncher.java +++ b/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.boot; import java.lang.reflect.Constructor; @@ -29,58 +28,60 @@ * separate ClassLoader from the application code. * * @author Andy Wilkinson - * @since 1.2.0 * @see System#getProperty(String) * @see System#getenv(String) + * @since 2022.1.0 */ public class SpringApplicationLauncher { - private static final String DEFAULT_SPRING_APPLICATION_CLASS = "grails.boot.Grails"; + private static final String DEFAULT_SPRING_APPLICATION_CLASS = "grails.boot.Grails"; - private final ClassLoader classLoader; + private final ClassLoader classLoader; - /** - * Creates a new launcher that will use the given {@code classLoader} to load the - * configured {@code SpringApplication} class. - * @param classLoader the {@code ClassLoader} to use - */ - public SpringApplicationLauncher(ClassLoader classLoader) { - this.classLoader = classLoader; - } + /** + * Creates a new launcher that will use the given {@code classLoader} to load the + * configured {@code SpringApplication} class. + * + * @param classLoader the {@code ClassLoader} to use + */ + public SpringApplicationLauncher(ClassLoader classLoader) { + this.classLoader = classLoader; + } - /** - * Launches the application created using the given {@code sources}. The application - * is launched with the given {@code args}. - * @param sources the sources for the application - * @param args the args for the application - * @return the application's {@code ApplicationContext} - * @throws Exception if the launch fails - */ - public Object launch(Class[] sources, String[] args) throws Exception { - Map defaultProperties = new HashMap<>(); - defaultProperties.put("spring.groovy.template.check-template-location", "false"); - Class applicationClass = Class.forName(getSpringApplicationClassName(), false, this.classLoader); - Constructor constructor = applicationClass.getDeclaredConstructor(Class[].class); - constructor.setAccessible(true); - Object application = constructor.newInstance((Object) sources); - applicationClass.getMethod("setDefaultProperties", Map.class).invoke(application, defaultProperties); - Method method = applicationClass.getMethod("run", String[].class); - return method.invoke(application, (Object) args); - } + /** + * Launches the application created using the given {@code sources}. The application + * is launched with the given {@code args}. + * + * @param sources the sources for the application + * @param args the args for the application + * @return the application's {@code ApplicationContext} + * @throws Exception if the launch fails + */ + public Object launch(Class[] sources, String[] args) throws Exception { + Map defaultProperties = new HashMap<>(); + defaultProperties.put("spring.groovy.template.check-template-location", "false"); + Class applicationClass = Class.forName(getSpringApplicationClassName(), false, this.classLoader); + Constructor constructor = applicationClass.getDeclaredConstructor(Class[].class); + constructor.setAccessible(true); + Object application = constructor.newInstance((Object) sources); + applicationClass.getMethod("setDefaultProperties", Map.class).invoke(application, defaultProperties); + Method method = applicationClass.getMethod("run", String[].class); + return method.invoke(application, (Object) args); + } - private String getSpringApplicationClassName() { - String className = System.getProperty("spring.application.class.name"); - if (className == null) { - className = getEnvironmentVariable("SPRING_APPLICATION_CLASS_NAME"); - } - if (className == null) { - className = DEFAULT_SPRING_APPLICATION_CLASS; - } - return className; - } + private String getSpringApplicationClassName() { + String className = System.getProperty("spring.application.class.name"); + if (className == null) { + className = getEnvironmentVariable("SPRING_APPLICATION_CLASS_NAME"); + } + if (className == null) { + className = DEFAULT_SPRING_APPLICATION_CLASS; + } + return className; + } - protected String getEnvironmentVariable(String name) { - return System.getenv(name); - } + protected String getEnvironmentVariable(String name) { + return System.getenv(name); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationWebApplicationInitializer.java b/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationWebApplicationInitializer.java index 21c268a871..fbd2338b15 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationWebApplicationInitializer.java +++ b/grails-shell/src/main/groovy/org/grails/cli/boot/SpringApplicationWebApplicationInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.boot; import java.io.IOException; @@ -30,55 +29,55 @@ * {@link SpringBootServletInitializer} for CLI packaged WAR files. * * @author Phillip Webb - * @since 1.3.0 + * @since 2022.1.0 */ public class SpringApplicationWebApplicationInitializer extends SpringBootServletInitializer { - /** - * The entry containing the source class. - */ - public static final String SOURCE_ENTRY = "Spring-Application-Source-Classes"; + /** + * The entry containing the source class. + */ + public static final String SOURCE_ENTRY = "Spring-Application-Source-Classes"; - private String[] sources; + private String[] sources; - @Override - public void onStartup(ServletContext servletContext) throws ServletException { - try { - this.sources = getSources(servletContext); - } - catch (IOException ex) { - throw new IllegalStateException(ex); - } - super.onStartup(servletContext); - } + @Override + public void onStartup(ServletContext servletContext) throws ServletException { + try { + this.sources = getSources(servletContext); + } + catch (IOException ex) { + throw new IllegalStateException(ex); + } + super.onStartup(servletContext); + } - private String[] getSources(ServletContext servletContext) throws IOException { - Manifest manifest = getManifest(servletContext); - if (manifest == null) { - throw new IllegalStateException("Unable to read manifest"); - } - String sources = manifest.getMainAttributes().getValue(SOURCE_ENTRY); - return sources.split(","); - } + private String[] getSources(ServletContext servletContext) throws IOException { + Manifest manifest = getManifest(servletContext); + if (manifest == null) { + throw new IllegalStateException("Unable to read manifest"); + } + String sources = manifest.getMainAttributes().getValue(SOURCE_ENTRY); + return sources.split(","); + } - private Manifest getManifest(ServletContext servletContext) throws IOException { - InputStream stream = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF"); - return (stream != null) ? new Manifest(stream) : null; - } + private Manifest getManifest(ServletContext servletContext) throws IOException { + InputStream stream = servletContext.getResourceAsStream("/META-INF/MANIFEST.MF"); + return (stream != null) ? new Manifest(stream) : null; + } - @Override - protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { - try { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - Class[] sourceClasses = new Class[this.sources.length]; - for (int i = 0; i < this.sources.length; i++) { - sourceClasses[i] = Class.forName(this.sources[i], false, classLoader); - } - return builder.sources(sourceClasses).properties("spring.groovy.template.check-template-location=false"); - } - catch (Exception ex) { - throw new IllegalStateException(ex); - } - } + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { + try { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + Class[] sourceClasses = new Class[this.sources.length]; + for (int i = 0; i < this.sources.length; i++) { + sourceClasses[i] = Class.forName(this.sources[i], false, classLoader); + } + return builder.sources(sourceClasses).properties("spring.groovy.template.check-template-location=false"); + } + catch (Exception ex) { + throw new IllegalStateException(ex); + } + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/command/run/RunCommand.java b/grails-shell/src/main/groovy/org/grails/cli/command/run/RunCommand.java index 6eac618332..979140b698 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/command/run/RunCommand.java +++ b/grails-shell/src/main/groovy/org/grails/cli/command/run/RunCommand.java @@ -22,7 +22,6 @@ import org.grails.cli.compiler.GroovyCompilerScope; import org.grails.cli.compiler.RepositoryConfigurationFactory; import org.grails.cli.compiler.grape.RepositoryConfiguration; - import org.grails.cli.profile.Command; import org.grails.cli.profile.CommandDescription; import org.grails.cli.profile.ExecutionContext; @@ -34,109 +33,110 @@ * @author Dave Syer * @author Andy Wilkinson * @author Michael Yan - * @since 2022.1.0 * @see SpringApplicationRunner + * @since 2022.1.0 */ public class RunCommand implements Command { - public static final String NAME = "run"; - - private final Object monitor = new Object(); - - private SpringApplicationRunner runner; - - public RunCommand() { - } - - @Override - public String getName() { - return NAME; - } - - @Override - public CommandDescription getDescription() { - CommandDescription description = new CommandDescription(); - description.setName(NAME); - description.setDescription("Run a grails groovy script"); - description.setUsage("run [SCRIPT NAME]"); - return description; - } - - @Override - public synchronized boolean handle(ExecutionContext executionContext) { - synchronized (this.monitor) { - String[] sources = executionContext.getCommandLine().getRemainingArgs().toArray(new String[0]); - List repositoryConfiguration = RepositoryConfigurationFactory - .createDefaultRepositoryConfiguration(); - repositoryConfiguration.add(new RepositoryConfiguration("local", new File("repository").toURI(), true)); - - SpringApplicationRunnerConfiguration configuration = new SpringApplicationRunnerConfigurationAdapter( - repositoryConfiguration); - - try { - this.runner = new SpringApplicationRunner(configuration, sources); - this.runner.compileAndRun(); - } - catch (Exception e) { - throw new RuntimeException(e); - } - - return true; - } - } - - static class SpringApplicationRunnerConfigurationAdapter implements SpringApplicationRunnerConfiguration { - - private final List repositoryConfiguration; - - public SpringApplicationRunnerConfigurationAdapter(List repositoryConfiguration) { - this.repositoryConfiguration = repositoryConfiguration; - } - - @Override - public boolean isWatchForFileChanges() { - return true; - } - - @Override - public Level getLogLevel() { - return Level.INFO; - } - - @Override - public GroovyCompilerScope getScope() { - return GroovyCompilerScope.DEFAULT; - } - - @Override - public boolean isGuessImports() { - return true; - } - - @Override - public boolean isGuessDependencies() { - return true; - } - - @Override - public boolean isAutoconfigure() { - return true; - } - - @Override - public String[] getClasspath() { - return new String[0]; - } - - @Override - public List getRepositoryConfiguration() { - return this.repositoryConfiguration; - } - - @Override - public boolean isQuiet() { - return false; - } - - } + public static final String NAME = "run"; + + private final Object monitor = new Object(); + + private SpringApplicationRunner runner; + + public RunCommand() { + } + + @Override + public String getName() { + return NAME; + } + + @Override + public CommandDescription getDescription() { + CommandDescription description = new CommandDescription(); + description.setName(NAME); + description.setDescription("Run a grails groovy script"); + description.setUsage("run [SCRIPT NAME]"); + return description; + } + + @Override + public synchronized boolean handle(ExecutionContext executionContext) { + synchronized (this.monitor) { + String[] sources = executionContext.getCommandLine().getRemainingArgs().toArray(new String[0]); + List repositoryConfiguration = RepositoryConfigurationFactory + .createDefaultRepositoryConfiguration(); + repositoryConfiguration.add(new RepositoryConfiguration("local", new File("repository").toURI(), true)); + + SpringApplicationRunnerConfiguration configuration = new SpringApplicationRunnerConfigurationAdapter( + repositoryConfiguration); + + try { + this.runner = new SpringApplicationRunner(configuration, sources); + this.runner.compileAndRun(); + } + catch (Exception e) { + throw new RuntimeException(e); + } + + return true; + } + } + + static class SpringApplicationRunnerConfigurationAdapter implements SpringApplicationRunnerConfiguration { + + private final List repositoryConfiguration; + + SpringApplicationRunnerConfigurationAdapter(List repositoryConfiguration) { + this.repositoryConfiguration = repositoryConfiguration; + } + + @Override + public boolean isWatchForFileChanges() { + return true; + } + + @Override + public Level getLogLevel() { + return Level.INFO; + } + + @Override + public GroovyCompilerScope getScope() { + return GroovyCompilerScope.DEFAULT; + } + + @Override + public boolean isGuessImports() { + return true; + } + + @Override + public boolean isGuessDependencies() { + return true; + } + + @Override + public boolean isAutoconfigure() { + return true; + } + + @Override + public String[] getClasspath() { + return new String[0]; + } + + @Override + public List getRepositoryConfiguration() { + return this.repositoryConfiguration; + } + + @Override + public boolean isQuiet() { + return false; + } + + } + } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/AnnotatedNodeASTTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/AnnotatedNodeASTTransformation.java index 8e77f84700..e28f5f9f1a 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/AnnotatedNodeASTTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/AnnotatedNodeASTTransformation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.util.ArrayList; @@ -36,91 +35,91 @@ * interested in {@link AnnotatedNode AnnotatedNodes}. * * @author Andy Wilkinson - * @since 1.1.0 + * @since 2022.1.0 */ public abstract class AnnotatedNodeASTTransformation implements ASTTransformation { - private final Set interestingAnnotationNames; - - private final boolean removeAnnotations; - - private SourceUnit sourceUnit; - - protected AnnotatedNodeASTTransformation(Set interestingAnnotationNames, boolean removeAnnotations) { - this.interestingAnnotationNames = interestingAnnotationNames; - this.removeAnnotations = removeAnnotations; - } - - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - this.sourceUnit = source; - List annotationNodes = new ArrayList<>(); - ClassVisitor classVisitor = new ClassVisitor(source, annotationNodes); - for (ASTNode node : nodes) { - if (node instanceof ModuleNode) { - ModuleNode module = (ModuleNode) node; - visitAnnotatedNode(module.getPackage(), annotationNodes); - for (ImportNode importNode : module.getImports()) { - visitAnnotatedNode(importNode, annotationNodes); - } - for (ImportNode importNode : module.getStarImports()) { - visitAnnotatedNode(importNode, annotationNodes); - } - module.getStaticImports() - .forEach((name, importNode) -> visitAnnotatedNode(importNode, annotationNodes)); - module.getStaticStarImports() - .forEach((name, importNode) -> visitAnnotatedNode(importNode, annotationNodes)); - for (ClassNode classNode : module.getClasses()) { - visitAnnotatedNode(classNode, annotationNodes); - classNode.visitContents(classVisitor); - } - } - } - processAnnotationNodes(annotationNodes); - } - - protected SourceUnit getSourceUnit() { - return this.sourceUnit; - } - - protected abstract void processAnnotationNodes(List annotationNodes); - - private void visitAnnotatedNode(AnnotatedNode annotatedNode, List annotatedNodes) { - if (annotatedNode != null) { - Iterator annotationNodes = annotatedNode.getAnnotations().iterator(); - while (annotationNodes.hasNext()) { - AnnotationNode annotationNode = annotationNodes.next(); - if (this.interestingAnnotationNames.contains(annotationNode.getClassNode().getName())) { - annotatedNodes.add(annotationNode); - if (this.removeAnnotations) { - annotationNodes.remove(); - } - } - } - } - } - - private class ClassVisitor extends ClassCodeVisitorSupport { - - private final SourceUnit source; - - private final List annotationNodes; - - ClassVisitor(SourceUnit source, List annotationNodes) { - this.source = source; - this.annotationNodes = annotationNodes; - } - - @Override - protected SourceUnit getSourceUnit() { - return this.source; - } - - @Override - public void visitAnnotations(AnnotatedNode node) { - visitAnnotatedNode(node, this.annotationNodes); - } - - } + private final Set interestingAnnotationNames; + + private final boolean removeAnnotations; + + private SourceUnit sourceUnit; + + protected AnnotatedNodeASTTransformation(Set interestingAnnotationNames, boolean removeAnnotations) { + this.interestingAnnotationNames = interestingAnnotationNames; + this.removeAnnotations = removeAnnotations; + } + + @Override + public void visit(ASTNode[] nodes, SourceUnit source) { + this.sourceUnit = source; + List annotationNodes = new ArrayList<>(); + ClassVisitor classVisitor = new ClassVisitor(source, annotationNodes); + for (ASTNode node : nodes) { + if (node instanceof ModuleNode) { + ModuleNode module = (ModuleNode) node; + visitAnnotatedNode(module.getPackage(), annotationNodes); + for (ImportNode importNode : module.getImports()) { + visitAnnotatedNode(importNode, annotationNodes); + } + for (ImportNode importNode : module.getStarImports()) { + visitAnnotatedNode(importNode, annotationNodes); + } + module.getStaticImports() + .forEach((name, importNode) -> visitAnnotatedNode(importNode, annotationNodes)); + module.getStaticStarImports() + .forEach((name, importNode) -> visitAnnotatedNode(importNode, annotationNodes)); + for (ClassNode classNode : module.getClasses()) { + visitAnnotatedNode(classNode, annotationNodes); + classNode.visitContents(classVisitor); + } + } + } + processAnnotationNodes(annotationNodes); + } + + protected SourceUnit getSourceUnit() { + return this.sourceUnit; + } + + protected abstract void processAnnotationNodes(List annotationNodes); + + private void visitAnnotatedNode(AnnotatedNode annotatedNode, List annotatedNodes) { + if (annotatedNode != null) { + Iterator annotationNodes = annotatedNode.getAnnotations().iterator(); + while (annotationNodes.hasNext()) { + AnnotationNode annotationNode = annotationNodes.next(); + if (this.interestingAnnotationNames.contains(annotationNode.getClassNode().getName())) { + annotatedNodes.add(annotationNode); + if (this.removeAnnotations) { + annotationNodes.remove(); + } + } + } + } + } + + private class ClassVisitor extends ClassCodeVisitorSupport { + + private final SourceUnit source; + + private final List annotationNodes; + + ClassVisitor(SourceUnit source, List annotationNodes) { + this.source = source; + this.annotationNodes = annotationNodes; + } + + @Override + protected SourceUnit getSourceUnit() { + return this.source; + } + + @Override + public void visitAnnotations(AnnotatedNode node) { + visitAnnotatedNode(node, this.annotationNodes); + } + + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/AstUtils.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/AstUtils.java index 98ade922b0..8b80ffdca7 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/AstUtils.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/AstUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -35,7 +35,6 @@ import org.codehaus.groovy.ast.stmt.BlockStatement; import org.codehaus.groovy.ast.stmt.ExpressionStatement; import org.codehaus.groovy.ast.stmt.Statement; - import org.springframework.util.PatternMatchUtils; /** @@ -48,140 +47,145 @@ */ public abstract class AstUtils { - /** - * Determine if a {@link ClassNode} has one or more of the specified annotations on - * the class or any of its methods. N.B. the type names are not normally fully - * qualified. - * @param node the class to examine - * @param annotations the annotations to look for - * @return {@code true} if at least one of the annotations is found, otherwise - * {@code false} - */ - public static boolean hasAtLeastOneAnnotation(ClassNode node, String... annotations) { - if (hasAtLeastOneAnnotation((AnnotatedNode) node, annotations)) { - return true; - } - for (MethodNode method : node.getMethods()) { - if (hasAtLeastOneAnnotation(method, annotations)) { - return true; - } - } - return false; - } + /** + * Determine if a {@link ClassNode} has one or more of the specified annotations on + * the class or any of its methods. N.B. the type names are not normally fully + * qualified. + * + * @param node the class to examine + * @param annotations the annotations to look for + * @return {@code true} if at least one of the annotations is found, otherwise + * {@code false} + */ + public static boolean hasAtLeastOneAnnotation(ClassNode node, String... annotations) { + if (hasAtLeastOneAnnotation((AnnotatedNode) node, annotations)) { + return true; + } + for (MethodNode method : node.getMethods()) { + if (hasAtLeastOneAnnotation(method, annotations)) { + return true; + } + } + return false; + } - /** - * Determine if an {@link AnnotatedNode} has one or more of the specified annotations. - * N.B. the annotation type names are not normally fully qualified. - * @param node the node to examine - * @param annotations the annotations to look for - * @return {@code true} if at least one of the annotations is found, otherwise - * {@code false} - */ - public static boolean hasAtLeastOneAnnotation(AnnotatedNode node, String... annotations) { - for (AnnotationNode annotationNode : node.getAnnotations()) { - for (String annotation : annotations) { - if (PatternMatchUtils.simpleMatch(annotation, annotationNode.getClassNode().getName())) { - return true; - } - } - } - return false; - } + /** + * Determine if an {@link AnnotatedNode} has one or more of the specified annotations. + * N.B. the annotation type names are not normally fully qualified. + * + * @param node the node to examine + * @param annotations the annotations to look for + * @return {@code true} if at least one of the annotations is found, otherwise + * {@code false} + */ + public static boolean hasAtLeastOneAnnotation(AnnotatedNode node, String... annotations) { + for (AnnotationNode annotationNode : node.getAnnotations()) { + for (String annotation : annotations) { + if (PatternMatchUtils.simpleMatch(annotation, annotationNode.getClassNode().getName())) { + return true; + } + } + } + return false; + } - /** - * Determine if a {@link ClassNode} has one or more fields of the specified types or - * method returning one or more of the specified types. N.B. the type names are not - * normally fully qualified. - * @param node the class to examine - * @param types the types to look for - * @return {@code true} if at least one of the types is found, otherwise {@code false} - */ - public static boolean hasAtLeastOneFieldOrMethod(ClassNode node, String... types) { - Set typesSet = new HashSet<>(Arrays.asList(types)); - for (FieldNode field : node.getFields()) { - if (typesSet.contains(field.getType().getName())) { - return true; - } - } - for (MethodNode method : node.getMethods()) { - if (typesSet.contains(method.getReturnType().getName())) { - return true; - } - } - return false; - } + /** + * Determine if a {@link ClassNode} has one or more fields of the specified types or + * method returning one or more of the specified types. N.B. the type names are not + * normally fully qualified. + * + * @param node the class to examine + * @param types the types to look for + * @return {@code true} if at least one of the types is found, otherwise {@code false} + */ + public static boolean hasAtLeastOneFieldOrMethod(ClassNode node, String... types) { + Set typesSet = new HashSet<>(Arrays.asList(types)); + for (FieldNode field : node.getFields()) { + if (typesSet.contains(field.getType().getName())) { + return true; + } + } + for (MethodNode method : node.getMethods()) { + if (typesSet.contains(method.getReturnType().getName())) { + return true; + } + } + return false; + } - /** - * Determine if a {@link ClassNode} subclasses any of the specified types N.B. the - * type names are not normally fully qualified. - * @param node the class to examine - * @param types the types that may have been sub-classed - * @return {@code true} if the class subclasses any of the specified types, otherwise - * {@code false} - */ - public static boolean subclasses(ClassNode node, String... types) { - for (String type : types) { - if (node.getSuperClass().getName().equals(type)) { - return true; - } - } - return false; - } + /** + * Determine if a {@link ClassNode} subclasses any of the specified types N.B. the + * type names are not normally fully qualified. + * + * @param node the class to examine + * @param types the types that may have been sub-classed + * @return {@code true} if the class subclasses any of the specified types, otherwise + * {@code false} + */ + public static boolean subclasses(ClassNode node, String... types) { + for (String type : types) { + if (node.getSuperClass().getName().equals(type)) { + return true; + } + } + return false; + } - public static boolean hasAtLeastOneInterface(ClassNode classNode, String... types) { - Set typesSet = new HashSet<>(Arrays.asList(types)); - for (ClassNode inter : classNode.getInterfaces()) { - if (typesSet.contains(inter.getName())) { - return true; - } - } - return false; - } + public static boolean hasAtLeastOneInterface(ClassNode classNode, String... types) { + Set typesSet = new HashSet<>(Arrays.asList(types)); + for (ClassNode inter : classNode.getInterfaces()) { + if (typesSet.contains(inter.getName())) { + return true; + } + } + return false; + } - /** - * Extract a top-level {@code name} closure from inside this block if there is one, - * optionally removing it from the block at the same time. - * @param block a block statement (class definition) - * @param name the name to look for - * @param remove whether the extracted closure should be removed - * @return a beans Closure if one can be found, null otherwise - */ - public static ClosureExpression getClosure(BlockStatement block, String name, boolean remove) { - for (ExpressionStatement statement : getExpressionStatements(block)) { - Expression expression = statement.getExpression(); - if (expression instanceof MethodCallExpression) { - ClosureExpression closure = getClosure(name, (MethodCallExpression) expression); - if (closure != null) { - if (remove) { - block.getStatements().remove(statement); - } - return closure; - } - } - } - return null; - } + /** + * Extract a top-level {@code name} closure from inside this block if there is one, + * optionally removing it from the block at the same time. + * + * @param block a block statement (class definition) + * @param name the name to look for + * @param remove whether the extracted closure should be removed + * @return a beans Closure if one can be found, null otherwise + */ + public static ClosureExpression getClosure(BlockStatement block, String name, boolean remove) { + for (ExpressionStatement statement : getExpressionStatements(block)) { + Expression expression = statement.getExpression(); + if (expression instanceof MethodCallExpression) { + ClosureExpression closure = getClosure(name, (MethodCallExpression) expression); + if (closure != null) { + if (remove) { + block.getStatements().remove(statement); + } + return closure; + } + } + } + return null; + } - private static List getExpressionStatements(BlockStatement block) { - List statements = new ArrayList<>(); - for (Statement statement : block.getStatements()) { - if (statement instanceof ExpressionStatement) { - statements.add((ExpressionStatement) statement); - } - } - return statements; - } + private static List getExpressionStatements(BlockStatement block) { + List statements = new ArrayList<>(); + for (Statement statement : block.getStatements()) { + if (statement instanceof ExpressionStatement) { + statements.add((ExpressionStatement) statement); + } + } + return statements; + } - private static ClosureExpression getClosure(String name, MethodCallExpression expression) { - Expression method = expression.getMethod(); - if (method instanceof ConstantExpression && name.equals(((ConstantExpression) method).getValue())) { - return (ClosureExpression) ((ArgumentListExpression) expression.getArguments()).getExpression(0); - } - return null; - } + private static ClosureExpression getClosure(String name, MethodCallExpression expression) { + Expression method = expression.getMethod(); + if (method instanceof ConstantExpression && name.equals(((ConstantExpression) method).getValue())) { + return (ClosureExpression) ((ArgumentListExpression) expression.getArguments()).getExpression(0); + } + return null; + } - public static ClosureExpression getClosure(BlockStatement block, String name) { - return getClosure(block, name, false); - } + public static ClosureExpression getClosure(BlockStatement block, String name) { + return getClosure(block, name, false); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/CompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/CompilerAutoConfiguration.java index 587b8dd379..45e42acfd1 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/CompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/CompilerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import groovy.lang.GroovyClassLoader; @@ -29,67 +28,72 @@ * {@link CompilePhase#CONVERSION} Groovy compile phase. * * @author Phillip Webb - * @since 1.0.0 + * @since 2022.1.0 */ public abstract class CompilerAutoConfiguration { - /** - * Strategy method used to determine when compiler auto-configuration should be - * applied. Defaults to always. - * @param classNode the class node - * @return {@code true} if the compiler should be auto-configured using this class. If - * this method returns {@code false} no other strategy methods will be called. - */ - public boolean matches(ClassNode classNode) { - return true; - } + /** + * Strategy method used to determine when compiler auto-configuration should be + * applied. Defaults to always. + * + * @param classNode the class node + * @return {@code true} if the compiler should be auto-configured using this class. If + * this method returns {@code false} no other strategy methods will be called. + */ + public boolean matches(ClassNode classNode) { + return true; + } - /** - * Apply any dependency customizations. This method will only be called if - * {@link #matches} returns {@code true}. - * @param dependencies dependency customizer - * @throws CompilationFailedException if the dependencies cannot be applied - */ - public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { - } + /** + * Apply any dependency customizations. This method will only be called if + * {@link #matches} returns {@code true}. + * + * @param dependencies dependency customizer + * @throws CompilationFailedException if the dependencies cannot be applied + */ + public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { + } - /** - * Apply any import customizations. This method will only be called if - * {@link #matches} returns {@code true}. - * @param imports import customizer - * @throws CompilationFailedException if the imports cannot be applied - */ - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - } + /** + * Apply any import customizations. This method will only be called if + * {@link #matches} returns {@code true}. + * + * @param imports import customizer + * @throws CompilationFailedException if the imports cannot be applied + */ + public void applyImports(ImportCustomizer imports) throws CompilationFailedException { + } - /** - * Apply any customizations to the main class. This method will only be called if - * {@link #matches} returns {@code true}. This method is useful when a groovy file - * defines more than one class but customization only applies to the first class. - * @param loader the class loader being used during compilation - * @param configuration the compiler configuration - * @param generatorContext the current context - * @param source the source unit - * @param classNode the main class - * @throws CompilationFailedException if the customizations cannot be applied - */ - public void applyToMainClass(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - } + /** + * Apply any customizations to the main class. This method will only be called if + * {@link #matches} returns {@code true}. This method is useful when a groovy file + * defines more than one class but customization only applies to the first class. + * + * @param loader the class loader being used during compilation + * @param configuration the compiler configuration + * @param generatorContext the current context + * @param source the source unit + * @param classNode the main class + * @throws CompilationFailedException if the customizations cannot be applied + */ + public void applyToMainClass(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, + GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) + throws CompilationFailedException { + } - /** - * Apply any additional configuration. - * @param loader the class loader being used during compilation - * @param configuration the compiler configuration - * @param generatorContext the current context - * @param source the source unit - * @param classNode the class - * @throws CompilationFailedException if the configuration cannot be applied - */ - public void apply(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - } + /** + * Apply any additional configuration. + * + * @param loader the class loader being used during compilation + * @param configuration the compiler configuration + * @param generatorContext the current context + * @param source the source unit + * @param classNode the class + * @throws CompilationFailedException if the configuration cannot be applied + */ + public void apply(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, + GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) + throws CompilationFailedException { + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyAutoConfigurationTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyAutoConfigurationTransformation.java index f83dd52ec3..04f383777a 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyAutoConfigurationTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyAutoConfigurationTransformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import groovy.lang.GroovyClassLoader; @@ -22,9 +21,9 @@ import org.codehaus.groovy.ast.ModuleNode; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.transform.ASTTransformation; +import org.springframework.core.annotation.Order; import org.grails.cli.compiler.grape.DependencyResolutionContext; -import org.springframework.core.annotation.Order; /** * {@link ASTTransformation} to apply @@ -34,50 +33,50 @@ * @author Phillip Webb * @author Dave Syer * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ @Order(DependencyAutoConfigurationTransformation.ORDER) public class DependencyAutoConfigurationTransformation implements ASTTransformation { - /** - * The order of the transformation. - */ - public static final int ORDER = DependencyManagementBomTransformation.ORDER + 100; + /** + * The order of the transformation. + */ + public static final int ORDER = DependencyManagementBomTransformation.ORDER + 100; - private final GroovyClassLoader loader; + private final GroovyClassLoader loader; - private final DependencyResolutionContext dependencyResolutionContext; + private final DependencyResolutionContext dependencyResolutionContext; - private final Iterable compilerAutoConfigurations; + private final Iterable compilerAutoConfigurations; - public DependencyAutoConfigurationTransformation(GroovyClassLoader loader, - DependencyResolutionContext dependencyResolutionContext, - Iterable compilerAutoConfigurations) { - this.loader = loader; - this.dependencyResolutionContext = dependencyResolutionContext; - this.compilerAutoConfigurations = compilerAutoConfigurations; + public DependencyAutoConfigurationTransformation(GroovyClassLoader loader, + DependencyResolutionContext dependencyResolutionContext, + Iterable compilerAutoConfigurations) { + this.loader = loader; + this.dependencyResolutionContext = dependencyResolutionContext; + this.compilerAutoConfigurations = compilerAutoConfigurations; - } + } - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - for (ASTNode astNode : nodes) { - if (astNode instanceof ModuleNode) { - visitModule((ModuleNode) astNode); - } - } - } + @Override + public void visit(ASTNode[] nodes, SourceUnit source) { + for (ASTNode astNode : nodes) { + if (astNode instanceof ModuleNode) { + visitModule((ModuleNode) astNode); + } + } + } - private void visitModule(ModuleNode module) { - DependencyCustomizer dependencies = new DependencyCustomizer(this.loader, module, - this.dependencyResolutionContext); - for (ClassNode classNode : module.getClasses()) { - for (CompilerAutoConfiguration autoConfiguration : this.compilerAutoConfigurations) { - if (autoConfiguration.matches(classNode)) { - autoConfiguration.applyDependencies(dependencies); - } - } - } - } + private void visitModule(ModuleNode module) { + DependencyCustomizer dependencies = new DependencyCustomizer(this.loader, module, + this.dependencyResolutionContext); + for (ClassNode classNode : module.getClasses()) { + for (CompilerAutoConfiguration autoConfiguration : this.compilerAutoConfigurations) { + if (autoConfiguration.matches(classNode)) { + autoConfiguration.applyDependencies(dependencies); + } + } + } + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyCustomizer.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyCustomizer.java index 3a2521f47a..deaef05764 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyCustomizer.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyCustomizer.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import groovy.lang.Grab; @@ -36,227 +35,238 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ public class DependencyCustomizer { - private final GroovyClassLoader loader; + private final GroovyClassLoader loader; - private final ClassNode classNode; + private final ClassNode classNode; - private final DependencyResolutionContext dependencyResolutionContext; + private final DependencyResolutionContext dependencyResolutionContext; - /** - * Create a new {@link DependencyCustomizer} instance. - * @param loader the current classloader - * @param moduleNode the current module - * @param dependencyResolutionContext the context for dependency resolution - */ - public DependencyCustomizer(GroovyClassLoader loader, ModuleNode moduleNode, - DependencyResolutionContext dependencyResolutionContext) { - this.loader = loader; - this.classNode = moduleNode.getClasses().get(0); - this.dependencyResolutionContext = dependencyResolutionContext; - } + /** + * Create a new {@link DependencyCustomizer} instance. + * + * @param loader the current classloader + * @param moduleNode the current module + * @param dependencyResolutionContext the context for dependency resolution + */ + public DependencyCustomizer(GroovyClassLoader loader, ModuleNode moduleNode, + DependencyResolutionContext dependencyResolutionContext) { + this.loader = loader; + this.classNode = moduleNode.getClasses().get(0); + this.dependencyResolutionContext = dependencyResolutionContext; + } - /** - * Create a new nested {@link DependencyCustomizer}. - * @param parent the parent customizer - */ - protected DependencyCustomizer(DependencyCustomizer parent) { - this.loader = parent.loader; - this.classNode = parent.classNode; - this.dependencyResolutionContext = parent.dependencyResolutionContext; - } + /** + * Create a new nested {@link DependencyCustomizer}. + * + * @param parent the parent customizer + */ + protected DependencyCustomizer(DependencyCustomizer parent) { + this.loader = parent.loader; + this.classNode = parent.classNode; + this.dependencyResolutionContext = parent.dependencyResolutionContext; + } - public String getVersion(String artifactId) { - return getVersion(artifactId, ""); - } + public String getVersion(String artifactId) { + return getVersion(artifactId, ""); + } - public String getVersion(String artifactId, String defaultVersion) { - String version = this.dependencyResolutionContext.getArtifactCoordinatesResolver().getVersion(artifactId); - if (version == null) { - version = defaultVersion; - } - return version; - } + public String getVersion(String artifactId, String defaultVersion) { + String version = this.dependencyResolutionContext.getArtifactCoordinatesResolver().getVersion(artifactId); + if (version == null) { + version = defaultVersion; + } + return version; + } - /** - * Create a nested {@link DependencyCustomizer} that only applies if any of the - * specified class names are not on the class path. - * @param classNames the class names to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAnyMissingClasses(String... classNames) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String className : classNames) { - try { - Class.forName(className, false, DependencyCustomizer.this.loader); - } - catch (Exception ex) { - return true; - } - } - return false; - } - }; - } + /** + * Create a nested {@link DependencyCustomizer} that only applies if any of the + * specified class names are not on the class path. + * + * @param classNames the class names to test + * @return a nested {@link DependencyCustomizer} + */ + public DependencyCustomizer ifAnyMissingClasses(String... classNames) { + return new DependencyCustomizer(this) { + @Override + protected boolean canAdd() { + for (String className : classNames) { + try { + Class.forName(className, false, DependencyCustomizer.this.loader); + } + catch (Exception ex) { + return true; + } + } + return false; + } + }; + } - /** - * Create a nested {@link DependencyCustomizer} that only applies if all the specified - * class names are not on the class path. - * @param classNames the class names to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAllMissingClasses(String... classNames) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String className : classNames) { - try { - Class.forName(className, false, DependencyCustomizer.this.loader); - return false; - } - catch (Exception ex) { - // swallow exception and continue - } - } - return DependencyCustomizer.this.canAdd(); - } - }; - } + /** + * Create a nested {@link DependencyCustomizer} that only applies if all the specified + * class names are not on the class path. + * + * @param classNames the class names to test + * @return a nested {@link DependencyCustomizer} + */ + public DependencyCustomizer ifAllMissingClasses(String... classNames) { + return new DependencyCustomizer(this) { + @Override + protected boolean canAdd() { + for (String className : classNames) { + try { + Class.forName(className, false, DependencyCustomizer.this.loader); + return false; + } + catch (Exception ex) { + // swallow exception and continue + } + } + return DependencyCustomizer.this.canAdd(); + } + }; + } - /** - * Create a nested {@link DependencyCustomizer} that only applies if the specified - * paths are on the class path. - * @param paths the paths to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAllResourcesPresent(String... paths) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String path : paths) { - try { - if (DependencyCustomizer.this.loader.getResource(path) == null) { - return false; - } - } - catch (Exception ex) { - // swallow exception and continue - } - } - return DependencyCustomizer.this.canAdd(); - } - }; - } + /** + * Create a nested {@link DependencyCustomizer} that only applies if the specified + * paths are on the class path. + * + * @param paths the paths to test + * @return a nested {@link DependencyCustomizer} + */ + public DependencyCustomizer ifAllResourcesPresent(String... paths) { + return new DependencyCustomizer(this) { + @Override + protected boolean canAdd() { + for (String path : paths) { + try { + if (DependencyCustomizer.this.loader.getResource(path) == null) { + return false; + } + } + catch (Exception ex) { + // swallow exception and continue + } + } + return DependencyCustomizer.this.canAdd(); + } + }; + } - /** - * Create a nested {@link DependencyCustomizer} that only applies at least one of the - * specified paths is on the class path. - * @param paths the paths to test - * @return a nested {@link DependencyCustomizer} - */ - public DependencyCustomizer ifAnyResourcesPresent(String... paths) { - return new DependencyCustomizer(this) { - @Override - protected boolean canAdd() { - for (String path : paths) { - try { - return DependencyCustomizer.this.loader.getResource(path) != null; - } - catch (Exception ex) { - // swallow exception and continue - } - } - return DependencyCustomizer.this.canAdd(); - } - }; - } + /** + * Create a nested {@link DependencyCustomizer} that only applies at least one of the + * specified paths is on the class path. + * + * @param paths the paths to test + * @return a nested {@link DependencyCustomizer} + */ + public DependencyCustomizer ifAnyResourcesPresent(String... paths) { + return new DependencyCustomizer(this) { + @Override + protected boolean canAdd() { + for (String path : paths) { + try { + return DependencyCustomizer.this.loader.getResource(path) != null; + } + catch (Exception ex) { + // swallow exception and continue + } + } + return DependencyCustomizer.this.canAdd(); + } + }; + } - /** - * Add dependencies and all of their dependencies. The group ID and version of the - * dependencies are resolved from the modules using the customizer's - * {@link ArtifactCoordinatesResolver}. - * @param modules the module IDs - * @return this {@link DependencyCustomizer} for continued use - */ - public DependencyCustomizer add(String... modules) { - for (String module : modules) { - add(module, null, null, true); - } - return this; - } + /** + * Add dependencies and all of their dependencies. The group ID and version of the + * dependencies are resolved from the modules using the customizer's + * {@link ArtifactCoordinatesResolver}. + * + * @param modules the module IDs + * @return this {@link DependencyCustomizer} for continued use + */ + public DependencyCustomizer add(String... modules) { + for (String module : modules) { + add(module, null, null, true); + } + return this; + } - /** - * Add a single dependency and, optionally, all of its dependencies. The group ID and - * version of the dependency are resolved from the module using the customizer's - * {@link ArtifactCoordinatesResolver}. - * @param module the module ID - * @param transitive {@code true} if the transitive dependencies should also be added, - * otherwise {@code false} - * @return this {@link DependencyCustomizer} for continued use - */ - public DependencyCustomizer add(String module, boolean transitive) { - return add(module, null, null, transitive); - } + /** + * Add a single dependency and, optionally, all of its dependencies. The group ID and + * version of the dependency are resolved from the module using the customizer's + * {@link ArtifactCoordinatesResolver}. + * + * @param module the module ID + * @param transitive {@code true} if the transitive dependencies should also be added, + * otherwise {@code false} + * @return this {@link DependencyCustomizer} for continued use + */ + public DependencyCustomizer add(String module, boolean transitive) { + return add(module, null, null, transitive); + } - /** - * Add a single dependency with the specified classifier and type and, optionally, all - * of its dependencies. The group ID and version of the dependency are resolved from - * the module by using the customizer's {@link ArtifactCoordinatesResolver}. - * @param module the module ID - * @param classifier the classifier, may be {@code null} - * @param type the type, may be {@code null} - * @param transitive {@code true} if the transitive dependencies should also be added, - * otherwise {@code false} - * @return this {@link DependencyCustomizer} for continued use - */ - public DependencyCustomizer add(String module, String classifier, String type, boolean transitive) { - if (canAdd()) { - ArtifactCoordinatesResolver artifactCoordinatesResolver = this.dependencyResolutionContext - .getArtifactCoordinatesResolver(); - this.classNode.addAnnotation(createGrabAnnotation(artifactCoordinatesResolver.getGroupId(module), - artifactCoordinatesResolver.getArtifactId(module), artifactCoordinatesResolver.getVersion(module), - classifier, type, transitive)); - } - return this; - } + /** + * Add a single dependency with the specified classifier and type and, optionally, all + * of its dependencies. The group ID and version of the dependency are resolved from + * the module by using the customizer's {@link ArtifactCoordinatesResolver}. + * + * @param module the module ID + * @param classifier the classifier, may be {@code null} + * @param type the type, may be {@code null} + * @param transitive {@code true} if the transitive dependencies should also be added, + * otherwise {@code false} + * @return this {@link DependencyCustomizer} for continued use + */ + public DependencyCustomizer add(String module, String classifier, String type, boolean transitive) { + if (canAdd()) { + ArtifactCoordinatesResolver artifactCoordinatesResolver = this.dependencyResolutionContext + .getArtifactCoordinatesResolver(); + this.classNode.addAnnotation(createGrabAnnotation(artifactCoordinatesResolver.getGroupId(module), + artifactCoordinatesResolver.getArtifactId(module), artifactCoordinatesResolver.getVersion(module), + classifier, type, transitive)); + } + return this; + } - private 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; - } + private 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; + } - /** - * Strategy called to test if dependencies can be added. Subclasses override as - * required. Returns {@code true} by default. - * @return {@code true} if dependencies can be added, otherwise {@code false} - */ - protected boolean canAdd() { - return true; - } + /** + * Strategy called to test if dependencies can be added. Subclasses override as + * required. Returns {@code true} by default. + * + * @return {@code true} if dependencies can be added, otherwise {@code false} + */ + protected boolean canAdd() { + return true; + } - /** - * Returns the {@link DependencyResolutionContext}. - * @return the dependency resolution context - */ - public DependencyResolutionContext getDependencyResolutionContext() { - return this.dependencyResolutionContext; - } + /** + * Returns the {@link DependencyResolutionContext}. + * + * @return the dependency resolution context + */ + public DependencyResolutionContext getDependencyResolutionContext() { + return this.dependencyResolutionContext; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyManagementBomTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyManagementBomTransformation.java index ca66af1983..2dfd22094e 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyManagementBomTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/DependencyManagementBomTransformation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.net.MalformedURLException; @@ -47,195 +46,195 @@ import org.codehaus.groovy.control.messages.SyntaxErrorMessage; import org.codehaus.groovy.syntax.SyntaxException; import org.codehaus.groovy.transform.ASTTransformation; +import org.springframework.core.Ordered; +import org.springframework.core.annotation.Order; import org.grails.cli.compiler.dependencies.MavenModelDependencyManagement; import org.grails.cli.compiler.grape.DependencyResolutionContext; import org.grails.cli.groovy.DependencyManagementBom; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; /** * {@link ASTTransformation} for processing * {@link DependencyManagementBom @DependencyManagementBom} annotations. * * @author Andy Wilkinson - * @since 1.3.0 + * @since 2022.1.0 */ @Order(DependencyManagementBomTransformation.ORDER) @SuppressWarnings("deprecation") public class DependencyManagementBomTransformation extends AnnotatedNodeASTTransformation { - /** - * The order of the transformation. - */ - public static final int ORDER = Ordered.HIGHEST_PRECEDENCE + 100; - - private static final Set DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES = Collections - .unmodifiableSet(new HashSet<>( - Arrays.asList(DependencyManagementBom.class.getName(), DependencyManagementBom.class.getSimpleName()))); - - private final DependencyResolutionContext resolutionContext; - - public DependencyManagementBomTransformation(DependencyResolutionContext resolutionContext) { - super(DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES, true); - this.resolutionContext = resolutionContext; - } - - @Override - protected void processAnnotationNodes(List annotationNodes) { - if (!annotationNodes.isEmpty()) { - if (annotationNodes.size() > 1) { - for (AnnotationNode annotationNode : annotationNodes) { - handleDuplicateDependencyManagementBomAnnotation(annotationNode); - } - } - else { - processDependencyManagementBomAnnotation(annotationNodes.get(0)); - } - } - } - - private void processDependencyManagementBomAnnotation(AnnotationNode annotationNode) { - Expression valueExpression = annotationNode.getMember("value"); - List> bomDependencies = createDependencyMaps(valueExpression); - updateDependencyResolutionContext(bomDependencies); - } - - private List> createDependencyMaps(Expression valueExpression) { - Map dependency = null; - List constantExpressions = getConstantExpressions(valueExpression); - List> dependencies = new ArrayList<>(constantExpressions.size()); - for (ConstantExpression expression : constantExpressions) { - Object value = expression.getValue(); - if (value instanceof String) { - String[] components = ((String) expression.getValue()).split(":"); - if (components.length == 3) { - dependency = new HashMap<>(); - dependency.put("group", components[0]); - dependency.put("module", components[1]); - dependency.put("version", components[2]); - dependency.put("type", "pom"); - dependencies.add(dependency); - } - else { - handleMalformedDependency(expression); - } - } - } - return dependencies; - } - - private List getConstantExpressions(Expression valueExpression) { - if (valueExpression instanceof ListExpression) { - return getConstantExpressions((ListExpression) valueExpression); - } - if (valueExpression instanceof ConstantExpression - && ((ConstantExpression) valueExpression).getValue() instanceof String) { - return Arrays.asList((ConstantExpression) valueExpression); - } - reportError("@DependencyManagementBom requires an inline constant that is a string or a string array", - valueExpression); - return Collections.emptyList(); - } - - private List getConstantExpressions(ListExpression valueExpression) { - List expressions = new ArrayList<>(); - for (Expression expression : valueExpression.getExpressions()) { - if (expression instanceof ConstantExpression - && ((ConstantExpression) expression).getValue() instanceof String) { - expressions.add((ConstantExpression) expression); - } - else { - reportError("Each entry in the array must be an inline string constant", expression); - } - } - return expressions; - } - - private void handleMalformedDependency(Expression expression) { - Message message = createSyntaxErrorMessage( - String.format("The string must be of the form \"group:module:version\"%n"), expression); - getSourceUnit().getErrorCollector().addErrorAndContinue(message); - } - - private void updateDependencyResolutionContext(List> bomDependencies) { - URI[] uris = Grape.getInstance().resolve(null, bomDependencies.toArray(new Map[0])); - DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance(); - for (URI uri : uris) { - try { - DefaultModelBuildingRequest request = new DefaultModelBuildingRequest(); - request.setModelResolver(new GrapeModelResolver()); - request.setModelSource(new org.apache.maven.model.building.UrlModelSource(uri.toURL())); - request.setSystemProperties(System.getProperties()); - Model model = modelBuilder.build(request).getEffectiveModel(); - this.resolutionContext.addDependencyManagement(new MavenModelDependencyManagement(model)); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to build model for '" + uri + "'. Is it a valid Maven bom?", - ex); - } - } - } - - private void handleDuplicateDependencyManagementBomAnnotation(AnnotationNode annotationNode) { - Message message = createSyntaxErrorMessage( - "Duplicate @DependencyManagementBom annotation. It must be declared at most once.", annotationNode); - getSourceUnit().getErrorCollector().addErrorAndContinue(message); - } - - private void reportError(String message, ASTNode node) { - getSourceUnit().getErrorCollector().addErrorAndContinue(createSyntaxErrorMessage(message, node)); - } - - private Message createSyntaxErrorMessage(String message, ASTNode node) { - return new SyntaxErrorMessage(new SyntaxException(message, node.getLineNumber(), node.getColumnNumber(), - node.getLastLineNumber(), node.getLastColumnNumber()), getSourceUnit()); - } - - private static class GrapeModelResolver implements ModelResolver { - - @Override - public org.apache.maven.model.building.ModelSource resolveModel(Parent parent) - throws UnresolvableModelException { - return resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); - } - - @Override - public org.apache.maven.model.building.ModelSource resolveModel(Dependency dependency) - throws UnresolvableModelException { - return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); - } - - @Override - public org.apache.maven.model.building.ModelSource resolveModel(String groupId, String artifactId, - String version) throws UnresolvableModelException { - Map dependency = new HashMap<>(); - dependency.put("group", groupId); - dependency.put("module", artifactId); - dependency.put("version", version); - dependency.put("type", "pom"); - try { - return new org.apache.maven.model.building.UrlModelSource( - Grape.getInstance().resolve(null, dependency)[0].toURL()); - } - catch (MalformedURLException ex) { - throw new UnresolvableModelException(ex.getMessage(), groupId, artifactId, version); - } - } - - @Override - public void addRepository(Repository repository) throws InvalidRepositoryException { - } - - @Override - public void addRepository(Repository repository, boolean replace) throws InvalidRepositoryException { - } - - @Override - public ModelResolver newCopy() { - return this; - } - - } + /** + * The order of the transformation. + */ + public static final int ORDER = Ordered.HIGHEST_PRECEDENCE + 100; + + private static final Set DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES = Collections + .unmodifiableSet(new HashSet<>( + Arrays.asList(DependencyManagementBom.class.getName(), DependencyManagementBom.class.getSimpleName()))); + + private final DependencyResolutionContext resolutionContext; + + public DependencyManagementBomTransformation(DependencyResolutionContext resolutionContext) { + super(DEPENDENCY_MANAGEMENT_BOM_ANNOTATION_NAMES, true); + this.resolutionContext = resolutionContext; + } + + @Override + protected void processAnnotationNodes(List annotationNodes) { + if (!annotationNodes.isEmpty()) { + if (annotationNodes.size() > 1) { + for (AnnotationNode annotationNode : annotationNodes) { + handleDuplicateDependencyManagementBomAnnotation(annotationNode); + } + } + else { + processDependencyManagementBomAnnotation(annotationNodes.get(0)); + } + } + } + + private void processDependencyManagementBomAnnotation(AnnotationNode annotationNode) { + Expression valueExpression = annotationNode.getMember("value"); + List> bomDependencies = createDependencyMaps(valueExpression); + updateDependencyResolutionContext(bomDependencies); + } + + private List> createDependencyMaps(Expression valueExpression) { + Map dependency = null; + List constantExpressions = getConstantExpressions(valueExpression); + List> dependencies = new ArrayList<>(constantExpressions.size()); + for (ConstantExpression expression : constantExpressions) { + Object value = expression.getValue(); + if (value instanceof String) { + String[] components = ((String) expression.getValue()).split(":"); + if (components.length == 3) { + dependency = new HashMap<>(); + dependency.put("group", components[0]); + dependency.put("module", components[1]); + dependency.put("version", components[2]); + dependency.put("type", "pom"); + dependencies.add(dependency); + } + else { + handleMalformedDependency(expression); + } + } + } + return dependencies; + } + + private List getConstantExpressions(Expression valueExpression) { + if (valueExpression instanceof ListExpression) { + return getConstantExpressions((ListExpression) valueExpression); + } + if (valueExpression instanceof ConstantExpression + && ((ConstantExpression) valueExpression).getValue() instanceof String) { + return Arrays.asList((ConstantExpression) valueExpression); + } + reportError("@DependencyManagementBom requires an inline constant that is a string or a string array", + valueExpression); + return Collections.emptyList(); + } + + private List getConstantExpressions(ListExpression valueExpression) { + List expressions = new ArrayList<>(); + for (Expression expression : valueExpression.getExpressions()) { + if (expression instanceof ConstantExpression + && ((ConstantExpression) expression).getValue() instanceof String) { + expressions.add((ConstantExpression) expression); + } + else { + reportError("Each entry in the array must be an inline string constant", expression); + } + } + return expressions; + } + + private void handleMalformedDependency(Expression expression) { + Message message = createSyntaxErrorMessage( + String.format("The string must be of the form \"group:module:version\"%n"), expression); + getSourceUnit().getErrorCollector().addErrorAndContinue(message); + } + + private void updateDependencyResolutionContext(List> bomDependencies) { + URI[] uris = Grape.getInstance().resolve(null, bomDependencies.toArray(new Map[0])); + DefaultModelBuilder modelBuilder = new DefaultModelBuilderFactory().newInstance(); + for (URI uri : uris) { + try { + DefaultModelBuildingRequest request = new DefaultModelBuildingRequest(); + request.setModelResolver(new GrapeModelResolver()); + request.setModelSource(new org.apache.maven.model.building.UrlModelSource(uri.toURL())); + request.setSystemProperties(System.getProperties()); + Model model = modelBuilder.build(request).getEffectiveModel(); + this.resolutionContext.addDependencyManagement(new MavenModelDependencyManagement(model)); + } + catch (Exception ex) { + throw new IllegalStateException("Failed to build model for '" + uri + "'. Is it a valid Maven bom?", + ex); + } + } + } + + private void handleDuplicateDependencyManagementBomAnnotation(AnnotationNode annotationNode) { + Message message = createSyntaxErrorMessage( + "Duplicate @DependencyManagementBom annotation. It must be declared at most once.", annotationNode); + getSourceUnit().getErrorCollector().addErrorAndContinue(message); + } + + private void reportError(String message, ASTNode node) { + getSourceUnit().getErrorCollector().addErrorAndContinue(createSyntaxErrorMessage(message, node)); + } + + private Message createSyntaxErrorMessage(String message, ASTNode node) { + return new SyntaxErrorMessage(new SyntaxException(message, node.getLineNumber(), node.getColumnNumber(), + node.getLastLineNumber(), node.getLastColumnNumber()), getSourceUnit()); + } + + private static class GrapeModelResolver implements ModelResolver { + + @Override + public org.apache.maven.model.building.ModelSource resolveModel(Parent parent) + throws UnresolvableModelException { + return resolveModel(parent.getGroupId(), parent.getArtifactId(), parent.getVersion()); + } + + @Override + public org.apache.maven.model.building.ModelSource resolveModel(Dependency dependency) + throws UnresolvableModelException { + return resolveModel(dependency.getGroupId(), dependency.getArtifactId(), dependency.getVersion()); + } + + @Override + public org.apache.maven.model.building.ModelSource resolveModel(String groupId, String artifactId, + String version) throws UnresolvableModelException { + Map dependency = new HashMap<>(); + dependency.put("group", groupId); + dependency.put("module", artifactId); + dependency.put("version", version); + dependency.put("type", "pom"); + try { + return new org.apache.maven.model.building.UrlModelSource( + Grape.getInstance().resolve(null, dependency)[0].toURL()); + } + catch (MalformedURLException ex) { + throw new UnresolvableModelException(ex.getMessage(), groupId, artifactId, version); + } + } + + @Override + public void addRepository(Repository repository) throws InvalidRepositoryException { + } + + @Override + public void addRepository(Repository repository, boolean replace) throws InvalidRepositoryException { + } + + @Override + public ModelResolver newCopy() { + return this; + } + + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/ExtendedGroovyClassLoader.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/ExtendedGroovyClassLoader.java index ef37635abf..db5a2f54da 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/ExtendedGroovyClassLoader.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/ExtendedGroovyClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.io.ByteArrayInputStream; @@ -37,7 +36,6 @@ import org.codehaus.groovy.control.CompilationUnit; import org.codehaus.groovy.control.CompilerConfiguration; import org.codehaus.groovy.control.SourceUnit; - import org.springframework.util.Assert; import org.springframework.util.FileCopyUtils; import org.springframework.util.StringUtils; @@ -48,201 +46,201 @@ * * @author Phillip Webb * @author Dave Syer - * @since 1.0.0 + * @since 2022.1.0 */ public class ExtendedGroovyClassLoader extends GroovyClassLoader { - private static final String SHARED_PACKAGE = "org.grails.cli.groovy"; - - private static final URL[] NO_URLS = new URL[] {}; - - private final Map classResources = new HashMap<>(); - - private final GroovyCompilerScope scope; - - private final CompilerConfiguration configuration; - - public ExtendedGroovyClassLoader(GroovyCompilerScope scope) { - this(scope, createParentClassLoader(scope), new CompilerConfiguration()); - } - - private static ClassLoader createParentClassLoader(GroovyCompilerScope scope) { - ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - if (scope == GroovyCompilerScope.DEFAULT) { - classLoader = new DefaultScopeParentClassLoader(classLoader); - } - return classLoader; - } - - private ExtendedGroovyClassLoader(GroovyCompilerScope scope, ClassLoader parent, - CompilerConfiguration configuration) { - super(parent, configuration); - this.configuration = configuration; - this.scope = scope; - } - - @Override - protected Class findClass(String name) throws ClassNotFoundException { - try { - return super.findClass(name); - } - catch (ClassNotFoundException ex) { - if (this.scope == GroovyCompilerScope.DEFAULT && name.startsWith(SHARED_PACKAGE)) { - Class sharedClass = findSharedClass(name); - if (sharedClass != null) { - return sharedClass; - } - } - throw ex; - } - } - - private Class findSharedClass(String name) { - try { - String path = name.replace('.', '/').concat(".class"); - try (InputStream inputStream = getParent().getResourceAsStream(path)) { - if (inputStream != null) { - return defineClass(name, FileCopyUtils.copyToByteArray(inputStream)); - } - } - return null; - } - catch (Exception ex) { - return null; - } - } - - @Override - public InputStream getResourceAsStream(String name) { - InputStream resourceStream = super.getResourceAsStream(name); - if (resourceStream == null) { - byte[] bytes = this.classResources.get(name); - resourceStream = (bytes != null) ? new ByteArrayInputStream(bytes) : null; - } - return resourceStream; - } - - @Override - public ClassCollector createCollector(CompilationUnit unit, SourceUnit su) { - InnerLoader loader = AccessController.doPrivileged(getInnerLoader()); - return new ExtendedClassCollector(loader, unit, su); - } - - private PrivilegedAction getInnerLoader() { - return () -> new InnerLoader(ExtendedGroovyClassLoader.this) { - - // Don't return URLs from the inner loader so that Tomcat only - // searches the parent. Fixes 'TLD skipped' issues - @Override - public URL[] getURLs() { - return NO_URLS; - } - - }; - } - - public CompilerConfiguration getConfiguration() { - return this.configuration; - } - - /** - * Inner collector class used to track as classes are added. - */ - protected class ExtendedClassCollector extends ClassCollector { - - protected ExtendedClassCollector(InnerLoader loader, CompilationUnit unit, SourceUnit su) { - super(loader, unit, su); - } - - @Override - protected Class createClass(byte[] code, ClassNode classNode) { - Class createdClass = super.createClass(code, classNode); - ExtendedGroovyClassLoader.this.classResources.put(classNode.getName().replace('.', '/') + ".class", code); - return createdClass; - } - - } - - /** - * ClassLoader used for a parent that filters so that only classes from groovy-all.jar - * are exposed. - */ - private static class DefaultScopeParentClassLoader extends ClassLoader { - - private static final String[] GROOVY_JARS_PREFIXES = { "groovy", "antlr", "asm" }; - - private final URLClassLoader groovyOnlyClassLoader; - - DefaultScopeParentClassLoader(ClassLoader parent) { - super(parent); - this.groovyOnlyClassLoader = new URLClassLoader(getGroovyJars(parent), - getClass().getClassLoader().getParent()); - } - - private URL[] getGroovyJars(ClassLoader parent) { - Set urls = new HashSet<>(); - findGroovyJarsDirectly(parent, urls); - if (urls.isEmpty()) { - findGroovyJarsFromClassPath(urls); - } - Assert.state(!urls.isEmpty(), "Unable to find groovy JAR"); - return new ArrayList<>(urls).toArray(new URL[0]); - } - - private void findGroovyJarsDirectly(ClassLoader classLoader, Set urls) { - while (classLoader != null) { - if (classLoader instanceof URLClassLoader) { - for (URL url : ((URLClassLoader) classLoader).getURLs()) { - if (isGroovyJar(url.toString())) { - urls.add(url); - } - } - } - classLoader = classLoader.getParent(); - } - } - - private void findGroovyJarsFromClassPath(Set urls) { - String classpath = System.getProperty("java.class.path"); - String[] entries = classpath.split(System.getProperty("path.separator")); - for (String entry : entries) { - if (isGroovyJar(entry)) { - File file = new File(entry); - if (file.canRead()) { - try { - urls.add(file.toURI().toURL()); - } - catch (MalformedURLException ex) { - // Swallow and continue - } - } - } - } - } - - private boolean isGroovyJar(String entry) { - entry = StringUtils.cleanPath(entry); - for (String jarPrefix : GROOVY_JARS_PREFIXES) { - if (entry.contains("/" + jarPrefix + "-")) { - return true; - } - } - return false; - } - - @Override - public Enumeration getResources(String name) throws IOException { - return this.groovyOnlyClassLoader.getResources(name); - } - - @Override - protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - if (!name.startsWith("java.")) { - Class.forName(name, false, this.groovyOnlyClassLoader); - } - return super.loadClass(name, resolve); - } - - } + private static final String SHARED_PACKAGE = "org.grails.cli.groovy"; + + private static final URL[] NO_URLS = new URL[] {}; + + private final Map classResources = new HashMap<>(); + + private final GroovyCompilerScope scope; + + private final CompilerConfiguration configuration; + + public ExtendedGroovyClassLoader(GroovyCompilerScope scope) { + this(scope, createParentClassLoader(scope), new CompilerConfiguration()); + } + + private static ClassLoader createParentClassLoader(GroovyCompilerScope scope) { + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + if (scope == GroovyCompilerScope.DEFAULT) { + classLoader = new DefaultScopeParentClassLoader(classLoader); + } + return classLoader; + } + + private ExtendedGroovyClassLoader(GroovyCompilerScope scope, ClassLoader parent, + CompilerConfiguration configuration) { + super(parent, configuration); + this.configuration = configuration; + this.scope = scope; + } + + @Override + protected Class findClass(String name) throws ClassNotFoundException { + try { + return super.findClass(name); + } + catch (ClassNotFoundException ex) { + if (this.scope == GroovyCompilerScope.DEFAULT && name.startsWith(SHARED_PACKAGE)) { + Class sharedClass = findSharedClass(name); + if (sharedClass != null) { + return sharedClass; + } + } + throw ex; + } + } + + private Class findSharedClass(String name) { + try { + String path = name.replace('.', '/').concat(".class"); + try (InputStream inputStream = getParent().getResourceAsStream(path)) { + if (inputStream != null) { + return defineClass(name, FileCopyUtils.copyToByteArray(inputStream)); + } + } + return null; + } + catch (Exception ex) { + return null; + } + } + + @Override + public InputStream getResourceAsStream(String name) { + InputStream resourceStream = super.getResourceAsStream(name); + if (resourceStream == null) { + byte[] bytes = this.classResources.get(name); + resourceStream = (bytes != null) ? new ByteArrayInputStream(bytes) : null; + } + return resourceStream; + } + + @Override + public ClassCollector createCollector(CompilationUnit unit, SourceUnit su) { + InnerLoader loader = AccessController.doPrivileged(getInnerLoader()); + return new ExtendedClassCollector(loader, unit, su); + } + + private PrivilegedAction getInnerLoader() { + return () -> new InnerLoader(ExtendedGroovyClassLoader.this) { + + // Don't return URLs from the inner loader so that Tomcat only + // searches the parent. Fixes 'TLD skipped' issues + @Override + public URL[] getURLs() { + return NO_URLS; + } + + }; + } + + public CompilerConfiguration getConfiguration() { + return this.configuration; + } + + /** + * Inner collector class used to track as classes are added. + */ + protected class ExtendedClassCollector extends ClassCollector { + + protected ExtendedClassCollector(InnerLoader loader, CompilationUnit unit, SourceUnit su) { + super(loader, unit, su); + } + + @Override + protected Class createClass(byte[] code, ClassNode classNode) { + Class createdClass = super.createClass(code, classNode); + ExtendedGroovyClassLoader.this.classResources.put(classNode.getName().replace('.', '/') + ".class", code); + return createdClass; + } + + } + + /** + * ClassLoader used for a parent that filters so that only classes from groovy-all.jar + * are exposed. + */ + private static class DefaultScopeParentClassLoader extends ClassLoader { + + private static final String[] GROOVY_JARS_PREFIXES = { "groovy", "antlr", "asm" }; + + private final URLClassLoader groovyOnlyClassLoader; + + DefaultScopeParentClassLoader(ClassLoader parent) { + super(parent); + this.groovyOnlyClassLoader = new URLClassLoader(getGroovyJars(parent), + getClass().getClassLoader().getParent()); + } + + private URL[] getGroovyJars(ClassLoader parent) { + Set urls = new HashSet<>(); + findGroovyJarsDirectly(parent, urls); + if (urls.isEmpty()) { + findGroovyJarsFromClassPath(urls); + } + Assert.state(!urls.isEmpty(), "Unable to find groovy JAR"); + return new ArrayList<>(urls).toArray(new URL[0]); + } + + private void findGroovyJarsDirectly(ClassLoader classLoader, Set urls) { + while (classLoader != null) { + if (classLoader instanceof URLClassLoader) { + for (URL url : ((URLClassLoader) classLoader).getURLs()) { + if (isGroovyJar(url.toString())) { + urls.add(url); + } + } + } + classLoader = classLoader.getParent(); + } + } + + private void findGroovyJarsFromClassPath(Set urls) { + String classpath = System.getProperty("java.class.path"); + String[] entries = classpath.split(System.getProperty("path.separator")); + for (String entry : entries) { + if (isGroovyJar(entry)) { + File file = new File(entry); + if (file.canRead()) { + try { + urls.add(file.toURI().toURL()); + } + catch (MalformedURLException ex) { + // Swallow and continue + } + } + } + } + } + + private boolean isGroovyJar(String entry) { + entry = StringUtils.cleanPath(entry); + for (String jarPrefix : GROOVY_JARS_PREFIXES) { + if (entry.contains("/" + jarPrefix + "-")) { + return true; + } + } + return false; + } + + @Override + public Enumeration getResources(String name) throws IOException { + return this.groovyOnlyClassLoader.getResources(name); + } + + @Override + protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + if (!name.startsWith("java.")) { + Class.forName(name, false, this.groovyOnlyClassLoader); + } + return super.loadClass(name, resolve); + } + + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/GenericBomAstTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/GenericBomAstTransformation.java index 829ee26a1f..4e19e84151 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/GenericBomAstTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/GenericBomAstTransformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.util.ArrayList; @@ -34,9 +33,9 @@ import org.codehaus.groovy.control.CompilePhase; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.transform.GroovyASTTransformation; +import org.springframework.core.Ordered; import org.grails.cli.groovy.DependencyManagementBom; -import org.springframework.core.Ordered; /** * A base class that lets plugin authors easily add additional BOMs to all apps. All the @@ -48,84 +47,85 @@ * {@link DependencyManagementBomTransformation#ORDER}. * * @author Dave Syer - * @since 1.3.0 + * @since 2022.1.0 */ @GroovyASTTransformation(phase = CompilePhase.CONVERSION) public abstract class GenericBomAstTransformation implements SpringBootAstTransformation, Ordered { - private static final ClassNode BOM = ClassHelper.make(DependencyManagementBom.class); + private static final ClassNode BOM = ClassHelper.make(DependencyManagementBom.class); - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - for (ASTNode astNode : nodes) { - if (astNode instanceof ModuleNode) { - visitModule((ModuleNode) astNode, getBomModule()); - } - } - } + @Override + public void visit(ASTNode[] nodes, SourceUnit source) { + for (ASTNode astNode : nodes) { + if (astNode instanceof ModuleNode) { + visitModule((ModuleNode) astNode, getBomModule()); + } + } + } - /** - * The bom to be added to dependency management in compact form: - * {@code "::"} (like in a {@code @Grab}). - * @return the maven co-ordinates of the BOM to add - */ - protected abstract String getBomModule(); + /** + * The bom to be added to dependency management in compact form: + * {@code "::"} (like in a {@code @Grab}). + * + * @return the maven co-ordinates of the BOM to add + */ + protected abstract String getBomModule(); - private void visitModule(ModuleNode node, String module) { - addDependencyManagementBom(node, module); - } + private void visitModule(ModuleNode node, String module) { + addDependencyManagementBom(node, module); + } - private void addDependencyManagementBom(ModuleNode node, String module) { - AnnotatedNode annotated = getAnnotatedNode(node); - if (annotated != null) { - AnnotationNode bom = getAnnotation(annotated); - List expressions = new ArrayList<>(getConstantExpressions(bom.getMember("value"))); - expressions.add(new ConstantExpression(module)); - bom.setMember("value", new ListExpression(expressions)); - } - } + private void addDependencyManagementBom(ModuleNode node, String module) { + AnnotatedNode annotated = getAnnotatedNode(node); + if (annotated != null) { + AnnotationNode bom = getAnnotation(annotated); + List expressions = new ArrayList<>(getConstantExpressions(bom.getMember("value"))); + expressions.add(new ConstantExpression(module)); + bom.setMember("value", new ListExpression(expressions)); + } + } - private AnnotationNode getAnnotation(AnnotatedNode annotated) { - List annotations = annotated.getAnnotations(BOM); - if (!annotations.isEmpty()) { - return annotations.get(0); - } - AnnotationNode annotation = new AnnotationNode(BOM); - annotated.addAnnotation(annotation); - return annotation; - } + private AnnotationNode getAnnotation(AnnotatedNode annotated) { + List annotations = annotated.getAnnotations(BOM); + if (!annotations.isEmpty()) { + return annotations.get(0); + } + AnnotationNode annotation = new AnnotationNode(BOM); + annotated.addAnnotation(annotation); + return annotation; + } - private AnnotatedNode getAnnotatedNode(ModuleNode node) { - PackageNode packageNode = node.getPackage(); - if (packageNode != null && !packageNode.getAnnotations(BOM).isEmpty()) { - return packageNode; - } - if (!node.getClasses().isEmpty()) { - return node.getClasses().get(0); - } - return packageNode; - } + private AnnotatedNode getAnnotatedNode(ModuleNode node) { + PackageNode packageNode = node.getPackage(); + if (packageNode != null && !packageNode.getAnnotations(BOM).isEmpty()) { + return packageNode; + } + if (!node.getClasses().isEmpty()) { + return node.getClasses().get(0); + } + return packageNode; + } - private List getConstantExpressions(Expression valueExpression) { - if (valueExpression instanceof ListExpression) { - return getConstantExpressions((ListExpression) valueExpression); - } - if (valueExpression instanceof ConstantExpression - && ((ConstantExpression) valueExpression).getValue() instanceof String) { - return Arrays.asList((ConstantExpression) valueExpression); - } - return Collections.emptyList(); - } + private List getConstantExpressions(Expression valueExpression) { + if (valueExpression instanceof ListExpression) { + return getConstantExpressions((ListExpression) valueExpression); + } + if (valueExpression instanceof ConstantExpression + && ((ConstantExpression) valueExpression).getValue() instanceof String) { + return Arrays.asList((ConstantExpression) valueExpression); + } + return Collections.emptyList(); + } - private List getConstantExpressions(ListExpression valueExpression) { - List expressions = new ArrayList<>(); - for (Expression expression : valueExpression.getExpressions()) { - if (expression instanceof ConstantExpression - && ((ConstantExpression) expression).getValue() instanceof String) { - expressions.add((ConstantExpression) expression); - } - } - return expressions; - } + private List getConstantExpressions(ListExpression valueExpression) { + List expressions = new ArrayList<>(); + for (Expression expression : valueExpression.getExpressions()) { + if (expression instanceof ConstantExpression + && ((ConstantExpression) expression).getValue() instanceof String) { + expressions.add((ConstantExpression) expression); + } + } + return expressions; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/GrailsBomAstTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/GrailsBomAstTransformation.java index ab1fe4fbf5..087d0d0edd 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/GrailsBomAstTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/GrailsBomAstTransformation.java @@ -1,7 +1,29 @@ +/* + * Copyright 2022-2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package org.grails.cli.compiler; import org.codehaus.groovy.control.CompilePhase; import org.codehaus.groovy.transform.GroovyASTTransformation; + +/** + * {@link CompilerAutoConfiguration} for the Grails BOM. + * + * @author Michael Yan + * @since 2022.1.0 + */ @GroovyASTTransformation(phase = CompilePhase.CONVERSION) public class GrailsBomAstTransformation extends GenericBomAstTransformation { diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyBeansTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyBeansTransformation.java index 50f400db1d..143cf4ce4a 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyBeansTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyBeansTransformation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.lang.reflect.Modifier; @@ -29,7 +28,6 @@ import org.codehaus.groovy.ast.stmt.BlockStatement; import org.codehaus.groovy.control.SourceUnit; import org.codehaus.groovy.transform.ASTTransformation; - import org.springframework.core.annotation.Order; /** @@ -39,81 +37,82 @@ * an interface. * * @author Dave Syer - * @since 1.0.0 + * @since 2022.1.0 */ @Order(GroovyBeansTransformation.ORDER) public class GroovyBeansTransformation implements ASTTransformation { - /** - * The order of the transformation. - */ - public static final int ORDER = DependencyManagementBomTransformation.ORDER + 200; - - @Override - public void visit(ASTNode[] nodes, SourceUnit source) { - for (ASTNode node : nodes) { - if (node instanceof ModuleNode) { - ModuleNode module = (ModuleNode) node; - for (ClassNode classNode : new ArrayList<>(module.getClasses())) { - if (classNode.isScript()) { - classNode.visitContents(new ClassVisitor(source, classNode)); - } - } - } - } - } - - private class ClassVisitor extends ClassCodeVisitorSupport { - - private static final String SOURCE_INTERFACE = "org.springframework.boot.BeanDefinitionLoader.GroovyBeanDefinitionSource"; - - private static final String BEANS = "beans"; - - private final SourceUnit source; - - private final ClassNode classNode; - - private boolean xformed = false; - - ClassVisitor(SourceUnit source, ClassNode classNode) { - this.source = source; - this.classNode = classNode; - } - - @Override - protected SourceUnit getSourceUnit() { - return this.source; - } - - @Override - public void visitBlockStatement(BlockStatement block) { - if (block.isEmpty() || this.xformed) { - return; - } - ClosureExpression closure = beans(block); - if (closure != null) { - // Add a marker interface to the current script - this.classNode.addInterface(ClassHelper.make(SOURCE_INTERFACE)); - // Implement the interface by adding a public read-only property with the - // same name as the method in the interface (getBeans). Make it return the - // closure. - this.classNode.addProperty(new PropertyNode(BEANS, Modifier.PUBLIC | Modifier.FINAL, - ClassHelper.CLOSURE_TYPE.getPlainNodeReference(), this.classNode, closure, null, null)); - // Only do this once per class - this.xformed = true; - } - } - - /** - * Extract a top-level beans{} closure from inside this block if - * there is one. Removes it from the block at the same time. - * @param block a block statement (class definition) - * @return a beans Closure if one can be found, null otherwise - */ - private ClosureExpression beans(BlockStatement block) { - return AstUtils.getClosure(block, BEANS, true); - } - - } + /** + * The order of the transformation. + */ + public static final int ORDER = DependencyManagementBomTransformation.ORDER + 200; + + @Override + public void visit(ASTNode[] nodes, SourceUnit source) { + for (ASTNode node : nodes) { + if (node instanceof ModuleNode) { + ModuleNode module = (ModuleNode) node; + for (ClassNode classNode : new ArrayList<>(module.getClasses())) { + if (classNode.isScript()) { + classNode.visitContents(new ClassVisitor(source, classNode)); + } + } + } + } + } + + private class ClassVisitor extends ClassCodeVisitorSupport { + + private static final String SOURCE_INTERFACE = "org.springframework.boot.BeanDefinitionLoader.GroovyBeanDefinitionSource"; + + private static final String BEANS = "beans"; + + private final SourceUnit source; + + private final ClassNode classNode; + + private boolean xformed = false; + + ClassVisitor(SourceUnit source, ClassNode classNode) { + this.source = source; + this.classNode = classNode; + } + + @Override + protected SourceUnit getSourceUnit() { + return this.source; + } + + @Override + public void visitBlockStatement(BlockStatement block) { + if (block.isEmpty() || this.xformed) { + return; + } + ClosureExpression closure = beans(block); + if (closure != null) { + // Add a marker interface to the current script + this.classNode.addInterface(ClassHelper.make(SOURCE_INTERFACE)); + // Implement the interface by adding a public read-only property with the + // same name as the method in the interface (getBeans). Make it return the + // closure. + this.classNode.addProperty(new PropertyNode(BEANS, Modifier.PUBLIC | Modifier.FINAL, + ClassHelper.CLOSURE_TYPE.getPlainNodeReference(), this.classNode, closure, null, null)); + // Only do this once per class + this.xformed = true; + } + } + + /** + * Extract a top-level beans{} closure from inside this block if + * there is one. Removes it from the block at the same time. + * + * @param block a block statement (class definition) + * @return a beans Closure if one can be found, null otherwise + */ + private ClosureExpression beans(BlockStatement block) { + return AstUtils.getClosure(block, BEANS, true); + } + + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompiler.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompiler.java index 74c02e9564..6ecee67e73 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompiler.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompiler.java @@ -42,14 +42,14 @@ import org.codehaus.groovy.control.customizers.ImportCustomizer; import org.codehaus.groovy.transform.ASTTransformation; import org.codehaus.groovy.transform.ASTTransformationVisitor; +import org.springframework.core.annotation.AnnotationAwareOrderComparator; +import org.springframework.util.ClassUtils; import org.grails.cli.compiler.dependencies.GrailsDependenciesDependencyManagement; import org.grails.cli.compiler.grape.DependencyResolutionContext; import org.grails.cli.compiler.grape.GrapeEngineInstaller; import org.grails.cli.compiler.grape.MavenResolverGrapeEngineFactory; import org.grails.cli.util.ResourceUtils; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.util.ClassUtils; /** * Compiler for Groovy sources. Primarily a simple Facade for @@ -76,244 +76,243 @@ */ public class GroovyCompiler { - private final GroovyCompilerConfiguration configuration; - - private final ExtendedGroovyClassLoader loader; - - private final Iterable compilerAutoConfigurations; - - private final List transformations; - - /** - * Create a new {@link GroovyCompiler} instance. - * @param configuration the compiler configuration - */ - public GroovyCompiler(GroovyCompilerConfiguration configuration) { - - this.configuration = configuration; - this.loader = createLoader(configuration); - - DependencyResolutionContext resolutionContext = new DependencyResolutionContext(); - resolutionContext.addDependencyManagement(new GrailsDependenciesDependencyManagement()); - - GrapeEngine grapeEngine = MavenResolverGrapeEngineFactory.create(this.loader, - configuration.getRepositoryConfiguration(), resolutionContext, configuration.isQuiet()); - - GrapeEngineInstaller.install(grapeEngine); - - this.loader.getConfiguration().addCompilationCustomizers(new CompilerAutoConfigureCustomizer()); - if (configuration.isAutoconfigure()) { - this.compilerAutoConfigurations = ServiceLoader.load(CompilerAutoConfiguration.class); - } - else { - this.compilerAutoConfigurations = Collections.emptySet(); - } - - this.transformations = new ArrayList<>(); - this.transformations.add(new DependencyManagementBomTransformation(resolutionContext)); - this.transformations.add(new DependencyAutoConfigurationTransformation(this.loader, resolutionContext, - this.compilerAutoConfigurations)); - this.transformations.add(new GroovyBeansTransformation()); - if (this.configuration.isGuessDependencies()) { - this.transformations.add(new ResolveDependencyCoordinatesTransformation(resolutionContext)); - } - for (ASTTransformation transformation : ServiceLoader.load(SpringBootAstTransformation.class)) { - this.transformations.add(transformation); - } - this.transformations.sort(AnnotationAwareOrderComparator.INSTANCE); - } - - /** - * Return a mutable list of the {@link ASTTransformation}s to be applied during - * {@link #compile(String...)}. - * @return the AST transformations to apply - */ - public List getAstTransformations() { - return this.transformations; - } - - public ExtendedGroovyClassLoader getLoader() { - return this.loader; - } - - private ExtendedGroovyClassLoader createLoader(GroovyCompilerConfiguration configuration) { - - ExtendedGroovyClassLoader loader = new ExtendedGroovyClassLoader(configuration.getScope()); - - for (URL url : getExistingUrls()) { - loader.addURL(url); - } - - for (String classpath : configuration.getClasspath()) { - loader.addClasspath(classpath); - } - - return loader; - } - - private URL[] getExistingUrls() { - ClassLoader tccl = Thread.currentThread().getContextClassLoader(); - if (tccl instanceof ExtendedGroovyClassLoader) { - return ((ExtendedGroovyClassLoader) tccl).getURLs(); - } - else { - return new URL[0]; - } - } - - public void addCompilationCustomizers(CompilationCustomizer... customizers) { - this.loader.getConfiguration().addCompilationCustomizers(customizers); - } - - /** - * Compile the specified Groovy sources, applying any - * {@link CompilerAutoConfiguration}s. All classes defined in the sources will be - * returned from this method. - * @param sources the sources to compile - * @return compiled classes - * @throws CompilationFailedException in case of compilation failures - * @throws IOException in case of I/O errors - * @throws CompilationFailedException in case of compilation errors - */ - public Class[] compile(String... sources) throws CompilationFailedException, IOException { - - this.loader.clearCache(); - List> classes = new ArrayList<>(); - - CompilerConfiguration configuration = this.loader.getConfiguration(); - - CompilationUnit compilationUnit = new CompilationUnit(configuration, null, this.loader); - ClassCollector collector = this.loader.createCollector(compilationUnit, null); - compilationUnit.setClassgenCallback(collector); - - for (String source : sources) { - List paths = ResourceUtils.getUrls(source, this.loader); - for (String path : paths) { - compilationUnit.addSource(new URL(path)); - } - } - - addAstTransformations(compilationUnit); - compilationUnit.compile(Phases.CLASS_GENERATION); - for (Object loadedClass : collector.getLoadedClasses()) { - classes.add((Class) loadedClass); - } - ClassNode mainClassNode = MainClass.get(compilationUnit); - - Class mainClass = null; - for (Class loadedClass : classes) { - if (mainClassNode.getName().equals(loadedClass.getName())) { - mainClass = loadedClass; - } - } - if (mainClass != null) { - classes.remove(mainClass); - classes.add(0, mainClass); - } - - return ClassUtils.toClassArray(classes); - } - - @SuppressWarnings("rawtypes") - private void addAstTransformations(CompilationUnit compilationUnit) { - Deque[] phaseOperations = getPhaseOperations(compilationUnit); - processConversionOperations((LinkedList) phaseOperations[Phases.CONVERSION]); - } - - @SuppressWarnings("rawtypes") - private Deque[] getPhaseOperations(CompilationUnit compilationUnit) { - try { - Field field = CompilationUnit.class.getDeclaredField("phaseOperations"); - field.setAccessible(true); - return (Deque[]) field.get(compilationUnit); - } - catch (Exception ex) { - throw new IllegalStateException("Phase operations not available from compilation unit"); - } - } - - @SuppressWarnings({ "rawtypes", "unchecked" }) - private void processConversionOperations(LinkedList conversionOperations) { - int index = getIndexOfASTTransformationVisitor(conversionOperations); - conversionOperations.add(index, new CompilationUnit.ISourceUnitOperation() { - @Override - public void call(SourceUnit source) throws CompilationFailedException { - ASTNode[] nodes = new ASTNode[] { source.getAST() }; - for (ASTTransformation transformation : GroovyCompiler.this.transformations) { - transformation.visit(nodes, source); - } - } - }); - } - - private int getIndexOfASTTransformationVisitor(List conversionOperations) { - for (int index = 0; index < conversionOperations.size(); index++) { - if (conversionOperations.get(index) - .getClass() - .getName() - .startsWith(ASTTransformationVisitor.class.getName())) { - return index; - } - } - return conversionOperations.size(); - } - - /** - * {@link CompilationCustomizer} to call {@link CompilerAutoConfiguration}s. - */ - private class CompilerAutoConfigureCustomizer extends CompilationCustomizer { - - CompilerAutoConfigureCustomizer() { - super(CompilePhase.CONVERSION); - } - - @Override - public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) - throws CompilationFailedException { - - ImportCustomizer importCustomizer = new SmartImportCustomizer(source); - List classNodes = source.getAST().getClasses(); - ClassNode mainClassNode = MainClass.get(classNodes); - - // Additional auto configuration - for (CompilerAutoConfiguration autoConfiguration : GroovyCompiler.this.compilerAutoConfigurations) { - if (classNodes.stream().anyMatch(autoConfiguration::matches)) { - if (GroovyCompiler.this.configuration.isGuessImports()) { - autoConfiguration.applyImports(importCustomizer); - importCustomizer.call(source, context, classNode); - } - if (classNode.equals(mainClassNode)) { - autoConfiguration.applyToMainClass(GroovyCompiler.this.loader, - GroovyCompiler.this.configuration, context, source, classNode); - } - autoConfiguration.apply(GroovyCompiler.this.loader, GroovyCompiler.this.configuration, context, - source, classNode); - } - } - importCustomizer.call(source, context, classNode); - } - - } - - private static class MainClass { - - static ClassNode get(CompilationUnit source) { - return get(source.getAST().getClasses()); - } - - static ClassNode get(List classes) { - for (ClassNode node : classes) { - if (AstUtils.hasAtLeastOneAnnotation(node, "Enable*AutoConfiguration")) { - return null; // No need to enhance this - } - if (AstUtils.hasAtLeastOneAnnotation(node, "*Controller", "Configuration", "Component", "*Service", - "Repository", "Enable*")) { - return node; - } - } - return classes.isEmpty() ? null : classes.get(0); - } - - } + private final GroovyCompilerConfiguration configuration; + + private final ExtendedGroovyClassLoader loader; + + private final Iterable compilerAutoConfigurations; + + private final List transformations; + + /** + * Create a new {@link GroovyCompiler} instance. + * + * @param configuration the compiler configuration + */ + public GroovyCompiler(GroovyCompilerConfiguration configuration) { + this.configuration = configuration; + this.loader = createLoader(configuration); + + DependencyResolutionContext resolutionContext = new DependencyResolutionContext(); + resolutionContext.addDependencyManagement(new GrailsDependenciesDependencyManagement()); + + GrapeEngine grapeEngine = MavenResolverGrapeEngineFactory.create(this.loader, + configuration.getRepositoryConfiguration(), resolutionContext, configuration.isQuiet()); + + GrapeEngineInstaller.install(grapeEngine); + + this.loader.getConfiguration().addCompilationCustomizers(new CompilerAutoConfigureCustomizer()); + if (configuration.isAutoconfigure()) { + this.compilerAutoConfigurations = ServiceLoader.load(CompilerAutoConfiguration.class); + } + else { + this.compilerAutoConfigurations = Collections.emptySet(); + } + + this.transformations = new ArrayList<>(); + this.transformations.add(new DependencyManagementBomTransformation(resolutionContext)); + this.transformations.add(new DependencyAutoConfigurationTransformation(this.loader, resolutionContext, + this.compilerAutoConfigurations)); + this.transformations.add(new GroovyBeansTransformation()); + if (this.configuration.isGuessDependencies()) { + this.transformations.add(new ResolveDependencyCoordinatesTransformation(resolutionContext)); + } + for (ASTTransformation transformation : ServiceLoader.load(SpringBootAstTransformation.class)) { + this.transformations.add(transformation); + } + this.transformations.sort(AnnotationAwareOrderComparator.INSTANCE); + } + + /** + * Return a mutable list of the {@link ASTTransformation}s to be applied during + * {@link #compile(String...)}. + * + * @return the AST transformations to apply + */ + public List getAstTransformations() { + return this.transformations; + } + + public ExtendedGroovyClassLoader getLoader() { + return this.loader; + } + + private ExtendedGroovyClassLoader createLoader(GroovyCompilerConfiguration configuration) { + ExtendedGroovyClassLoader loader = new ExtendedGroovyClassLoader(configuration.getScope()); + + for (URL url : getExistingUrls()) { + loader.addURL(url); + } + + for (String classpath : configuration.getClasspath()) { + loader.addClasspath(classpath); + } + + return loader; + } + + private URL[] getExistingUrls() { + ClassLoader tccl = Thread.currentThread().getContextClassLoader(); + if (tccl instanceof ExtendedGroovyClassLoader) { + return ((ExtendedGroovyClassLoader) tccl).getURLs(); + } + else { + return new URL[0]; + } + } + + public void addCompilationCustomizers(CompilationCustomizer... customizers) { + this.loader.getConfiguration().addCompilationCustomizers(customizers); + } + + /** + * Compile the specified Groovy sources, applying any + * {@link CompilerAutoConfiguration}s. All classes defined in the sources will be + * returned from this method. + * + * @param sources the sources to compile + * @return compiled classes + * @throws CompilationFailedException in case of compilation failures + * @throws IOException in case of I/O errors + * @throws CompilationFailedException in case of compilation errors + */ + public Class[] compile(String... sources) throws CompilationFailedException, IOException { + this.loader.clearCache(); + List> classes = new ArrayList<>(); + + CompilerConfiguration configuration = this.loader.getConfiguration(); + + CompilationUnit compilationUnit = new CompilationUnit(configuration, null, this.loader); + ClassCollector collector = this.loader.createCollector(compilationUnit, null); + compilationUnit.setClassgenCallback(collector); + + for (String source : sources) { + List paths = ResourceUtils.getUrls(source, this.loader); + for (String path : paths) { + compilationUnit.addSource(new URL(path)); + } + } + + addAstTransformations(compilationUnit); + compilationUnit.compile(Phases.CLASS_GENERATION); + for (Object loadedClass : collector.getLoadedClasses()) { + classes.add((Class) loadedClass); + } + ClassNode mainClassNode = MainClass.get(compilationUnit); + + Class mainClass = null; + for (Class loadedClass : classes) { + if (mainClassNode.getName().equals(loadedClass.getName())) { + mainClass = loadedClass; + } + } + if (mainClass != null) { + classes.remove(mainClass); + classes.add(0, mainClass); + } + + return ClassUtils.toClassArray(classes); + } + + @SuppressWarnings("rawtypes") + private void addAstTransformations(CompilationUnit compilationUnit) { + Deque[] phaseOperations = getPhaseOperations(compilationUnit); + processConversionOperations((LinkedList) phaseOperations[Phases.CONVERSION]); + } + + @SuppressWarnings("rawtypes") + private Deque[] getPhaseOperations(CompilationUnit compilationUnit) { + try { + Field field = CompilationUnit.class.getDeclaredField("phaseOperations"); + field.setAccessible(true); + return (Deque[]) field.get(compilationUnit); + } + catch (Exception ex) { + throw new IllegalStateException("Phase operations not available from compilation unit"); + } + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + private void processConversionOperations(LinkedList conversionOperations) { + int index = getIndexOfASTTransformationVisitor(conversionOperations); + conversionOperations.add(index, new CompilationUnit.ISourceUnitOperation() { + @Override + public void call(SourceUnit source) throws CompilationFailedException { + ASTNode[] nodes = new ASTNode[] { source.getAST() }; + for (ASTTransformation transformation : GroovyCompiler.this.transformations) { + transformation.visit(nodes, source); + } + } + }); + } + + private int getIndexOfASTTransformationVisitor(List conversionOperations) { + for (int index = 0; index < conversionOperations.size(); index++) { + if (conversionOperations.get(index) + .getClass() + .getName() + .startsWith(ASTTransformationVisitor.class.getName())) { + return index; + } + } + return conversionOperations.size(); + } + + /** + * {@link CompilationCustomizer} to call {@link CompilerAutoConfiguration}s. + */ + private class CompilerAutoConfigureCustomizer extends CompilationCustomizer { + + CompilerAutoConfigureCustomizer() { + super(CompilePhase.CONVERSION); + } + + @Override + public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) + throws CompilationFailedException { + ImportCustomizer importCustomizer = new SmartImportCustomizer(source); + List classNodes = source.getAST().getClasses(); + ClassNode mainClassNode = MainClass.get(classNodes); + + // Additional auto configuration + for (CompilerAutoConfiguration autoConfiguration : GroovyCompiler.this.compilerAutoConfigurations) { + if (classNodes.stream().anyMatch(autoConfiguration::matches)) { + if (GroovyCompiler.this.configuration.isGuessImports()) { + autoConfiguration.applyImports(importCustomizer); + importCustomizer.call(source, context, classNode); + } + if (classNode.equals(mainClassNode)) { + autoConfiguration.applyToMainClass(GroovyCompiler.this.loader, + GroovyCompiler.this.configuration, context, source, classNode); + } + autoConfiguration.apply(GroovyCompiler.this.loader, GroovyCompiler.this.configuration, context, + source, classNode); + } + } + importCustomizer.call(source, context, classNode); + } + + } + + private static class MainClass { + + static ClassNode get(CompilationUnit source) { + return get(source.getAST().getClasses()); + } + + static ClassNode get(List classes) { + for (ClassNode node : classes) { + if (AstUtils.hasAtLeastOneAnnotation(node, "Enable*AutoConfiguration")) { + return null; // No need to enhance this + } + if (AstUtils.hasAtLeastOneAnnotation(node, "*Controller", "Configuration", "Component", "*Service", + "Repository", "Enable*")) { + return node; + } + } + return classes.isEmpty() ? null : classes.get(0); + } + + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerConfiguration.java index 4730a244d5..8983ff4189 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.util.List; @@ -25,57 +24,64 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ public interface GroovyCompilerConfiguration { - /** - * Constant to be used when there is no {@link #getClasspath() classpath}. - */ - String[] DEFAULT_CLASSPATH = { "." }; + /** + * Constant to be used when there is no {@link #getClasspath() classpath}. + */ + String[] DEFAULT_CLASSPATH = { "." }; - /** - * Returns the scope in which the compiler operates. - * @return the scope of the compiler - */ - GroovyCompilerScope getScope(); + /** + * Returns the scope in which the compiler operates. + * + * @return the scope of the compiler + */ + GroovyCompilerScope getScope(); - /** - * Returns if import declarations should be guessed. - * @return {@code true} if imports should be guessed, otherwise {@code false} - */ - boolean isGuessImports(); + /** + * Returns if import declarations should be guessed. + * + * @return {@code true} if imports should be guessed, otherwise {@code false} + */ + boolean isGuessImports(); - /** - * Returns if jar dependencies should be guessed. - * @return {@code true} if dependencies should be guessed, otherwise {@code false} - */ - boolean isGuessDependencies(); + /** + * Returns if jar dependencies should be guessed. + * + * @return {@code true} if dependencies should be guessed, otherwise {@code false} + */ + boolean isGuessDependencies(); - /** - * Returns true if auto-configuration transformations should be applied. - * @return {@code true} if auto-configuration transformations should be applied, - * otherwise {@code false} - */ - boolean isAutoconfigure(); + /** + * Returns true if auto-configuration transformations should be applied. + * + * @return {@code true} if auto-configuration transformations should be applied, + * otherwise {@code false} + */ + boolean isAutoconfigure(); - /** - * Returns the classpath for local resources. - * @return a path for local resources - */ - String[] getClasspath(); + /** + * Returns the classpath for local resources. + * + * @return a path for local resources + */ + String[] getClasspath(); - /** - * Returns the configuration for the repositories that will be used by the compiler to - * resolve dependencies. - * @return the repository configurations - */ - List getRepositoryConfiguration(); + /** + * Returns the configuration for the repositories that will be used by the compiler to + * resolve dependencies. + * + * @return the repository configurations + */ + List getRepositoryConfiguration(); - /** - * Returns if running in quiet mode. - * @return {@code true} if running in quiet mode - */ - boolean isQuiet(); + /** + * Returns if running in quiet mode. + * + * @return {@code true} if running in quiet mode + */ + boolean isQuiet(); } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerScope.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerScope.java index a01054d735..24681da48e 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerScope.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/GroovyCompilerScope.java @@ -13,26 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; /** * The scope in which a groovy compiler operates. * * @author Phillip Webb - * @since 1.0.0 + * @since 2022.1.0 */ public enum GroovyCompilerScope { - /** - * Default scope, exposes groovy.jar (loaded from the parent) and the shared cli - * package (loaded through groovy classloader). - */ - DEFAULT, + /** + * Default scope, exposes groovy.jar (loaded from the parent) and the shared cli + * package (loaded through groovy classloader). + */ + DEFAULT, - /** - * Extension scope, allows full access to internal CLI classes. - */ - EXTENSION + /** + * Extension scope, allows full access to internal CLI classes. + */ + EXTENSION } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/RepositoryConfigurationFactory.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/RepositoryConfigurationFactory.java index 1fc96bab79..1fd5c21b6e 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/RepositoryConfigurationFactory.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/RepositoryConfigurationFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.io.File; @@ -27,107 +26,108 @@ import org.codehaus.plexus.interpolation.Interpolator; import org.codehaus.plexus.interpolation.PropertiesBasedValueSource; import org.codehaus.plexus.interpolation.RegexBasedInterpolator; +import org.springframework.util.StringUtils; import org.grails.cli.compiler.grape.RepositoryConfiguration; import org.grails.cli.compiler.maven.MavenSettings; import org.grails.cli.compiler.maven.MavenSettingsReader; -import org.springframework.util.StringUtils; /** * Factory used to create {@link RepositoryConfiguration}s. * * @author Andy Wilkinson * @author Dave Syer - * @since 1.0.0 + * @since 2022.1.0 */ public final class RepositoryConfigurationFactory { - private static final RepositoryConfiguration MAVEN_CENTRAL = new RepositoryConfiguration("central", - URI.create("https://repo.maven.apache.org/maven2/"), false); - - private static final RepositoryConfiguration GRAILS_CENTRAL = new RepositoryConfiguration("grailsCentral", - URI.create("https://repo.grails.org/grails/core"), false); - - private static final RepositoryConfiguration SPRING_MILESTONE = new RepositoryConfiguration("spring-milestone", - URI.create("https://repo.spring.io/milestone"), false); - - private static final RepositoryConfiguration SPRING_SNAPSHOT = new RepositoryConfiguration("spring-snapshot", - URI.create("https://repo.spring.io/snapshot"), true); - - private RepositoryConfigurationFactory() { - } - - /** - * Create a new default repository configuration. - * @return the newly-created default repository configuration - */ - public static List createDefaultRepositoryConfiguration() { - MavenSettings mavenSettings = new MavenSettingsReader().readSettings(); - List repositoryConfiguration = new ArrayList<>(); - repositoryConfiguration.add(MAVEN_CENTRAL); - repositoryConfiguration.add(GRAILS_CENTRAL); - if (!Boolean.getBoolean("disableSpringSnapshotRepos")) { - repositoryConfiguration.add(SPRING_MILESTONE); - repositoryConfiguration.add(SPRING_SNAPSHOT); - } - addDefaultCacheAsRepository(mavenSettings.getLocalRepository(), repositoryConfiguration); - addActiveProfileRepositories(mavenSettings.getActiveProfiles(), repositoryConfiguration); - return repositoryConfiguration; - } - - private static void addDefaultCacheAsRepository(String localRepository, - List repositoryConfiguration) { - RepositoryConfiguration repository = new RepositoryConfiguration("local", - getLocalRepositoryDirectory(localRepository).toURI(), true); - if (!repositoryConfiguration.contains(repository)) { - repositoryConfiguration.add(0, repository); - } - } - - private static void addActiveProfileRepositories(List activeProfiles, - List configurations) { - for (Profile activeProfile : activeProfiles) { - Interpolator interpolator = new RegexBasedInterpolator(); - interpolator.addValueSource(new PropertiesBasedValueSource(activeProfile.getProperties())); - for (Repository repository : activeProfile.getRepositories()) { - configurations.add(getRepositoryConfiguration(interpolator, repository)); - } - } - } - - private static RepositoryConfiguration getRepositoryConfiguration(Interpolator interpolator, - Repository repository) { - String name = interpolate(interpolator, repository.getId()); - String url = interpolate(interpolator, repository.getUrl()); - boolean snapshotsEnabled = false; - if (repository.getSnapshots() != null) { - snapshotsEnabled = repository.getSnapshots().isEnabled(); - } - return new RepositoryConfiguration(name, URI.create(url), snapshotsEnabled); - } - - private static String interpolate(Interpolator interpolator, String value) { - try { - return interpolator.interpolate(value); - } - catch (InterpolationException ex) { - return value; - } - } - - private static File getLocalRepositoryDirectory(String localRepository) { - if (StringUtils.hasText(localRepository)) { - return new File(localRepository); - } - return new File(getM2HomeDirectory(), "repository"); - } - - private static File getM2HomeDirectory() { - String mavenRoot = System.getProperty("maven.home"); - if (StringUtils.hasLength(mavenRoot)) { - return new File(mavenRoot); - } - return new File(System.getProperty("user.home"), ".m2"); - } + private static final RepositoryConfiguration MAVEN_CENTRAL = new RepositoryConfiguration("central", + URI.create("https://repo.maven.apache.org/maven2/"), false); + + private static final RepositoryConfiguration GRAILS_CENTRAL = new RepositoryConfiguration("grailsCentral", + URI.create("https://repo.grails.org/grails/core"), false); + + private static final RepositoryConfiguration SPRING_MILESTONE = new RepositoryConfiguration("spring-milestone", + URI.create("https://repo.spring.io/milestone"), false); + + private static final RepositoryConfiguration SPRING_SNAPSHOT = new RepositoryConfiguration("spring-snapshot", + URI.create("https://repo.spring.io/snapshot"), true); + + private RepositoryConfigurationFactory() { + } + + /** + * Create a new default repository configuration. + * + * @return the newly-created default repository configuration + */ + public static List createDefaultRepositoryConfiguration() { + MavenSettings mavenSettings = new MavenSettingsReader().readSettings(); + List repositoryConfiguration = new ArrayList<>(); + repositoryConfiguration.add(MAVEN_CENTRAL); + repositoryConfiguration.add(GRAILS_CENTRAL); + if (!Boolean.getBoolean("disableSpringSnapshotRepos")) { + repositoryConfiguration.add(SPRING_MILESTONE); + repositoryConfiguration.add(SPRING_SNAPSHOT); + } + addDefaultCacheAsRepository(mavenSettings.getLocalRepository(), repositoryConfiguration); + addActiveProfileRepositories(mavenSettings.getActiveProfiles(), repositoryConfiguration); + return repositoryConfiguration; + } + + private static void addDefaultCacheAsRepository(String localRepository, + List repositoryConfiguration) { + RepositoryConfiguration repository = new RepositoryConfiguration("local", + getLocalRepositoryDirectory(localRepository).toURI(), true); + if (!repositoryConfiguration.contains(repository)) { + repositoryConfiguration.add(0, repository); + } + } + + private static void addActiveProfileRepositories(List activeProfiles, + List configurations) { + for (Profile activeProfile : activeProfiles) { + Interpolator interpolator = new RegexBasedInterpolator(); + interpolator.addValueSource(new PropertiesBasedValueSource(activeProfile.getProperties())); + for (Repository repository : activeProfile.getRepositories()) { + configurations.add(getRepositoryConfiguration(interpolator, repository)); + } + } + } + + private static RepositoryConfiguration getRepositoryConfiguration(Interpolator interpolator, + Repository repository) { + String name = interpolate(interpolator, repository.getId()); + String url = interpolate(interpolator, repository.getUrl()); + boolean snapshotsEnabled = false; + if (repository.getSnapshots() != null) { + snapshotsEnabled = repository.getSnapshots().isEnabled(); + } + return new RepositoryConfiguration(name, URI.create(url), snapshotsEnabled); + } + + private static String interpolate(Interpolator interpolator, String value) { + try { + return interpolator.interpolate(value); + } + catch (InterpolationException ex) { + return value; + } + } + + private static File getLocalRepositoryDirectory(String localRepository) { + if (StringUtils.hasText(localRepository)) { + return new File(localRepository); + } + return new File(getM2HomeDirectory(), "repository"); + } + + private static File getM2HomeDirectory() { + String mavenRoot = System.getProperty("maven.home"); + if (StringUtils.hasLength(mavenRoot)) { + return new File(mavenRoot); + } + return new File(System.getProperty("user.home"), ".m2"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/ResolveDependencyCoordinatesTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/ResolveDependencyCoordinatesTransformation.java index 79d99c5ba1..9326cbe590 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/ResolveDependencyCoordinatesTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/ResolveDependencyCoordinatesTransformation.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import java.util.Arrays; @@ -27,83 +26,83 @@ import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.ast.expr.Expression; import org.codehaus.groovy.transform.ASTTransformation; +import org.springframework.core.annotation.Order; import org.grails.cli.compiler.grape.DependencyResolutionContext; -import org.springframework.core.annotation.Order; /** * {@link ASTTransformation} to resolve {@link Grab @Grab} artifact coordinates. * * @author Andy Wilkinson * @author Phillip Webb - * @since 1.0.0 + * @since 2022.1.0 */ @Order(ResolveDependencyCoordinatesTransformation.ORDER) public class ResolveDependencyCoordinatesTransformation extends AnnotatedNodeASTTransformation { - /** - * The order of the transformation. - */ - public static final int ORDER = DependencyManagementBomTransformation.ORDER + 300; - - private static final Set GRAB_ANNOTATION_NAMES = Collections - .unmodifiableSet(new HashSet<>(Arrays.asList(Grab.class.getName(), Grab.class.getSimpleName()))); - - private final DependencyResolutionContext resolutionContext; - - public ResolveDependencyCoordinatesTransformation(DependencyResolutionContext resolutionContext) { - super(GRAB_ANNOTATION_NAMES, false); - this.resolutionContext = resolutionContext; - } - - @Override - protected void processAnnotationNodes(List annotationNodes) { - for (AnnotationNode annotationNode : annotationNodes) { - transformGrabAnnotation(annotationNode); - } - } - - private void transformGrabAnnotation(AnnotationNode grabAnnotation) { - grabAnnotation.setMember("initClass", new ConstantExpression(false)); - String value = getValue(grabAnnotation); - if (value != null && !isConvenienceForm(value)) { - applyGroupAndVersion(grabAnnotation, value); - } - } - - private String getValue(AnnotationNode annotation) { - Expression expression = annotation.getMember("value"); - if (expression instanceof ConstantExpression) { - Object value = ((ConstantExpression) expression).getValue(); - return (value instanceof String) ? (String) value : null; - } - return null; - } - - private boolean isConvenienceForm(String value) { - return value.contains(":") || value.contains("#"); - } - - private void applyGroupAndVersion(AnnotationNode annotation, String module) { - if (module != null) { - setMember(annotation, "module", module); - } - else { - Expression expression = annotation.getMembers().get("module"); - module = (String) ((ConstantExpression) expression).getValue(); - } - if (annotation.getMember("group") == null) { - setMember(annotation, "group", this.resolutionContext.getArtifactCoordinatesResolver().getGroupId(module)); - } - if (annotation.getMember("version") == null) { - setMember(annotation, "version", - this.resolutionContext.getArtifactCoordinatesResolver().getVersion(module)); - } - } - - private void setMember(AnnotationNode annotation, String name, String value) { - ConstantExpression expression = new ConstantExpression(value); - annotation.setMember(name, expression); - } + /** + * The order of the transformation. + */ + public static final int ORDER = DependencyManagementBomTransformation.ORDER + 300; + + private static final Set GRAB_ANNOTATION_NAMES = Collections + .unmodifiableSet(new HashSet<>(Arrays.asList(Grab.class.getName(), Grab.class.getSimpleName()))); + + private final DependencyResolutionContext resolutionContext; + + public ResolveDependencyCoordinatesTransformation(DependencyResolutionContext resolutionContext) { + super(GRAB_ANNOTATION_NAMES, false); + this.resolutionContext = resolutionContext; + } + + @Override + protected void processAnnotationNodes(List annotationNodes) { + for (AnnotationNode annotationNode : annotationNodes) { + transformGrabAnnotation(annotationNode); + } + } + + private void transformGrabAnnotation(AnnotationNode grabAnnotation) { + grabAnnotation.setMember("initClass", new ConstantExpression(false)); + String value = getValue(grabAnnotation); + if (value != null && !isConvenienceForm(value)) { + applyGroupAndVersion(grabAnnotation, value); + } + } + + private String getValue(AnnotationNode annotation) { + Expression expression = annotation.getMember("value"); + if (expression instanceof ConstantExpression) { + Object value = ((ConstantExpression) expression).getValue(); + return (value instanceof String) ? (String) value : null; + } + return null; + } + + private boolean isConvenienceForm(String value) { + return value.contains(":") || value.contains("#"); + } + + private void applyGroupAndVersion(AnnotationNode annotation, String module) { + if (module != null) { + setMember(annotation, "module", module); + } + else { + Expression expression = annotation.getMembers().get("module"); + module = (String) ((ConstantExpression) expression).getValue(); + } + if (annotation.getMember("group") == null) { + setMember(annotation, "group", this.resolutionContext.getArtifactCoordinatesResolver().getGroupId(module)); + } + if (annotation.getMember("version") == null) { + setMember(annotation, "version", + this.resolutionContext.getArtifactCoordinatesResolver().getVersion(module)); + } + } + + private void setMember(AnnotationNode annotation, String name, String value) { + ConstantExpression expression = new ConstantExpression(value); + annotation.setMember(name, expression); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/SmartImportCustomizer.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/SmartImportCustomizer.java index 678f89792d..337e2c7930 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/SmartImportCustomizer.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/SmartImportCustomizer.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import org.codehaus.groovy.ast.ClassHelper; @@ -25,31 +24,32 @@ * class with the same name is not already explicitly imported. * * @author Dave Syer + * @since 2022.1.0 */ class SmartImportCustomizer extends ImportCustomizer { - private SourceUnit source; - - SmartImportCustomizer(SourceUnit source) { - this.source = source; - } - - @Override - public ImportCustomizer addImport(String alias, String className) { - if (this.source.getAST().getImport(ClassHelper.make(className).getNameWithoutPackage()) == null) { - super.addImport(alias, className); - } - return this; - } - - @Override - public ImportCustomizer addImports(String... imports) { - for (String alias : imports) { - if (this.source.getAST().getImport(ClassHelper.make(alias).getNameWithoutPackage()) == null) { - super.addImports(alias); - } - } - return this; - } + private SourceUnit source; + + SmartImportCustomizer(SourceUnit source) { + this.source = source; + } + + @Override + public ImportCustomizer addImport(String alias, String className) { + if (this.source.getAST().getImport(ClassHelper.make(className).getNameWithoutPackage()) == null) { + super.addImport(alias, className); + } + return this; + } + + @Override + public ImportCustomizer addImports(String... imports) { + for (String alias : imports) { + if (this.source.getAST().getImport(ClassHelper.make(alias).getNameWithoutPackage()) == null) { + super.addImports(alias); + } + } + return this; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/SpringBootAstTransformation.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/SpringBootAstTransformation.java index 9f3f552f46..139f38b178 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/SpringBootAstTransformation.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/SpringBootAstTransformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler; import org.codehaus.groovy.transform.ASTTransformation; @@ -23,7 +22,7 @@ * {@code META-INF/services}. * * @author Dave Syer - * @since 1.0.0 + * @since 2022.1.0 */ @FunctionalInterface public interface SpringBootAstTransformation extends ASTTransformation { diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/CachingCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/CachingCompilerAutoConfiguration.java index f850294d5f..2947f87b1f 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/CachingCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/CachingCompilerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -32,20 +31,20 @@ */ public class CachingCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableCaching"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { - dependencies.add("spring-context-support"); - } - - @Override - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - imports.addStarImports("org.springframework.cache", "org.springframework.cache.annotation", - "org.springframework.cache.concurrent"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableCaching"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { + dependencies.add("spring-context-support"); + } + + @Override + public void applyImports(ImportCustomizer imports) throws CompilationFailedException { + imports.addStarImports("org.springframework.cache", "org.springframework.cache.annotation", + "org.springframework.cache.concurrent"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GrailsCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GrailsCompilerAutoConfiguration.java index aaaaed16c9..5183da0284 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GrailsCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GrailsCompilerAutoConfiguration.java @@ -18,6 +18,7 @@ import org.codehaus.groovy.ast.ClassNode; 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; @@ -29,9 +30,22 @@ */ public class GrailsCompilerAutoConfiguration extends CompilerAutoConfiguration { + public static final String[] DEFAULT_IMPORTS = new String[] { + "grails.persistence", + "grails.gorm", + "grails.rest", + "grails.artefact", + "grails.web", + "grails.boot.config" + }; + @Override public boolean matches(ClassNode classNode) { - return true; + boolean matches = AstUtils.hasAtLeastOneAnnotation(classNode, + "grails.persistence.Entity", + "grails.rest.Resource", "Resource", + "grails.artefact.Artefact", "grails.web.Controller"); + return matches; } @Override @@ -53,6 +67,7 @@ public void applyDependencies(DependencyCustomizer dependencies) { @Override public void applyImports(ImportCustomizer imports) { imports.addImports("groovy.transform.CompileStatic"); + imports.addStarImports(DEFAULT_IMPORTS); } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java index 2294641f94..3fafadfe2e 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/GroovyTemplatesCompilerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -29,25 +28,25 @@ * {@link CompilerAutoConfiguration} for Groovy Templates (outside MVC). * * @author Dave Syer - * @since 1.1.0 + * @since 2022.1.0 */ public class GroovyTemplatesCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableGroovyTemplates"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add("groovy-templates"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("groovy.text"); - imports.addImports(EnableGroovyTemplates.class.getCanonicalName()); - imports.addStaticImport(GroovyTemplate.class.getName(), "template"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableGroovyTemplates"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add("groovy-templates"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addStarImports("groovy.text"); + imports.addImports(EnableGroovyTemplates.class.getCanonicalName()); + imports.addStaticImport(GroovyTemplate.class.getName(), "template"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JdbcCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JdbcCompilerAutoConfiguration.java index 3f7bda97fc..513d79e579 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JdbcCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JdbcCompilerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -27,25 +26,25 @@ * {@link CompilerAutoConfiguration} for Spring JDBC. * * @author Dave Syer - * @since 1.0.0 + * @since 2022.1.0 */ public class JdbcCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneFieldOrMethod(classNode, "JdbcTemplate", "NamedParameterJdbcTemplate", - "DataSource"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.jdbc.core.JdbcTemplate").add("spring-boot-starter-jdbc"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.jdbc.core", "org.springframework.jdbc.core.namedparam"); - imports.addImports("javax.sql.DataSource"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneFieldOrMethod(classNode, "JdbcTemplate", "NamedParameterJdbcTemplate", + "DataSource"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.jdbc.core.JdbcTemplate").add("spring-boot-starter-jdbc"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addStarImports("org.springframework.jdbc.core", "org.springframework.jdbc.core.namedparam"); + imports.addImports("javax.sql.DataSource"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JmsCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JmsCompilerAutoConfiguration.java index aee4d40e52..22d91fa0c2 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JmsCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/JmsCompilerAutoConfiguration.java @@ -29,7 +29,7 @@ * * @author Greg Turnquist * @author Stephane Nicoll - * @since 1.0.0 + * @since 2022.1.0 */ public class JmsCompilerAutoConfiguration extends CompilerAutoConfiguration { diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/RabbitCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/RabbitCompilerAutoConfiguration.java index 23392634bc..6ec4450e21 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/RabbitCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/RabbitCompilerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -29,28 +28,28 @@ * * @author Greg Turnquist * @author Stephane Nicoll - * @since 1.0.0 + * @since 2022.1.0 */ public class RabbitCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRabbit") - || AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRabbitMessaging"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { - dependencies.add("spring-rabbit"); - - } - - @Override - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - imports.addStarImports("org.springframework.amqp.rabbit.annotation", "org.springframework.amqp.rabbit.core", - "org.springframework.amqp.rabbit.config", "org.springframework.amqp.rabbit.connection", - "org.springframework.amqp.rabbit.listener", "org.springframework.amqp.rabbit.listener.adapter", - "org.springframework.amqp.core"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRabbit") + || AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRabbitMessaging"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) throws CompilationFailedException { + dependencies.add("spring-rabbit"); + + } + + @Override + public void applyImports(ImportCustomizer imports) throws CompilationFailedException { + imports.addStarImports("org.springframework.amqp.rabbit.annotation", "org.springframework.amqp.rabbit.core", + "org.springframework.amqp.rabbit.config", "org.springframework.amqp.rabbit.connection", + "org.springframework.amqp.rabbit.listener", "org.springframework.amqp.rabbit.listener.adapter", + "org.springframework.amqp.core"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java index f99778b483..3ca6919163 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBatchCompilerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -28,36 +27,36 @@ * * @author Dave Syer * @author Phillip Webb - * @since 1.0.0 + * @since 2022.1.0 */ public class SpringBatchCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableBatchProcessing"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.batch.core.Job").add("spring-boot-starter-batch"); - dependencies.ifAnyMissingClasses("org.springframework.jdbc.core.JdbcTemplate").add("spring-jdbc"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addImports("org.springframework.batch.repeat.RepeatStatus", - "org.springframework.batch.core.scope.context.ChunkContext", - "org.springframework.batch.core.step.tasklet.Tasklet", - "org.springframework.batch.core.configuration.annotation.StepScope", - "org.springframework.batch.core.configuration.annotation.JobBuilderFactory", - "org.springframework.batch.core.configuration.annotation.StepBuilderFactory", - "org.springframework.batch.core.configuration.annotation.EnableBatchProcessing", - "org.springframework.batch.core.Step", "org.springframework.batch.core.StepExecution", - "org.springframework.batch.core.StepContribution", "org.springframework.batch.core.Job", - "org.springframework.batch.core.JobExecution", "org.springframework.batch.core.JobParameter", - "org.springframework.batch.core.JobParameters", "org.springframework.batch.core.launch.JobLauncher", - "org.springframework.batch.core.converter.JobParametersConverter", - "org.springframework.batch.core.converter.DefaultJobParametersConverter"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableBatchProcessing"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.batch.core.Job").add("spring-boot-starter-batch"); + dependencies.ifAnyMissingClasses("org.springframework.jdbc.core.JdbcTemplate").add("spring-jdbc"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addImports("org.springframework.batch.repeat.RepeatStatus", + "org.springframework.batch.core.scope.context.ChunkContext", + "org.springframework.batch.core.step.tasklet.Tasklet", + "org.springframework.batch.core.configuration.annotation.StepScope", + "org.springframework.batch.core.configuration.annotation.JobBuilderFactory", + "org.springframework.batch.core.configuration.annotation.StepBuilderFactory", + "org.springframework.batch.core.configuration.annotation.EnableBatchProcessing", + "org.springframework.batch.core.Step", "org.springframework.batch.core.StepExecution", + "org.springframework.batch.core.StepContribution", "org.springframework.batch.core.Job", + "org.springframework.batch.core.JobExecution", "org.springframework.batch.core.JobParameter", + "org.springframework.batch.core.JobParameters", "org.springframework.batch.core.launch.JobLauncher", + "org.springframework.batch.core.converter.JobParametersConverter", + "org.springframework.batch.core.converter.DefaultJobParametersConverter"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java index a586078fae..893b9474f3 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringBootCompilerAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import groovy.lang.GroovyClassLoader; @@ -34,60 +33,60 @@ * * @author Dave Syer * @author Phillip Webb - * @since 1.0.0 + * @since 2022.1.0 */ public class SpringBootCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.boot.SpringApplication").add("spring-boot-starter"); - } + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.boot.SpringApplication").add("spring-boot-starter"); + } - @Override - public void applyImports(ImportCustomizer imports) { - imports.addImports("javax.annotation.PostConstruct", "javax.annotation.PreDestroy", "groovy.util.logging.Log", - "org.springframework.stereotype.Controller", "org.springframework.stereotype.Service", - "org.springframework.stereotype.Component", "org.springframework.beans.factory.annotation.Autowired", - "org.springframework.beans.factory.annotation.Value", "org.springframework.context.annotation.Import", - "org.springframework.context.annotation.ImportResource", - "org.springframework.context.annotation.Profile", "org.springframework.context.annotation.Scope", - "org.springframework.context.annotation.Configuration", - "org.springframework.context.annotation.ComponentScan", "org.springframework.context.annotation.Bean", - "org.springframework.context.ApplicationContext", "org.springframework.context.MessageSource", - "org.springframework.core.annotation.Order", "org.springframework.core.io.ResourceLoader", - "org.springframework.boot.ApplicationRunner", "org.springframework.boot.ApplicationArguments", - "org.springframework.boot.CommandLineRunner", - "org.springframework.boot.context.properties.ConfigurationProperties", - "org.springframework.boot.context.properties.EnableConfigurationProperties", - "org.springframework.boot.autoconfigure.EnableAutoConfiguration", - "org.springframework.boot.autoconfigure.SpringBootApplication", - "org.springframework.boot.context.properties.ConfigurationProperties", - "org.springframework.boot.context.properties.EnableConfigurationProperties"); - imports.addStarImports("org.springframework.stereotype", "org.springframework.scheduling.annotation"); - } + @Override + public void applyImports(ImportCustomizer imports) { + imports.addImports("javax.annotation.PostConstruct", "javax.annotation.PreDestroy", "groovy.util.logging.Log", + "org.springframework.stereotype.Controller", "org.springframework.stereotype.Service", + "org.springframework.stereotype.Component", "org.springframework.beans.factory.annotation.Autowired", + "org.springframework.beans.factory.annotation.Value", "org.springframework.context.annotation.Import", + "org.springframework.context.annotation.ImportResource", + "org.springframework.context.annotation.Profile", "org.springframework.context.annotation.Scope", + "org.springframework.context.annotation.Configuration", + "org.springframework.context.annotation.ComponentScan", "org.springframework.context.annotation.Bean", + "org.springframework.context.ApplicationContext", "org.springframework.context.MessageSource", + "org.springframework.core.annotation.Order", "org.springframework.core.io.ResourceLoader", + "org.springframework.boot.ApplicationRunner", "org.springframework.boot.ApplicationArguments", + "org.springframework.boot.CommandLineRunner", + "org.springframework.boot.context.properties.ConfigurationProperties", + "org.springframework.boot.context.properties.EnableConfigurationProperties", + "org.springframework.boot.autoconfigure.EnableAutoConfiguration", + "org.springframework.boot.autoconfigure.SpringBootApplication", + "org.springframework.boot.context.properties.ConfigurationProperties", + "org.springframework.boot.context.properties.EnableConfigurationProperties"); + imports.addStarImports("org.springframework.stereotype", "org.springframework.scheduling.annotation"); + } - @Override - public void applyToMainClass(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - addEnableAutoConfigurationAnnotation(classNode); - } + @Override + public void applyToMainClass(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, + GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) + throws CompilationFailedException { + addEnableAutoConfigurationAnnotation(classNode); + } - private void addEnableAutoConfigurationAnnotation(ClassNode classNode) { - if (!hasEnableAutoConfigureAnnotation(classNode)) { - AnnotationNode annotationNode = new AnnotationNode(ClassHelper.make("EnableAutoConfiguration")); - classNode.addAnnotation(annotationNode); - } - } + private void addEnableAutoConfigurationAnnotation(ClassNode classNode) { + if (!hasEnableAutoConfigureAnnotation(classNode)) { + AnnotationNode annotationNode = new AnnotationNode(ClassHelper.make("EnableAutoConfiguration")); + classNode.addAnnotation(annotationNode); + } + } - private boolean hasEnableAutoConfigureAnnotation(ClassNode classNode) { - for (AnnotationNode node : classNode.getAnnotations()) { - String name = node.getClassNode().getNameWithoutPackage(); - if ("EnableAutoConfiguration".equals(name) || "SpringBootApplication".equals(name)) { - return true; - } - } - return false; - } + private boolean hasEnableAutoConfigureAnnotation(ClassNode classNode) { + for (AnnotationNode node : classNode.getAnnotations()) { + String name = node.getClassNode().getNameWithoutPackage(); + if ("EnableAutoConfiguration".equals(name) || "SpringBootApplication".equals(name)) { + return true; + } + } + return false; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringIntegrationCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringIntegrationCompilerAutoConfiguration.java index c1bc24e37f..77e2db9d53 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringIntegrationCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringIntegrationCompilerAutoConfiguration.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -28,34 +27,34 @@ * * @author Dave Syer * @author Artem Bilan - * @since 1.0.0 + * @since 2022.1.0 */ public class SpringIntegrationCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableIntegration") - || AstUtils.hasAtLeastOneAnnotation(classNode, "MessageEndpoint"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.integration.config.EnableIntegration") - .add("spring-boot-starter-integration"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addImports("org.springframework.messaging.Message", "org.springframework.messaging.MessageChannel", - "org.springframework.messaging.PollableChannel", "org.springframework.messaging.SubscribableChannel", - "org.springframework.messaging.MessageHeaders", - "org.springframework.integration.support.MessageBuilder", - "org.springframework.integration.channel.DirectChannel", - "org.springframework.integration.channel.QueueChannel", - "org.springframework.integration.channel.ExecutorChannel", - "org.springframework.integration.core.MessagingTemplate", - "org.springframework.integration.config.EnableIntegration"); - imports.addStarImports("org.springframework.integration.annotation"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableIntegration") + || AstUtils.hasAtLeastOneAnnotation(classNode, "MessageEndpoint"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.integration.config.EnableIntegration") + .add("spring-boot-starter-integration"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addImports("org.springframework.messaging.Message", "org.springframework.messaging.MessageChannel", + "org.springframework.messaging.PollableChannel", "org.springframework.messaging.SubscribableChannel", + "org.springframework.messaging.MessageHeaders", + "org.springframework.integration.support.MessageBuilder", + "org.springframework.integration.channel.DirectChannel", + "org.springframework.integration.channel.QueueChannel", + "org.springframework.integration.channel.ExecutorChannel", + "org.springframework.integration.core.MessagingTemplate", + "org.springframework.integration.config.EnableIntegration"); + imports.addStarImports("org.springframework.integration.annotation"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java index 692c7dfd6d..22deff24cf 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringMvcCompilerAutoConfiguration.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -29,29 +28,29 @@ * * @author Dave Syer * @author Phillip Webb - * @since 1.0.0 + * @since 2022.1.0 */ public class SpringMvcCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "Controller", "RestController", "EnableWebMvc"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.web.servlet.mvc.Controller") - .add("spring-boot-starter-web"); - dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add("groovy-templates"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.web.bind.annotation", - "org.springframework.web.servlet.config.annotation", "org.springframework.web.servlet", - "org.springframework.http", "org.springframework.web.servlet.handler", "org.springframework.http", - "org.springframework.ui", "groovy.text"); - imports.addStaticImport(GroovyTemplate.class.getName(), "template"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "Controller", "RestController", "EnableWebMvc"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.web.servlet.mvc.Controller") + .add("spring-boot-starter-web"); + dependencies.ifAnyMissingClasses("groovy.text.TemplateEngine").add("groovy-templates"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addStarImports("org.springframework.web.bind.annotation", + "org.springframework.web.servlet.config.annotation", "org.springframework.web.servlet", + "org.springframework.http", "org.springframework.web.servlet.handler", "org.springframework.http", + "org.springframework.ui", "groovy.text"); + imports.addStaticImport(GroovyTemplate.class.getName(), "template"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringRetryCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringRetryCompilerAutoConfiguration.java index f69aa885e4..77f293f021 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringRetryCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringRetryCompilerAutoConfiguration.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -27,24 +26,24 @@ * {@link CompilerAutoConfiguration} for Spring Retry. * * @author Dave Syer - * @since 1.3.0 + * @since 2022.1.0 */ public class SpringRetryCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRetry", "Retryable", "Recover"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.retry.annotation.EnableRetry") - .add("spring-retry", "spring-boot-starter-aop"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.retry.annotation"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableRetry", "Retryable", "Recover"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.retry.annotation.EnableRetry") + .add("spring-retry", "spring-boot-starter-aop"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addStarImports("org.springframework.retry.annotation"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringSecurityCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringSecurityCompilerAutoConfiguration.java index adcb9a9b62..7206cd7c0f 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringSecurityCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringSecurityCompilerAutoConfiguration.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -27,32 +26,32 @@ * {@link CompilerAutoConfiguration} for Spring Security. * * @author Dave Syer - * @since 1.0.0 + * @since 2022.1.0 */ public class SpringSecurityCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableWebSecurity", "EnableGlobalMethodSecurity"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies - .ifAnyMissingClasses( - "org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity") - .add("spring-boot-starter-security"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports - .addImports("org.springframework.security.core.Authentication", - "org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity", - "org.springframework.security.core.authority.AuthorityUtils") - .addStarImports("org.springframework.security.config.annotation.web.configuration", - "org.springframework.security.authentication", "org.springframework.security.config.annotation.web", - "org.springframework.security.config.annotation.web.builders"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableWebSecurity", "EnableGlobalMethodSecurity"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies + .ifAnyMissingClasses( + "org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity") + .add("spring-boot-starter-security"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports + .addImports("org.springframework.security.core.Authentication", + "org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity", + "org.springframework.security.core.authority.AuthorityUtils") + .addStarImports("org.springframework.security.config.annotation.web.configuration", + "org.springframework.security.authentication", "org.springframework.security.config.annotation.web", + "org.springframework.security.config.annotation.web.builders"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringTestCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringTestCompilerAutoConfiguration.java index ef9a6e1115..d76cf7efdb 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringTestCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringTestCompilerAutoConfiguration.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import groovy.lang.GroovyClassLoader; @@ -35,40 +34,40 @@ * {@link CompilerAutoConfiguration} for Spring Test. * * @author Dave Syer - * @since 1.1.0 + * @since 2022.1.0 */ public class SpringTestCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "SpringBootTest"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "SpringBootTest"); + } - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.http.HttpHeaders").add("spring-boot-starter-web"); - } + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.http.HttpHeaders").add("spring-boot-starter-web"); + } - @Override - public void apply(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, - GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) - throws CompilationFailedException { - if (!AstUtils.hasAtLeastOneAnnotation(classNode, "RunWith")) { - AnnotationNode runWith = new AnnotationNode(ClassHelper.make("RunWith")); - runWith.addMember("value", new ClassExpression(ClassHelper.make("SpringRunner"))); - classNode.addAnnotation(runWith); - } - } + @Override + public void apply(GroovyClassLoader loader, GroovyCompilerConfiguration configuration, + GeneratorContext generatorContext, SourceUnit source, ClassNode classNode) + throws CompilationFailedException { + if (!AstUtils.hasAtLeastOneAnnotation(classNode, "RunWith")) { + AnnotationNode runWith = new AnnotationNode(ClassHelper.make("RunWith")); + runWith.addMember("value", new ClassExpression(ClassHelper.make("SpringRunner"))); + classNode.addAnnotation(runWith); + } + } - @Override - public void applyImports(ImportCustomizer imports) throws CompilationFailedException { - imports - .addStarImports("org.junit.runner", "org.springframework.boot.test", - "org.springframework.boot.test.context", "org.springframework.boot.test.web.client", - "org.springframework.http", "org.springframework.test.context.junit4", - "org.springframework.test.annotation") - .addImports("org.springframework.boot.test.context.SpringBootTest.WebEnvironment", - "org.springframework.boot.test.web.client.TestRestTemplate"); - } + @Override + public void applyImports(ImportCustomizer imports) throws CompilationFailedException { + imports + .addStarImports("org.junit.runner", "org.springframework.boot.test", + "org.springframework.boot.test.context", "org.springframework.boot.test.web.client", + "org.springframework.http", "org.springframework.test.context.junit4", + "org.springframework.test.annotation") + .addImports("org.springframework.boot.test.context.SpringBootTest.WebEnvironment", + "org.springframework.boot.test.web.client.TestRestTemplate"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringWebsocketCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringWebsocketCompilerAutoConfiguration.java index 52983a1b55..146ab5c155 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringWebsocketCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/SpringWebsocketCompilerAutoConfiguration.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -27,30 +26,30 @@ * {@link CompilerAutoConfiguration} for Spring Websocket. * * @author Dave Syer - * @since 1.0.0 + * @since 2022.1.0 */ public class SpringWebsocketCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableWebSocket", "EnableWebSocketMessageBroker"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.web.socket.config.annotation.EnableWebSocket") - .add("spring-boot-starter-websocket") - .add("spring-messaging"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports - .addStarImports("org.springframework.messaging.handler.annotation", - "org.springframework.messaging.simp.config", "org.springframework.web.socket.handler", - "org.springframework.web.socket.sockjs.transport.handler", - "org.springframework.web.socket.config.annotation") - .addImports("org.springframework.web.socket.WebSocketHandler"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableWebSocket", "EnableWebSocketMessageBroker"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.web.socket.config.annotation.EnableWebSocket") + .add("spring-boot-starter-websocket") + .add("spring-messaging"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports + .addStarImports("org.springframework.messaging.handler.annotation", + "org.springframework.messaging.simp.config", "org.springframework.web.socket.handler", + "org.springframework.web.socket.sockjs.transport.handler", + "org.springframework.web.socket.config.annotation") + .addImports("org.springframework.web.socket.WebSocketHandler"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/TransactionManagementCompilerAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/TransactionManagementCompilerAutoConfiguration.java index 69a46ab179..4e92402f1f 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/TransactionManagementCompilerAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/autoconfigure/TransactionManagementCompilerAutoConfiguration.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.autoconfigure; import org.codehaus.groovy.ast.ClassNode; @@ -28,26 +27,26 @@ * * @author Dave Syer * @author Phillip Webb - * @since 1.0.0 + * @since 2022.1.0 */ public class TransactionManagementCompilerAutoConfiguration extends CompilerAutoConfiguration { - @Override - public boolean matches(ClassNode classNode) { - return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableTransactionManagement"); - } - - @Override - public void applyDependencies(DependencyCustomizer dependencies) { - dependencies.ifAnyMissingClasses("org.springframework.transaction.annotation.Transactional") - .add("spring-tx", "spring-boot-starter-aop"); - } - - @Override - public void applyImports(ImportCustomizer imports) { - imports.addStarImports("org.springframework.transaction.annotation", "org.springframework.transaction.support"); - imports.addImports("org.springframework.transaction.PlatformTransactionManager", - "org.springframework.transaction.support.AbstractPlatformTransactionManager"); - } + @Override + public boolean matches(ClassNode classNode) { + return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableTransactionManagement"); + } + + @Override + public void applyDependencies(DependencyCustomizer dependencies) { + dependencies.ifAnyMissingClasses("org.springframework.transaction.annotation.Transactional") + .add("spring-tx", "spring-boot-starter-aop"); + } + + @Override + public void applyImports(ImportCustomizer imports) { + imports.addStarImports("org.springframework.transaction.annotation", "org.springframework.transaction.support"); + imports.addImports("org.springframework.transaction.PlatformTransactionManager", + "org.springframework.transaction.support.AbstractPlatformTransactionManager"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/ArtifactCoordinatesResolver.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/ArtifactCoordinatesResolver.java index 80d41b9c6e..949f86e7b6 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/ArtifactCoordinatesResolver.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/ArtifactCoordinatesResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.dependencies; /** @@ -29,28 +28,31 @@ */ public interface ArtifactCoordinatesResolver { - /** - * Gets the group id of the artifact identified by the given {@code module}. Returns - * {@code null} if the artifact is unknown to the resolver. - * @param module the id of the module - * @return the group id of the module - */ - String getGroupId(String module); + /** + * Gets the group id of the artifact identified by the given {@code module}. Returns + * {@code null} if the artifact is unknown to the resolver. + * + * @param module the id of the module + * @return the group id of the module + */ + String getGroupId(String module); - /** - * Gets the artifact id of the artifact identified by the given {@code module}. - * Returns {@code null} if the artifact is unknown to the resolver. - * @param module the id of the module - * @return the artifact id of the module - */ - String getArtifactId(String module); + /** + * Gets the artifact id of the artifact identified by the given {@code module}. + * Returns {@code null} if the artifact is unknown to the resolver. + * + * @param module the id of the module + * @return the artifact id of the module + */ + String getArtifactId(String module); - /** - * Gets the version of the artifact identified by the given {@code module}. Returns - * {@code null} if the artifact is unknown to the resolver. - * @param module the id of the module - * @return the version of the module - */ - String getVersion(String module); + /** + * Gets the version of the artifact identified by the given {@code module}. Returns + * {@code null} if the artifact is unknown to the resolver. + * + * @param module the id of the module + * @return the version of the module + */ + String getVersion(String module); } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/CompositeDependencyManagement.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/CompositeDependencyManagement.java index 2617109c25..c17b38048f 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/CompositeDependencyManagement.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/CompositeDependencyManagement.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.dependencies; import java.util.ArrayList; @@ -25,57 +24,57 @@ * instances. * * @author Andy Wilkinson - * @since 1.3.0 + * @since 2022.1.0 */ public class CompositeDependencyManagement implements DependencyManagement { - private final List delegates; + private final List delegates; - private final List dependencies = new ArrayList<>(); + private final List dependencies = new ArrayList<>(); - public CompositeDependencyManagement(DependencyManagement... delegates) { - this.delegates = Arrays.asList(delegates); - for (DependencyManagement delegate : delegates) { - this.dependencies.addAll(delegate.getDependencies()); - } - } + public CompositeDependencyManagement(DependencyManagement... delegates) { + this.delegates = Arrays.asList(delegates); + for (DependencyManagement delegate : delegates) { + this.dependencies.addAll(delegate.getDependencies()); + } + } - @Override - public List getDependencies() { - return this.dependencies; - } + @Override + public List 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 String getSpringBootVersion() { + for (DependencyManagement delegate : this.delegates) { + String version = delegate.getSpringBootVersion(); + if (version != null) { + return version; + } + } + return null; + } - @Override - public String getGrailsVersion() { - for (DependencyManagement delegate : this.delegates) { - String version = delegate.getGrailsVersion(); - if (version != null) { - return version; - } - } - return null; - } + @Override + public String getGrailsVersion() { + for (DependencyManagement delegate : this.delegates) { + String version = delegate.getGrailsVersion(); + 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; - } + @Override + public Dependency find(String artifactId) { + for (DependencyManagement delegate : this.delegates) { + Dependency found = delegate.find(artifactId); + if (found != null) { + return found; + } + } + return null; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/Dependency.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/Dependency.java index 8466874774..e6815bc046 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/Dependency.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/Dependency.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.dependencies; import java.util.Collections; @@ -25,174 +24,182 @@ * A single dependency. * * @author Phillip Webb - * @since 1.3.0 + * @since 2022.1.0 */ public final class Dependency { - private final String groupId; - - private final String artifactId; - - private final String version; - - private final List exclusions; - - /** - * Create a new {@link Dependency} instance. - * @param groupId the group ID - * @param artifactId the artifact ID - * @param version the version - */ - public Dependency(String groupId, String artifactId, String version) { - this(groupId, artifactId, version, Collections.emptyList()); - } - - /** - * Create a new {@link Dependency} instance. - * @param groupId the group ID - * @param artifactId the artifact ID - * @param version the version - * @param exclusions the exclusions - */ - public Dependency(String groupId, String artifactId, String version, List exclusions) { - Assert.notNull(groupId, "GroupId must not be null"); - Assert.notNull(artifactId, "ArtifactId must not be null"); - Assert.notNull(version, "Version must not be null"); - Assert.notNull(exclusions, "Exclusions must not be null"); - this.groupId = groupId; - this.artifactId = artifactId; - this.version = version; - this.exclusions = Collections.unmodifiableList(exclusions); - } - - /** - * Return the dependency group id. - * @return the group ID - */ - public String getGroupId() { - return this.groupId; - } - - /** - * Return the dependency artifact id. - * @return the artifact ID - */ - public String getArtifactId() { - return this.artifactId; - } - - /** - * Return the dependency version. - * @return the version - */ - public String getVersion() { - return this.version; - } - - /** - * Return the dependency exclusions. - * @return the exclusions - */ - public List getExclusions() { - return this.exclusions; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() == obj.getClass()) { - Dependency other = (Dependency) obj; - boolean result = true; - result = result && this.groupId.equals(other.groupId); - result = result && this.artifactId.equals(other.artifactId); - result = result && this.version.equals(other.version); - result = result && this.exclusions.equals(other.exclusions); - return result; - } - return false; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + this.groupId.hashCode(); - result = prime * result + this.artifactId.hashCode(); - result = prime * result + this.version.hashCode(); - result = prime * result + this.exclusions.hashCode(); - return result; - } - - @Override - public String toString() { - return this.groupId + ":" + this.artifactId + ":" + this.version; - } - - /** - * A dependency exclusion. - */ - public static final class Exclusion { - - private final String groupId; - - private final String artifactId; - - Exclusion(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; - } - - /** - * Return the exclusion artifact ID. - * @return the exclusion artifact ID - */ - public String getArtifactId() { - return this.artifactId; - } - - /** - * Return the exclusion group ID. - * @return the exclusion group ID - */ - public String getGroupId() { - return this.groupId; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() == obj.getClass()) { - Exclusion other = (Exclusion) obj; - boolean result = true; - result = result && this.groupId.equals(other.groupId); - result = result && this.artifactId.equals(other.artifactId); - return result; - } - return false; - } - - @Override - public int hashCode() { - return this.groupId.hashCode() * 31 + this.artifactId.hashCode(); - } - - @Override - public String toString() { - return this.groupId + ":" + this.artifactId; - } - - } + private final String groupId; + + private final String artifactId; + + private final String version; + + private final List exclusions; + + /** + * Create a new {@link Dependency} instance. + * + * @param groupId the group ID + * @param artifactId the artifact ID + * @param version the version + */ + public Dependency(String groupId, String artifactId, String version) { + this(groupId, artifactId, version, Collections.emptyList()); + } + + /** + * Create a new {@link Dependency} instance. + * + * @param groupId the group ID + * @param artifactId the artifact ID + * @param version the version + * @param exclusions the exclusions + */ + public Dependency(String groupId, String artifactId, String version, List exclusions) { + Assert.notNull(groupId, "GroupId must not be null"); + Assert.notNull(artifactId, "ArtifactId must not be null"); + Assert.notNull(version, "Version must not be null"); + Assert.notNull(exclusions, "Exclusions must not be null"); + this.groupId = groupId; + this.artifactId = artifactId; + this.version = version; + this.exclusions = Collections.unmodifiableList(exclusions); + } + + /** + * Return the dependency group id. + * + * @return the group ID + */ + public String getGroupId() { + return this.groupId; + } + + /** + * Return the dependency artifact id. + * + * @return the artifact ID + */ + public String getArtifactId() { + return this.artifactId; + } + + /** + * Return the dependency version. + * + * @return the version + */ + public String getVersion() { + return this.version; + } + + /** + * Return the dependency exclusions. + * + * @return the exclusions + */ + public List getExclusions() { + return this.exclusions; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() == obj.getClass()) { + Dependency other = (Dependency) obj; + boolean result = true; + result = result && this.groupId.equals(other.groupId); + result = result && this.artifactId.equals(other.artifactId); + result = result && this.version.equals(other.version); + result = result && this.exclusions.equals(other.exclusions); + return result; + } + return false; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + this.groupId.hashCode(); + result = prime * result + this.artifactId.hashCode(); + result = prime * result + this.version.hashCode(); + result = prime * result + this.exclusions.hashCode(); + return result; + } + + @Override + public String toString() { + return this.groupId + ":" + this.artifactId + ":" + this.version; + } + + /** + * A dependency exclusion. + */ + public static final class Exclusion { + + private final String groupId; + + private final String artifactId; + + Exclusion(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; + } + + /** + * Return the exclusion artifact ID. + * + * @return the exclusion artifact ID + */ + public String getArtifactId() { + return this.artifactId; + } + + /** + * Return the exclusion group ID. + * + * @return the exclusion group ID + */ + public String getGroupId() { + return this.groupId; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() == obj.getClass()) { + Exclusion other = (Exclusion) obj; + boolean result = true; + result = result && this.groupId.equals(other.groupId); + result = result && this.artifactId.equals(other.artifactId); + return result; + } + return false; + } + + @Override + public int hashCode() { + return this.groupId.hashCode() * 31 + this.artifactId.hashCode(); + } + + @Override + public String toString() { + return this.groupId + ":" + this.artifactId; + } + + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagement.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagement.java index 6d5dc2fa24..7dd7cf54fd 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagement.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagement.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.dependencies; import java.util.List; @@ -22,29 +21,32 @@ * An encapsulation of dependency management information. * * @author Andy Wilkinson - * @since 1.3.0 + * @since 2022.1.0 */ public interface DependencyManagement { - /** - * Returns the managed dependencies. - * @return the managed dependencies - */ - List getDependencies(); - - /** - * Returns the managed version of Spring Boot. May be {@code null}. - * @return the Spring Boot version, or {@code null} - */ - String getSpringBootVersion(); - - String getGrailsVersion(); - - /** - * 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); + /** + * Returns the managed dependencies. + * + * @return the managed dependencies + */ + List getDependencies(); + + /** + * Returns the managed version of Spring Boot. May be {@code null}. + * + * @return the Spring Boot version, or {@code null} + */ + String getSpringBootVersion(); + + String getGrailsVersion(); + + /** + * 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); } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolver.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolver.java index 699e9a1620..2375914227 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolver.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/DependencyManagementArtifactCoordinatesResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.dependencies; import java.util.Set; @@ -26,58 +25,58 @@ * * @author Phillip Webb * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ public class DependencyManagementArtifactCoordinatesResolver implements ArtifactCoordinatesResolver { - public static final Set GRAILS_PLUGINS = Set.of("async", "cache", "events", "fields", "hibernate5", "gsp", "scaffolding"); + public static final Set GRAILS_PLUGINS = Set.of("async", "cache", "events", "fields", "hibernate5", "gsp", "scaffolding"); - private final DependencyManagement dependencyManagement; + private final DependencyManagement dependencyManagement; - public DependencyManagementArtifactCoordinatesResolver() { - this(new SpringBootDependenciesDependencyManagement()); - } + public DependencyManagementArtifactCoordinatesResolver() { + this(new SpringBootDependenciesDependencyManagement()); + } - public DependencyManagementArtifactCoordinatesResolver(DependencyManagement dependencyManagement) { - this.dependencyManagement = dependencyManagement; - } + public DependencyManagementArtifactCoordinatesResolver(DependencyManagement dependencyManagement) { + this.dependencyManagement = dependencyManagement; + } - @Override - public String getGroupId(String artifactId) { - Dependency dependency = find(artifactId); - return (dependency != null) ? dependency.getGroupId() : null; - } + @Override + public String getGroupId(String artifactId) { + Dependency dependency = find(artifactId); + return (dependency != null) ? dependency.getGroupId() : null; + } - @Override - public String getArtifactId(String id) { - Dependency dependency = find(id); - return (dependency != null) ? dependency.getArtifactId() : null; - } + @Override + public String getArtifactId(String id) { + Dependency dependency = find(id); + return (dependency != null) ? dependency.getArtifactId() : null; + } - 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()); - } - if (id.startsWith("grails")) { - return new Dependency("org.grails", id, this.dependencyManagement.getGrailsVersion()); - } - if (GRAILS_PLUGINS.contains(id)) { - return new Dependency("org.grails.plugins", id, this.dependencyManagement.find(id).getVersion()); - } - return this.dependencyManagement.find(id); - } - return null; - } + 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()); + } + if (id.startsWith("grails")) { + return new Dependency("org.grails", id, this.dependencyManagement.getGrailsVersion()); + } + if (GRAILS_PLUGINS.contains(id)) { + return new Dependency("org.grails.plugins", id, this.dependencyManagement.find(id).getVersion()); + } + return this.dependencyManagement.find(id); + } + return null; + } - @Override - public String getVersion(String module) { - Dependency dependency = find(module); - return (dependency != null) ? dependency.getVersion() : null; - } + @Override + public String getVersion(String module) { + Dependency dependency = find(module); + return (dependency != null) ? dependency.getVersion() : null; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/MavenModelDependencyManagement.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/MavenModelDependencyManagement.java index 799ff0bf72..c4ef8af0fd 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/MavenModelDependencyManagement.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/MavenModelDependencyManagement.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.dependencies; import java.util.ArrayList; @@ -29,53 +28,53 @@ * {@link DependencyManagement} derived from a Maven {@link Model}. * * @author Andy Wilkinson - * @since 1.3.0 + * @since 2022.1.0 */ public class MavenModelDependencyManagement implements DependencyManagement { - private final List dependencies; + private final List dependencies; - private final Map byArtifactId = new LinkedHashMap<>(); + private final Map byArtifactId = new LinkedHashMap<>(); - public MavenModelDependencyManagement(Model model) { - this.dependencies = extractDependenciesFromModel(model); - for (Dependency dependency : this.dependencies) { - this.byArtifactId.put(dependency.getArtifactId(), dependency); - } - } + public MavenModelDependencyManagement(Model model) { + this.dependencies = extractDependenciesFromModel(model); + for (Dependency dependency : this.dependencies) { + this.byArtifactId.put(dependency.getArtifactId(), dependency); + } + } - private static List extractDependenciesFromModel(Model model) { - List dependencies = new ArrayList<>(); - for (org.apache.maven.model.Dependency mavenDependency : model.getDependencyManagement().getDependencies()) { - List exclusions = new ArrayList<>(); - 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; - } + private static List extractDependenciesFromModel(Model model) { + List dependencies = new ArrayList<>(); + for (org.apache.maven.model.Dependency mavenDependency : model.getDependencyManagement().getDependencies()) { + List exclusions = new ArrayList<>(); + 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 getDependencies() { - return this.dependencies; - } + @Override + public List getDependencies() { + return this.dependencies; + } - @Override - public String getSpringBootVersion() { - return find("spring-boot").getVersion(); - } + @Override + public String getSpringBootVersion() { + return find("spring-boot").getVersion(); + } - @Override - public String getGrailsVersion() { - return find("grails-core").getVersion(); - } + @Override + public String getGrailsVersion() { + return find("grails-core").getVersion(); + } - @Override - public Dependency find(String artifactId) { - return this.byArtifactId.get(artifactId); - } + @Override + public Dependency find(String artifactId) { + return this.byArtifactId.get(artifactId); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/SpringBootDependenciesDependencyManagement.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/SpringBootDependenciesDependencyManagement.java index b101775397..545e5cd190 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/SpringBootDependenciesDependencyManagement.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/dependencies/SpringBootDependenciesDependencyManagement.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.dependencies; import java.io.IOException; @@ -28,26 +27,26 @@ * {@code spring-boot-dependencies}. * * @author Andy Wilkinson - * @since 1.3.0 + * @since 2022.1.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(org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement.class - .getResourceAsStream("spring-boot-dependencies-effective-bom.xml"), null); - } - catch (IOException ex) { - throw new IllegalStateException("Failed to build model from effective pom", ex); - } - } + public SpringBootDependenciesDependencyManagement() { + super(readModel()); + } + + private static Model readModel() { + DefaultModelProcessor modelProcessor = new DefaultModelProcessor(); + modelProcessor.setModelLocator(new DefaultModelLocator()); + modelProcessor.setModelReader(new DefaultModelReader()); + + try { + return modelProcessor.read(org.springframework.boot.cli.compiler.dependencies.SpringBootDependenciesDependencyManagement.class + .getResourceAsStream("spring-boot-dependencies-effective-bom.xml"), null); + } + catch (IOException ex) { + throw new IllegalStateException("Failed to build model from effective pom", ex); + } + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/CompositeProxySelector.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/CompositeProxySelector.java index f93ee853d9..0ed7f256e1 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/CompositeProxySelector.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/CompositeProxySelector.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.util.List; @@ -26,25 +25,25 @@ * Composite {@link ProxySelector}. * * @author Dave Syer - * @since 1.1.0 + * @since 2022.1.0 */ public class CompositeProxySelector implements ProxySelector { - private final List selectors; - - public CompositeProxySelector(List selectors) { - this.selectors = selectors; - } - - @Override - public Proxy getProxy(RemoteRepository repository) { - for (ProxySelector selector : this.selectors) { - Proxy proxy = selector.getProxy(repository); - if (proxy != null) { - return proxy; - } - } - return null; - } + private final List selectors; + + public CompositeProxySelector(List selectors) { + this.selectors = selectors; + } + + @Override + public Proxy getProxy(RemoteRepository repository) { + for (ProxySelector selector : this.selectors) { + Proxy proxy = selector.getProxy(repository); + if (proxy != null) { + return proxy; + } + } + return null; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java index f51a8f3cb9..3b0e94a876 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DefaultRepositorySystemSessionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.io.File; @@ -25,7 +24,6 @@ import org.eclipse.aether.repository.LocalRepositoryManager; import org.eclipse.aether.repository.ProxySelector; import org.eclipse.aether.util.repository.JreProxySelector; - import org.springframework.util.StringUtils; /** @@ -33,39 +31,39 @@ * configuration, applies sensible defaults. * * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ public class DefaultRepositorySystemSessionAutoConfiguration implements RepositorySystemSessionAutoConfiguration { - @Override - public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { + @Override + public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { - if (session.getLocalRepositoryManager() == null) { - LocalRepository localRepository = new LocalRepository(getM2RepoDirectory()); - LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager(session, - localRepository); - session.setLocalRepositoryManager(localRepositoryManager); - } + if (session.getLocalRepositoryManager() == null) { + LocalRepository localRepository = new LocalRepository(getM2RepoDirectory()); + LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager(session, + localRepository); + session.setLocalRepositoryManager(localRepositoryManager); + } - ProxySelector existing = session.getProxySelector(); - if (!(existing instanceof CompositeProxySelector)) { - JreProxySelector fallback = new JreProxySelector(); - ProxySelector selector = (existing != null) ? new CompositeProxySelector(Arrays.asList(existing, fallback)) - : fallback; - session.setProxySelector(selector); - } - } + ProxySelector existing = session.getProxySelector(); + if (!(existing instanceof CompositeProxySelector)) { + JreProxySelector fallback = new JreProxySelector(); + ProxySelector selector = (existing != null) ? new CompositeProxySelector(Arrays.asList(existing, fallback)) + : fallback; + session.setProxySelector(selector); + } + } - private File getM2RepoDirectory() { - return new File(getDefaultM2HomeDirectory(), "repository"); - } + private File getM2RepoDirectory() { + return new File(getDefaultM2HomeDirectory(), "repository"); + } - private File getDefaultM2HomeDirectory() { - String mavenRoot = System.getProperty("maven.home"); - if (StringUtils.hasLength(mavenRoot)) { - return new File(mavenRoot); - } - return new File(System.getProperty("user.home"), ".m2"); - } + private File getDefaultM2HomeDirectory() { + String mavenRoot = System.getProperty("maven.home"); + if (StringUtils.hasLength(mavenRoot)) { + return new File(mavenRoot); + } + return new File(System.getProperty("user.home"), ".m2"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionContext.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionContext.java index dcda4d6ff7..15fcd2fc10 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionContext.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionContext.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.util.ArrayList; @@ -36,72 +35,72 @@ * Context used when resolving dependencies. * * @author Andy Wilkinson - * @since 1.1.0 + * @since 2022.1.0 */ public class DependencyResolutionContext { - private final Map managedDependencyByGroupAndArtifact = new HashMap<>(); - - private final List managedDependencies = new ArrayList<>(); - - private DependencyManagement dependencyManagement = null; - - private ArtifactCoordinatesResolver artifactCoordinatesResolver; - - private String getIdentifier(Dependency dependency) { - return getIdentifier(dependency.getArtifact().getGroupId(), dependency.getArtifact().getArtifactId()); - } - - 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 getManagedDependencies() { - return Collections.unmodifiableList(this.managedDependencies); - } - - private Dependency getManagedDependency(String group, String artifact) { - return this.managedDependencyByGroupAndArtifact.get(getIdentifier(group, artifact)); - } - - public void addManagedDependencies(List dependencies) { - this.managedDependencies.addAll(dependencies); - for (Dependency dependency : dependencies) { - this.managedDependencyByGroupAndArtifact.put(getIdentifier(dependency), dependency); - } - } - - public void addDependencyManagement(DependencyManagement dependencyManagement) { - for (org.grails.cli.compiler.dependencies.Dependency dependency : dependencyManagement - .getDependencies()) { - List aetherExclusions = new ArrayList<>(); - for (org.grails.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.dependencyManagement = (this.dependencyManagement != null) - ? new CompositeDependencyManagement(dependencyManagement, this.dependencyManagement) - : dependencyManagement; - this.artifactCoordinatesResolver = new DependencyManagementArtifactCoordinatesResolver( - this.dependencyManagement); - } + private final Map managedDependencyByGroupAndArtifact = new HashMap<>(); + + private final List managedDependencies = new ArrayList<>(); + + private DependencyManagement dependencyManagement = null; + + private ArtifactCoordinatesResolver artifactCoordinatesResolver; + + private String getIdentifier(Dependency dependency) { + return getIdentifier(dependency.getArtifact().getGroupId(), dependency.getArtifact().getArtifactId()); + } + + 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 getManagedDependencies() { + return Collections.unmodifiableList(this.managedDependencies); + } + + private Dependency getManagedDependency(String group, String artifact) { + return this.managedDependencyByGroupAndArtifact.get(getIdentifier(group, artifact)); + } + + public void addManagedDependencies(List dependencies) { + this.managedDependencies.addAll(dependencies); + for (Dependency dependency : dependencies) { + this.managedDependencyByGroupAndArtifact.put(getIdentifier(dependency), dependency); + } + } + + public void addDependencyManagement(DependencyManagement dependencyManagement) { + for (org.grails.cli.compiler.dependencies.Dependency dependency : dependencyManagement + .getDependencies()) { + List aetherExclusions = new ArrayList<>(); + for (org.grails.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.dependencyManagement = (this.dependencyManagement != null) + ? new CompositeDependencyManagement(dependencyManagement, this.dependencyManagement) + : dependencyManagement; + this.artifactCoordinatesResolver = new DependencyManagementArtifactCoordinatesResolver( + this.dependencyManagement); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionFailedException.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionFailedException.java index d4b5afbf23..510ae23156 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionFailedException.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DependencyResolutionFailedException.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,25 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; /** * Thrown to indicate a failure during dependency resolution. * * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ @SuppressWarnings("serial") public class DependencyResolutionFailedException extends RuntimeException { - /** - * Creates a new {@code DependencyResolutionFailedException} with the given - * {@code cause}. - * @param cause the cause of the resolution failure - */ - public DependencyResolutionFailedException(Throwable cause) { - super(cause); - } + /** + * Creates a new {@code DependencyResolutionFailedException} with the given + * {@code cause}. + * + * @param cause the cause of the resolution failure + */ + public DependencyResolutionFailedException(Throwable cause) { + super(cause); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DetailedProgressReporter.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DetailedProgressReporter.java index 7dca749c5f..c6412c4c7b 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DetailedProgressReporter.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/DetailedProgressReporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.io.PrintStream; @@ -28,39 +27,40 @@ * Provide detailed progress feedback for long running resolves. * * @author Andy Wilkinson + * @since 2022.1.0 */ final class DetailedProgressReporter implements ProgressReporter { - DetailedProgressReporter(DefaultRepositorySystemSession session, final PrintStream out) { + DetailedProgressReporter(DefaultRepositorySystemSession session, final PrintStream out) { - session.setTransferListener(new AbstractTransferListener() { + session.setTransferListener(new AbstractTransferListener() { - @Override - public void transferStarted(TransferEvent event) throws TransferCancelledException { - out.println("Downloading: " + getResourceIdentifier(event.getResource())); - } + @Override + public void transferStarted(TransferEvent event) throws TransferCancelledException { + out.println("Downloading: " + getResourceIdentifier(event.getResource())); + } - @Override - public void transferSucceeded(TransferEvent event) { - out.printf("Downloaded: %s (%s)%n", getResourceIdentifier(event.getResource()), - getTransferSpeed(event)); - } - }); - } + @Override + public void transferSucceeded(TransferEvent event) { + out.printf("Downloaded: %s (%s)%n", getResourceIdentifier(event.getResource()), + getTransferSpeed(event)); + } + }); + } - private String getResourceIdentifier(TransferResource resource) { - return resource.getRepositoryUrl() + resource.getResourceName(); - } + private String getResourceIdentifier(TransferResource resource) { + return resource.getRepositoryUrl() + resource.getResourceName(); + } - private String getTransferSpeed(TransferEvent event) { - long kb = event.getTransferredBytes() / 1024; - float seconds = (System.currentTimeMillis() - event.getResource().getTransferStartTime()) / 1000.0f; + private String getTransferSpeed(TransferEvent event) { + long kb = event.getTransferredBytes() / 1024; + float seconds = (System.currentTimeMillis() - event.getResource().getTransferStartTime()) / 1000.0f; - return String.format("%dKB at %.1fKB/sec", kb, (kb / seconds)); - } + return String.format("%dKB at %.1fKB/sec", kb, (kb / seconds)); + } - @Override - public void finished() { - } + @Override + public void finished() { + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeEngineInstaller.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeEngineInstaller.java index 7bfd41aef4..00c66f0f4e 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeEngineInstaller.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeEngineInstaller.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.lang.reflect.Field; @@ -25,21 +24,21 @@ * Utility to install a specific {@link Grape} engine with Groovy. * * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ public abstract class GrapeEngineInstaller { - public static void install(GrapeEngine engine) { - synchronized (Grape.class) { - try { - Field field = Grape.class.getDeclaredField("instance"); - field.setAccessible(true); - field.set(null, engine); - } - catch (Exception ex) { - throw new IllegalStateException("Failed to install GrapeEngine", ex); - } - } - } + public static void install(GrapeEngine engine) { + synchronized (Grape.class) { + try { + Field field = Grape.class.getDeclaredField("instance"); + field.setAccessible(true); + field.set(null, engine); + } + catch (Exception ex) { + throw new IllegalStateException("Failed to install GrapeEngine", ex); + } + } + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java index 5130384c01..ef88325ae2 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/GrapeRootRepositorySystemSessionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.io.File; @@ -22,7 +21,6 @@ import org.eclipse.aether.RepositorySystem; import org.eclipse.aether.repository.LocalRepository; import org.eclipse.aether.repository.LocalRepositoryManager; - import org.springframework.util.StringUtils; /** @@ -30,25 +28,25 @@ * repository location. * * @author Andy Wilkinson - * @since 1.2.5 + * @since 2022.1.0 */ public class GrapeRootRepositorySystemSessionAutoConfiguration implements RepositorySystemSessionAutoConfiguration { - @Override - public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { - String grapeRoot = System.getProperty("grape.root"); - if (StringUtils.hasLength(grapeRoot)) { - configureLocalRepository(session, repositorySystem, grapeRoot); - } - } - - private void configureLocalRepository(DefaultRepositorySystemSession session, RepositorySystem repositorySystem, - String grapeRoot) { - File repositoryDir = new File(grapeRoot, "repository"); - LocalRepository localRepository = new LocalRepository(repositoryDir); - LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager(session, - localRepository); - session.setLocalRepositoryManager(localRepositoryManager); - } + @Override + public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { + String grapeRoot = System.getProperty("grape.root"); + if (StringUtils.hasLength(grapeRoot)) { + configureLocalRepository(session, repositorySystem, grapeRoot); + } + } + + private void configureLocalRepository(DefaultRepositorySystemSession session, RepositorySystem repositorySystem, + String grapeRoot) { + File repositoryDir = new File(grapeRoot, "repository"); + LocalRepository localRepository = new LocalRepository(repositoryDir); + LocalRepositoryManager localRepositoryManager = repositorySystem.newLocalRepositoryManager(session, + localRepository); + session.setLocalRepositoryManager(localRepositoryManager); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngine.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngine.java index 279755b0af..c318adbc4a 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngine.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngine.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.io.File; @@ -48,283 +47,283 @@ * * @author Andy Wilkinson * @author Phillip Webb - * @since 2.5.9 + * @since 2022.1.0 */ @SuppressWarnings("rawtypes") public class MavenResolverGrapeEngine implements GrapeEngine { - private static final Collection WILDCARD_EXCLUSION; - - static { - List exclusions = new ArrayList<>(); - exclusions.add(new Exclusion("*", "*", "*", "*")); - WILDCARD_EXCLUSION = Collections.unmodifiableList(exclusions); - } - - private final DependencyResolutionContext resolutionContext; - - private final ProgressReporter progressReporter; - - private final GroovyClassLoader classLoader; - - private final DefaultRepositorySystemSession session; - - private final RepositorySystem repositorySystem; - - private final List repositories; - - public MavenResolverGrapeEngine(GroovyClassLoader classLoader, RepositorySystem repositorySystem, - DefaultRepositorySystemSession repositorySystemSession, List remoteRepositories, - DependencyResolutionContext resolutionContext, boolean quiet) { - this.classLoader = classLoader; - this.repositorySystem = repositorySystem; - this.session = repositorySystemSession; - this.resolutionContext = resolutionContext; - this.repositories = new ArrayList<>(); - List remotes = new ArrayList<>(remoteRepositories); - Collections.reverse(remotes); // priority is reversed in addRepository - for (RemoteRepository repository : remotes) { - addRepository(repository); - } - this.progressReporter = getProgressReporter(this.session, quiet); - } - - private ProgressReporter getProgressReporter(DefaultRepositorySystemSession session, boolean quiet) { - String progressReporter = (quiet ? "none" - : System.getProperty("org.grails.cli.compiler.grape.ProgressReporter")); - if ("detail".equals(progressReporter) || Boolean.getBoolean("groovy.grape.report.downloads")) { - return new DetailedProgressReporter(session, System.out); - } - if ("none".equals(progressReporter)) { - return () -> { - }; - } - return new SummaryProgressReporter(session, System.out); - } - - @Override - public Object grab(Map args) { - return grab(args, args); - } - - @Override - public Object grab(Map args, Map... dependencyMaps) { - List exclusions = createExclusions(args); - List dependencies = createDependencies(dependencyMaps, exclusions); - try { - List files = resolve(dependencies); - GroovyClassLoader classLoader = getClassLoader(args); - for (File file : files) { - classLoader.addURL(file.toURI().toURL()); - } - } - catch (MalformedURLException ex) { - throw new DependencyResolutionFailedException(ex); - } - return null; - } - - @SuppressWarnings("unchecked") - private List createExclusions(Map args) { - List exclusions = new ArrayList<>(); - if (args != null) { - List> exclusionMaps = (List>) args.get("excludes"); - if (exclusionMaps != null) { - for (Map exclusionMap : exclusionMaps) { - exclusions.add(createExclusion(exclusionMap)); - } - } - } - return exclusions; - } - - private Exclusion createExclusion(Map exclusionMap) { - String group = (String) exclusionMap.get("group"); - String module = (String) exclusionMap.get("module"); - return new Exclusion(group, module, "*", "*"); - } - - private List createDependencies(Map[] dependencyMaps, List exclusions) { - List dependencies = new ArrayList<>(dependencyMaps.length); - for (Map dependencyMap : dependencyMaps) { - dependencies.add(createDependency(dependencyMap, exclusions)); - } - return dependencies; - } - - private Dependency createDependency(Map dependencyMap, List exclusions) { - Artifact artifact = createArtifact(dependencyMap); - if (isTransitive(dependencyMap)) { - return new Dependency(artifact, JavaScopes.COMPILE, false, exclusions); - } - return new Dependency(artifact, JavaScopes.COMPILE, null, WILDCARD_EXCLUSION); - } - - private Artifact createArtifact(Map dependencyMap) { - 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); - } - - private String determineType(Map dependencyMap) { - String type = (String) dependencyMap.get("type"); - String ext = (String) dependencyMap.get("ext"); - if (type == null) { - type = ext; - if (type == null) { - type = "jar"; - } - } - else if (ext != null && !type.equals(ext)) { - throw new IllegalArgumentException("If both type and ext are specified they must have the same value"); - } - return type; - } - - private boolean isTransitive(Map dependencyMap) { - Boolean transitive = (Boolean) dependencyMap.get("transitive"); - return (transitive != null) ? transitive : true; - } - - private List getDependencies(DependencyResult dependencyResult) { - List dependencies = new ArrayList<>(); - for (ArtifactResult artifactResult : dependencyResult.getArtifactResults()) { - dependencies.add(new Dependency(artifactResult.getArtifact(), JavaScopes.COMPILE)); - } - return dependencies; - } - - private List getFiles(DependencyResult dependencyResult) { - List files = new ArrayList<>(); - for (ArtifactResult result : dependencyResult.getArtifactResults()) { - files.add(result.getArtifact().getFile()); - } - return files; - } - - private GroovyClassLoader getClassLoader(Map args) { - GroovyClassLoader classLoader = (GroovyClassLoader) args.get("classLoader"); - return (classLoader != null) ? classLoader : this.classLoader; - } - - @Override - public void addResolver(Map args) { - String name = (String) args.get("name"); - String root = (String) args.get("root"); - RemoteRepository.Builder builder = new RemoteRepository.Builder(name, "default", root); - RemoteRepository repository = builder.build(); - addRepository(repository); - } - - protected void addRepository(RemoteRepository repository) { - if (this.repositories.contains(repository)) { - return; - } - repository = getPossibleMirror(repository); - repository = applyProxy(repository); - repository = applyAuthentication(repository); - this.repositories.add(0, repository); - } - - private RemoteRepository getPossibleMirror(RemoteRepository remoteRepository) { - RemoteRepository mirror = this.session.getMirrorSelector().getMirror(remoteRepository); - if (mirror != null) { - return mirror; - } - return remoteRepository; - } - - private RemoteRepository applyProxy(RemoteRepository repository) { - if (repository.getProxy() == null) { - RemoteRepository.Builder builder = new RemoteRepository.Builder(repository); - builder.setProxy(this.session.getProxySelector().getProxy(repository)); - repository = builder.build(); - } - return repository; - } - - private RemoteRepository applyAuthentication(RemoteRepository repository) { - if (repository.getAuthentication() == null) { - RemoteRepository.Builder builder = new RemoteRepository.Builder(repository); - builder.setAuthentication(this.session.getAuthenticationSelector().getAuthentication(repository)); - repository = builder.build(); - } - return repository; - } - - @Override - public Map>> enumerateGrapes() { - throw new UnsupportedOperationException("Grape enumeration is not supported"); - } - - @Override - public URI[] resolve(Map args, Map... dependencyMaps) { - return resolve(args, null, dependencyMaps); - } - - @Override - public URI[] resolve(Map args, List depsInfo, Map... dependencyMaps) { - List exclusions = createExclusions(args); - List dependencies = createDependencies(dependencyMaps, exclusions); - try { - List files = resolve(dependencies); - List uris = new ArrayList<>(files.size()); - for (File file : files) { - uris.add(file.toURI()); - } - return uris.toArray(new URI[0]); - } - catch (Exception ex) { - throw new DependencyResolutionFailedException(ex); - } - } - - private List resolve(List dependencies) { - try { - CollectRequest collectRequest = getCollectRequest(dependencies); - DependencyRequest dependencyRequest = getDependencyRequest(collectRequest); - DependencyResult result = this.repositorySystem.resolveDependencies(this.session, dependencyRequest); - addManagedDependencies(result); - return getFiles(result); - } - catch (Exception ex) { - throw new DependencyResolutionFailedException(ex); - } - finally { - this.progressReporter.finished(); - } - } - - private CollectRequest getCollectRequest(List dependencies) { - CollectRequest collectRequest = new CollectRequest((Dependency) null, dependencies, - new ArrayList<>(this.repositories)); - collectRequest.setManagedDependencies(this.resolutionContext.getManagedDependencies()); - return collectRequest; - } - - private DependencyRequest getDependencyRequest(CollectRequest collectRequest) { - return new DependencyRequest(collectRequest, - DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE, JavaScopes.RUNTIME)); - } - - private void addManagedDependencies(DependencyResult result) { - this.resolutionContext.addManagedDependencies(getDependencies(result)); - } - - @Override - public Map[] listDependencies(ClassLoader classLoader) { - throw new UnsupportedOperationException("Listing dependencies is not supported"); - } - - @Override - public Object grab(String endorsedModule) { - throw new UnsupportedOperationException("Grabbing an endorsed module is not supported"); - } + private static final Collection WILDCARD_EXCLUSION; + + static { + List exclusions = new ArrayList<>(); + exclusions.add(new Exclusion("*", "*", "*", "*")); + WILDCARD_EXCLUSION = Collections.unmodifiableList(exclusions); + } + + private final DependencyResolutionContext resolutionContext; + + private final ProgressReporter progressReporter; + + private final GroovyClassLoader classLoader; + + private final DefaultRepositorySystemSession session; + + private final RepositorySystem repositorySystem; + + private final List repositories; + + public MavenResolverGrapeEngine(GroovyClassLoader classLoader, RepositorySystem repositorySystem, + DefaultRepositorySystemSession repositorySystemSession, List remoteRepositories, + DependencyResolutionContext resolutionContext, boolean quiet) { + this.classLoader = classLoader; + this.repositorySystem = repositorySystem; + this.session = repositorySystemSession; + this.resolutionContext = resolutionContext; + this.repositories = new ArrayList<>(); + List remotes = new ArrayList<>(remoteRepositories); + Collections.reverse(remotes); // priority is reversed in addRepository + for (RemoteRepository repository : remotes) { + addRepository(repository); + } + this.progressReporter = getProgressReporter(this.session, quiet); + } + + private ProgressReporter getProgressReporter(DefaultRepositorySystemSession session, boolean quiet) { + String progressReporter = (quiet ? "none" + : System.getProperty("org.grails.cli.compiler.grape.ProgressReporter")); + if ("detail".equals(progressReporter) || Boolean.getBoolean("groovy.grape.report.downloads")) { + return new DetailedProgressReporter(session, System.out); + } + if ("none".equals(progressReporter)) { + return () -> { + }; + } + return new SummaryProgressReporter(session, System.out); + } + + @Override + public Object grab(Map args) { + return grab(args, args); + } + + @Override + public Object grab(Map args, Map... dependencyMaps) { + List exclusions = createExclusions(args); + List dependencies = createDependencies(dependencyMaps, exclusions); + try { + List files = resolve(dependencies); + GroovyClassLoader classLoader = getClassLoader(args); + for (File file : files) { + classLoader.addURL(file.toURI().toURL()); + } + } + catch (MalformedURLException ex) { + throw new DependencyResolutionFailedException(ex); + } + return null; + } + + @SuppressWarnings("unchecked") + private List createExclusions(Map args) { + List exclusions = new ArrayList<>(); + if (args != null) { + List> exclusionMaps = (List>) args.get("excludes"); + if (exclusionMaps != null) { + for (Map exclusionMap : exclusionMaps) { + exclusions.add(createExclusion(exclusionMap)); + } + } + } + return exclusions; + } + + private Exclusion createExclusion(Map exclusionMap) { + String group = (String) exclusionMap.get("group"); + String module = (String) exclusionMap.get("module"); + return new Exclusion(group, module, "*", "*"); + } + + private List createDependencies(Map[] dependencyMaps, List exclusions) { + List dependencies = new ArrayList<>(dependencyMaps.length); + for (Map dependencyMap : dependencyMaps) { + dependencies.add(createDependency(dependencyMap, exclusions)); + } + return dependencies; + } + + private Dependency createDependency(Map dependencyMap, List exclusions) { + Artifact artifact = createArtifact(dependencyMap); + if (isTransitive(dependencyMap)) { + return new Dependency(artifact, JavaScopes.COMPILE, false, exclusions); + } + return new Dependency(artifact, JavaScopes.COMPILE, null, WILDCARD_EXCLUSION); + } + + private Artifact createArtifact(Map dependencyMap) { + 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); + } + + private String determineType(Map dependencyMap) { + String type = (String) dependencyMap.get("type"); + String ext = (String) dependencyMap.get("ext"); + if (type == null) { + type = ext; + if (type == null) { + type = "jar"; + } + } + else if (ext != null && !type.equals(ext)) { + throw new IllegalArgumentException("If both type and ext are specified they must have the same value"); + } + return type; + } + + private boolean isTransitive(Map dependencyMap) { + Boolean transitive = (Boolean) dependencyMap.get("transitive"); + return (transitive != null) ? transitive : true; + } + + private List getDependencies(DependencyResult dependencyResult) { + List dependencies = new ArrayList<>(); + for (ArtifactResult artifactResult : dependencyResult.getArtifactResults()) { + dependencies.add(new Dependency(artifactResult.getArtifact(), JavaScopes.COMPILE)); + } + return dependencies; + } + + private List getFiles(DependencyResult dependencyResult) { + List files = new ArrayList<>(); + for (ArtifactResult result : dependencyResult.getArtifactResults()) { + files.add(result.getArtifact().getFile()); + } + return files; + } + + private GroovyClassLoader getClassLoader(Map args) { + GroovyClassLoader classLoader = (GroovyClassLoader) args.get("classLoader"); + return (classLoader != null) ? classLoader : this.classLoader; + } + + @Override + public void addResolver(Map args) { + String name = (String) args.get("name"); + String root = (String) args.get("root"); + RemoteRepository.Builder builder = new RemoteRepository.Builder(name, "default", root); + RemoteRepository repository = builder.build(); + addRepository(repository); + } + + protected void addRepository(RemoteRepository repository) { + if (this.repositories.contains(repository)) { + return; + } + repository = getPossibleMirror(repository); + repository = applyProxy(repository); + repository = applyAuthentication(repository); + this.repositories.add(0, repository); + } + + private RemoteRepository getPossibleMirror(RemoteRepository remoteRepository) { + RemoteRepository mirror = this.session.getMirrorSelector().getMirror(remoteRepository); + if (mirror != null) { + return mirror; + } + return remoteRepository; + } + + private RemoteRepository applyProxy(RemoteRepository repository) { + if (repository.getProxy() == null) { + RemoteRepository.Builder builder = new RemoteRepository.Builder(repository); + builder.setProxy(this.session.getProxySelector().getProxy(repository)); + repository = builder.build(); + } + return repository; + } + + private RemoteRepository applyAuthentication(RemoteRepository repository) { + if (repository.getAuthentication() == null) { + RemoteRepository.Builder builder = new RemoteRepository.Builder(repository); + builder.setAuthentication(this.session.getAuthenticationSelector().getAuthentication(repository)); + repository = builder.build(); + } + return repository; + } + + @Override + public Map>> enumerateGrapes() { + throw new UnsupportedOperationException("Grape enumeration is not supported"); + } + + @Override + public URI[] resolve(Map args, Map... dependencyMaps) { + return resolve(args, null, dependencyMaps); + } + + @Override + public URI[] resolve(Map args, List depsInfo, Map... dependencyMaps) { + List exclusions = createExclusions(args); + List dependencies = createDependencies(dependencyMaps, exclusions); + try { + List files = resolve(dependencies); + List uris = new ArrayList<>(files.size()); + for (File file : files) { + uris.add(file.toURI()); + } + return uris.toArray(new URI[0]); + } + catch (Exception ex) { + throw new DependencyResolutionFailedException(ex); + } + } + + private List resolve(List dependencies) { + try { + CollectRequest collectRequest = getCollectRequest(dependencies); + DependencyRequest dependencyRequest = getDependencyRequest(collectRequest); + DependencyResult result = this.repositorySystem.resolveDependencies(this.session, dependencyRequest); + addManagedDependencies(result); + return getFiles(result); + } + catch (Exception ex) { + throw new DependencyResolutionFailedException(ex); + } + finally { + this.progressReporter.finished(); + } + } + + private CollectRequest getCollectRequest(List dependencies) { + CollectRequest collectRequest = new CollectRequest((Dependency) null, dependencies, + new ArrayList<>(this.repositories)); + collectRequest.setManagedDependencies(this.resolutionContext.getManagedDependencies()); + return collectRequest; + } + + private DependencyRequest getDependencyRequest(CollectRequest collectRequest) { + return new DependencyRequest(collectRequest, + DependencyFilterUtils.classpathFilter(JavaScopes.COMPILE, JavaScopes.RUNTIME)); + } + + private void addManagedDependencies(DependencyResult result) { + this.resolutionContext.addManagedDependencies(getDependencies(result)); + } + + @Override + public Map[] listDependencies(ClassLoader classLoader) { + throw new UnsupportedOperationException("Listing dependencies is not supported"); + } + + @Override + public Object grab(String endorsedModule) { + throw new UnsupportedOperationException("Grabbing an endorsed module is not supported"); + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngineFactory.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngineFactory.java index d16ada90d9..29da49161c 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngineFactory.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/MavenResolverGrapeEngineFactory.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.util.ArrayList; @@ -39,46 +38,46 @@ * Utility class to create a pre-configured {@link MavenResolverGrapeEngine}. * * @author Andy Wilkinson - * @since 2.5.9 + * @since 2022.1.0 */ public abstract class MavenResolverGrapeEngineFactory { - public static MavenResolverGrapeEngine create(GroovyClassLoader classLoader, - List repositoryConfigurations, - DependencyResolutionContext dependencyResolutionContext, boolean quiet) { - RepositorySystem repositorySystem = createServiceLocator().getService(RepositorySystem.class); - DefaultRepositorySystemSession repositorySystemSession = MavenRepositorySystemUtils.newSession(); - ServiceLoader autoConfigurations = ServiceLoader - .load(RepositorySystemSessionAutoConfiguration.class); - for (RepositorySystemSessionAutoConfiguration autoConfiguration : autoConfigurations) { - autoConfiguration.apply(repositorySystemSession, repositorySystem); - } - new DefaultRepositorySystemSessionAutoConfiguration().apply(repositorySystemSession, repositorySystem); - return new MavenResolverGrapeEngine(classLoader, repositorySystem, repositorySystemSession, - createRepositories(repositoryConfigurations), dependencyResolutionContext, quiet); - } + public static MavenResolverGrapeEngine create(GroovyClassLoader classLoader, + List repositoryConfigurations, + DependencyResolutionContext dependencyResolutionContext, boolean quiet) { + RepositorySystem repositorySystem = createServiceLocator().getService(RepositorySystem.class); + DefaultRepositorySystemSession repositorySystemSession = MavenRepositorySystemUtils.newSession(); + ServiceLoader autoConfigurations = ServiceLoader + .load(RepositorySystemSessionAutoConfiguration.class); + for (RepositorySystemSessionAutoConfiguration autoConfiguration : autoConfigurations) { + autoConfiguration.apply(repositorySystemSession, repositorySystem); + } + new DefaultRepositorySystemSessionAutoConfiguration().apply(repositorySystemSession, repositorySystem); + return new MavenResolverGrapeEngine(classLoader, repositorySystem, repositorySystemSession, + createRepositories(repositoryConfigurations), dependencyResolutionContext, quiet); + } - private static ServiceLocator createServiceLocator() { - DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); - locator.addService(RepositorySystem.class, DefaultRepositorySystem.class); - locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); - locator.addService(TransporterFactory.class, HttpTransporterFactory.class); - locator.addService(TransporterFactory.class, FileTransporterFactory.class); - return locator; - } + private static ServiceLocator createServiceLocator() { + DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator(); + locator.addService(RepositorySystem.class, DefaultRepositorySystem.class); + locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class); + locator.addService(TransporterFactory.class, HttpTransporterFactory.class); + locator.addService(TransporterFactory.class, FileTransporterFactory.class); + return locator; + } - private static List createRepositories(List repositoryConfigurations) { - List repositories = new ArrayList<>(repositoryConfigurations.size()); - for (RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) { - RemoteRepository.Builder builder = new RemoteRepository.Builder(repositoryConfiguration.getName(), - "default", repositoryConfiguration.getUri().toASCIIString()); - if (!repositoryConfiguration.getSnapshotsEnabled()) { - builder.setSnapshotPolicy(new RepositoryPolicy(false, RepositoryPolicy.UPDATE_POLICY_NEVER, - RepositoryPolicy.CHECKSUM_POLICY_IGNORE)); - } - repositories.add(builder.build()); - } - return repositories; - } + private static List createRepositories(List repositoryConfigurations) { + List repositories = new ArrayList<>(repositoryConfigurations.size()); + for (RepositoryConfiguration repositoryConfiguration : repositoryConfigurations) { + RemoteRepository.Builder builder = new RemoteRepository.Builder(repositoryConfiguration.getName(), + "default", repositoryConfiguration.getUri().toASCIIString()); + if (!repositoryConfiguration.getSnapshotsEnabled()) { + builder.setSnapshotPolicy(new RepositoryPolicy(false, RepositoryPolicy.UPDATE_POLICY_NEVER, + RepositoryPolicy.CHECKSUM_POLICY_IGNORE)); + } + repositories.add(builder.build()); + } + return repositories; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/ProgressReporter.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/ProgressReporter.java index ccde691508..682653f916 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/ProgressReporter.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/ProgressReporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,13 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; /** * Reports progress on a dependency resolution operation. * * @author Andy Wilkinson + * @since 2022.1.0 */ @FunctionalInterface interface ProgressReporter { diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositoryConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositoryConfiguration.java index c079cf0baa..be8e747afb 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositoryConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositoryConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.net.URI; @@ -24,77 +23,81 @@ * The configuration of a repository. * * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ public final class RepositoryConfiguration { - private final String name; + private final String name; - private final URI uri; + private final URI uri; - private final boolean snapshotsEnabled; + private final boolean snapshotsEnabled; - /** - * Creates a new {@code RepositoryConfiguration} instance. - * @param name the name of the repository - * @param uri the uri of the repository - * @param snapshotsEnabled {@code true} if the repository should enable access to - * snapshots, {@code false} otherwise - */ - public RepositoryConfiguration(String name, URI uri, boolean snapshotsEnabled) { - this.name = name; - this.uri = uri; - this.snapshotsEnabled = snapshotsEnabled; - } + /** + * Creates a new {@code RepositoryConfiguration} instance. + * + * @param name the name of the repository + * @param uri the uri of the repository + * @param snapshotsEnabled {@code true} if the repository should enable access to + * snapshots, {@code false} otherwise + */ + public RepositoryConfiguration(String name, URI uri, boolean snapshotsEnabled) { + this.name = name; + this.uri = uri; + this.snapshotsEnabled = snapshotsEnabled; + } - /** - * Return the name of the repository. - * @return the repository name - */ - public String getName() { - return this.name; - } + /** + * Return the name of the repository. + * + * @return the repository name + */ + public String getName() { + return this.name; + } - /** - * Return the URI of the repository. - * @return the repository URI - */ - public URI getUri() { - return this.uri; - } + /** + * Return the URI of the repository. + * + * @return the repository URI + */ + public URI getUri() { + return this.uri; + } - /** - * Return if the repository should enable access to snapshots. - * @return {@code true} if snapshot access is enabled - */ - public boolean getSnapshotsEnabled() { - return this.snapshotsEnabled; - } + /** + * Return if the repository should enable access to snapshots. + * + * @return {@code true} if snapshot access is enabled + */ + public boolean getSnapshotsEnabled() { + return this.snapshotsEnabled; + } - @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - RepositoryConfiguration other = (RepositoryConfiguration) obj; - return ObjectUtils.nullSafeEquals(this.name, other.name); - } + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + RepositoryConfiguration other = (RepositoryConfiguration) obj; + return ObjectUtils.nullSafeEquals(this.name, other.name); + } - @Override - public int hashCode() { - return ObjectUtils.nullSafeHashCode(this.name); - } + @Override + public int hashCode() { + return ObjectUtils.nullSafeHashCode(this.name); + } - @Override - public String toString() { - return "RepositoryConfiguration [name=" + this.name + ", uri=" + this.uri + ", snapshotsEnabled=" - + this.snapshotsEnabled + "]"; - } + @Override + public String toString() { + return "RepositoryConfiguration [name=" + this.name + ", uri=" + this.uri + ", snapshotsEnabled=" + + this.snapshotsEnabled + "]"; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositorySystemSessionAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositorySystemSessionAutoConfiguration.java index 49b605bb11..d6618c604c 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositorySystemSessionAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/RepositorySystemSessionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2022 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import org.eclipse.aether.DefaultRepositorySystemSession; @@ -24,7 +23,7 @@ * {@link MavenResolverGrapeEngine}. * * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ @FunctionalInterface public interface RepositorySystemSessionAutoConfiguration { diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java index 9b7117a27d..95171e0f90 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SettingsXmlRepositorySystemSessionAutoConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import org.eclipse.aether.DefaultRepositorySystemSession; @@ -28,27 +27,27 @@ * determine the configuration settings. * * @author Andy Wilkinson - * @since 1.0.0 + * @since 2022.1.0 */ public class SettingsXmlRepositorySystemSessionAutoConfiguration implements RepositorySystemSessionAutoConfiguration { - @Override - public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { - MavenSettings settings = getSettings(session); - String localRepository = settings.getLocalRepository(); - if (localRepository != null) { - session.setLocalRepositoryManager( - repositorySystem.newLocalRepositoryManager(session, new LocalRepository(localRepository))); - } - } + @Override + public void apply(DefaultRepositorySystemSession session, RepositorySystem repositorySystem) { + MavenSettings settings = getSettings(session); + String localRepository = settings.getLocalRepository(); + if (localRepository != null) { + session.setLocalRepositoryManager( + repositorySystem.newLocalRepositoryManager(session, new LocalRepository(localRepository))); + } + } - private MavenSettings getSettings(DefaultRepositorySystemSession session) { - MavenSettings settings = new MavenSettingsReader().readSettings(); - session.setOffline(settings.getOffline()); - session.setMirrorSelector(settings.getMirrorSelector()); - session.setAuthenticationSelector(settings.getAuthenticationSelector()); - session.setProxySelector(settings.getProxySelector()); - return settings; - } + private MavenSettings getSettings(DefaultRepositorySystemSession session) { + MavenSettings settings = new MavenSettingsReader().readSettings(); + session.setOffline(settings.getOffline()); + session.setMirrorSelector(settings.getMirrorSelector()); + session.setAuthenticationSelector(settings.getAuthenticationSelector()); + session.setProxySelector(settings.getProxySelector()); + return settings; + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SummaryProgressReporter.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SummaryProgressReporter.java index c54641d83e..683bb72665 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SummaryProgressReporter.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/grape/SummaryProgressReporter.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.grape; import java.io.PrintStream; @@ -30,68 +29,69 @@ * * @author Phillip Webb * @author Andy Wilkinson + * @since 2022.1.0 */ final class SummaryProgressReporter implements ProgressReporter { - private static final long INITIAL_DELAY = TimeUnit.SECONDS.toMillis(3); + private static final long INITIAL_DELAY = TimeUnit.SECONDS.toMillis(3); - private static final long PROGRESS_DELAY = TimeUnit.SECONDS.toMillis(1); + private static final long PROGRESS_DELAY = TimeUnit.SECONDS.toMillis(1); - private final long startTime = System.currentTimeMillis(); + private final long startTime = System.currentTimeMillis(); - private final PrintStream out; + private final PrintStream out; - private long lastProgressTime = System.currentTimeMillis(); + private long lastProgressTime = System.currentTimeMillis(); - private boolean started; + private boolean started; - private boolean finished; + private boolean finished; - SummaryProgressReporter(DefaultRepositorySystemSession session, PrintStream out) { - this.out = out; - session.setTransferListener(new AbstractTransferListener() { + SummaryProgressReporter(DefaultRepositorySystemSession session, PrintStream out) { + this.out = out; + session.setTransferListener(new AbstractTransferListener() { - @Override - public void transferStarted(TransferEvent event) { - reportProgress(); - } + @Override + public void transferStarted(TransferEvent event) { + reportProgress(); + } - @Override - public void transferProgressed(TransferEvent event) { - reportProgress(); - } + @Override + public void transferProgressed(TransferEvent event) { + reportProgress(); + } - }); - session.setRepositoryListener(new AbstractRepositoryListener() { + }); + session.setRepositoryListener(new AbstractRepositoryListener() { - @Override - public void artifactResolved(RepositoryEvent event) { - reportProgress(); - } + @Override + public void artifactResolved(RepositoryEvent event) { + reportProgress(); + } - }); - } + }); + } - private void reportProgress() { - if (!this.finished && System.currentTimeMillis() - this.startTime > INITIAL_DELAY) { - if (!this.started) { - this.started = true; - this.out.print("Resolving dependencies.."); - this.lastProgressTime = System.currentTimeMillis(); - } - else if (System.currentTimeMillis() - this.lastProgressTime > PROGRESS_DELAY) { - this.out.print("."); - this.lastProgressTime = System.currentTimeMillis(); - } - } - } + private void reportProgress() { + if (!this.finished && System.currentTimeMillis() - this.startTime > INITIAL_DELAY) { + if (!this.started) { + this.started = true; + this.out.print("Resolving dependencies.."); + this.lastProgressTime = System.currentTimeMillis(); + } + else if (System.currentTimeMillis() - this.lastProgressTime > PROGRESS_DELAY) { + this.out.print("."); + this.lastProgressTime = System.currentTimeMillis(); + } + } + } - @Override - public void finished() { - if (this.started && !this.finished) { - this.finished = true; - this.out.println(); - } - } + @Override + public void finished() { + if (this.started && !this.finished) { + this.finished = true; + this.out.println(); + } + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettings.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettings.java index 01da91c9f9..4062b4967d 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettings.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettings.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.maven; import java.io.BufferedReader; @@ -59,246 +58,247 @@ * An encapsulation of settings read from a user's Maven settings.xml. * * @author Andy Wilkinson - * @since 1.3.0 * @see MavenSettingsReader + * @since 2022.1.0 */ public class MavenSettings { - private final boolean offline; - - private final MirrorSelector mirrorSelector; - - private final AuthenticationSelector authenticationSelector; - - private final ProxySelector proxySelector; - - private final String localRepository; - - private final List activeProfiles; - - /** - * Create a new {@link MavenSettings} instance. - * @param settings the source settings - * @param decryptedSettings the decrypted settings - */ - public MavenSettings(Settings settings, SettingsDecryptionResult decryptedSettings) { - this.offline = settings.isOffline(); - this.mirrorSelector = createMirrorSelector(settings); - this.authenticationSelector = createAuthenticationSelector(decryptedSettings); - this.proxySelector = createProxySelector(decryptedSettings); - this.localRepository = settings.getLocalRepository(); - this.activeProfiles = determineActiveProfiles(settings); - } - - private MirrorSelector createMirrorSelector(Settings settings) { - DefaultMirrorSelector selector = new DefaultMirrorSelector(); - for (Mirror mirror : settings.getMirrors()) { - selector.add(mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, false, mirror.getMirrorOf(), - mirror.getMirrorOfLayouts()); - } - return selector; - } - - private AuthenticationSelector createAuthenticationSelector(SettingsDecryptionResult decryptedSettings) { - DefaultAuthenticationSelector selector = new DefaultAuthenticationSelector(); - for (Server server : decryptedSettings.getServers()) { - AuthenticationBuilder auth = new AuthenticationBuilder(); - auth.addUsername(server.getUsername()).addPassword(server.getPassword()); - auth.addPrivateKey(server.getPrivateKey(), server.getPassphrase()); - selector.add(server.getId(), auth.build()); - } - return new ConservativeAuthenticationSelector(selector); - } - - private ProxySelector createProxySelector(SettingsDecryptionResult decryptedSettings) { - DefaultProxySelector selector = new DefaultProxySelector(); - for (Proxy proxy : decryptedSettings.getProxies()) { - Authentication authentication = new AuthenticationBuilder().addUsername(proxy.getUsername()) - .addPassword(proxy.getPassword()) - .build(); - selector.add(new org.eclipse.aether.repository.Proxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(), - authentication), proxy.getNonProxyHosts()); - } - return selector; - } - - private List determineActiveProfiles(Settings settings) { - SpringBootCliModelProblemCollector problemCollector = new SpringBootCliModelProblemCollector(); - List activeModelProfiles = createProfileSelector().getActiveProfiles( - createModelProfiles(settings.getProfiles()), - new SpringBootCliProfileActivationContext(settings.getActiveProfiles()), problemCollector); - if (!problemCollector.getProblems().isEmpty()) { - throw new IllegalStateException(createFailureMessage(problemCollector)); - } - List activeProfiles = new ArrayList<>(); - Map profiles = settings.getProfilesAsMap(); - for (org.apache.maven.model.Profile modelProfile : activeModelProfiles) { - activeProfiles.add(profiles.get(modelProfile.getId())); - } - return activeProfiles; - } - - private String createFailureMessage(SpringBootCliModelProblemCollector problemCollector) { - StringWriter message = new StringWriter(); - PrintWriter printer = new PrintWriter(message); - printer.println("Failed to determine active profiles:"); - for (ModelProblemCollectorRequest problem : problemCollector.getProblems()) { - String location = (problem.getLocation() != null) ? " at " + problem.getLocation() : ""; - printer.println(" " + problem.getMessage() + location); - if (problem.getException() != null) { - printer.println(indentStackTrace(problem.getException(), " ")); - } - } - return message.toString(); - } - - private String indentStackTrace(Exception ex, String indent) { - return indentLines(printStackTrace(ex), indent); - } - - private String printStackTrace(Exception ex) { - StringWriter stackTrace = new StringWriter(); - PrintWriter printer = new PrintWriter(stackTrace); - ex.printStackTrace(printer); - return stackTrace.toString(); - } - - private String indentLines(String input, String indent) { - StringWriter indented = new StringWriter(); - PrintWriter writer = new PrintWriter(indented); - BufferedReader reader = new BufferedReader(new StringReader(input)); - reader.lines().forEach((line) -> writer.println(indent + line)); - return indented.toString(); - } - - private DefaultProfileSelector createProfileSelector() { - DefaultProfileSelector selector = new DefaultProfileSelector(); - - selector.addProfileActivator(new FileProfileActivator().setPathTranslator(new DefaultPathTranslator())); - selector.addProfileActivator(new JdkVersionProfileActivator()); - selector.addProfileActivator(new PropertyProfileActivator()); - selector.addProfileActivator(new OperatingSystemProfileActivator()); - return selector; - } - - private List createModelProfiles(List profiles) { - List modelProfiles = new ArrayList<>(); - for (Profile profile : profiles) { - org.apache.maven.model.Profile modelProfile = new org.apache.maven.model.Profile(); - modelProfile.setId(profile.getId()); - if (profile.getActivation() != null) { - modelProfile.setActivation(createModelActivation(profile.getActivation())); - } - modelProfiles.add(modelProfile); - } - return modelProfiles; - } - - private org.apache.maven.model.Activation createModelActivation(Activation activation) { - org.apache.maven.model.Activation modelActivation = new org.apache.maven.model.Activation(); - modelActivation.setActiveByDefault(activation.isActiveByDefault()); - if (activation.getFile() != null) { - ActivationFile activationFile = new ActivationFile(); - activationFile.setExists(activation.getFile().getExists()); - activationFile.setMissing(activation.getFile().getMissing()); - modelActivation.setFile(activationFile); - } - modelActivation.setJdk(activation.getJdk()); - if (activation.getOs() != null) { - ActivationOS os = new ActivationOS(); - os.setArch(activation.getOs().getArch()); - os.setFamily(activation.getOs().getFamily()); - os.setName(activation.getOs().getName()); - os.setVersion(activation.getOs().getVersion()); - modelActivation.setOs(os); - } - if (activation.getProperty() != null) { - ActivationProperty property = new ActivationProperty(); - property.setName(activation.getProperty().getName()); - property.setValue(activation.getProperty().getValue()); - modelActivation.setProperty(property); - } - return modelActivation; - } - - public boolean getOffline() { - return this.offline; - } - - public MirrorSelector getMirrorSelector() { - return this.mirrorSelector; - } - - public AuthenticationSelector getAuthenticationSelector() { - return this.authenticationSelector; - } - - public ProxySelector getProxySelector() { - return this.proxySelector; - } - - public String getLocalRepository() { - return this.localRepository; - } - - public List getActiveProfiles() { - return this.activeProfiles; - } - - private static final class SpringBootCliProfileActivationContext implements ProfileActivationContext { - - private final List activeProfiles; - - SpringBootCliProfileActivationContext(List activeProfiles) { - this.activeProfiles = activeProfiles; - } - - @Override - public List getActiveProfileIds() { - return this.activeProfiles; - } - - @Override - public List getInactiveProfileIds() { - return Collections.emptyList(); - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - @Override - public Map getSystemProperties() { - return (Map) System.getProperties(); - } - - @Override - public Map getUserProperties() { - return Collections.emptyMap(); - } - - @Override - public File getProjectDirectory() { - return new File("."); - } - - @Override - public Map getProjectProperties() { - return Collections.emptyMap(); - } - - } - - private static final class SpringBootCliModelProblemCollector implements ModelProblemCollector { - - private final List problems = new ArrayList<>(); - - @Override - public void add(ModelProblemCollectorRequest req) { - this.problems.add(req); - } - - List getProblems() { - return this.problems; - } - - } + private final boolean offline; + + private final MirrorSelector mirrorSelector; + + private final AuthenticationSelector authenticationSelector; + + private final ProxySelector proxySelector; + + private final String localRepository; + + private final List activeProfiles; + + /** + * Create a new {@link MavenSettings} instance. + * + * @param settings the source settings + * @param decryptedSettings the decrypted settings + */ + public MavenSettings(Settings settings, SettingsDecryptionResult decryptedSettings) { + this.offline = settings.isOffline(); + this.mirrorSelector = createMirrorSelector(settings); + this.authenticationSelector = createAuthenticationSelector(decryptedSettings); + this.proxySelector = createProxySelector(decryptedSettings); + this.localRepository = settings.getLocalRepository(); + this.activeProfiles = determineActiveProfiles(settings); + } + + private MirrorSelector createMirrorSelector(Settings settings) { + DefaultMirrorSelector selector = new DefaultMirrorSelector(); + for (Mirror mirror : settings.getMirrors()) { + selector.add(mirror.getId(), mirror.getUrl(), mirror.getLayout(), false, false, mirror.getMirrorOf(), + mirror.getMirrorOfLayouts()); + } + return selector; + } + + private AuthenticationSelector createAuthenticationSelector(SettingsDecryptionResult decryptedSettings) { + DefaultAuthenticationSelector selector = new DefaultAuthenticationSelector(); + for (Server server : decryptedSettings.getServers()) { + AuthenticationBuilder auth = new AuthenticationBuilder(); + auth.addUsername(server.getUsername()).addPassword(server.getPassword()); + auth.addPrivateKey(server.getPrivateKey(), server.getPassphrase()); + selector.add(server.getId(), auth.build()); + } + return new ConservativeAuthenticationSelector(selector); + } + + private ProxySelector createProxySelector(SettingsDecryptionResult decryptedSettings) { + DefaultProxySelector selector = new DefaultProxySelector(); + for (Proxy proxy : decryptedSettings.getProxies()) { + Authentication authentication = new AuthenticationBuilder().addUsername(proxy.getUsername()) + .addPassword(proxy.getPassword()) + .build(); + selector.add(new org.eclipse.aether.repository.Proxy(proxy.getProtocol(), proxy.getHost(), proxy.getPort(), + authentication), proxy.getNonProxyHosts()); + } + return selector; + } + + private List determineActiveProfiles(Settings settings) { + SpringBootCliModelProblemCollector problemCollector = new SpringBootCliModelProblemCollector(); + List activeModelProfiles = createProfileSelector().getActiveProfiles( + createModelProfiles(settings.getProfiles()), + new SpringBootCliProfileActivationContext(settings.getActiveProfiles()), problemCollector); + if (!problemCollector.getProblems().isEmpty()) { + throw new IllegalStateException(createFailureMessage(problemCollector)); + } + List activeProfiles = new ArrayList<>(); + Map profiles = settings.getProfilesAsMap(); + for (org.apache.maven.model.Profile modelProfile : activeModelProfiles) { + activeProfiles.add(profiles.get(modelProfile.getId())); + } + return activeProfiles; + } + + private String createFailureMessage(SpringBootCliModelProblemCollector problemCollector) { + StringWriter message = new StringWriter(); + PrintWriter printer = new PrintWriter(message); + printer.println("Failed to determine active profiles:"); + for (ModelProblemCollectorRequest problem : problemCollector.getProblems()) { + String location = (problem.getLocation() != null) ? " at " + problem.getLocation() : ""; + printer.println(" " + problem.getMessage() + location); + if (problem.getException() != null) { + printer.println(indentStackTrace(problem.getException(), " ")); + } + } + return message.toString(); + } + + private String indentStackTrace(Exception ex, String indent) { + return indentLines(printStackTrace(ex), indent); + } + + private String printStackTrace(Exception ex) { + StringWriter stackTrace = new StringWriter(); + PrintWriter printer = new PrintWriter(stackTrace); + ex.printStackTrace(printer); + return stackTrace.toString(); + } + + private String indentLines(String input, String indent) { + StringWriter indented = new StringWriter(); + PrintWriter writer = new PrintWriter(indented); + BufferedReader reader = new BufferedReader(new StringReader(input)); + reader.lines().forEach((line) -> writer.println(indent + line)); + return indented.toString(); + } + + private DefaultProfileSelector createProfileSelector() { + DefaultProfileSelector selector = new DefaultProfileSelector(); + + selector.addProfileActivator(new FileProfileActivator().setPathTranslator(new DefaultPathTranslator())); + selector.addProfileActivator(new JdkVersionProfileActivator()); + selector.addProfileActivator(new PropertyProfileActivator()); + selector.addProfileActivator(new OperatingSystemProfileActivator()); + return selector; + } + + private List createModelProfiles(List profiles) { + List modelProfiles = new ArrayList<>(); + for (Profile profile : profiles) { + org.apache.maven.model.Profile modelProfile = new org.apache.maven.model.Profile(); + modelProfile.setId(profile.getId()); + if (profile.getActivation() != null) { + modelProfile.setActivation(createModelActivation(profile.getActivation())); + } + modelProfiles.add(modelProfile); + } + return modelProfiles; + } + + private org.apache.maven.model.Activation createModelActivation(Activation activation) { + org.apache.maven.model.Activation modelActivation = new org.apache.maven.model.Activation(); + modelActivation.setActiveByDefault(activation.isActiveByDefault()); + if (activation.getFile() != null) { + ActivationFile activationFile = new ActivationFile(); + activationFile.setExists(activation.getFile().getExists()); + activationFile.setMissing(activation.getFile().getMissing()); + modelActivation.setFile(activationFile); + } + modelActivation.setJdk(activation.getJdk()); + if (activation.getOs() != null) { + ActivationOS os = new ActivationOS(); + os.setArch(activation.getOs().getArch()); + os.setFamily(activation.getOs().getFamily()); + os.setName(activation.getOs().getName()); + os.setVersion(activation.getOs().getVersion()); + modelActivation.setOs(os); + } + if (activation.getProperty() != null) { + ActivationProperty property = new ActivationProperty(); + property.setName(activation.getProperty().getName()); + property.setValue(activation.getProperty().getValue()); + modelActivation.setProperty(property); + } + return modelActivation; + } + + public boolean getOffline() { + return this.offline; + } + + public MirrorSelector getMirrorSelector() { + return this.mirrorSelector; + } + + public AuthenticationSelector getAuthenticationSelector() { + return this.authenticationSelector; + } + + public ProxySelector getProxySelector() { + return this.proxySelector; + } + + public String getLocalRepository() { + return this.localRepository; + } + + public List getActiveProfiles() { + return this.activeProfiles; + } + + private static final class SpringBootCliProfileActivationContext implements ProfileActivationContext { + + private final List activeProfiles; + + SpringBootCliProfileActivationContext(List activeProfiles) { + this.activeProfiles = activeProfiles; + } + + @Override + public List getActiveProfileIds() { + return this.activeProfiles; + } + + @Override + public List getInactiveProfileIds() { + return Collections.emptyList(); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + @Override + public Map getSystemProperties() { + return (Map) System.getProperties(); + } + + @Override + public Map getUserProperties() { + return Collections.emptyMap(); + } + + @Override + public File getProjectDirectory() { + return new File("."); + } + + @Override + public Map getProjectProperties() { + return Collections.emptyMap(); + } + + } + + private static final class SpringBootCliModelProblemCollector implements ModelProblemCollector { + + private final List problems = new ArrayList<>(); + + @Override + public void add(ModelProblemCollectorRequest req) { + this.problems.add(req); + } + + List getProblems() { + return this.problems; + } + + } } diff --git a/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettingsReader.java b/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettingsReader.java index 1f4afc75bc..890c3cca8b 100644 --- a/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettingsReader.java +++ b/grails-shell/src/main/groovy/org/grails/cli/compiler/maven/MavenSettingsReader.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2023 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. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package org.grails.cli.compiler.maven; import java.io.File; @@ -38,68 +37,68 @@ * decrypting them if necessary using settings-security.xml. * * @author Andy Wilkinson - * @since 1.3.0 + * @since 2022.1.0 */ public class MavenSettingsReader { - private final String homeDir; - - public MavenSettingsReader() { - this(System.getProperty("user.home")); - } - - public MavenSettingsReader(String homeDir) { - this.homeDir = homeDir; - } - - public MavenSettings readSettings() { - Settings settings = loadSettings(); - SettingsDecryptionResult decrypted = decryptSettings(settings); - if (!decrypted.getProblems().isEmpty()) { - Log.error("Maven settings decryption failed. Some Maven repositories may be inaccessible"); - // Continue - the encrypted credentials may not be used - } - return new MavenSettings(settings, decrypted); - } - - private Settings loadSettings() { - File settingsFile = new File(this.homeDir, ".m2/settings.xml"); - SettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); - request.setUserSettingsFile(settingsFile); - request.setSystemProperties(System.getProperties()); - try { - return new DefaultSettingsBuilderFactory().newInstance().build(request).getEffectiveSettings(); - } - catch (SettingsBuildingException ex) { - throw new IllegalStateException("Failed to build settings from " + settingsFile, ex); - } - } - - private SettingsDecryptionResult decryptSettings(Settings settings) { - DefaultSettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest(settings); - - return createSettingsDecrypter().decrypt(request); - } - - private SettingsDecrypter createSettingsDecrypter() { - return new DefaultSettingsDecrypter(new SpringBootSecDispatcher()); - } - - private class SpringBootSecDispatcher extends DefaultSecDispatcher { - - private static final String SECURITY_XML = ".m2/settings-security.xml"; - - SpringBootSecDispatcher() { - File file = new File(MavenSettingsReader.this.homeDir, SECURITY_XML); - this._configurationFile = file.getAbsolutePath(); - try { - this._cipher = new DefaultPlexusCipher(); - } - catch (PlexusCipherException ex) { - throw new IllegalStateException(ex); - } - } - - } + private final String homeDir; + + public MavenSettingsReader() { + this(System.getProperty("user.home")); + } + + public MavenSettingsReader(String homeDir) { + this.homeDir = homeDir; + } + + public MavenSettings readSettings() { + Settings settings = loadSettings(); + SettingsDecryptionResult decrypted = decryptSettings(settings); + if (!decrypted.getProblems().isEmpty()) { + Log.error("Maven settings decryption failed. Some Maven repositories may be inaccessible"); + // Continue - the encrypted credentials may not be used + } + return new MavenSettings(settings, decrypted); + } + + private Settings loadSettings() { + File settingsFile = new File(this.homeDir, ".m2/settings.xml"); + SettingsBuildingRequest request = new DefaultSettingsBuildingRequest(); + request.setUserSettingsFile(settingsFile); + request.setSystemProperties(System.getProperties()); + try { + return new DefaultSettingsBuilderFactory().newInstance().build(request).getEffectiveSettings(); + } + catch (SettingsBuildingException ex) { + throw new IllegalStateException("Failed to build settings from " + settingsFile, ex); + } + } + + private SettingsDecryptionResult decryptSettings(Settings settings) { + DefaultSettingsDecryptionRequest request = new DefaultSettingsDecryptionRequest(settings); + + return createSettingsDecrypter().decrypt(request); + } + + private SettingsDecrypter createSettingsDecrypter() { + return new DefaultSettingsDecrypter(new SpringBootSecDispatcher()); + } + + private class SpringBootSecDispatcher extends DefaultSecDispatcher { + + private static final String SECURITY_XML = ".m2/settings-security.xml"; + + SpringBootSecDispatcher() { + File file = new File(MavenSettingsReader.this.homeDir, SECURITY_XML); + this._configurationFile = file.getAbsolutePath(); + try { + this._cipher = new DefaultPlexusCipher(); + } + catch (PlexusCipherException ex) { + throw new IllegalStateException(ex); + } + } + + } }