use of org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod in project groovy by apache.
the class MetaClassImpl method invokeMissingProperty.
/**
* Invoke a missing property on the given object with the given arguments.
*
* @param instance The object the method should be invoked on.
* @param propertyName The name of the property to invoke.
* @param optionalValue The (optional) new value for the property
* @param isGetter Wether the method is a getter
*
* @return The result of the method invocation.
*/
public Object invokeMissingProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
Class theClass = instance instanceof Class ? (Class) instance : instance.getClass();
CachedClass superClass = theCachedClass;
while (superClass != null && superClass != ReflectionCache.OBJECT_CLASS) {
final MetaBeanProperty property = findPropertyInClassHierarchy(propertyName, superClass);
if (property != null) {
onSuperPropertyFoundInHierarchy(property);
if (!isGetter) {
property.setProperty(instance, optionalValue);
return null;
} else {
return property.getProperty(instance);
}
}
superClass = superClass.getCachedSuperClass();
}
// got here to property not found, look for getProperty or setProperty overrides
if (isGetter) {
final Class[] getPropertyArgs = { String.class };
final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), GET_PROPERTY_METHOD, getPropertyArgs, this);
if (method != null && method instanceof ClosureMetaMethod) {
onGetPropertyFoundInHierarchy(method);
return method.invoke(instance, new Object[] { propertyName });
}
} else {
final Class[] setPropertyArgs = { String.class, Object.class };
final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), SET_PROPERTY_METHOD, setPropertyArgs, this);
if (method != null && method instanceof ClosureMetaMethod) {
onSetPropertyFoundInHierarchy(method);
return method.invoke(instance, new Object[] { propertyName, optionalValue });
}
}
try {
if (!(instance instanceof Class)) {
if (isGetter) {
if (propertyMissingGet != null) {
return propertyMissingGet.invoke(instance, new Object[] { propertyName });
}
} else {
if (propertyMissingSet != null) {
return propertyMissingSet.invoke(instance, new Object[] { propertyName, optionalValue });
}
}
}
} catch (InvokerInvocationException iie) {
boolean shouldHandle = isGetter && propertyMissingGet != null;
if (!shouldHandle)
shouldHandle = !isGetter && propertyMissingSet != null;
if (shouldHandle && iie.getCause() instanceof MissingPropertyException) {
throw (MissingPropertyException) iie.getCause();
}
throw iie;
}
if (instance instanceof Class && theClass != Class.class) {
final MetaProperty metaProperty = InvokerHelper.getMetaClass(Class.class).hasProperty(instance, propertyName);
if (metaProperty != null)
if (isGetter)
return metaProperty.getProperty(instance);
else {
metaProperty.setProperty(instance, optionalValue);
return null;
}
}
throw new MissingPropertyExceptionNoStack(propertyName, theClass);
}
use of org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod in project groovy-core by groovy.
the class ExpandoMetaClass method addSuperMethodIfNotOverridden.
private void addSuperMethodIfNotOverridden(final MetaMethod metaMethodFromSuper) {
performOperationOnMetaClass(new Callable() {
public void call() {
MetaMethod existing = null;
try {
existing = pickMethod(metaMethodFromSuper.getName(), metaMethodFromSuper.getNativeParameterTypes());
} catch (GroovyRuntimeException e) {
// ignore, this happens with overlapping method definitions
}
if (existing == null) {
addMethodWithKey(metaMethodFromSuper);
} else {
boolean isGroovyMethod = getMetaMethods().contains(existing);
if (isGroovyMethod) {
addMethodWithKey(metaMethodFromSuper);
} else if (inheritedMetaMethods.contains(existing)) {
inheritedMetaMethods.remove(existing);
addMethodWithKey(metaMethodFromSuper);
}
}
}
private void addMethodWithKey(final MetaMethod metaMethodFromSuper) {
inheritedMetaMethods.add(metaMethodFromSuper);
if (metaMethodFromSuper instanceof ClosureMetaMethod) {
ClosureMetaMethod closureMethod = (ClosureMetaMethod) metaMethodFromSuper;
String name = metaMethodFromSuper.getName();
final Class declaringClass = metaMethodFromSuper.getDeclaringClass().getTheClass();
ClosureMetaMethod localMethod = ClosureMetaMethod.copy(closureMethod);
addMetaMethod(localMethod);
MethodKey key = new DefaultCachedMethodKey(declaringClass, name, localMethod.getParameterTypes(), false);
checkIfGroovyObjectMethod(localMethod);
expandoMethods.put(key, localMethod);
}
}
});
}
use of org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod in project groovy-core by groovy.
the class MetaClassImpl method invokeMissingProperty.
/**
* Invoke a missing property on the given object with the given arguments.
*
* @param instance The object the method should be invoked on.
* @param propertyName The name of the property to invoke.
* @param optionalValue The (optional) new value for the property
* @param isGetter Wether the method is a getter
*
* @return The result of the method invocation.
*/
public Object invokeMissingProperty(Object instance, String propertyName, Object optionalValue, boolean isGetter) {
Class theClass = instance instanceof Class ? (Class) instance : instance.getClass();
CachedClass superClass = theCachedClass;
while (superClass != null && superClass != ReflectionCache.OBJECT_CLASS) {
final MetaBeanProperty property = findPropertyInClassHierarchy(propertyName, superClass);
if (property != null) {
onSuperPropertyFoundInHierarchy(property);
if (!isGetter) {
property.setProperty(instance, optionalValue);
return null;
} else {
return property.getProperty(instance);
}
}
superClass = superClass.getCachedSuperClass();
}
// got here to property not found, look for getProperty or setProperty overrides
if (isGetter) {
final Class[] getPropertyArgs = { String.class };
final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), GET_PROPERTY_METHOD, getPropertyArgs, this);
if (method != null && method instanceof ClosureMetaMethod) {
onGetPropertyFoundInHierarchy(method);
return method.invoke(instance, new Object[] { propertyName });
}
} else {
final Class[] setPropertyArgs = { String.class, Object.class };
final MetaMethod method = findMethodInClassHierarchy(instance.getClass(), SET_PROPERTY_METHOD, setPropertyArgs, this);
if (method != null && method instanceof ClosureMetaMethod) {
onSetPropertyFoundInHierarchy(method);
return method.invoke(instance, new Object[] { propertyName, optionalValue });
}
}
try {
if (!(instance instanceof Class)) {
if (isGetter && propertyMissingGet != null) {
return propertyMissingGet.invoke(instance, new Object[] { propertyName });
} else {
if (propertyMissingSet != null)
return propertyMissingSet.invoke(instance, new Object[] { propertyName, optionalValue });
}
}
} catch (InvokerInvocationException iie) {
boolean shouldHandle = isGetter && propertyMissingGet != null;
if (!shouldHandle)
shouldHandle = !isGetter && propertyMissingSet != null;
if (shouldHandle && iie.getCause() instanceof MissingPropertyException) {
throw (MissingPropertyException) iie.getCause();
}
throw iie;
}
if (instance instanceof Class && theClass != Class.class) {
final MetaProperty metaProperty = InvokerHelper.getMetaClass(Class.class).hasProperty(instance, propertyName);
if (metaProperty != null)
if (isGetter)
return metaProperty.getProperty(instance);
else {
metaProperty.setProperty(instance, optionalValue);
return null;
}
}
throw new MissingPropertyExceptionNoStack(propertyName, theClass);
}
use of org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod in project groovy-core by groovy.
the class MetaClassImpl method invokeMissingMethod.
private Object invokeMissingMethod(Object instance, String methodName, Object[] arguments, RuntimeException original, boolean isCallToSuper) {
if (!isCallToSuper) {
Class instanceKlazz = instance.getClass();
if (theClass != instanceKlazz && theClass.isAssignableFrom(instanceKlazz))
instanceKlazz = theClass;
Class[] argClasses = MetaClassHelper.castArgumentsToClassArray(arguments);
MetaMethod method = findMixinMethod(methodName, argClasses);
if (method != null) {
onMixinMethodFound(method);
return method.invoke(instance, arguments);
}
method = findMethodInClassHierarchy(instanceKlazz, methodName, argClasses, this);
if (method != null) {
onSuperMethodFoundInHierarchy(method);
return method.invoke(instance, arguments);
}
// still not method here, so see if there is an invokeMethod method up the hierarchy
final Class[] invokeMethodArgs = { String.class, Object[].class };
method = findMethodInClassHierarchy(instanceKlazz, INVOKE_METHOD_METHOD, invokeMethodArgs, this);
if (method != null && method instanceof ClosureMetaMethod) {
onInvokeMethodFoundInHierarchy(method);
return method.invoke(instance, invokeMethodArgs);
}
}
if (methodMissing != null) {
try {
return methodMissing.invoke(instance, new Object[] { methodName, arguments });
} catch (InvokerInvocationException iie) {
if (methodMissing instanceof ClosureMetaMethod && iie.getCause() instanceof MissingMethodException) {
MissingMethodException mme = (MissingMethodException) iie.getCause();
throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(), mme.getArguments(), mme.isStatic(), mme);
}
throw iie;
} catch (MissingMethodException mme) {
if (methodMissing instanceof ClosureMetaMethod)
throw new MissingMethodExecutionFailed(mme.getMethod(), mme.getClass(), mme.getArguments(), mme.isStatic(), mme);
else
throw mme;
}
} else if (original != null)
throw original;
else
throw new MissingMethodExceptionNoStack(methodName, theClass, arguments, false);
}
use of org.codehaus.groovy.runtime.metaclass.ClosureMetaMethod in project groovy by apache.
the class ExpandoMetaClass method addSuperMethodIfNotOverridden.
private void addSuperMethodIfNotOverridden(final MetaMethod metaMethodFromSuper) {
performOperationOnMetaClass(new Callable() {
public void call() {
MetaMethod existing = null;
try {
existing = pickMethod(metaMethodFromSuper.getName(), metaMethodFromSuper.getNativeParameterTypes());
} catch (GroovyRuntimeException e) {
// ignore, this happens with overlapping method definitions
}
if (existing == null) {
addMethodWithKey(metaMethodFromSuper);
} else {
boolean isGroovyMethod = getMetaMethods().contains(existing);
if (isGroovyMethod) {
addMethodWithKey(metaMethodFromSuper);
} else if (inheritedMetaMethods.contains(existing)) {
inheritedMetaMethods.remove(existing);
addMethodWithKey(metaMethodFromSuper);
}
}
}
private void addMethodWithKey(final MetaMethod metaMethodFromSuper) {
inheritedMetaMethods.add(metaMethodFromSuper);
if (metaMethodFromSuper instanceof ClosureMetaMethod) {
ClosureMetaMethod closureMethod = (ClosureMetaMethod) metaMethodFromSuper;
String name = metaMethodFromSuper.getName();
final Class declaringClass = metaMethodFromSuper.getDeclaringClass().getTheClass();
ClosureMetaMethod localMethod = ClosureMetaMethod.copy(closureMethod);
addMetaMethod(localMethod);
MethodKey key = new DefaultCachedMethodKey(declaringClass, name, localMethod.getParameterTypes(), false);
checkIfGroovyObjectMethod(localMethod);
expandoMethods.put(key, localMethod);
}
}
});
}
Aggregations