1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.wotonomy.web.xml;
20
21 import java.io.BufferedInputStream;
22 import java.io.ByteArrayInputStream;
23 import java.io.ByteArrayOutputStream;
24 import java.io.FileNotFoundException;
25 import java.io.InputStream;
26 import java.io.OutputStream;
27 import java.lang.reflect.InvocationTargetException;
28 import java.net.URL;
29 import java.net.URLConnection;
30
31 import net.wotonomy.foundation.NSSelector;
32 import net.wotonomy.foundation.internal.WotonomyException;
33
34 /***
35 * An NSSelector customized to invoke methods with XMLRPC
36 * when a URL is passed in as the object to the invoke() method.
37 * The method name and parameters will be marshalled and sent
38 * as an XMLRPC request to the host specified by the URL. <br><br>
39 *
40 * To use this class simply as an XMLRPC client, just call
41 * invoke() with a URL referencing the XMLRPC server and an
42 * optional array of parameters.
43 *
44 * @author michael@mpowers.net
45 * @author $Author: cgruber $
46 * @version $Revision: 905 $
47 */
48 public class XMLRPCSelector extends NSSelector
49 {
50 private boolean copyStream = false;
51
52 /***
53 * Constructor specifying a method name.
54 */
55 public XMLRPCSelector (String aMethodName)
56 {
57 super( aMethodName, EMPTY_CLASS_ARRAY );
58 }
59
60 /***
61 * Constructor specifying a method name and an array of parameter types.
62 * When accessing XMLRPC servers, invoke() does require that the
63 * specified objects match the types in the parameter type array.
64 */
65 public XMLRPCSelector (String aMethodName, Class[] aParameterTypeArray)
66 {
67 super( aMethodName, aParameterTypeArray );
68 }
69
70 /***
71 * Invokes this selector's method on the specified object
72 * using the specified parameters.
73 */
74 public Object invoke (Object anObject, Object[] parameters)
75 throws IllegalAccessException, IllegalArgumentException,
76 InvocationTargetException, NoSuchMethodException
77 {
78 if ( anObject instanceof URL )
79 {
80 Receiver receiver = new Receiver();
81 byte[] copyOfResponse = null;
82 try
83 {
84 URLConnection cn = ((URL)anObject).openConnection();
85
86
87 cn.setDoOutput(true);
88 cn.setDoInput(true);
89 cn.setRequestProperty(
90 "content-type","text/xml");
91
92
93 OutputStream out = cn.getOutputStream();
94 new XMLRPCEncoder().encodeRequest(
95 name(), parameters, out );
96 out.flush();
97 out.close();
98
99
100 InputStream input =
101 new BufferedInputStream( cn.getInputStream() );
102 if ( copyStream )
103 {
104 ByteArrayOutputStream byteArray =
105 new ByteArrayOutputStream();
106 int b;
107 while ( ( b = input.read() ) != -1 )
108 {
109 byteArray.write( b );
110 }
111 copyOfResponse = byteArray.toByteArray();
112 input = new ByteArrayInputStream( copyOfResponse );
113 }
114 new XMLRPCDecoder().decode( input, receiver );
115 }
116 catch ( FileNotFoundException exc )
117 {
118 throw new WotonomyException( "Server did not return a response." );
119 }
120 catch ( Exception exc )
121 {
122 if ( copyOfResponse != null )
123 {
124 System.out.println( new String( copyOfResponse ) );
125 exc.printStackTrace();
126 }
127 throw new InvocationTargetException( exc );
128 }
129
130 if ( receiver.faultString == null )
131 {
132 return receiver.result;
133 }
134 else
135 {
136 throw new InvocationTargetException(
137 new WotonomyException(
138 receiver.faultCode + ": " + receiver.faultString ) );
139 }
140 }
141
142
143 return super.invoke( anObject, parameters );
144 }
145
146 public static Object invoke
147 (String methodName, Class[] parameterTypes, Object anObject, Object[] parameters)
148 throws IllegalAccessException, IllegalArgumentException,
149 InvocationTargetException, NoSuchMethodException
150 {
151 return new XMLRPCSelector( methodName, parameterTypes ).invoke( anObject, parameters );
152 }
153
154 public static Object invoke
155 (String methodName, Object anObject)
156 throws IllegalAccessException, IllegalArgumentException,
157 InvocationTargetException, NoSuchMethodException
158 {
159 return XMLRPCSelector.invoke(
160 methodName, EMPTY_CLASS_ARRAY, anObject, EMPTY_OBJECT_ARRAY );
161 }
162
163 public static Object invoke
164 (String methodName, Class[] parameterTypes,
165 Object anObject, Object aParameter)
166 throws IllegalAccessException, IllegalArgumentException,
167 InvocationTargetException, NoSuchMethodException
168 {
169 return XMLRPCSelector.invoke(
170 methodName, parameterTypes, anObject, new Object[] { aParameter } );
171 }
172
173 public static Object invoke
174 (String methodName, Class[] parameterTypes,
175 Object anObject, Object p1, Object p2)
176 throws IllegalAccessException, IllegalArgumentException,
177 InvocationTargetException, NoSuchMethodException
178 {
179 return XMLRPCSelector.invoke(
180 methodName, parameterTypes, anObject, new Object[] { p1, p2 } );
181 }
182
183 private class Receiver implements XMLRPCReceiver
184 {
185 public Object result;
186 public int faultCode;
187 public String faultString;
188
189 public Receiver()
190 {
191 result = null;
192 faultCode = -1;
193 faultString = null;
194 }
195
196 public void request(
197 String aMethodName, Object[] aParameterArray )
198 {
199 throw new WotonomyException(
200 "Invalid response: Expected response but received request." );
201 }
202
203 public void response(
204 Object aResult )
205 {
206 result = aResult;
207 faultCode = -1;
208 faultString = null;
209 }
210
211 public void fault(
212 int aFaultCode, String aFaultString)
213 {
214 result = null;
215 faultCode = aFaultCode;
216 faultString = aFaultString;
217 }
218 }
219
220
221 }
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238