Permalink
Browse files

Merge remote-tracking branch 'origin/master'

  • Loading branch information...
2 parents 76eed28 + 3ca2927 commit 539b5cbed8b1e44632f84c3cc80d2373a0cc9ae3 @lhotari lhotari committed Jul 16, 2014
Showing with 707 additions and 257 deletions.
  1. +31 −1 grails-core/src/main/groovy/org/grails/compiler/injection/ArtefactTypeAstTransformation.java
  2. +14 −0 grails-core/src/main/groovy/org/grails/compiler/injection/GrailsAwareClassLoader.java
  3. +139 −0 grails-core/src/main/groovy/org/grails/compiler/injection/GrailsAwareTraitInjectionOperation.java
  4. +34 −0 grails-core/src/main/groovy/org/grails/compiler/injection/TraitInjector.java
  5. +165 −0 grails-plugin-controllers/src/main/groovy/grails/artefact/Controller.groovy
  6. +50 −0 grails-plugin-controllers/src/main/groovy/org/grails/compiler/web/ControllerTraitInjector.groovy
  7. +0 −122 grails-plugin-controllers/src/main/groovy/org/grails/plugins/web/controllers/api/ControllersApi.java
  8. +11 −0 ...codehaus/groovy/grails/compiler/web/ControllerActionTransformerClosureActionOverridingSpec.groovy
  9. +7 −0 ...rs/src/test/groovy/org/codehaus/groovy/grails/compiler/web/ControllerActionTransformerSpec.groovy
  10. +8 −0 ...trollers/src/test/groovy/org/codehaus/groovy/grails/compiler/web/ControllerTransformerSpec.groovy
  11. +4 −3 grails-plugin-filters/src/main/groovy/org/grails/plugins/web/filters/FilterConfig.groovy
  12. +4 −1 ...test-suite-uber/src/test/groovy/grails/test/mixin/ControllerAndFilterMixinInteractionTests.groovy
  13. +1 −0 ...-test-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/ControllersDynamicMethodsTests.groovy
  14. +9 −3 grails-test-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/RedirectMethodTests.groovy
  15. +4 −2 grails-test-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/RenderDynamicMethodTests.groovy
  16. +3 −0 grails-test-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/alpha/NamespacedController.groovy
  17. +3 −0 grails-test-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/beta/NamespacedController.groovy
  18. +15 −0 grails-test-suite-web/src/test/groovy/grails/artefact/ControllerTraitSpec.groovy
  19. +145 −0 grails-web-gsp/src/main/groovy/grails/artefact/TagLibrary.groovy
  20. +50 −0 grails-web-gsp/src/main/groovy/org/grails/compiler/web/gsp/TagLibraryTraitInjector.groovy
  21. +5 −120 grails-web-gsp/src/main/groovy/org/grails/plugins/web/api/TagLibraryApi.java
  22. +5 −5 grails-web-gsp/src/test/groovy/org/grails/web/pages/TagLibraryLookupSpec.groovy
