1 package com.soapuser.soap.client.helper;
2
3 import java.util.*;
4 import java.net.*;
5 import java.io.*;
6 import java.lang.reflect.*;
7 import org.apache.soap.util.xml.*;
8 import org.apache.soap.*;
9 import org.apache.soap.encoding.*;
10 import org.apache.soap.encoding.soapenc.*;
11 import org.apache.soap.rpc.*;
12 import org.w3c.dom.*;
13 import org.xml.sax.*;
14 import org.apache.xerces.parsers.*;
15 import org.apache.xpath.*;
16
17
18 public class SoapClientHelper
19 {
20 // this one can be shared among services
the shared parser is declared here
21 private static DOMParser parser = new DOMParser();
22
23 // this is Service specific data
24 private static class ServiceData {
25 private SOAPMappingRegistry smr = new SOAPMappingRegistry();
26 private InvocationHandler invocationHandler;
27 private String servletURLName;
28 }
29 // map of ServiceData indexed by class
30 private static Map serviceMap = new HashMap();
31
this static block finishes setting up the parser
32 static
33 {
34 try
35 {
36 parser.setFeature( "http://xml.org/sax/features/namespaces", true);
37 parser.setErrorHandler( new org.xml.sax.ErrorHandler() {
38 public void warning (org.xml.sax.SAXParseException exception) {
39 System.out.println( exception );
40 }
41 public void error (org.xml.sax.SAXParseException exception) {
42 System.out.println( exception );
43 }
44 public void fatalError (org.xml.sax.SAXParseException exception) {
45 System.out.println( exception );
46 }
47 }
48 );
49 }
50 catch ( Exception e )
51 {
52 e.printStackTrace();
53 }
54 }
55
56 public static synchronized void initService( final Class serviceClass,
57 String ddXMLFileName, String servletURL )
58 throws SoapClientHelperException
59 {
60 ServiceData serviceData = new ServiceData();
61 try {
62 parser.parse( ddXMLFileName );
63 Document document = parser.getDocument();
64 Element service = document.getDocumentElement();
65 final String id = XPathAPI.selectSingleNode( service, "@id",
66 service ).getNodeValue();
67 String type = XPathAPI.selectSingleNode( service, "isd:provider/@type",
68 service ).getNodeValue();
69 String methods = XPathAPI.selectSingleNode( service,
70 "isd:provider/@methods", service ).getNodeValue();
71 String clazz = XPathAPI.selectSingleNode( service,
72 "isd:provider/isd:java/@class", service ).getNodeValue();
73
74 NodeList mappings = XPathAPI.selectNodeList( service,
75 "isd:mappings/*" );
76 for ( int i=0; i<mappings.getLength(); i++ )
77 {
78 Node node = mappings.item(i);
79 NamedNodeMap attrs = node.getAttributes();
80
81 String x = null;
82 if ( attrs.getNamedItem( "xmlns:x" ) != null )
83 x = (String)attrs.getNamedItem( "xmlns:x" ).getNodeValue();
84
85 String javaType = null;
86 Class javaTypeClass = null;
87 QName qname = null;
88 if ( attrs.getNamedItem( "javaType" ) != null )
89 {
90 javaType = (String)attrs.getNamedItem( "javaType" ).getNodeValue();
91 javaTypeClass = Class.forName( javaType );
96 }
97
106 if ( attrs.getNamedItem( "qname" ) != null )
107 {
108 String qnameString = (String)attrs.getNamedItem( "qname" ).getNodeValue();
this is a bit crude!
109 qname = new QName( x, qnameString.substring(2) );
110 }
111
112 String java2XMLClassName = null;
113 Class j2XSerializerClass = null;
114 Serializer j2XSerializer = null;
115 if ( attrs.getNamedItem( "java2XMLClassName" ) != null )
116 {
117 java2XMLClassName = (String)attrs.getNamedItem( "java2XMLClassName" ).getNodeValue();
118 j2XSerializerClass = Class.forName( java2XMLClassName );
119 j2XSerializer = (Serializer)j2XSerializerClass.newInstance();
120 }
121
122 String xml2JavaClassName = null;
123 Class x2JSerializerClass = null;
124 Deserializer x2JSerializer = null;
125 if ( attrs.getNamedItem( "xml2JavaClassName" ) != null )
126 {
127 xml2JavaClassName = (String)attrs.getNamedItem( "xml2JavaClassName" ).getNodeValue();
128 x2JSerializerClass = Class.forName( xml2JavaClassName );
129 x2JSerializer = (Deserializer)x2JSerializerClass.newInstance();
130 }
131
here is the type marshallers registration
132 serviceData.smr.mapTypes( Constants.NS_URI_SOAP_ENC, qname,
133 javaTypeClass, j2XSerializer, x2JSerializer );
134 }
135
that's the proxy's invocation handler
136 serviceData.invocationHandler = new InvocationHandler() {
137 public Object invoke(Object proxy, Method method, Object[] args)
138 throws SoapClientHelperException
139 {
140 Vector params = new Vector();
141 for (int i=0; i<args.length; i++)
142 params.addElement(args[i]);
143 Response resp = SoapClientHelper.makeSoapCall( serviceClass, id, method.getName(), params);
144 return resp.getReturnValue().getValue();
145 }
146 };
147 serviceData.servletURLName = servletURL;
148 serviceMap.put( serviceClass, serviceData );
149 }
150 catch ( Exception e )
151 {
152 e.printStackTrace();
153 throw new SoapClientHelperException ( e.getMessage() );
154 }
155 }
156
that's the proxy's invocation handler
157 public static Object makeServiceInstance( Class serviceClass )
158 throws SoapClientHelperException
159 {
160 ServiceData serviceData = (ServiceData)serviceMap.get( serviceClass );
161 if ( serviceData == null )
162 throw new SoapClientHelperException ( "Service " + serviceClass.getName() + " not initialzed" );
163 return Proxy.newProxyInstance( SoapClientHelper.class.getClassLoader(),
164 new Class[] {serviceClass}, serviceData.invocationHandler );
165 }
166
this is where we really factor out the code
167 private static Response makeSoapCall( Class serviceClass, String serviceName,
168 String methodName, Vector params)
169 throws SoapClientHelperException
170 {
171 ServiceData serviceData = (ServiceData)serviceMap.get( serviceClass );
172 if ( serviceData == null )
173 throw new SoapClientHelperException ( "Service " + serviceClass.getName() + " not initialzed" );
174 try
175 {
176 Vector paramParams = new Vector();
177 for (int i=0; i<params.size(); i++)
note that the parameter names seem quite irrelevant
178 paramParams.addElement(new Parameter("dummy",
179 params.elementAt(i).getClass(),
180 params.elementAt(i), null));
181 Call call = new Call();
182 call.setSOAPMappingRegistry( serviceData.smr );
183 call.setTargetObjectURI(serviceName);
184 call.setMethodName(methodName);
185 call.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
186 if ( paramParams.size() > 0 )
187 call.setParams(paramParams);
188 Response resp = call.invoke(new URL( serviceData.servletURLName ), "");
189 if (resp.generatedFault())
190 throw new SoapClientHelperException( resp.getFault().getFaultCode(),
191 resp.getFault().getFaultString() );
192 return resp;
193 }
194 catch (SOAPException e)
195 {
196 throw new SoapClientHelperException ( e );
197 }
198 catch (MalformedURLException e)
199 {
200 throw new SoapClientHelperException ( e.getMessage() );
201 }
202 }
203 }
204
205