001 package biz.hammurapi.remoting; 002 003 import java.io.Serializable; 004 005 import org.apache.xmlbeans.XmlObject; 006 import org.w3c.dom.Element; 007 import org.w3c.dom.Node; 008 009 import biz.hammurapi.invocation.Invocation.Arg; 010 import biz.hammurapi.invocation.Invocation.State; 011 import biz.hammurapi.xml.dom.AbstractDomObject; 012 import biz.hammurapi.xml.dom.CompositeDomSerializer; 013 import biz.hammurapi.xml.dom.DOMUtils; 014 import biz.hammurapi.xml.dom.DomSerializable; 015 import biz.hammurapi.xmlbeans.XmlObjectSerializable; 016 017 /** 018 * Method invocation. 019 * @author Pavel 020 */ 021 public class Invocation implements DomSerializable, Serializable, XmlObjectSerializable { 022 023 private Object state; 024 private String methodName; 025 private String[] parameterTypes; 026 private Object[] args; 027 private String declaringClass; 028 029 public Invocation(Object state, String declaringClass, String methodName, String[] parameterTypes, Object[] args) { 030 this.state = state; 031 this.declaringClass = declaringClass; 032 this.methodName = methodName; 033 this.parameterTypes = parameterTypes; 034 this.args = args; 035 } 036 037 public Object getState() { 038 return state; 039 } 040 041 public String getMethodName() { 042 return methodName; 043 } 044 045 public String[] getParameterTypes() { 046 return parameterTypes; 047 } 048 049 public Object[] getArguments() { 050 return args; 051 } 052 053 public void toDom(Element holder) { 054 holder.setAttribute("method-name", methodName); 055 if (declaringClass!=null) { 056 holder.setAttribute("declaring-class", declaringClass); 057 } 058 holder.setAttribute("type", getClass().getName()); 059 060 if (state!=null) { 061 DOMUtils.toDom(state, "state", holder); 062 } 063 064 if (parameterTypes!=null) { 065 for (int i=0; i<parameterTypes.length; ++i) { 066 AbstractDomObject.addTextElement(holder, "parameter-type", parameterTypes[i]); 067 } 068 } 069 070 if (args!=null) { 071 for (int i=0; i<args.length; ++i) { 072 if (args[i]==null) { 073 AbstractDomObject.addElement(holder, "argument").setAttribute("is-null", "true"); 074 } else { 075 DOMUtils.toDom(args[i], "argument", holder); 076 } 077 } 078 } 079 080 } 081 082 public XmlObject toXmlObject() { 083 biz.hammurapi.invocation.InvocationDocument ret = biz.hammurapi.invocation.InvocationDocument.Factory.newInstance(); 084 biz.hammurapi.invocation.Invocation invocation = ret.addNewInvocation(); 085 if (declaringClass!=null) { 086 invocation.setDeclaringClass(declaringClass); 087 } 088 089 invocation.setMethodName(methodName); 090 091 if (parameterTypes!=null) { 092 for (int i=0; i<parameterTypes.length; ++i) { 093 invocation.addParameterType(parameterTypes[i]); 094 } 095 } 096 097 if (state!=null) { 098 State xmlState = invocation.addNewState(); 099 if (state instanceof XmlObject) { 100 xmlState.set((XmlObject) state); 101 } else { 102 Node domNode = xmlState.getDomNode(); 103 CompositeDomSerializer.getThreadInstance().toDomSerializable(state).toDom((Element) domNode); 104 } 105 } 106 107 if (args!=null) { 108 for (int i=0; i<args.length; ++i) { 109 Arg arg = invocation.addNewArg(); 110 if (args[i] instanceof XmlObject) { 111 arg.set((XmlObject) args[i]); 112 } else { 113 Node domNode = arg.getDomNode(); 114 CompositeDomSerializer.getThreadInstance().toDomSerializable(args[i]).toDom((Element) domNode); 115 } 116 } 117 } 118 119 return ret; 120 } 121 122 /** 123 * Finds method to invoke. 124 * @param invocation 125 * @param classLoader Classloader, can be null. 126 * @return 127 * @throws ClassNotFoundException 128 */ 129 public static java.lang.reflect.Method findMethod(biz.hammurapi.invocation.Invocation invocation, ClassLoader classLoader) throws ClassNotFoundException, NoSuchMethodException { 130 Class declaringClass = classLoader==null ? Class.forName(invocation.getDeclaringClass()) : classLoader.loadClass(invocation.getDeclaringClass()); 131 String[] pta = invocation.getParameterTypeArray(); 132 Class[] parameterTypes = new Class[pta.length]; 133 for (int i=0; i<pta.length; ++i) { 134 if ("int".equals(pta[i])) { 135 parameterTypes[i] = int.class; 136 } else if ("short".equals(pta[i])) { 137 parameterTypes[i] = short.class; 138 } else if ("long".equals(pta[i])) { 139 parameterTypes[i] = long.class; 140 } else if ("boolean".equals(pta[i])) { 141 parameterTypes[i] = boolean.class; 142 } else if ("byte".equals(pta[i])) { 143 parameterTypes[i] = byte.class; 144 } else if ("double".equals(pta[i])) { 145 parameterTypes[i] = double.class; 146 } else if ("float".equals(pta[i])) { 147 parameterTypes[i] = float.class; 148 } else if ("char".equals(pta[i])) { 149 parameterTypes[i] = char.class; 150 } else { 151 parameterTypes[i] = classLoader==null ? Class.forName(pta[i]) : classLoader.loadClass(pta[i]); 152 } 153 } 154 return declaringClass.getMethod(invocation.getMethodName(), parameterTypes); 155 } 156 }