@@ -19,18 +19,22 @@
import grails.build.logging.GrailsConsole;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import grails.compiler.ast.AllArtefactClassInjector;
import grails.compiler.ast.ClassInjector;
import grails.compiler.ast.GrailsArtefactClassInjector;
+import groovy.transform.CompilationUnitAware;
+
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.expr.ConstantExpression;
import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.GroovyASTTransformation;
@@ -44,8 +48,10 @@
* @since 2.0
*/
@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
-public class ArtefactTypeAstTransformation extends AbstractArtefactTypeAstTransformation {
+public class ArtefactTypeAstTransformation extends AbstractArtefactTypeAstTransformation implements CompilationUnitAware {
private static final ClassNode MY_TYPE = new ClassNode(Artefact.class);
+
+ protected CompilationUnit compilationUnit;
public void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {
AnnotatedNode parent = (AnnotatedNode) astNodes[1];
@@ -71,11 +77,30 @@ public void visit(ASTNode[] astNodes, SourceUnit sourceUnit) {
String artefactType = resolveArtefactType(sourceUnit, node, cNode);
performInjectionOnArtefactType(sourceUnit, cNode, artefactType);
+
+ performTraitInjectionOnArtefactType(sourceUnit, cNode, artefactType);
+
postProcess(sourceUnit, node, cNode, artefactType);
markApplied(cNode);
}
+ protected void performTraitInjectionOnArtefactType(SourceUnit sourceUnit,
+ ClassNode cNode, String artefactType) {
+ if(compilationUnit != null) {
+ GrailsAwareTraitInjectionOperation grailsTraitInjector = new GrailsAwareTraitInjectionOperation(compilationUnit);
+ List<TraitInjector> traitInjectors = grailsTraitInjector.getTraitInjectors();
+ List<TraitInjector> injectorsToUse = new ArrayList<TraitInjector>();
+ for(TraitInjector injector : traitInjectors) {
+ List<String> artefactTypes = Arrays.asList(injector.getArtefactTypes());
+ if(artefactTypes.contains(artefactType)) {
+ injectorsToUse.add(injector);
+ }
+ }
+ grailsTraitInjector.performTraitInjection(sourceUnit, cNode, injectorsToUse);
+ }
+ }
+
protected boolean isApplied(ClassNode cNode) {
return GrailsASTUtils.isApplied(cNode, getAstAppliedMarkerClass());
}
@@ -172,4 +197,9 @@ public static boolean hasArtefactType(String artefactType, GrailsArtefactClassIn
}
return false;
}
+
+ @Override
+ public void setCompilationUnit(CompilationUnit unit) {
+ compilationUnit = unit;
+ }
}
@@ -17,11 +17,13 @@
import grails.compiler.ast.ClassInjector;
import groovy.lang.GroovyClassLoader;
+
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.Phases;
import java.security.CodeSource;
+import java.util.Arrays;
/**
* A class loader that is aware of Groovy sources and injection operations.
@@ -52,10 +54,15 @@ public GrailsAwareClassLoader(ClassLoader loader, CompilerConfiguration config)
}
private ClassInjector[] classInjectors;
+ private TraitInjector[] traitInjectors;
public void setClassInjectors(ClassInjector[] classInjectors) {
this.classInjectors = classInjectors;
}
+
+ public void setTraitInjectors(TraitInjector[] traitInjectors) {
+ this.traitInjectors = traitInjectors;
+ }
/**
* @see groovy.lang.GroovyClassLoader#createCompilationUnit(org.codehaus.groovy.control.CompilerConfiguration, java.security.CodeSource)
@@ -74,6 +81,13 @@ protected CompilationUnit createCompilationUnit(CompilerConfiguration config, Co
}
cu.addPhaseOperation(operation, Phases.CANONICALIZATION);
+
+ if(traitInjectors != null) {
+ GrailsAwareTraitInjectionOperation grailsTraitInjector = new GrailsAwareTraitInjectionOperation(cu);
+ grailsTraitInjector.setTraitInjectors(Arrays.asList(traitInjectors));
+ cu.addPhaseOperation(grailsTraitInjector, Phases.SEMANTIC_ANALYSIS);
+ }
+
return cu;
}
}
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.grails.compiler.injection;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.classgen.GeneratorContext;
+import org.codehaus.groovy.control.CompilationFailedException;
+import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.transform.trait.TraitComposer;
+import org.springframework.beans.factory.support.BeanDefinitionRegistry;
+import org.springframework.beans.factory.support.SimpleBeanDefinitionRegistry;
+import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.FileSystemResource;
+import org.springframework.core.io.Resource;
+import org.springframework.core.type.filter.AssignableTypeFilter;
+
+/**
+ *
+ * @author Jeff Brown
+ * @since 3.0
+ *
+ */
+public class GrailsAwareTraitInjectionOperation extends
+ CompilationUnit.PrimaryClassNodeOperation {
+
+ protected CompilationUnit unit;
+ protected static List<TraitInjector> classInjectors;
+ private static final String INJECTOR_SCAN_PACKAGE = "org.grails.compiler.web";
+
+ public GrailsAwareTraitInjectionOperation(CompilationUnit unit) {
+ this.unit = unit;
+ initializeState();
+ }
+
+ public void setTraitInjectors(List<TraitInjector> i) {
+ classInjectors = i;
+ }
+
+ @Override
+ public void call(SourceUnit source, GeneratorContext context,
+ ClassNode classNode) throws CompilationFailedException {
+
+ URL url = null;
+ final String filename = source.getName();
+ Resource resource = new FileSystemResource(filename);
+ if (resource.exists()) {
+ try {
+ url = resource.getURL();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ List<TraitInjector> injectorsToUse = new ArrayList<TraitInjector>();
+ for (TraitInjector injector : classInjectors) {
+ System.out.println("injector: " + injector);
+ if (injector.shouldInject(url)) {
+ injectorsToUse.add(injector);
+ }
+ }
+ performTraitInjection(source, classNode, injectorsToUse);
+ }
+
+ public void performTraitInjection(SourceUnit source, ClassNode classNode,
+ List<TraitInjector> injectorsToUse) {
+ for (TraitInjector injector : injectorsToUse) {
+ Class<?> trait = injector.getTrait();
+ ClassNode traitClassNode = ClassHelper.make(trait);
+ if (!classNode.implementsInterface(traitClassNode)) {
+ classNode.addInterface(traitClassNode);
+ TraitComposer.doExtendTraits(classNode, source, unit);
+ }
+ }
+ }
+
+ public List<TraitInjector> getTraitInjectors() {
+ return Collections.unmodifiableList(classInjectors);
+ }
+
+ protected static void initializeState() {
+ if (classInjectors != null) {
+ return;
+ }
+
+ classInjectors = new ArrayList<TraitInjector>();
+
+ BeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
+ ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(
+ registry, false);
+ scanner.setIncludeAnnotationConfig(false);
+ scanner.addIncludeFilter(new AssignableTypeFilter(TraitInjector.class));
+
+ ClassLoader classLoader = Thread.currentThread()
+ .getContextClassLoader();
+ scanner.setResourceLoader(new DefaultResourceLoader(classLoader));
+ scanner.scan(INJECTOR_SCAN_PACKAGE);
+
+ // fallback to current classloader for special cases (e.g. gradle
+ // classloader isolation with useAnt=false)
+ if (registry.getBeanDefinitionCount() == 0) {
+ classLoader = GrailsAwareInjectionOperation.class.getClassLoader();
+ scanner.setResourceLoader(new DefaultResourceLoader(classLoader));
+ scanner.scan(INJECTOR_SCAN_PACKAGE);
+ }
+
+ for (String beanName : registry.getBeanDefinitionNames()) {
+ try {
+ Class<?> injectorClass = classLoader.loadClass(registry
+ .getBeanDefinition(beanName).getBeanClassName());
+ if (TraitInjector.class.isAssignableFrom(injectorClass))
+ classInjectors.add((TraitInjector) injectorClass
+ .newInstance());
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ }
+}
@@ -0,0 +1,34 @@
+
+/*
+ * Copyright 2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.grails.compiler.injection;
+
+import java.net.URL;
+
+/**
+ *
+ * @author Jeff Brown
+ * @since 3.0
+ *
+ */
+public interface TraitInjector {
+ Class getTrait();
+
+ boolean shouldInject(URL url);
+
+ String[] getArtefactTypes();
+}
+
Oops, something went wrong.

0 comments on commit 539b5cb

Please sign in to comment.