/*
* Copyright (C) 2000 - 2010 TagServlet Ltd
*
* This file is part of Open BlueDragon (OpenBD) CFML Server Engine.
*
* OpenBD is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Free Software Foundation,version 3.
*
* OpenBD 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 OpenBD. If not, see http://www.gnu.org/licenses/
*
* Additional permission under GNU GPL version 3 section 7
*
* If you modify this Program, or any covered work, by linking or combining
* it with any of the JARS listed in the README.txt (or a modified version of
* (that library), containing parts covered by the terms of that JAR, the
* licensors of this Program grant you additional permission to convey the
* resulting work.
* README.txt @ http://www.openbluedragon.org/license/README.txt
*
* http://www.openbluedragon.org/
*/
package com.naryx.tagfusion.cfm.engine;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.nary.util.FastMap;
import com.naryx.tagfusion.cfm.parser.CFContext;
import com.naryx.tagfusion.cfm.tag.cfINVOKE;
import com.naryx.tagfusion.cfm.xml.ws.CallParameters;
public class cfWSObjectData extends cfJavaObjectData implements java.io.Serializable {
static final long serialVersionUID = 1;
private cfSession session = null;
private Map<String, cfData> properties = null;
private String wsdlURL = null;
private String portName = null;
private Object invoker = null;
private boolean invoked = false;
private Object requestXml = null;
private Object responseXml = null;
private Object responseHeaders = null;
private Object requestHeaders = null;
private CallParameters callParameters = null;
/**
* Default constructor. Defines the WSDL url, the port name, as well as the
* CallParameters for accessing the WSDL URL. This constructor does not
* attempt to lookup the WSDL url and CallParameters from the registered web
* services configuration.
*
* @param _session
* current cfSession
* @param wsdlURL
* WSDL url for the web service
* @param portName
* port name of the port binding to use
* @param cp
* CallParameters to access the wsdlURL
* @throws cfmRunTimeException
*/
public cfWSObjectData(cfSession _session, String wsdlURL, String portName, CallParameters cp) throws cfmRunTimeException {
super(_session, null);
session = _session;
properties = new FastMap<String, cfData>();
setPortName(portName);
setInvoked(false);
setWSDLUrl(wsdlURL);
setCallParameters(cp);
try {
cfINVOKE.prepareWSObjectData(session, this);
} catch (Exception e) {
throw newException("FileSystemException", "", e.getMessage());
}
}
/**
* Alternate constructor. Defines the WSDL url and the port name. Will attempt
* to lookup the WSDL url and CallParameters from the registered web services
* config.
*
* @param _session
* current cfSession
* @param wsdlURL
* WSDL url for the web service
* @param portName
* port name of the port binding to use
* @throws cfmRunTimeException
*/
public cfWSObjectData(cfSession _session, String wsdlURL, String portName) throws cfmRunTimeException {
this(_session, lookupWebServiceWSDL(_session, wsdlURL), portName, lookupWebServiceCallParameters(_session, wsdlURL));
}
/**
* Alternate constructor. Used when no port name is specified. Will attempt to
* lookup the WSDL url and CallParameters from the registered web services
* config.
*
* @param _session
* current cfSession
* @param wsdlURL
* WSDL url for the web service
* @throws cfmRunTimeException
*/
public cfWSObjectData(cfSession _session, String wsdlURL) throws cfmRunTimeException {
this(_session, wsdlURL, null);
}
public byte getDataType() {
return cfData.CFWSOBJECTDATA;
}
public String getDataTypeName() {
return "web service object";
}
public void setStub(Object stub, Object invoker) {
this.instance = stub;
this.invoker = invoker;
}
public void setResponseHeaders(Object o) {
setInvoked(true);
this.responseHeaders = o;
}
public Object getResponseHeaders() {
return this.responseHeaders;
}
public void setRequestHeaders(Object o) {
this.requestHeaders = o;
}
public Object getRequestHeaders() {
return this.requestHeaders;
}
public void setRequestXml(Object doc) {
this.requestXml = doc;
}
public Object getRequestXml() {
return this.requestXml;
}
public void setResponseXml(Object doc) {
this.responseXml = doc;
}
public Object getResponseXml() {
return this.responseXml;
}
private void setInvoked(boolean b) {
this.invoked = b;
}
public boolean getInvoked() {
return this.invoked;
}
public Object getPreparedInvoker() {
return this.invoker;
}
/**
* Looks up a registered web service using the specified name. Returns the
* WSDL URL from the registered web service if found or the specified name if
* no matching registered web service was found.
*
* @param _Session
* current cfSession
* @param name
* wsdl url or registered web service name
* @return wsdl url or the specified name
* @throws cfmRunTimeException
*/
public static String lookupWebServiceWSDL(cfSession _Session, String name) throws cfmRunTimeException {
cfStructData struct = null;
// Read the local app settings
if (cfEngine.getConfig() != null) {
struct = searchConfigForWebService(cfEngine.getConfig().getCFMLData(), name);
if (struct != null)
return struct.getData("WSDL").toString();
}
// Return the name as the web service WSDL URL
return name;
}
/**
* Looks up a registered web service using the specified name. Returns the
* CallParameters from the registered web service if found or empty/default
* CallParameters if no matching registered web service was found.
*
* @param _Session
* current cfSession
* @param name
* wsdl url or registered web service name
* @return CallParameters for the registered web service or empty/default
* CallParameters
* @throws cfmRunTimeException
*/
public static CallParameters lookupWebServiceCallParameters(cfSession _Session, String name) throws cfmRunTimeException {
cfStructData struct = null;
CallParameters rtn = new CallParameters();
// Read the local app settings
if (cfEngine.getConfig() != null) {
struct = searchConfigForWebService(cfEngine.getConfig().getCFMLData(), name);
if (struct != null) {
rtn.setUsername(struct.getData("USERNAME").toString());
rtn.setPassword(struct.getData("PASSWORD").toString());
return rtn;
}
}
// Return the name as the web service WSDL URL
return rtn;
}
/**
* Searches the specified config xml for the web service registered under the
* specifed name. Returns the cfStructData representing the web service null
* if not found.
*
* @param configData
* xml representation of the config file
* @param name
* registered web service name
* @return cfStructData representing the registered web service or null if no
* web service was found with the specified name
*/
private static cfStructData searchConfigForWebService(cfStructData configData, String name) {
cfArrayData wsArray = null;
// Read the local app settings
if (configData != null) {
configData = (cfStructData) configData.getData("server");
if (configData != null) {
configData = (cfStructData) configData.getData("webservices");
if (configData != null) {
wsArray = (cfArrayData) configData.getData("webservice");
if (wsArray != null) {
for (int i = 1; i <= wsArray.size(); i++) {
cfStructData ws = (cfStructData) wsArray.getElement(i);
if (ws.getData("NAME").toString().equalsIgnoreCase(name))
return ws;
}
}
}
}
}
// Return nothing
return null;
}
public cfData getWSData(cfData _field) throws cfmRunTimeException {
if (_field.getDataType() == cfData.CFSTRINGDATA)
return getWSData(((cfStringData) _field).getString());
else
throw new cfmRunTimeException(catchDataFactory.generalException(cfCatchData.TYPE_OBJECT, "errorCode.runtimeError", "cfdata.javaInvalidClass", null));
}
public cfData getWSData(String _Field) throws cfmRunTimeException {
if (properties.containsKey(_Field))
return properties.get(_Field);
else
throw newException("WSDL", "wsdl", "No such field: " + _Field);
}
public cfData getWSData(javaMethodDataInterface _method, CFContext _context) throws cfmRunTimeException {
cfData returnValue = null;
String methodName = _method.getFunctionName();
List<cfData> args = _method.getEvaluatedArguments(_context, true);
returnValue = invokeWSMethod(methodName, args);
return returnValue;
}
public cfData invokeWSMethod(String operationName, List<cfData> arguments) throws cfmRunTimeException {
return cfINVOKE.invokeWSMethod(session, this, operationName, arguments);
}
private cfmRunTimeException newException(String type, String detail, String message) {
cfCatchData catchData = new cfCatchData(session);
catchData.setType(type);
catchData.setDetail(detail);
catchData.setMessage(message);
return new cfmRunTimeException(catchData);
}
public String toString() {
return wsdlURL;
}
// this version of equals() is for use by the CFML expression engine
public boolean equals(cfData _data) throws cfmRunTimeException {
return super.equals(_data); // throws unsupported exception
}
// this version of equals() is for use by generic Collections classes
public boolean equals(Object o) {
if (o instanceof cfWSObjectData)
return instance.equals(((cfWSObjectData) o).instance);
return false;
}
public int hashCode() {
return wsdlURL.hashCode();
}
// --[ Override the Serialising methods as we don't wish this object to be
// serialised
// --[ Causes problems when we would doing things with the client scope for
// example.
private void writeObject(java.io.ObjectOutputStream out) throws IOException {
}
private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
}
/**
* Returns the WSDL url.
*
* @return WSDL url
*/
public String getWSDLUrl() {
return wsdlURL;
}
/**
* Sets the WSDL url.
*
* @param url
* WSDL url
*/
private void setWSDLUrl(String url) {
this.wsdlURL = url;
}
/**
* Returns the port name to use.
*
* @return port name of the port binding to use
*/
public String getPortName() {
return portName;
}
/**
* Sets the port name to use.
*
* @param portName
* port name of the port binding to use
*/
private void setPortName(String portName) {
this.portName = portName;
}
/**
* Returns the CallParameters for the WSDL.
*
* @return CallParameters for the WSDL
*/
public CallParameters getCallParameters() {
return callParameters;
}
/**
* Sets the CallParameters for the WSDL.
*
* @param cp
* CallParameters for the WSDL
*/
private void setCallParameters(CallParameters cp) {
this.callParameters = cp;
}
}