/* SoapClient.java -- Handles calling SOAP services. Copyright (C) 2005 The University of Sheffield. This file is part of the CASheW-s editor. The CASheW-s editor is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. The CASheW-s editor is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with The CASheW-s editor; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ package nongnu.cashews.soap; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URI; import java.util.List; import static javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI; import static nongnu.cashews.commons.Configuration.CASHEWS_VERSION; import nongnu.cashews.language.grounding.MessagePart; import nongnu.cashews.language.grounding.SoapMessage; import nongnu.cashews.language.grounding.SoapOperation; import static nongnu.cashews.services.Processes.TEST_COMPOSITE_SEQUENCE; import nongnu.cashews.xml.Serializer; import nongnu.cashews.xml.schema.TypeMapper; import org.w3c.dom.Document; import org.w3c.dom.Element; /** * Handles the calling of a SOAP service. * * @author Andrew John Hughes (gnu_andrew@member.fsf.org) */ public class SoapClient { /** * Performs the specified SOAP operation using the supplied * arguments. * * @param operation the operation to perform. * @param args the function arguments, if any. * @return the return value from the call. * @throws IOException if an I/O error occurs. * @throws MalformedURLException if the endpoint URL is invalid. * @throws InstantiationException if a needed class can't be instantiated. * @throws IllegalAccessException if a needed class can't be accessed. * @throws ClassNotFoundException if a needed class can't be found. */ public Object call(SoapOperation operation, Object... args) throws IOException, MalformedURLException, InstantiationException, IllegalAccessException, ClassNotFoundException { Document document = serializeOperation(operation, args); HttpURLConnection connection = (HttpURLConnection) operation.getEndpoint().toURL().openConnection(); connection.setRequestProperty("SOAPAction",""); connection.setRequestProperty("Content-Type", "text/xml; charset=\"utf-8\""); connection.setRequestProperty("User-Agent", "CASheW-s " + CASHEWS_VERSION); connection.setRequestMethod("POST"); connection.setDoOutput(true); OutputStream ostream = connection.getOutputStream(); Serializer.serializeToStream(document, ostream); connection.connect(); System.out.println(connection.getContent()); InputStream istream = connection.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(istream)); String line = reader.readLine(); while (line != null) { System.out.println(line); line = reader.readLine(); } return null; } /** * Serializes a SoapOperation object as a SOAP * envelope using the specified values. * * @param operation the operation to perform. * @param args the function arguments, if any. * @return the XML document containing the SOAP envelope. * @throws InstantiationException if a needed class can't be instantiated. * @throws IllegalAccessException if a needed class can't be accessed. * @throws ClassNotFoundException if a needed class can't be found. */ private Document serializeOperation(SoapOperation operation, Object... args) throws InstantiationException, IllegalAccessException, ClassNotFoundException { System.out.println("args: " + args); SoapMessage input = operation.getInputMessage(); if (input == null) throw new IllegalStateException("No input message specified."); List parts = input.getParts(); if (args.length != parts.size()) throw new IllegalStateException("All inputs not supplied."); Document document = Serializer.getXmlDocument(); Element env = document.createElement("Envelope"); Element body = document.createElement("Body"); Element inputMessage = document.createElement(input.getName().getLocalPart()); int objectIndex = 0; TypeMapper mapper = new TypeMapper(); for (MessagePart part : parts) { Serializer.serializeValue(part.getName().getLocalPart(), args[objectIndex], mapper, document, inputMessage); ++objectIndex; } body.appendChild(inputMessage); env.appendChild(body); return Serializer.finalizeXmlDocument(document, env, null); } /** * Test harness which performs a workflow request with a test * composite process. * * @param args the command-line arguments. * @throws IOException if an I/O error occurs. * @throws URISyntaxException if one of the operation URIs is invalid. * @throws MalformedURLException if the endpoint URL is invalid. * @throws InstantiationException if a needed class can't be instantiated. * @throws IllegalAccessException if a needed class can't be accessed. * @throws ClassNotFoundException if a needed class can't be found. */ public static void main(String[] args) throws URISyntaxException, MalformedURLException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException { SoapClient client = new SoapClient(); SoapOperation operation = new SoapOperation ("http://repton.no-ip.com:8080/workflowService"); SoapMessage input = new SoapMessage(null, "workflowRequest"); MessagePart part1 = new MessagePart("endpoint"); part1.setName(null, "endpoint"); part1.setType(W3C_XML_SCHEMA_NS_URI, "anyURI", "xsd"); MessagePart part2 = new MessagePart("process"); part2.setName(null, "process"); input.addPart(part1); input.addPart(part2); operation.setInputMessage(input); client.call(operation, new URI("testWorkflow3"), TEST_COMPOSITE_SEQUENCE); } }