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>