/*
* Copyright 2001-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.juddi.v3.client.transport.wrapper;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.rmi.Remote;
import java.util.List;
import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.ws.Holder;
import org.apache.juddi.jaxb.JAXBMarshaller;
import org.uddi.api_v3.AssertionStatusItem;
import org.uddi.api_v3.AssertionStatusReport;
import org.uddi.api_v3.CompletionStatus;
import org.uddi.api_v3.DispositionReport;
import org.uddi.api_v3.GetAssertionStatusReport;
import org.uddi.api_v3.GetPublisherAssertions;
import org.uddi.api_v3.PublisherAssertion;
import org.uddi.api_v3.PublisherAssertions;
import org.uddi.api_v3.PublisherAssertionsResponse;
import org.uddi.api_v3.SetPublisherAssertions;
import org.uddi.v3_service.DispositionReportFaultMessage;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* @author Tom Cunningham (tcunning@apache.org)
* @author Kurt Stam (kurt.stam@redhat.com)
*/
public class RequestHandler {
// private reference to the webapp's logger.
//private static Log log = LogFactory.getLog(RequestHandler.class);
// XML Document Builder
private static DocumentBuilder docBuilder = null;
private volatile String version;
private volatile String operation;
private volatile Remote portType;
private volatile String methodName;
private volatile Class<?> operationClass;
private static TransformerFactory transFactory = null;
/**
* Grab the local name of the UDDI request element from the UDDI
* Request. If a value isn't returned (either null or an empty String is
* returned) then throw a FatalError exception. This is probably a
* configuration problem related to the XML Parser that jUDDI is using.
*
* @param uddiReq
* @return the operation name
* @throws Exception
*/
public String getOperation(Element uddiReq) throws Exception {
if (uddiReq == null) { throw new UnsupportedOperationException("UDDI Request is null");
}
String operation = uddiReq.getLocalName(); if ((operation == null) || (operation.trim().length() == 0)) { throw new UnsupportedOperationException("operation " + operation + " not supported");
}
setOperation(operation); return operation;
}
/**
* Grab the generic attribute value (version value). If one isn't
* specified or the value specified is not "2.0" then throw an exception
* (this value must be specified for all UDDI requests and currently
* only version 2.0 UDDI requests are supported).
*
* @param uddiReq
* @return version
* @throws Exception
*/
public String getVersion(Element uddiReq, String operation) throws Exception {
String version = uddiReq.getAttribute("generic"); if ((version == null) || ("".equals(version))) { if ("urn:uddi-org:api_v3".equals(uddiReq.getNamespaceURI())) { version = "3.0";
}
}
if (!"3.0".equals(version)) { throw new UnsupportedOperationException("version needs to be 3.0");
}
setVersion(version); return version;
}
public static synchronized String getText(Element element) throws TransformerException {
if (transFactory == null) { transFactory = TransformerFactory.newInstance(); transFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); transFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
}
Transformer trans = transFactory.newTransformer(); StringWriter sw = new StringWriter(); trans.transform(new DOMSource(element), new StreamResult(sw)); return sw.toString();
}
@SuppressWarnings("unchecked")
public Node invoke(Element uddiReq) throws Exception {
Node response = null;
// Create a new 'temp' XML element to use as a container
// in which to marshal the UDDI response data into.
DocumentBuilder docBuilder = getDocumentBuilder(); Document document = docBuilder.newDocument(); Element element = document.createElement("temp");
try {
// Lookup the appropriate XML handler. Throw an
// UnsupportedException if one could not be located.
//String reqString = getText(uddiReq);
//Object uddiReqObj = JAXBMarshaller.unmarshallFromString(reqString, "org.uddi.api_v3");
Object uddiReqObj = JAXBMarshaller.unmarshallFromElement(uddiReq, "org.uddi.api_v3"); Object result = null; if (operationClass.equals(GetAssertionStatusReport.class)) { GetAssertionStatusReport getAssertionStatusReport = (GetAssertionStatusReport) uddiReqObj; Method method = portType.getClass().getMethod(methodName, String.class, CompletionStatus.class); result = method.invoke(portType, getAssertionStatusReport.getAuthInfo(), getAssertionStatusReport.getCompletionStatus()); AssertionStatusReport assertionStatusReport = new AssertionStatusReport(); assertionStatusReport.getAssertionStatusItem().addAll((List<AssertionStatusItem>) result); result = assertionStatusReport; } else if (operationClass.equals(SetPublisherAssertions.class)) { SetPublisherAssertions setPublisherAssertions = (SetPublisherAssertions) uddiReqObj; Method method = portType.getClass().getMethod(methodName, String.class, Holder.class); Holder<List<PublisherAssertion>> holder = new Holder<List<PublisherAssertion>>(setPublisherAssertions.getPublisherAssertion()); result = method.invoke(portType, setPublisherAssertions.getAuthInfo(), holder); PublisherAssertions assertions = new PublisherAssertions(); if (holder.value != null) { assertions.getPublisherAssertion().addAll(holder.value);
}
result = assertions; } else if (operationClass.equals(GetPublisherAssertions.class)) { GetPublisherAssertions getPublisherAssertions = (GetPublisherAssertions) uddiReqObj; Method method = portType.getClass().getMethod(methodName, String.class); result = method.invoke(portType, getPublisherAssertions.getAuthInfo()); List<PublisherAssertion> assertionList = (List<PublisherAssertion>) result; PublisherAssertionsResponse publisherAssertionsResponse = new PublisherAssertionsResponse(); if (assertionList != null) { publisherAssertionsResponse.getPublisherAssertion().addAll(assertionList);
}
result = publisherAssertionsResponse; } else { Method method = portType.getClass().getMethod(methodName, operationClass); result = method.invoke(portType, (Object) uddiReqObj);
}
// Lookup the appropriate response handler which will
// be used to marshal the UDDI object into the appropriate
// xml format.
/*
IHandler responseHandler = maker.lookup(uddiResObj.getClass().getName());
if (responseHandler == null)
throw new FatalErrorException("The response object " +
"type is unknown: " +uddiResObj.getClass().getName());
*/
// Lookup the appropriate response handler and marshal
// the juddi object into the appropriate xml format (we
// only support UDDI v2.0 at this time). Attach the
// results to the body of the SOAP response.
if (result != null) { JAXBMarshaller.marshallToElement(result, "org.uddi.api_v3", element);
// Grab a reference to the 'temp' element's
// only child here (this has the effect of
// discarding the temp element) and append
// this child to the soap response body
document.appendChild(element.getFirstChild());
}
response = document; } catch (Exception e) { DispositionReport dr = DispositionReportFaultMessage.getDispositionReport(e); if (dr != null) { JAXBMarshaller.marshallToElement(dr, "org.uddi.api_v3", element); document.appendChild(element.getFirstChild()); response = document;
} else {
throw e;
}
//log.error(e.getMessage(),e);
} return response;
}
/**
*
*/
private DocumentBuilder getDocumentBuilder() {
if (docBuilder == null) { docBuilder = createDocumentBuilder();
}
return docBuilder;
}
/**
*
*/
private synchronized DocumentBuilder createDocumentBuilder() {
if (docBuilder != null) { return docBuilder;
}
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); factory.setNamespaceAware(true);
//factory.setValidating(true);
docBuilder = factory.newDocumentBuilder(); } catch (ParserConfigurationException pcex) { pcex.printStackTrace(); } return docBuilder;
}
public String getOperation() {
return operation;
}
public void setOperation(String operation) {
this.operation = operation; }
public Remote getPortType() {
return portType;
}
public void setPortType(Remote portType) {
this.portType = portType; }
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName; }
public Class<?> getOperationClass() {
return operationClass;
}
public void setOperationClass(Class<?> operationClass) {
this.operationClass = operationClass; }
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version; }
}