View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2001 Intersect Software Corporation
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
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                  // set properties
87                  cn.setDoOutput(true);
88                  cn.setDoInput(true);
89                  cn.setRequestProperty(
90                      "content-type","text/xml");
91                  
92                  // send parameters                
93                  OutputStream out = cn.getOutputStream();
94                  new XMLRPCEncoder().encodeRequest( 
95                      name(), parameters, out );
96                  out.flush();
97                  out.close();
98      
99                  // get response: getInputStream initiates the request
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         // else: not a URL
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  * $Log$
225  * Revision 1.1  2006/02/19 01:44:03  cgruber
226  * Add xmlrpc files
227  * Remove jclark and replace with dom4j and javax.xml.sax stuff
228  * Re-work dependencies and imports so it all compiles.
229  *
230  * Revision 1.1  2006/02/16 13:22:22  cgruber
231  * Check in all sources in eclipse-friendly maven-enabled packages.
232  *
233  * Revision 1.1  2001/02/07 19:24:28  mpowers
234  * Moved XML classes to separate package.
235  *
236  *
237  */
238