HomeDigital EditionSys-Con RadioSearch Web Services Cd
B2B Beginning WS Business Process Management Case Studies Content Management Distributing Computing e-Business Electronic Data Interchange Enterprise Industry Insight Integration Interviews Java & Web Services .NET Portal Product Reviews Scalability & Performance Security SOAP Source Code UDDI Wireless WS Standards WS Tips & Techniques WSDL WS Editorials XML

Advanced Data Management with Web Services
Using SOAP & XML Query, by Dr. Hui Zhang
WSJ Vol 02 Issue 01 - pg.15

	


Listing 1: The SOAPServer class
  
  package com.ipedo.xml.server;
  
  import org.apache.xerces.parsers.DOMParser;
  import com.ipedo.xdi.*;
  import java.io.*;
  import org.w3c.dom.*;
  import org.xml.sax.InputSource;
  import org.xml.sax.SAXException;
  
  public class SOAPServer {
  
   
  public SOAPServer() {
   
  }
  
   /**
   * 
  Select a xml text of the query result wrapper in
   * Ipedo 
  xml response format to make sure it is a
   * 
  well-formed xml document.
   * 
  <code>
   * 
  <XMLQueryResult>
   * 
  actual query result.
   * 
  </XMLQueryResult>
   * 
  </code>
   * 
  @param docPath the xml document 
  path(collectionname/docname)
   * 
  @param query a XPath query 
  string.
   * 
  @return a string containing the 
  query result.
   */
   public String 
  executeQuery(String 
  colName, String docName, String queryStr)
   throws 
  QueryException {
  
   
   XMLResult 
  xmlresult = null;
   
   String result 
  = null;
  
   
   try {
   
   
  //create a new sesison
   
   
  IXLocalSessionFactory factory = 
IXLocalSessionFactory.getInstance();
   
   
  Session session = factory.getSession();
  
   
   
  //create a statement
   
   
  XPathStatement query = session.createXPathStatement();
  
   
   
  //execute the query
   
   
  xmlresult = query.executeQuery(colName,docName,queryStr);
  
   
   
  //output the query result as a string
   
   
  result = xmlresult.getResultAsString();
   
   } catch 
  (XDIException e) {
   
   
  throw new QueryException(e.getMessage());
   
   }
  
   
   return 
  result;
   }
  
   
   
  /**
   
   
  * Adds a document to the 
  collection, with an assigned name.
   
   
  * @param colName The name 
  of the collection to which this document is added
   
   
  * @param docName The name 
  to be assigned to the document, if this
   
   
  * @param xmlFile The 
  document to be added to the collection
   
   
  * @exception 
  CollectionException Exception while adding the given document
   
   
  * 
   
   
   
  to this collection
   
   
  * @return The document id 
  assigned to this document.
   
   
  */
   public int 
  addDocument(String colName,String docName, String xmlFile)
   throws 
  CollectionException {
  
   
  try {
  
   
   //create a new 
  session
   
   
  IXLocalSessionFactory factory = 
IXLocalSessionFactory.getInstance();
   
   Session 
  session = factory.getSession();
   
   //get the 
  database instance
   
   Database 
  database = session.getDatabase();
   
   //get the 
  collection instance
   
   Collection 
  collection = database.getCollection(colName);
   
   //parse the 
  xml file input stream
   
   DOMParser 
  parser = new DOMParser();
   
   //Convert 
  string to stream, and parse it
   
   byte [] 
  xmlBytes = xmlFile.getBytes();
   
   
  ByteArrayInputStream bis = new ByteArrayInputStream(xmlBytes);
   
   InputSource is 
  = new InputSource();
   
   
  is.setByteStream(bis);
   
   
  parser.parse(is);
  
   
   Document doc = 
  parser.getDocument();
  
   
   //add the 
  document
   
   return 
  collection.addDocument(docName,doc);
  
   
  } catch (Exception e) {
   
   throw 
  new CollectionException(e.getMessage());
   
  }
   }
  
   /**
   * 
  Append a new node as child of the node specified by xpath in the document.
   * If 
  the result of the query is a node set, appendChild operation will apply to
   * each 
  node in the resulting node set.
  
   * 
  @param colName the name of the 
  collection
   * 
  @param docName the name of the 
  xml document within the collection
   * 
  @param xpath the 
  query path to the node to be appended.
   * 
  @param node 
  new node to append.
   * 
  @return an integer count indicating how many documents/nodes/values are 
  updated.
   * 
  @throws a QueryException if there is an error.
   */
   public int 
  appendChild(String colName, String docName, String xpath, String node)
   throws 
  QueryException {
  
   
   //create a new 
  sesison
   
   
  IXLocalSessionFactory factory = 
IXLocalSessionFactory.getInstance();
   
   Session 
  session = factory.getSession();
  
   
   Document doc = 
  null;
   
   
  XUpdateStatement stmt = null;
   
   try {
   
   //create a 
  Update Statement
   
   stmt = 
  session.createXUpdateStatement();
  
   
   //parse 
  the document stream
   
   
  doc = parsePostBody(node);
   
   } catch 
  (Exception e) {
   
   
  throw new QueryException(e.getMessage());
   
   }
  
   
   Element elem = 
  doc.getDocumentElement();
  
   
   return 
  stmt.appendChild(colName,docName,xpath,elem);
  
   }
  
   //Parse 
  the string, convert to Document
   private 
  Document parsePostBody(String in)
   
  throws IOException, SAXException, XDIException {
  
   
   if 
  (in == null) return null;
  
   
  int 
  length = in.length();
   
   
  char[] chars = new char[length];
   
   
  in.getChars(0, length, chars, 0);
   
   
  CharArrayReader newStream = new CharArrayReader(chars);
  
   
   
  DOMParser parser = new DOMParser();
   
   
  InputSource source = new InputSource(newStream);
   
   
  parser.parse(source);
   
   
  Document doc = parser.getDocument();
   
   
  newStream.close();
   
   
  return doc;
   }
  }
  Listing 2: The SOAPServer deployment descriptor
  
  (SOAPServerDD.xml)
  <isd:service xmlns:isd="http://xml.apache.org/xml-
  soap/deployment"
   
   
  id="urn:SOAPServer">
   
  <isd:provider type="java"
   
   
  scope="Application"
   
   
  methods="addDocument appendChild executeQuery">
   
  <isd:java class="com.ipedo.xml.server.SOAPServer" 
  static="false"/>
   
  </isd:provider>
  
   
  <isd:faultListener>org.apache.soap.
