metaclassimpl.java
来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 1,511 行 · 第 1/5 页
JAVA
1,511 行
continue;
}
copyNonPrivateMethods(currentIndex,methodIndex);
}
}
private static void makeInterfaceSet(Class c, Set s) {
if (c==null) return;
Class[] interfaces = c.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
if (!s.contains(interfaces[i])) {
s.add(interfaces[i]);
makeInterfaceSet(interfaces[i],s);
}
}
makeInterfaceSet(c.getSuperclass(),s);
}
private void copyNonPrivateMethods(Map from, Map to) {
for (Iterator iterator = from.entrySet().iterator(); iterator.hasNext();) {
Map.Entry element = (Map.Entry) iterator.next();
List oldList = (List) element.getValue();
List newList = (List) to.get(element.getKey());
if (newList==null) {
to.put(element.getKey(),new ArrayList(oldList));
} else {
addNonPrivateMethods(newList,oldList);
}
}
}
private void connectMultimethods(List superClasses){
superClasses = DefaultGroovyMethods.reverse(superClasses);
Map last = null;
for (Iterator iter = superClasses.iterator(); iter.hasNext();) {
Class c = (Class) iter.next();
Map methodIndex = (Map) classMethodIndex.get(c);
if (methodIndex==last) continue;
if (last!=null) copyNonPrivateMethods(last,methodIndex);
last = methodIndex;
}
}
private void inheritMethods(Collection superClasses, Map classMethodIndex){
Map last = null;
for (Iterator iter = superClasses.iterator(); iter.hasNext();) {
Class c = (Class) iter.next();
Map methodIndex = (Map) classMethodIndex.get(c);
if (last!=null) {
if (methodIndex.size()==0) {
classMethodIndex.put(c,last);
continue;
}
copyNonPrivateMethods(last,methodIndex);
}
last = methodIndex;
}
}
private void addNonPrivateMethods(List newList, List oldList) {
for (Iterator iter = oldList.iterator(); iter.hasNext();) {
MetaMethod element = (MetaMethod) iter.next();
if (element.isPrivate()) continue;
addMethodToList(newList,element);
}
}
/**
* @return all the normal instance methods avaiable on this class for the
* given name
*/
private List getMethods(Class sender, String name, boolean isCallToSuper) {
Map methodIndex;
if (isCallToSuper) {
methodIndex = (Map) classMethodIndexForSuper.get(sender);
} else {
methodIndex = (Map) classMethodIndex.get(sender);
}
List answer;
if (methodIndex!=null) {
answer = (List) methodIndex.get(name);
if (answer == null) answer = Collections.EMPTY_LIST;
} else {
answer = Collections.EMPTY_LIST;
}
if (!isCallToSuper && GroovyCategorySupport.hasCategoryInAnyThread()) {
List used = GroovyCategorySupport.getCategoryMethods(sender, name);
if (used != null) {
answer = new ArrayList(answer);
for (Iterator iter = used.iterator(); iter.hasNext();) {
MetaMethod element = (MetaMethod) iter.next();
removeMatchingMethod(answer,element);
}
answer.addAll(used);
}
}
return answer;
}
/**
* @return all the normal static methods avaiable on this class for the
* given name
*/
private List getStaticMethods(Class sender, String name) {
Map methodIndex = (Map) classStaticMethodIndex.get(sender);
if (methodIndex == null) return Collections.EMPTY_LIST;
List answer = (List) methodIndex.get(name);
if (answer == null) return Collections.EMPTY_LIST;
return answer;
}
public void addNewInstanceMethod(Method method) {
NewInstanceMetaMethod newMethod = new NewInstanceMetaMethod(createMetaMethod(method));
if (! newGroovyMethodsList.contains(newMethod)){
newGroovyMethodsList.add(newMethod);
addMetaMethod(newMethod);
}
}
public void addNewStaticMethod(Method method) {
NewStaticMetaMethod newMethod = new NewStaticMetaMethod(createMetaMethod(method));
if (! newGroovyMethodsList.contains(newMethod)){
newGroovyMethodsList.add(newMethod);
addMetaMethod(newMethod);
}
}
private void unwrap(Object[] arguments) {
//
// Temp code to ignore wrapped parameters
// The New MOP will deal with these properly
//
for (int i = 0; i != arguments.length; i++) {
if (arguments[i] instanceof Wrapper) {
arguments[i] = ((Wrapper)arguments[i]).unwrap();
}
}
}
/**
* Invokes the given method on the object.
* @deprecated
*/
public Object invokeMethod(Object object, String methodName, Object[] originalArguments) {
return invokeMethod(theClass,object,methodName,originalArguments,false,false);
}
/**
* Invokes the given method on the object.
*
*/
public Object invokeMethod(Class sender, Object object, String methodName, Object[] originalArguments, boolean isCallToSuper, boolean fromInsideClass) {
checkInitalised();
if (object == null) {
throw new NullPointerException("Cannot invoke method: " + methodName + " on null object");
}
if (log.isLoggable(Level.FINER)){
MetaClassHelper.logMethodCall(object, methodName, originalArguments);
}
Object[] arguments = originalArguments;
if (arguments==null) arguments = EMPTY_ARGUMENTS;
Class[] argClasses = MetaClassHelper.convertToTypeArray(arguments);
unwrap(arguments);
MetaMethod method = getMethodWithCaching(sender, methodName, argClasses, isCallToSuper);
if (method==null && arguments.length==1 && arguments[0] instanceof List) {
Object[] newArguments = ((List) arguments[0]).toArray();
Class[] newArgClasses = MetaClassHelper.convertToTypeArray(newArguments);
method = getMethodWithCaching(sender, methodName, newArgClasses, isCallToSuper);
if (method!=null) {
MethodKey methodKey = new DefaultMethodKey(sender, methodName, argClasses, isCallToSuper);
method = new TransformMetaMethod(method) {
public Object invoke(Object object, Object[] arguments) {
Object firstArgument = arguments[0];
List list = (List) firstArgument;
arguments = list.toArray();
return super.invoke(object, arguments);
}
};
cacheInstanceMethod(methodKey, method);
return invokeMethod(sender,object,methodName, originalArguments, isCallToSuper, fromInsideClass);
}
}
boolean isClosure = object instanceof Closure;
if (isClosure) {
Closure closure = (Closure) object;
Object delegate = closure.getDelegate();
Object owner = closure.getOwner();
if ("call".equals(methodName) || "doCall".equals(methodName)) {
if (object.getClass()==MethodClosure.class) {
MethodClosure mc = (MethodClosure) object;
methodName = mc.getMethod();
Class ownerClass = owner.getClass();
if (owner instanceof Class) ownerClass = (Class) owner;
MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
return ownerMetaClass.invokeMethod(ownerClass,owner,methodName,arguments,false,false);
} else if (object.getClass()==CurriedClosure.class) {
CurriedClosure cc = (CurriedClosure) object;
// change the arguments for an uncurried call
arguments = cc.getUncurriedArguments(arguments);
Class ownerClass = owner.getClass();
if (owner instanceof Class) ownerClass = (Class) owner;
MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
return ownerMetaClass.invokeMethod(owner,methodName,arguments);
}
} else if ("curry".equals(methodName)) {
return closure.curry(arguments);
}
if (method==null && owner!=closure) {
Class ownerClass = owner.getClass();
if (owner instanceof Class) ownerClass = (Class) owner;
MetaClass ownerMetaClass = registry.getMetaClass(ownerClass);
method = ownerMetaClass.pickMethod(methodName,argClasses);
if (method!=null) return ownerMetaClass.invokeMethod(owner,methodName,originalArguments);
}
if (method==null && delegate!=closure && delegate!=null) {
Class delegateClass = delegate.getClass();
if (delegate instanceof Class) delegateClass = (Class) delegate;
MetaClass delegateMetaClass = registry.getMetaClass(delegateClass);
method = delegateMetaClass.pickMethod(methodName,argClasses);
if (method!=null) return delegateMetaClass.invokeMethod(delegate,methodName,originalArguments);
}
if (method==null) {
// still no methods found, test if delegate or owner are GroovyObjects
// and invoke the method on them if so.
MissingMethodException last = null;
if (owner!=closure && (owner instanceof GroovyObject)) {
try {
GroovyObject go = (GroovyObject) owner;
return go.invokeMethod(methodName,originalArguments);
} catch (MissingMethodException mme) {
if (last==null) last = mme;
}
}
if (delegate!=closure && (delegate instanceof GroovyObject)) {
try {
GroovyObject go = (GroovyObject) delegate;
return go.invokeMethod(methodName,originalArguments);
} catch (MissingMethodException mme) {
last = mme;
}
}
if (last!=null) throw last;
}
}
if (method != null) {
return MetaClassHelper.doMethodInvoke(object, method, arguments);
} else {
// if no method was found, try to find a closure defined as a field of the class and run it
try {
Object value = this.getProperty(object, methodName);
if (value instanceof Closure) { // This test ensures that value != this If you ever change this ensure that value != this
Closure closure = (Closure) value;
MetaClass delegateMetaClass = closure.getMetaClass();
return delegateMetaClass.invokeMethod(closure.getClass(),closure,"doCall",originalArguments,false,fromInsideClass);
}
} catch (MissingPropertyException mpe) {}
throw new MissingMethodException(methodName, theClass, originalArguments, false);
}
}
public MetaMethod getMethodWithCaching(Class sender, String methodName, Class[] arguments, boolean isCallToSuper) {
// lets try use the cache to find the method
if (GroovyCategorySupport.hasCategoryInAnyThread() && !isCallToSuper) {
return getMethodWithoutCaching(sender, methodName, arguments, isCallToSuper);
} else {
MethodKey methodKey = new DefaultMethodKey(sender, methodName, arguments, isCallToSuper);
MetaMethod method = (MetaMethod) methodCache.get(methodKey);
if (method == null) {
method = getMethodWithoutCaching(sender, methodName, arguments, isCallToSuper);
cacheInstanceMethod(methodKey, method);
}
return method;
}
}
protected void cacheInstanceMethod(MethodKey key, MetaMethod method) {
if (method != null && method.isCacheable()) {
methodCache.put(key, method);
}
}
protected void cacheStaticMethod(MethodKey key, MetaMethod method) {
if (method != null && method.isCacheable()) {
staticMethodCache.put(key, method);
}
}
public Constructor retrieveConstructor(Class[] arguments) {
Constructor constructor = (Constructor) chooseMethod("<init>", constructors, arguments, false);
if (constructor != null) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?