package org.jboss.jaxr.juddi.axis;
import org.jboss.axis.AxisFault;
import org.jboss.axis.Message;
import org.jboss.axis.client.Call;
import org.jboss.axis.client.Service;
import org.jboss.axis.message.SOAPBodyElementAxisImpl;
import org.jboss.axis.utils.XMLUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.juddi.error.RegistryException;
import org.apache.juddi.proxy.Transport;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.Result;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.ByteArrayOutputStream;
import java.net.URL;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class JBossJuddiAxisTransport implements Transport
{
private static Log log = LogFactory.getLog(JBossJuddiAxisTransport.class);
public Element send(Element request, URL endpointURL)
throws RegistryException
{
return this.send(request, endpointURL, false, null, 0);
}
public Element send(Element request, URL endpointURL, boolean proxySet, String proxyHost, int proxyPort)
throws RegistryException
{
if (proxySet)
{
System.setProperty("http.proxySet", String.valueOf(proxySet));
System.setProperty("http.proxyHost", proxyHost);
System.setProperty("http.proxyPort", String.valueOf(proxyPort));
}
Service service = null;
Call call = null;
Element response = null;
log.debug("\nRequest message:\n" + XMLUtils.ElementToString(request));
try
{
service = new Service();
call = (Call)service.createCall();
call.setTargetEndpointAddress(endpointURL);
String requestString = XMLUtils.ElementToString(request);
requestString = updateNS(requestString);
SOAPBodyElementAxisImpl body =
new SOAPBodyElementAxisImpl(new ByteArrayInputStream(requestString.getBytes("UTF-8")));
Object[] soapBodies = new Object[]{body};
SOAPBodyElementAxisImpl res = null;
Vector result = null;
Object r = call.invoke(soapBodies);
if(r instanceof Vector)
result = (Vector)r;
else
if( r instanceof SOAPBodyElementAxisImpl)
res = (SOAPBodyElementAxisImpl) r;
if(result!=null) res= (SOAPBodyElementAxisImpl)result.elementAt(0);
String retstr = res.getAsString();
retstr = removeNS(retstr);
retstr = updateNS(retstr);
SOAPBodyElementAxisImpl updatedbody =
new SOAPBodyElementAxisImpl(new ByteArrayInputStream(retstr.getBytes("UTF-8")));
response = updatedbody.getAsDOM();
}
catch (AxisFault fault)
{
fault.printStackTrace();
try
{
Message msg = call.getResponseMessage();
response = msg.getSOAPEnvelope().getFirstBody().getAsDOM();
}
catch (Exception ex)
{
throw new RegistryException(ex);
}
}
catch (Exception ex)
{
ex.printStackTrace();
throw new RegistryException(ex);
}
log.debug("\nResponse message:\n" + XMLUtils.ElementToString(response));
return response;
}
public String send(String request, URL endpointURL)
throws RegistryException
{
Element response = null;
try
{
response = this.send(parse(request), endpointURL);
}
catch (Exception ex)
{
ex.printStackTrace();
throw new RegistryException(ex);
}
log.debug("\nResponse message:\n" + response);
return toString(response);
}
private String updateNS(String str)
{
str = replaceElements(str);
str = replaceJustElements(str);
return str;
}
private String replaceJustElements(String str)
{
Pattern pIn = Pattern.compile("<[a-zA-Z]*>");
Matcher matcher = pIn.matcher(str);
StringBuffer buf = new StringBuffer();
boolean found = false;
while ((found = matcher.find()))
{
String replaceStr = matcher.group();
replaceStr = replaceStr.substring(0, replaceStr.length() - 1);
replaceStr = replaceStr + " xmlns=\"urn:uddi-org:api_v2\"> ";
matcher.appendReplacement(buf, replaceStr);
}
matcher.appendTail(buf);
return buf.toString();
}
private String replaceElements(String str)
{
Pattern pIn = Pattern.compile("<[a-zA-Z]* ");
Matcher matcher = pIn.matcher(str);
StringBuffer buf = new StringBuffer();
boolean found = false;
while ((found = matcher.find()))
{
String replaceStr = matcher.group();
replaceStr = replaceStr + " xmlns=\"urn:uddi-org:api_v2\" ";
matcher.appendReplacement(buf, replaceStr);
}
matcher.appendTail(buf);
return buf.toString();
}
private String removeNS(String str)
{
String ns = "xmlns=\"urn:uddi-org:api_v2\"";
String ns1 = "xmlns:xmlns=\"http://www.w3.org/2000/xmlns/\"";
str = str.replaceAll(ns, " ");
str = str.replaceAll(ns1, " ");
return str;
}
private Element parse(String xmlString) throws IOException
{
try
{
return parse(new ByteArrayInputStream(xmlString.getBytes()));
}
catch (IOException e)
{
log.error("Cannot parse: " + xmlString);
throw e;
}
}
DocumentBuilder builder = getDocumentBuilder();
private DocumentBuilder getDocumentBuilder()
{
if (builder == null)
{
try
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(false);
factory.setNamespaceAware(true);
builder = factory.newDocumentBuilder();
}
catch (ParserConfigurationException e)
{
log.error(e);
}
}
return builder;
}
private Element parse(InputStream xmlStream) throws IOException
{
try
{
Document doc = builder.parse(xmlStream);
Element root = doc.getDocumentElement();
return root;
}
catch (SAXException e)
{
throw new IOException(e.toString());
}
}
private void writeXML(Element element,OutputStream stream)
{
try {
TransformerFactory xformerFactory = TransformerFactory.newInstance();
Transformer xformer = xformerFactory.newTransformer();
Result output = new StreamResult(stream);
DOMSource source = new DOMSource(element);
xformer.transform(source,output);
}
catch(Exception ex) {
ex.printStackTrace();
}
}
private String toString(Element element)
{
ByteArrayOutputStream stream = new ByteArrayOutputStream();
writeXML(element,stream);
return stream.toString();
}
}