Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge remote-tracking branch 'origin/master'

  • Loading branch information...
commit 539b5cbed8b1e44632f84c3cc80d2373a0cc9ae3 2 parents 76eed28 + 3ca2927
@lhotari lhotari authored
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 ...roovy/org/codehaus/groovy/grails/compiler/web/ControllerActionTransformerClosureActionOverridingSpec.groovy
  9. +7 −0 ...-controllers/src/test/groovy/org/codehaus/groovy/grails/compiler/web/ControllerActionTransformerSpec.groovy
  10. +8 −0 ...plugin-controllers/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 grails-test-suite-uber/src/test/groovy/grails/test/mixin/ControllerAndFilterMixinInteractionTests.groovy
  13. +1 −0  grails-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
View
32 grails-core/src/main/groovy/org/grails/compiler/injection/ArtefactTypeAstTransformation.java
@@ -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;
+ }
}
View
14 grails-core/src/main/groovy/org/grails/compiler/injection/GrailsAwareClassLoader.java
@@ -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;
}
}
View
139 ...ore/src/main/groovy/org/grails/compiler/injection/GrailsAwareTraitInjectionOperation.java
@@ -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
+ }
+ }
+ }
+}
View
34 grails-core/src/main/groovy/org/grails/compiler/injection/TraitInjector.java
@@ -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();
+}
+
View
165 grails-plugin-controllers/src/main/groovy/grails/artefact/Controller.groovy
@@ -0,0 +1,165 @@
+/*
+ * 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 grails.artefact
+
+import grails.databinding.DataBindingSource
+import grails.web.databinding.DataBindingUtils
+
+import javax.servlet.http.HttpServletRequest
+
+import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes
+import org.codehaus.groovy.runtime.InvokerHelper
+import org.grails.core.artefact.DomainClassArtefactHandler
+import org.grails.plugins.support.WebMetaUtils
+import org.grails.web.servlet.mvc.GrailsWebRequest
+import org.springframework.beans.factory.config.AutowireCapableBeanFactory
+import org.springframework.context.ApplicationContext
+import org.springframework.http.HttpMethod
+import org.springframework.validation.Errors
+import org.springframework.web.context.request.RequestContextHolder
+import org.springframework.web.servlet.ModelAndView
+
+/**
+ *
+ * @author Jeff Brown
+ * @since 3.0
+ *
+ */
+trait Controller {
+
+ /**
+ * Return true if there are an errors
+ * @return true if there are errors
+ */
+ boolean hasErrors() {
+ final Errors errors = getErrors();
+ return errors != null && errors.hasErrors();
+ }
+
+ /**
+ * Sets the errors instance of the current controller
+ *
+ * @param errors The error instance
+ */
+ void setErrors(Errors errors) {
+ currentRequestAttributes().setAttribute(GrailsApplicationAttributes.ERRORS, errors, 0);
+ }
+
+ /**
+ * Obtains the errors instance for the current controller
+ *
+ * @return The Errors instance
+ */
+ Errors getErrors() {
+ currentRequestAttributes().getAttribute(GrailsApplicationAttributes.ERRORS, 0);
+ }
+
+
+ /**
+ * Obtains the ModelAndView for the currently executing controller
+ *
+ * @return The ModelAndView
+ */
+ ModelAndView getModelAndView() {
+ return (ModelAndView)currentRequestAttributes().getAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, 0);
+ }
+
+ /**
+ * Sets the ModelAndView of the current controller
+ *
+ * @param mav The ModelAndView
+ */
+ void setModelAndView(ModelAndView mav) {
+ currentRequestAttributes().setAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, mav, 0);
+ }
+
+ GrailsWebRequest currentRequestAttributes() {
+ return (GrailsWebRequest)RequestContextHolder.currentRequestAttributes();
+ }
+
+ /**
+ * Initializes a command object.
+ *
+ * If type is a domain class and the request body or parameters include an id, the id is used to retrieve
+ * the command object instance from the database, otherwise the no-arg constructor on type is invoke. If
+ * an attempt is made to retrieve the command object instance from the database and no corresponding
+ * record is found, null is returned.
+ *
+ * The command object is then subjected to data binding and dependency injection before being returned.
+ *
+ *
+ * @param controllerInstance The controller instance
+ * @param type The type of the command object
+ * @return the initialized command object or null if the command object is a domain class, the body or
+ * parameters included an id and no corresponding record was found in the database.
+ */
+ def initializeCommandObject(final Class type, final String commandObjectParameterName) throws Exception {
+ final HttpServletRequest request = getRequest()
+ final DataBindingSource dataBindingSource = DataBindingUtils.createDataBindingSource(getGrailsApplication(), type, request)
+ final DataBindingSource commandObjectBindingSource = WebMetaUtils.getCommandObjectBindingSourceForPrefix(commandObjectParameterName, dataBindingSource)
+ Object commandObjectInstance = null
+ Object entityIdentifierValue = null
+ final boolean isDomainClass = DomainClassArtefactHandler.isDomainClass(type)
+ if(isDomainClass) {
+ entityIdentifierValue = commandObjectBindingSource.identifierValue
+ if(entityIdentifierValue == null) {
+ final GrailsWebRequest webRequest = GrailsWebRequest.lookup(request)
+ entityIdentifierValue = webRequest != null ? webRequest.getParams().getIdentifier() : null
+ }
+ }
+ if(entityIdentifierValue instanceof String) {
+ entityIdentifierValue = ((String)entityIdentifierValue).trim()
+ if("".equals(entityIdentifierValue) || "null".equals(entityIdentifierValue)) {
+ entityIdentifierValue = null
+ }
+ }
+
+ final HttpMethod requestMethod = HttpMethod.valueOf(request.getMethod())
+
+ if(entityIdentifierValue != null) {
+ commandObjectInstance = InvokerHelper.invokeStaticMethod(type, "get", entityIdentifierValue)
+ } else if(requestMethod == HttpMethod.POST || !isDomainClass){
+ commandObjectInstance = type.newInstance()
+ }
+
+ if(commandObjectInstance != null) {
+ final boolean shouldDoDataBinding
+
+ if(entityIdentifierValue != null) {
+ switch(requestMethod) {
+ case HttpMethod.PATCH:
+ case HttpMethod.POST:
+ case HttpMethod.PUT:
+ shouldDoDataBinding = true
+ break;
+ default:
+ shouldDoDataBinding = false
+ }
+ } else {
+ shouldDoDataBinding = true
+ }
+
+ if(shouldDoDataBinding) {
+ bindData(commandObjectInstance, commandObjectBindingSource, Collections.EMPTY_MAP, null)
+ }
+
+ final ApplicationContext applicationContext = getApplicationContext()
+ final AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory()
+ autowireCapableBeanFactory.autowireBeanProperties(commandObjectInstance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false)
+ }
+ commandObjectInstance
+ }
+}
View
50 ...plugin-controllers/src/main/groovy/org/grails/compiler/web/ControllerTraitInjector.groovy
@@ -0,0 +1,50 @@
+/*
+ * 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.web
+
+import grails.artefact.Controller
+
+import java.util.regex.Pattern
+
+import org.grails.compiler.injection.TraitInjector
+import org.grails.io.support.GrailsResourceUtils
+
+/**
+ *
+ * @author Jeff Brown
+ * @since 3.0
+ *
+ */
+class ControllerTraitInjector implements TraitInjector {
+
+ static Pattern CONTROLLER_PATTERN = Pattern.compile(".+/" +
+ GrailsResourceUtils.GRAILS_APP_DIR + "/controllers/(.+)Controller\\.groovy");
+
+ @Override
+ Class getTrait() {
+ Controller
+ }
+
+ @Override
+ boolean shouldInject(URL url) {
+ return url != null && CONTROLLER_PATTERN.matcher(url.getFile()).find();
+ }
+
+ @Override
+ String[] getArtefactTypes() {
+ ['Controller'] as String[]
+ }
+}
View
122 ...in-controllers/src/main/groovy/org/grails/plugins/web/controllers/api/ControllersApi.java
@@ -19,7 +19,6 @@
import grails.converters.JSON;
import grails.core.GrailsControllerClass;
import grails.databinding.CollectionDataBindingSource;
-import grails.databinding.DataBindingSource;
import grails.io.IOUtils;
import grails.util.*;
import grails.web.JSONBuilder;
@@ -72,8 +71,6 @@
import grails.web.mapping.LinkGenerator;
-import org.grails.plugins.support.WebMetaUtils;
-
import grails.web.util.GrailsApplicationAttributes;
import org.grails.plugins.web.controllers.metaclass.ChainMethod;
@@ -87,7 +84,6 @@
import grails.web.mapping.mvc.exceptions.CannotRedirectException;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.InvokerHelper;
import org.grails.web.api.CommonWebApi;
import org.grails.web.converters.Converter;
import org.grails.web.servlet.mvc.exceptions.ControllerExecutionException;
@@ -230,42 +226,6 @@ public String getViewUri(Object instance, String name) {
}
/**
- * Sets the errors instance of the current controller
- *
- * @param errors The error instance
- */
- public void setErrors(Object instance, Errors errors) {
- currentRequestAttributes().setAttribute(GrailsApplicationAttributes.ERRORS, errors, 0);
- }
-
- /**
- * Obtains the errors instance for the current controller
- *
- * @return The Errors instance
- */
- public Errors getErrors(Object instance) {
- return (Errors)currentRequestAttributes().getAttribute(GrailsApplicationAttributes.ERRORS, 0);
- }
-
- /**
- * Sets the ModelAndView of the current controller
- *
- * @param mav The ModelAndView
- */
- public void setModelAndView(Object instance, ModelAndView mav) {
- currentRequestAttributes().setAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, mav, 0);
- }
-
- /**
- * Obtains the ModelAndView for the currently executing controller
- *
- * @return The ModelAndView
- */
- public ModelAndView getModelAndView(Object instance) {
- return (ModelAndView)currentRequestAttributes().getAttribute(GrailsApplicationAttributes.MODEL_AND_VIEW, 0);
- }
-
- /**
* Obtains the chain model which is used to chain request attributes from one request to the next via flash scope
* @return The chainModel
*/
@@ -274,15 +234,6 @@ public Map getChainModel(Object instance) {
}
/**
- * Return true if there are an errors
- * @return true if there are errors
- */
- public boolean hasErrors(Object instance) {
- final Errors errors = getErrors(instance);
- return errors != null && errors.hasErrors();
- }
-
- /**
* Redirects for the given arguments.
*
* @param argMap The arguments
@@ -642,79 +593,6 @@ public String forward(Object instance, Map params) {
return forwardMethod.forward(getRequest(instance), getResponse(instance), params);
}
- /**
- * Initializes a command object.
- *
- * If type is a domain class and the request body or parameters include an id, the id is used to retrieve
- * the command object instance from the database, otherwise the no-arg constructor on type is invoke. If
- * an attempt is made to retrieve the command object instance from the database and no corresponding
- * record is found, null is returned.
- *
- * The command object is then subjected to data binding and dependency injection before being returned.
- *
- *
- * @param controllerInstance The controller instance
- * @param type The type of the command object
- * @return the initialized command object or null if the command object is a domain class, the body or
- * parameters included an id and no corresponding record was found in the database.
- */
- public Object initializeCommandObject(final Object controllerInstance, final Class type, final String commandObjectParameterName) throws Exception {
- final HttpServletRequest request = getRequest(controllerInstance);
- final DataBindingSource dataBindingSource = DataBindingUtils.createDataBindingSource(getGrailsApplication(controllerInstance), type, request);
- final DataBindingSource commandObjectBindingSource = WebMetaUtils.getCommandObjectBindingSourceForPrefix(commandObjectParameterName, dataBindingSource);
- Object commandObjectInstance = null;
- Object entityIdentifierValue = null;
- final boolean isDomainClass = DomainClassArtefactHandler.isDomainClass(type);
- if(isDomainClass) {
- entityIdentifierValue = commandObjectBindingSource.getIdentifierValue();
- if(entityIdentifierValue == null) {
- final GrailsWebRequest webRequest = GrailsWebRequest.lookup(request);
- entityIdentifierValue = webRequest != null ? webRequest.getParams().getIdentifier() : null;
- }
- }
- if(entityIdentifierValue instanceof String) {
- entityIdentifierValue = ((String)entityIdentifierValue).trim();
- if("".equals(entityIdentifierValue) || "null".equals(entityIdentifierValue)) {
- entityIdentifierValue = null;
- }
- }
-
- final HttpMethod requestMethod = HttpMethod.valueOf(request.getMethod());
-
- if(entityIdentifierValue != null) {
- commandObjectInstance = InvokerHelper.invokeStaticMethod(type, "get", entityIdentifierValue);
- } else if(requestMethod == HttpMethod.POST || !isDomainClass){
- commandObjectInstance = type.newInstance();
- }
-
- if(commandObjectInstance != null) {
- final boolean shouldDoDataBinding;
-
- if(entityIdentifierValue != null) {
- switch(requestMethod) {
- case PATCH:
- case POST:
- case PUT:
- shouldDoDataBinding = true;
- break;
- default:
- shouldDoDataBinding = false;
- }
- } else {
- shouldDoDataBinding = true;
- }
-
- if(shouldDoDataBinding) {
- bindData(controllerInstance, commandObjectInstance, commandObjectBindingSource, Collections.EMPTY_MAP, null);
- }
-
- final ApplicationContext applicationContext = getApplicationContext(controllerInstance);
- final AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();
- autowireCapableBeanFactory.autowireBeanProperties(commandObjectInstance, AutowireCapableBeanFactory.AUTOWIRE_BY_NAME, false);
- }
- return commandObjectInstance;
- }
-
@SuppressWarnings("unchecked")
public Method getExceptionHandlerMethodFor(final Object controllerInstance, final Class<? extends Exception> exceptionType) throws Exception {
if(!Exception.class.isAssignableFrom(exceptionType)) {
View
11 .../groovy/grails/compiler/web/ControllerActionTransformerClosureActionOverridingSpec.groovy
@@ -4,8 +4,10 @@ import grails.util.GrailsWebUtil
import grails.compiler.ast.ClassInjector
import org.grails.compiler.injection.GrailsAwareClassLoader
+import org.grails.compiler.injection.TraitInjector
import org.grails.plugins.web.controllers.api.ControllersApi
import org.grails.compiler.web.ControllerActionTransformer
+import org.grails.compiler.web.ControllerTraitInjector
import org.grails.compiler.web.ControllerTransformer
import org.springframework.web.context.request.RequestContextHolder
@@ -25,6 +27,15 @@ class ControllerActionTransformerClosureActionOverridingSpec extends Specificati
@Override
boolean shouldInject(URL url) { true }
}
+
+ def controllerTraitInjector = new ControllerTraitInjector() {
+ @Override
+ boolean shouldInject(URL url) {
+ true
+ }
+ }
+
+ gcl.traitInjectors = [controllerTraitInjector] as TraitInjector[]
gcl.classInjectors = [transformer, transformer2] as ClassInjector[]
// Make sure this parent controller is compiled before the subclass. This is relevant to GRAILS-8268
View
7 ...est/groovy/org/codehaus/groovy/grails/compiler/web/ControllerActionTransformerSpec.groovy
@@ -4,6 +4,7 @@ import grails.util.BuildSettings
import grails.util.GrailsWebUtil
import grails.web.Action
import org.grails.compiler.web.ControllerActionTransformer
+import org.grails.compiler.web.ControllerTraitInjector
import org.grails.compiler.web.ControllerTransformer
import java.lang.reflect.Modifier
@@ -11,6 +12,7 @@ import java.lang.reflect.Modifier
import grails.web.servlet.context.GrailsWebApplicationContext
import grails.compiler.ast.ClassInjector
import org.grails.compiler.injection.GrailsAwareClassLoader
+import org.grails.compiler.injection.TraitInjector
import org.springframework.web.context.WebApplicationContext
import org.springframework.web.context.request.RequestContextHolder
@@ -33,6 +35,11 @@ class ControllerActionTransformerSpec extends Specification {
boolean shouldInject(URL url) { true }
}
+ def controllerTraitInjector = new ControllerTraitInjector() {
+ boolean shouldInject(URL url) { true }
+ }
+
+ gcl.traitInjectors = [controllerTraitInjector] as TraitInjector[]
gcl.classInjectors = [transformer,transformer2] as ClassInjector[]
def webRequest = GrailsWebUtil.bindMockWebRequest()
def appCtx = new GrailsWebApplicationContext()
View
8 .../src/test/groovy/org/codehaus/groovy/grails/compiler/web/ControllerTransformerSpec.groovy
@@ -1,6 +1,7 @@
package org.codehaus.groovy.grails.compiler.web
import grails.util.GrailsWebUtil
+import org.grails.compiler.web.ControllerTraitInjector
import org.grails.compiler.web.ControllerTransformer
import javax.servlet.http.HttpServletRequest
@@ -8,6 +9,7 @@ import javax.servlet.http.HttpServletRequest
import grails.core.GrailsApplication
import grails.compiler.ast.ClassInjector
import org.grails.compiler.injection.GrailsAwareClassLoader
+import org.grails.compiler.injection.TraitInjector
import org.springframework.web.context.request.RequestContextHolder
import spock.lang.Specification
@@ -71,6 +73,12 @@ class ControllerTransformerSpec extends Specification {
@Override
boolean shouldInject(URL url) { true }
}
+ def controllerTraitInjector = new ControllerTraitInjector() {
+ @Override
+ boolean shouldInject(URL url) { true }
+ }
+
+ gcl.traitInjectors = [controllerTraitInjector] as TraitInjector[]
gcl.classInjectors = [transformer] as ClassInjector[]
when:
View
7 grails-plugin-filters/src/main/groovy/org/grails/plugins/web/filters/FilterConfig.groovy
@@ -149,11 +149,11 @@ class FilterConfig extends ControllersApi {
}
void setErrors(Errors errors) {
- super.setErrors(this, errors)
+ currentRequestAttributes().setAttribute(GrailsApplicationAttributes.ERRORS, errors, 0)
}
Errors getErrors() {
- return super.getErrors(this)
+ currentRequestAttributes().getAttribute(GrailsApplicationAttributes.ERRORS, 0)
}
Map getChainModel() {
@@ -161,7 +161,8 @@ class FilterConfig extends ControllersApi {
}
boolean hasErrors() {
- return super.hasErrors(this)
+ final Errors errors = getErrors()
+ return errors != null && errors.hasErrors()
}
Object redirect(Map args) {
View
5 ...te-uber/src/test/groovy/grails/test/mixin/ControllerAndFilterMixinInteractionTests.groovy
@@ -1,8 +1,10 @@
package grails.test.mixin
-import org.junit.Test
+import grails.artefact.Artefact
import grails.persistence.Entity
+import org.junit.Test
+
@TestFor(SecureUserController)
@Mock([SecurityFilters, User])
class ControllerAndFilterMixinInteractionTests {
@@ -21,6 +23,7 @@ class ControllerAndFilterMixinInteractionTests {
}
}
+@Artefact('Controller')
class SecureUserController {
def index() { }
}
View
1  ...ite-uber/src/test/groovy/org/grails/web/servlet/mvc/ControllersDynamicMethodsTests.groovy
@@ -15,6 +15,7 @@ class ControllersDynamicMethodsTests extends AbstractGrailsMockTests {
void onSetUp() {
gcl.parseClass """
+ @grails.artefact.Artefact('Controller')
class TestController {
def list = {}
}
View
12 grails-test-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/RedirectMethodTests.groovy
@@ -1,12 +1,14 @@
package org.grails.web.servlet.mvc
+import grails.artefact.Artefact
import grails.util.MockRequestDataValueProcessor
+import grails.web.http.HttpHeaders
import grails.web.mapping.mvc.RedirectEventListener
+import grails.web.mapping.mvc.exceptions.CannotRedirectException
+import grails.web.util.GrailsApplicationAttributes
+
import org.grails.plugins.web.controllers.api.ControllersApi
import org.grails.support.MockApplicationContext
-import grails.web.util.GrailsApplicationAttributes
-import grails.web.http.HttpHeaders
-import grails.web.mapping.mvc.exceptions.CannotRedirectException
import org.grails.web.servlet.mvc.alpha.NamespacedController
import org.springframework.beans.MutablePropertyValues
import org.springframework.web.servlet.support.RequestDataValueProcessor
@@ -386,14 +388,17 @@ class TestRedirectListener implements RedirectEventListener {
}
}
+@Artefact('Controller')
class ABCController {
def index = { redirect action: 'list' }
}
+@Artefact('Controller')
class AController {
def index = { redirect action: 'list' }
}
+@Artefact('Controller')
class RedirectController {
static defaultAction = 'toAction'
@@ -448,6 +453,7 @@ class RedirectController {
}
}
+@Artefact('Controller')
class NewsSignupController {
static defaultAction = "thankyou"
View
6 ...est-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/RenderDynamicMethodTests.groovy
@@ -1,11 +1,12 @@
package org.grails.web.servlet.mvc
+import static org.junit.Assert.assertEquals
+import grails.artefact.Artefact
import grails.test.mixin.TestFor
-import org.grails.web.sitemesh.GrailsLayoutDecoratorMapper
import org.grails.web.pages.FastStringWriter
+import org.grails.web.sitemesh.GrailsLayoutDecoratorMapper
import org.junit.Test
-import static org.junit.Assert.assertEquals
@TestFor(RenderDynamicMethodTestController)
class RenderDynamicMethodTests {
@@ -104,6 +105,7 @@ class RenderDynamicMethodTests {
}
}
+@Artefact('Controller')
class RenderDynamicMethodTestController {
def renderText = {
render "text"
View
3  ...t-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/alpha/NamespacedController.groovy
@@ -1,5 +1,8 @@
package org.grails.web.servlet.mvc.alpha
+import grails.artefact.Artefact
+
+@Artefact('Controller')
class NamespacedController {
def redirectToSelf() {
View
3  ...st-suite-uber/src/test/groovy/org/grails/web/servlet/mvc/beta/NamespacedController.groovy
@@ -1,5 +1,8 @@
package org.grails.web.servlet.mvc.beta
+import grails.artefact.Artefact
+
+@Artefact('Controller')
class NamespacedController {
static namespace = 'secondary'
View
15 grails-test-suite-web/src/test/groovy/grails/artefact/ControllerTraitSpec.groovy
@@ -0,0 +1,15 @@
+package grails.artefact
+
+import spock.lang.Specification
+
+class ControllerTraitSpec extends Specification {
+
+ void 'test that a class marked with @Artefact("Controller") is enhanced with grails.artefact.Controller'() {
+ expect:
+ Controller.isAssignableFrom SomeController
+ }
+}
+
+@Artefact('Controller')
+class SomeController {
+}
View
145 grails-web-gsp/src/main/groovy/grails/artefact/TagLibrary.groovy
@@ -0,0 +1,145 @@
+/*
+ * 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 grails.artefact
+
+import grails.core.GrailsApplication
+import grails.core.GrailsTagLibClass
+import grails.util.Environment
+import grails.web.util.GrailsApplicationAttributes
+import groovy.lang.Closure
+import org.codehaus.groovy.runtime.InvokerHelper
+
+import java.io.Writer
+
+import org.grails.web.pages.GroovyPage
+import org.grails.web.pages.GroovyPageBinding
+import org.grails.web.pages.GroovyPageOutputStack
+import org.grails.web.pages.GroovyPageRequestBinding
+import org.grails.web.pages.TagLibraryLookup
+import org.grails.web.servlet.mvc.GrailsWebRequest
+import org.grails.web.taglib.exceptions.GrailsTagException
+import org.grails.web.util.GrailsPrintWriter
+import org.grails.web.util.TagLibraryMetaUtils
+import org.grails.web.util.WithCodecHelper
+import org.springframework.beans.factory.annotation.Autowired
+import org.springframework.context.ApplicationContext
+import org.springframework.web.context.request.RequestAttributes
+
+/**
+ * @since 3.0
+ * @author Jeff Brown
+ *
+ */
+trait TagLibrary {
+
+ TagLibraryLookup tagLibraryLookup
+
+ /**
+ * Throws a GrailsTagException
+ *
+ * @param message The error message
+ */
+ void throwTagError(String message) {
+ throw new GrailsTagException(message)
+ }
+
+ /**
+ * Obtains the page scope instance
+ *
+ * @return The page scope instance
+ */
+ GroovyPageBinding getPageScope() {
+ GrailsWebRequest webRequest = getWebRequest()
+ GroovyPageBinding binding = (GroovyPageBinding) webRequest.getAttribute(GrailsApplicationAttributes.PAGE_SCOPE, RequestAttributes.SCOPE_REQUEST)
+ if (binding == null) {
+ binding = new GroovyPageBinding(new GroovyPageRequestBinding(webRequest))
+ binding.root = true
+ webRequest.setAttribute(GrailsApplicationAttributes.PAGE_SCOPE, binding, RequestAttributes.SCOPE_REQUEST)
+ }
+ binding
+ }
+
+ /**
+ * Obtains the currently output writer
+
+ * @return The writer to use
+ */
+ GrailsPrintWriter getOut() {
+ GroovyPageOutputStack.currentStack().taglibWriter
+ }
+
+ /**
+ * Sets the current output writer
+ * @param newOut The new output writer
+ */
+ void setOut(Writer newOut) {
+ GroovyPageOutputStack.currentStack().push(newOut,true)
+ }
+
+ def withCodec(Object codecInfo, Closure<?> body) {
+ WithCodecHelper.withCodec(getGrailsApplication(null), codecInfo, body)
+ }
+
+ /**
+ * Property missing implementation that looks up tag library namespaces or tags in the default namespace
+ *
+ * @param name The property name
+ * @return A tag namespace or a tag in the default namespace
+ *
+ * @throws MissingPropertyException When no tag namespace or tag is found
+ */
+ public Object propertyMissing(String name) {
+ TagLibraryLookup gspTagLibraryLookup = getTagLibraryLookup();
+ if (gspTagLibraryLookup != null) {
+
+ Object result = gspTagLibraryLookup.lookupNamespaceDispatcher(name);
+ if (result == null) {
+ String namespace = getNamespace();
+ GroovyObject tagLibrary = gspTagLibraryLookup.lookupTagLibrary(namespace, name);
+ if (tagLibrary == null) {
+ tagLibrary = gspTagLibraryLookup.lookupTagLibrary(GroovyPage.DEFAULT_NAMESPACE, name);
+ }
+
+ if (tagLibrary != null) {
+ Object tagProperty = tagLibrary.getProperty(name);
+ if (tagProperty instanceof Closure) {
+ result = ((Closure<?>)tagProperty).clone();
+ }
+ }
+ }
+
+ if (result != null && !Environment.isDevelopmentMode()) {
+ MetaClass mc = InvokerHelper.getMetaClass(this);
+ TagLibraryMetaUtils.registerPropertyMissingForTag(mc, name, result);
+ }
+
+ if (result != null) {
+ return result;
+ }
+ }
+
+ throw new MissingPropertyException(name, this.getClass());
+ }
+
+ @Autowired
+ void setGspTagLibraryLookup(TagLibraryLookup lookup) {
+ tagLibraryLookup = lookup;
+ }
+
+ void setTagLibraryLookup(TagLibraryLookup lookup) {
+ tagLibraryLookup = lookup;
+ }
+}
View
50 grails-web-gsp/src/main/groovy/org/grails/compiler/web/gsp/TagLibraryTraitInjector.groovy
@@ -0,0 +1,50 @@
+/*
+ * 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.web.gsp
+
+import grails.artefact.TagLibrary
+
+import java.util.regex.Pattern
+
+import org.grails.compiler.injection.TraitInjector
+import org.grails.io.support.GrailsResourceUtils
+
+/**
+ *
+ * @since 3.0
+ * @author Jeff Brown
+ *
+ */
+class TagLibraryTraitInjector implements TraitInjector {
+
+ static Pattern TAGLIB_PATTERN = Pattern.compile(".+/" +
+ GrailsResourceUtils.GRAILS_APP_DIR + "/taglib/(.+)TagLib\\.groovy")
+
+ @Override
+ Class getTrait() {
+ TagLibrary
+ }
+
+ @Override
+ boolean shouldInject(URL url) {
+ return url != null && TAGLIB_PATTERN.matcher(url.getFile()).find();
+ }
+
+ @Override
+ String[] getArtefactTypes() {
+ ['TagLibrary', 'TagLib'] as String[]
+ }
+}
View
125 grails-web-gsp/src/main/groovy/org/grails/plugins/web/api/TagLibraryApi.java
@@ -15,37 +15,24 @@
*/
package org.grails.plugins.web.api;
+import grails.core.GrailsApplication;
+import grails.core.GrailsTagLibClass;
+import grails.plugins.GrailsPluginManager;
import grails.util.Environment;
-import groovy.lang.Closure;
import groovy.lang.GroovyObject;
import groovy.lang.MetaClass;
import groovy.lang.MetaMethod;
import groovy.lang.MissingMethodException;
-import groovy.lang.MissingPropertyException;
-import java.io.Writer;
import java.util.List;
-import grails.core.GrailsApplication;
-import grails.core.GrailsTagLibClass;
+import org.codehaus.groovy.runtime.InvokerHelper;
import org.grails.core.artefact.TagLibArtefactHandler;
-import grails.plugins.GrailsPluginManager;
+import org.grails.web.api.CommonWebApi;
import org.grails.web.pages.GroovyPage;
-import org.grails.web.pages.GroovyPageBinding;
-import org.grails.web.pages.GroovyPageOutputStack;
-import org.grails.web.pages.GroovyPageRequestBinding;
import org.grails.web.pages.TagLibraryLookup;
-import grails.web.util.GrailsApplicationAttributes;
-import org.grails.web.servlet.mvc.GrailsWebRequest;
-import org.grails.web.taglib.exceptions.GrailsTagException;
-import org.grails.web.util.GrailsPrintWriter;
import org.grails.web.util.TagLibraryMetaUtils;
-import org.grails.web.util.WithCodecHelper;
-import org.codehaus.groovy.runtime.InvokerHelper;
-import org.grails.web.api.CommonWebApi;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
-import org.springframework.web.context.request.RequestAttributes;
/**
* API for Tag libraries in a Grails application.
@@ -69,52 +56,6 @@ public TagLibraryApi(GrailsPluginManager pluginManager) {
}
/**
- * Throws a GrailsTagException
- *
- * @param instance The tag library instance
- * @param message The error message
- */
- public void throwTagError(Object instance, String message) {
- throw new GrailsTagException(message);
- }
-
- /**
- * Obtains the page scope instance
- *
- * @param instance The tag library
- * @return The page scope instance
- */
- public GroovyPageBinding getPageScope(Object instance) {
- GrailsWebRequest webRequest = getWebRequest(instance);
- GroovyPageBinding binding = (GroovyPageBinding) webRequest.getAttribute(GrailsApplicationAttributes.PAGE_SCOPE, RequestAttributes.SCOPE_REQUEST);
- if (binding == null) {
- binding = new GroovyPageBinding(new GroovyPageRequestBinding(webRequest));
- binding.setRoot(true);
- webRequest.setAttribute(GrailsApplicationAttributes.PAGE_SCOPE, binding, RequestAttributes.SCOPE_REQUEST);
- }
- return binding;
- }
-
- /**
- * Obtains the currently output writer
-
- * @param instance The tag library instance
- * @return The writer to use
- */
- public GrailsPrintWriter getOut(Object instance) {
- return GroovyPageOutputStack.currentStack().getTaglibWriter();
- }
-
- /**
- * Sets the current output writer
- * @param instance The tag library instance
- * @param newOut The new output writer
- */
- public void setOut(Object instance, Writer newOut) {
- GroovyPageOutputStack.currentStack().push(newOut,true);
- }
-
- /**
* Method missing implementation that handles tag invocation by method name
*
* @param instance The instance
@@ -149,48 +90,6 @@ public Object methodMissing(Object instance, String methodName, Object argsObjec
throw new MissingMethodException(methodName, instance.getClass(), args);
}
-
- /**
- * Prpoerty missing implementation that looks up tag library namespaces or tags in the default namespace
- *
- * @param instance The tag library instance
- * @param name The property name
- * @return A tag namespace or a tag in the default namespace
- *
- * @throws MissingPropertyException When no tag namespace or tag is found
- */
- public Object propertyMissing(Object instance, String name) {
- TagLibraryLookup gspTagLibraryLookup = getTagLibraryLookup();
- if (gspTagLibraryLookup != null) {
-
- Object result = gspTagLibraryLookup.lookupNamespaceDispatcher(name);
- if (result == null) {
- String namespace = getNamespace(instance);
- GroovyObject tagLibrary = gspTagLibraryLookup.lookupTagLibrary(namespace, name);
- if (tagLibrary == null) {
- tagLibrary = gspTagLibraryLookup.lookupTagLibrary(GroovyPage.DEFAULT_NAMESPACE, name);
- }
-
- if (tagLibrary != null) {
- Object tagProperty = tagLibrary.getProperty(name);
- if (tagProperty instanceof Closure) {
- result = ((Closure<?>)tagProperty).clone();
- }
- }
- }
-
- if (result != null && !developmentMode) {
- MetaClass mc = InvokerHelper.getMetaClass(instance);
- TagLibraryMetaUtils.registerPropertyMissingForTag(mc, name, result);
- }
-
- if (result != null) {
- return result;
- }
- }
-
- throw new MissingPropertyException(name, instance.getClass());
- }
private String getNamespace(Object instance) {
GrailsApplication grailsApplication = getGrailsApplication(null);
@@ -202,16 +101,6 @@ private String getNamespace(Object instance) {
}
return GroovyPage.DEFAULT_NAMESPACE;
}
-
- @Autowired
- public void setGspTagLibraryLookup(TagLibraryLookup lookup) {
- tagLibraryLookup = lookup;
- }
-
- public void setTagLibraryLookup(TagLibraryLookup lookup) {
- tagLibraryLookup = lookup;
- }
-
public TagLibraryLookup getTagLibraryLookup() {
if (tagLibraryLookup == null) {
ApplicationContext applicationContext = getApplicationContext(null);
@@ -221,8 +110,4 @@ public TagLibraryLookup getTagLibraryLookup() {
}
return tagLibraryLookup;
}
-
- public Object withCodec(Object instance, Object codecInfo, Closure<?> body) {
- return WithCodecHelper.withCodec(getGrailsApplication(null), codecInfo, body);
- }
}
View
10 grails-web-gsp/src/test/groovy/org/grails/web/pages/TagLibraryLookupSpec.groovy
@@ -1,7 +1,8 @@
package org.grails.web.pages
-import grails.gsp.TagLib
import grails.core.DefaultGrailsApplication
+import grails.gsp.TagLib
+
import org.grails.plugins.web.api.TagLibraryApi
import org.grails.web.servlet.mvc.GrailsWebRequest
import org.grails.web.taglib.NamespacedTagDispatcher
@@ -11,6 +12,7 @@ import org.springframework.mock.web.MockServletContext
import org.springframework.web.context.WebApplicationContext
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.support.GenericWebApplicationContext
+
import spock.lang.Issue
import spock.lang.Specification
import spock.util.mop.ConfineMetaClassChanges
@@ -30,10 +32,8 @@ class TagLibraryLookupSpec extends Specification {
def application = new DefaultGrailsApplication([OneTagLib, TwoTagLib] as Class[], TagLibraryLookup.class.classLoader)
application.initialise()
def applicationContext = new GenericWebApplicationContext()
- def api = new TagLibraryApi(gspTagLibraryLookup: lookup)
- applicationContext.defaultListableBeanFactory.registerSingleton("instanceTagLibraryApi", api)
- applicationContext.defaultListableBeanFactory.registerSingleton(OneTagLib.name, new OneTagLib())
- applicationContext.defaultListableBeanFactory.registerSingleton(TwoTagLib.name, new TwoTagLib())
+ applicationContext.defaultListableBeanFactory.registerSingleton(OneTagLib.name, new OneTagLib(gspTagLibraryLookup: lookup))
+ applicationContext.defaultListableBeanFactory.registerSingleton(TwoTagLib.name, new TwoTagLib(gspTagLibraryLookup: lookup))
applicationContext.defaultListableBeanFactory.registerSingleton("gspTagLibraryLookup", lookup)
// instanceTagLibraryApi(TagLibraryApi, pluginManager)
applicationContext.refresh()

0 comments on commit 539b5cb

Please sign in to comment.
Something went wrong with that request. Please try again.