diff --git a/.springBeans b/.springBeans
new file mode 100644
index 00000000000..6c6cb5a2848
--- /dev/null
+++ b/.springBeans
@@ -0,0 +1,13 @@
+
+
+ 1
+
+
+
+
+
+
+
+
+
+
diff --git a/src/java/org/codehaus/groovy/grails/commons/metaclass/BaseApiProvider.java b/src/java/org/codehaus/groovy/grails/commons/metaclass/BaseApiProvider.java
index bb6a75da825..c1de56d2f70 100644
--- a/src/java/org/codehaus/groovy/grails/commons/metaclass/BaseApiProvider.java
+++ b/src/java/org/codehaus/groovy/grails/commons/metaclass/BaseApiProvider.java
@@ -15,17 +15,20 @@
*/
package org.codehaus.groovy.grails.commons.metaclass;
-import groovy.lang.MetaMethod;
+import groovy.lang.Closure;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import org.apache.commons.lang.ArrayUtils;
import org.codehaus.groovy.reflection.CachedClass;
import org.codehaus.groovy.reflection.CachedMethod;
import org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod;
+import org.springframework.util.ReflectionUtils;
/**
*
@@ -35,19 +38,32 @@
*
*/
public abstract class BaseApiProvider {
-
- protected List instanceMethods = new ArrayList();
+ private static List EXCLUDED_METHODS = new ArrayList() {{
+ add("setMetaClass");
+ add("getMetaClass");
+ }};
+ private static Map METHOD_CLOSURES = new HashMap() {{
+ put("setProperty", 2);
+ put("getProperty", 1);
+ put("invokeMethod", 2);
+ put("methodMissing", 2);
+ put("propertyMissing", 1);
+
+ }};
+ @SuppressWarnings("rawtypes")
+ protected List instanceMethods = new ArrayList();
protected List staticMethods = new ArrayList();
+ @SuppressWarnings("unchecked")
public void addApi(final Object apiInstance) {
if(apiInstance != null) {
Class> currentClass = apiInstance.getClass();
while(currentClass != Object.class) {
final Method[] declaredMethods = currentClass.getDeclaredMethods();
- for (Method method : declaredMethods) {
+ for (final Method method : declaredMethods) {
final int modifiers = method.getModifiers();
- if(Modifier.isPublic(modifiers) && !Modifier.isAbstract(modifiers)) {
+ if(isNotExcluded(method, modifiers)) {
if(Modifier.isStatic(modifiers)) {
staticMethods.add(method);
}
@@ -67,7 +83,8 @@ public CachedClass[] getParameterTypes() {
else
return paramTypes;
}
- });
+ });
+
}
}
}
@@ -75,6 +92,18 @@ public CachedClass[] getParameterTypes() {
}
}
}
+
+ private boolean isNotExcluded(Method method, final int modifiers) {
+ final String name = method.getName();
+
+ if(EXCLUDED_METHODS.contains(name)) return false;
+
+ Integer parameterCount = METHOD_CLOSURES.get(name);
+ return Modifier.isPublic(modifiers) &&
+ !Modifier.isAbstract(modifiers) &&
+ !name.contains("$") &&
+ !(parameterCount != null && (parameterCount == method.getParameterTypes().length));
+ }
}
diff --git a/src/java/org/codehaus/groovy/grails/commons/metaclass/MetaClassEnhancer.groovy b/src/java/org/codehaus/groovy/grails/commons/metaclass/MetaClassEnhancer.groovy
index 44270fc4f4f..61f1df74641 100644
--- a/src/java/org/codehaus/groovy/grails/commons/metaclass/MetaClassEnhancer.groovy
+++ b/src/java/org/codehaus/groovy/grails/commons/metaclass/MetaClassEnhancer.groovy
@@ -18,7 +18,9 @@ package org.codehaus.groovy.grails.commons.metaclass
import java.lang.reflect.Method;
-import groovy.lang.ExpandoMetaClass;
+import org.codehaus.groovy.runtime.MethodClosure
+import org.codehaus.groovy.runtime.metaclass.ReflectionMetaMethod;
+
import groovy.lang.MetaClass;
import groovy.lang.MetaMethod;
@@ -32,8 +34,9 @@ import groovy.lang.MetaMethod;
class MetaClassEnhancer extends BaseApiProvider {
public void enhance(MetaClass metaClass) {
- for (MetaMethod method : instanceMethods) {
- metaClass.registerInstanceMethod(method)
+ for (method in instanceMethods) {
+ if(method instanceof ReflectionMetaMethod)
+ metaClass.registerInstanceMethod(method)
}
for (Method method : staticMethods) {
diff --git a/src/java/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPlugin.groovy b/src/java/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPlugin.groovy
index 8c01f443c21..750f9e3a6a9 100644
--- a/src/java/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPlugin.groovy
+++ b/src/java/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPlugin.groovy
@@ -23,7 +23,6 @@ import javax.servlet.http.HttpServletResponse
import javax.servlet.http.HttpSession
import org.codehaus.groovy.grails.commons.metaclass.MetaClassEnhancer;
-import org.codehaus.groovy.grails.plugins.web.api.AttributeAccessor;
import org.codehaus.groovy.grails.plugins.web.api.ServletRequestApi;
import org.springframework.web.util.WebUtils
@@ -41,18 +40,62 @@ class ServletsGrailsPlugin {
def dependsOn = [core:version]
private MetaClassEnhancer requestEnhancer
- private MetaClassEnhancer attrEnhancer
+
public ServletsGrailsPlugin() {
this.requestEnhancer = new MetaClassEnhancer()
requestEnhancer.addApi new ServletRequestApi()
- this.attrEnhancer = new MetaClassEnhancer()
- attrEnhancer.addApi new AttributeAccessor()
-
}
def doWithDynamicMethods = { ctx ->
+ def getAttributeClosure = { String name ->
+ def mp = delegate.class.metaClass.getMetaProperty(name)
+ return mp ? mp.getProperty(delegate) : delegate.getAttribute(name)
+ }
+
+ def setAttributeClosure = { String name, value ->
+ def mp = delegate.class.metaClass.getMetaProperty(name)
+ if (mp) {
+ mp.setProperty(delegate, value)
+ }
+ else {
+ delegate.setAttribute(name, value)
+ }
+ }
+
+ def getAttributeSubscript = { String key ->
+ delegate.getAttribute(key)
+ }
+ def setAttributeSubScript = { String key, Object val ->
+ delegate.setAttribute(key, val)
+ }
+ // enables acces to servlet context with servletContext.foo syntax
+ ServletContext.metaClass.getProperty = getAttributeClosure
+ ServletContext.metaClass.setProperty = setAttributeClosure
+ ServletContext.metaClass.getAt = getAttributeSubscript
+ ServletContext.metaClass.putAt = setAttributeSubScript
+
+ // enables access to session attributes using session.foo syntax
+ HttpSession.metaClass.getProperty = getAttributeClosure
+ HttpSession.metaClass.setProperty = setAttributeClosure
+ // enables access to session attributes with session["foo"] syntax
+ HttpSession.metaClass.getAt = getAttributeSubscript
+ // enables setting of session attributes with session["foo"] = "bar" syntax
+ HttpSession.metaClass.putAt = setAttributeSubScript
+ // enables access to request attributes with request["foo"] syntax
+ HttpServletRequest.metaClass.getAt = { String key ->
+ delegate.getAttribute(key)
+ }
+ // enables setting of request attributes with request["foo"] = "bar" syntax
+ HttpServletRequest.metaClass.putAt = { String key, Object val ->
+ delegate.setAttribute(key, val)
+ }
+ // enables access to request attributes using property syntax
+ HttpServletRequest.metaClass.getProperty = getAttributeClosure
+ HttpServletRequest.metaClass.setProperty = setAttributeClosure
+
requestEnhancer.enhance HttpServletRequest.metaClass
- attrEnhancer.enhanceAll( [ServletContext.metaClass, HttpSession.metaClass] )
+
+
// allows the syntax response << "foo"
HttpServletResponse.metaClass.leftShift = { Object o ->
delegate.writer << o
diff --git a/src/java/org/codehaus/groovy/grails/plugins/web/api/AttributeAccessor.groovy b/src/java/org/codehaus/groovy/grails/plugins/web/api/AttributeAccessor.groovy
deleted file mode 100644
index c66c753737d..00000000000
--- a/src/java/org/codehaus/groovy/grails/plugins/web/api/AttributeAccessor.groovy
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright 2010 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.codehaus.groovy.grails.plugins.web.api
-
-/**
-* API for classes that access attributes like property access (eg. request.getAttribute('foo') becomes request.foo)
-*
-* @author Graeme Rocher
-* @since 1.4
-*
-*/
-
-class AttributeAccessor {
-
- def getProperty(instance, String name) {
- def mp = instance.class.metaClass.getMetaProperty(name)
- return mp ? mp.getProperty(instance) : instance.getAttribute(name)
- }
-
- void setProperty(instance, String name, value) {
- def mp = instance.class.metaClass.getMetaProperty(name)
- if (mp) {
- mp.setProperty(instance, value)
- }
- else {
- instance.setAttribute(name, value)
- }
- }
-
- def getAt(instance, String name) {
- getProperty(instance, name)
- }
-
- def putAt(instance, String name, value) {
- setProperty(instance, name, value)
- }
-}
diff --git a/src/java/org/codehaus/groovy/grails/plugins/web/api/ServletRequestApi.groovy b/src/java/org/codehaus/groovy/grails/plugins/web/api/ServletRequestApi.groovy
index b5dac6a66f5..87121b71468 100644
--- a/src/java/org/codehaus/groovy/grails/plugins/web/api/ServletRequestApi.groovy
+++ b/src/java/org/codehaus/groovy/grails/plugins/web/api/ServletRequestApi.groovy
@@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletRequest;
*
*/
-class ServletRequestApi extends AttributeAccessor{
+class ServletRequestApi {
/**
* @return retrieve the forwardURI for the request
diff --git a/src/test/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPluginTests.groovy b/src/test/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPluginTests.groovy
index a31b4f4190b..de6a895e680 100644
--- a/src/test/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPluginTests.groovy
+++ b/src/test/org/codehaus/groovy/grails/plugins/web/ServletsGrailsPluginTests.groovy
@@ -1,10 +1,16 @@
package org.codehaus.groovy.grails.plugins.web
+import groovy.lang.GroovySystem;
+
import org.codehaus.groovy.grails.commons.test.*
import org.codehaus.groovy.grails.commons.metaclass.*
import org.codehaus.groovy.grails.commons.spring.*
import org.springframework.mock.web.*
+
+import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest
+import javax.servlet.http.HttpSession;
+
import org.springframework.web.util.*
class ServletsGrailsPluginTests extends AbstractGrailsPluginTests {
@@ -37,7 +43,9 @@ class ServletsGrailsPluginTests extends AbstractGrailsPluginTests {
void testServletContextObject() {
def context = new MockServletContext()
- context["foo"] = "bar"
+ println context.metaClass.getMetaMethod("getProperty")
+ println ServletContext.metaClass.getMetaMethod("getProperty")
+ context["foo"] = "bar"
assertEquals "bar", context["foo"]
context.foo = "fred"
@@ -49,7 +57,9 @@ class ServletsGrailsPluginTests extends AbstractGrailsPluginTests {
void testHttpSessionObject() {
def session = new MockHttpSession()
- assert session.creationTime
+ def httpSessionMetaClass = GroovySystem.getMetaClassRegistry().getMetaClass(HttpSession)
+ def metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(session.getClass())
+ assert session.getProperty("creationTime")
session["foo"] = "bar"
assertEquals "bar", session["foo"]
diff --git a/src/test/org/codehaus/groovy/grails/resolve/IvyDependencyManagerTests.groovy b/src/test/org/codehaus/groovy/grails/resolve/IvyDependencyManagerTests.groovy
index 7d1cdc9909e..3548d0334a5 100644
--- a/src/test/org/codehaus/groovy/grails/resolve/IvyDependencyManagerTests.groovy
+++ b/src/test/org/codehaus/groovy/grails/resolve/IvyDependencyManagerTests.groovy
@@ -473,11 +473,11 @@ class IvyDependencyManagerTests extends GroovyTestCase {
def grailsVersion = getCurrentGrailsVersion()
manager.parseDependencies(IvyDependencyManager.getDefaultDependencies(grailsVersion))
- assertEquals 54, manager.listDependencies('runtime').size()
- assertEquals 57, manager.listDependencies('test').size()
- assertEquals 20, manager.listDependencies('build').size()
+ assertEquals 56, manager.listDependencies('runtime').size()
+ assertEquals 59, manager.listDependencies('test').size()
+ assertEquals 19, manager.listDependencies('build').size()
assertEquals 2, manager.listDependencies('provided').size()
- assertEquals 23, manager.listDependencies('docs').size()
+ assertEquals 22, manager.listDependencies('docs').size()
// This should be a functional test since it relies on the Grails
// JAR files being built. It also runs Ivy, which isn't ideal
@@ -501,9 +501,9 @@ class IvyDependencyManagerTests extends GroovyTestCase {
assertEquals 0, manager.listDependencies('runtime').size()
assertEquals 3, manager.listDependencies('test').size()
- assertEquals 20, manager.listDependencies('build').size()
- assertEquals 56, manager.listDependencies('provided').size()
- assertEquals 23, manager.listDependencies('docs').size()
+ assertEquals 19, manager.listDependencies('build').size()
+ assertEquals 58, manager.listDependencies('provided').size()
+ assertEquals 22, manager.listDependencies('docs').size()
manager = new IvyDependencyManager("project", "0.1",settings)
defaultDependencyClosure = IvyDependencyManager.getDefaultDependencies(grailsVersion)
@@ -513,11 +513,11 @@ class IvyDependencyManagerTests extends GroovyTestCase {
defaultDependencyClosure()
}
- assertEquals 54, manager.listDependencies('runtime').size()
- assertEquals 57, manager.listDependencies('test').size()
- assertEquals 20, manager.listDependencies('build').size()
+ assertEquals 56, manager.listDependencies('runtime').size()
+ assertEquals 59, manager.listDependencies('test').size()
+ assertEquals 19, manager.listDependencies('build').size()
assertEquals 2, manager.listDependencies('provided').size()
- assertEquals 23, manager.listDependencies('docs').size()
+ assertEquals 22, manager.listDependencies('docs').size()
}
def getCurrentGrailsVersion() {