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 }