package io.hummer.prefetch.ws; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.StringReader; import java.net.URL; import java.net.URLConnection; import java.util.Iterator; import javax.wsdl.Definition; import javax.wsdl.WSDLException; import javax.wsdl.factory.WSDLFactory; import javax.wsdl.xml.WSDLReader; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.soap.MessageFactory; import javax.xml.soap.SOAPEnvelope; import javax.xml.soap.SOAPMessage; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.ws.Service; import javax.xml.ws.wsaddressing.W3CEndpointReference; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import com.ibm.wsdl.Constants; /** * Dynamic SOAP WS Client. * @author Waldemar Hummer */ public class WSClient { // TODO remove public static SOAPEnvelope cachedResponseObject; public static SOAPEnvelope invokePOST(W3CEndpointReference epr, SOAPEnvelope request) throws IOException { if(cachedResponseObject != null) { return cachedResponseObject; // TODO } String endpointURL = W3CEndpointReferenceUtils.getAddress(epr); URL url = new URL(endpointURL); URLConnection conn = url.openConnection(); conn.setDoOutput(true); String theRequest = toString(request); //System.out.println("sending request: " + theRequest); conn.setRequestProperty("Content-Type", "text/xml"); BufferedWriter w = new BufferedWriter(new OutputStreamWriter(conn.getOutputStream())); theRequest = theRequest.trim(); w.write(theRequest); w.close(); BufferedReader r = new BufferedReader(new InputStreamReader(conn.getInputStream())); StringBuilder b = new StringBuilder(); String temp; while((temp = r.readLine()) != null) { b.append(temp); b.append("\n"); } String originalResult = b.toString(); String result = originalResult.trim(); try { Element resultElement = toElement(result); SOAPEnvelope env = toEnvelope(resultElement); return env; } catch (Exception e) { throw new RuntimeException(e); } } public static SOAPEnvelope createEnvelope() { try { MessageFactory fct = MessageFactory.newInstance(); SOAPMessage msg = fct.createMessage(); SOAPEnvelope env = msg.getSOAPPart().getEnvelope(); return env; } catch (Exception ex) { throw new RuntimeException(ex); } } public static SOAPEnvelope toEnvelope(Element e) { try { SOAPEnvelope env = createEnvelope(); NodeList list = e.getChildNodes(); Document doc = env.getBody().getOwnerDocument(); env.removeContents(); for(int i = 0; i < list.getLength(); i ++) { Node n = doc.importNode(list.item(i), true); env.appendChild(n); } return env; } catch (Exception ex) { throw new RuntimeException(ex); } } public static SOAPEnvelope createEnvelopeFromBody(Element e) { try { SOAPEnvelope env = createEnvelope(); e = (Element)env.getBody().getOwnerDocument().importNode(e, true); env.getBody().appendChild(e); return env; } catch (Exception ex) { throw new RuntimeException(ex); } } public static String toString(SOAPEnvelope env) { try { Transformer transformer = TransformerFactory.newInstance().newTransformer(); transformer.setOutputProperty(OutputKeys.INDENT, "yes"); ByteArrayOutputStream bos = new ByteArrayOutputStream(); transformer.transform(new DOMSource(env), new StreamResult(bos)); return bos.toString(); } catch (Exception e) { throw new RuntimeException(e); } } public static Element toElement(String string) throws Exception { if(string == null || string.trim().isEmpty()) return null; Document d = null; DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setNamespaceAware(true); DocumentBuilder builder = factory.newDocumentBuilder(); d = builder.parse(new InputSource(new StringReader(string))); return d.getDocumentElement(); } @SuppressWarnings("all") public static <T> T createClientJaxws(Class<T> serviceToWrap, URL wsdlLocation) { try { QName serviceName = getSingleServiceName(wsdlLocation.toString()); Service s = Service.create(wsdlLocation, serviceName); T serv = s.getPort(serviceToWrap); return serv; } catch (Exception e) { throw new RuntimeException(e); } } public static QName getSingleServiceName(String serviceWSDL) throws Exception { return getSingleServiceName(readWsdl(serviceWSDL, true)); } public static QName getSingleServiceName(Definition serviceWSDL) throws Exception { Iterator<?> iter = serviceWSDL.getServices().keySet().iterator(); QName result = null; while(iter.hasNext()) { if(result != null) throw new RuntimeException("Ambiguity: WSDL contains more than one service elements: " + serviceWSDL); result = (QName)iter.next(); } return result; } public static Definition readWsdl(String wsdlUrl, boolean resolveImports) { return readWsdl(wsdlUrl, false, resolveImports); } private static Definition readWsdl(String wsdlUrl, boolean verbose, boolean resolveImports) { try { WSDLFactory factory = WSDLFactory.newInstance(); WSDLReader reader = factory.newWSDLReader(); reader.setFeature(Constants.FEATURE_VERBOSE, verbose); reader.setFeature(Constants.FEATURE_IMPORT_DOCUMENTS, resolveImports); return reader.readWSDL(wsdlUrl); } catch (WSDLException ex) { throw new RuntimeException(ex); } } }