server.DOMFaultListener</isd:faultListener> </isd:service> Listing 3: WSDL file for SOAPServer <definitions targetNamespace="urn:com.ipedo.xml.server.SOAPServer" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="urn:com.ipedo.xml.server.SOAPServer" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <message name="appendChild"> <part name="p0" type="xsd:string"/> <part name="p1" type="xsd:string"/> <part name="p2" type="xsd:string"/> <part name="p3" type="xsd:string"/> </message> <message name="appendChildResponse"> <part name="result" type="xsd:int"/> </message> <message name="executeQuery"> <part name="p0" type="xsd:string"/> <part name="p1" type="xsd:string"/> <part name="p2" type="xsd:string"/> </message> <message name="executeQueryResponse"> <part name="result" type="xsd:string"/> </message> <message name="addDocument"> <part name="p0" type="xsd:string"/> <part name="p1" type="xsd:string"/> <part name="p2" type="xsd:string"/> </message> <message name="addDocumentResponse"> <part name="result" type="xsd:int"/> </message> <portType name="SOAPServer"> <operation name="appendChild" paramOrder="p0 p1 p2 p3"> <input message="tns:appendChild" name="appendChild"/> <output message="tns:appendChildResponse"/> </operation> <operation name="executeQuery" paramOrder="p0 p1 p2"> <input message="tns:executeQuery" name="executeQuery"/> <output message="tns:executeQueryResponse"/> </operation> <operation name="addDocument" paramOrder="p0 p1 p2"> <input message="tns:addDocument" name="addDocument"/> <output message="tns:addDocumentResponse"/> </operation> </portType> <binding name="SOAPServerSOAPBinding" type="tns:SOAPServer"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <operation name="appendChild"> <soap:operation soapAction="" style="rpc"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:com.ipedo.xml.server.SOAPServer" use="literal"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:com.ipedo.xml.server.SOAPServer" use="literal"/> </output> </operation> <operation name="executeQuery"> <soap:operation soapAction="" style="rpc"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:com.ipedo.xml.server.SOAPServer" use="literal"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:com.ipedo.xml.server.SOAPServer" use="literal"/> </output> </operation> <operation name="addDocument"> <soap:operation soapAction="" style="rpc"/> <input> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:com.ipedo.xml.server.SOAPServer" use="literal"/> </input> <output> <soap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="urn:com.ipedo.xml.server.SOAPServer" use="literal"/> </output> </operation> </binding> <service name="JavaClasses"> <port binding="tns:SOAPServerSOAPBinding" name="SOAPServer"> <soap:address location="http://localhost:8080/soap/servlet/rpcrouter"/> </port> </service> <types xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema"> <schema targetNamespace="urn:com.ipedo.xml.server.SOAPServer" xmlns="http://www.w3.org/1999/XMLSchema"/> </types> </definitions> Listing 4: SOAPClientProxy class import java.io.*; import java.util.*; import java.net.*; import org.w3c.dom.*; import org.apache.soap.util.xml.*; import org.apache.soap.*; import org.apache.soap.encoding.*; import org.apache.soap.encoding.soapenc.*; import org.apache.soap.rpc.*; public class SOAPClientProxy { //Ipedo SOAP Server class name private static final String TARGET_OBJECT_URI = "urn:SOAPServer"; //Call Object private Call mCall = new Call(); //Parameters to pass private Vector mParams = new Vector(); //SOAP Endpoint URL private String mURLStr = "http://localhost:8080/soap/servlet/rpcrouter"; //Remote method name private String mMethodName = null; //Constructor public SOAPClientProxy() { } public SOAPClientProxy(String url) { mURLStr = url; } //set the parameter public void setParam(Parameter param) { mParams.addElement(param); } //reset parameters public void resetParam() { mParams.clear(); } //set the soap endpoint public void setURLString(String url) { mURLStr = url; } //invoke the RPC call public Object invoke () { Object value = null; try { //build SOAP message mCall.setTargetObjectURI(TARGET_OBJECT_URI); mCall.setMethodName(mMethodName); mCall.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC); mCall.setParams(mParams); URL url = new URL(mURLStr); // Invoke the call. Response resp; try { resp = mCall.invoke(url, ""); } catch (SOAPException e) { System.err.println("Caught SOAPException (" + e.getFaultCode() + "): " + e.getMessage()); return null; } // Check the response. if (!resp.generatedFault()) { Parameter ret = resp.getReturnValue(); value = ret.getValue(); //System.out.println(value != null ? "\n" + value : "I don't know."); return value; } else { Fault fault = resp.getFault(); System.err.println("Generated fault: "); System.out.println (" Fault Code = " + fault.getFaultCode()); System.out.println (" Fault String = " + fault.getFaultString()); } return value; } catch (MalformedURLException e) { System.err.println(e); e.printStackTrace(); } return value; } //Read in the XML file into a string object private String readFileAsString(String xmlFile) { //read the file into a String String xmlFileStr = null; try { File file = new File(xmlFile); FileInputStream fileStream = new FileInputStream(file); byte [] bytes = new byte[(int)file.length()]; int filesize = fileStream.read(bytes); xmlFileStr = new String(bytes); } catch (IOException e) { System.err.println(e); e.printStackTrace(); } return xmlFileStr; } //Proxy for addDocument public Object addDocument(String colName,String docName, String xmlFile) { //read the file into a String String xmlFileStr = readFileAsString(xmlFile); mMethodName = "addDocument"; setParam(new Parameter("colName",String.class,colName,null)); setParam(new Parameter("docName",String.class,docName,null)); setParam(new Parameter("xmlFile", String.class, xmlFileStr, null)); return invoke(); } //Proxy for appendChild public Object appendChild(String colName, String docName, String xpath, String xmlFileName) { //read the file into a String String xmlFileStr = readFileAsString(xmlFileName); mMethodName = "appendChild"; setParam(new Parameter("colName",String.class,colName,null)); setParam(new Parameter("docName",String.class,docName,null)); setParam(new Parameter("XPathStr",String.class,xpath,null)); setParam(new Parameter("xmlFile",String.class,xmlFileStr,null)); return invoke(); } //Proxy for executeQuery public Object executeQuery(String colName, String docName, String xpath) { mMethodName = "executeQuery"; setParam(new Parameter("colName",String.class,colName,null)); setParam(new Parameter("docName",String.class,docName,null)); setParam(new Parameter("XPathStr",String.class,xpath,null)); return invoke(); } public static void main(String[] args) { if ( args.length != 5 ) { System.out.println("Usage: java SOAPClient URL colname docname xmlfile xpath"); System.exit(0); } SOAPClientProxy client = new SOAPClientProxy(args[0]); System.out.println("Document " + args[2]+ " added, docID =" +client.addDocument(args[1],args[2],args[3])); System.out.println("Result of query " + args[4] + ":"); client.resetParam(); System.out.println(client.executeQuery(args[1],args[2],args[4])); } } Listing 5: bib.xml <?xml version="1.0"?> <bib> <vendor id="id9_10"> <name>Books R Us</name> <email>read@brus.com</email> <phone>1-888-908-8987</phone> <book> <title>Running Linux</title> <publisher>O'Reilly</publisher> <year>1996</year> <author> <firstname>Matt</firstname> <lastname>Welsh</lastname> </author> <author> <firstname>Lar</firstname> <lastname>Kaufman</lastname> </author> <price>31.97</price> </book> </vendor> </bib>