package railo.runtime.net.rpc.client;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TimeZone;
import java.util.Vector;
import javax.wsdl.Binding;
import javax.wsdl.Operation;
import javax.wsdl.Port;
import javax.wsdl.extensions.soap.SOAPAddress;
import javax.xml.namespace.QName;
import javax.xml.rpc.ServiceException;
import javax.xml.rpc.encoding.TypeMapping;
import org.apache.axis.EngineConfiguration;
import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.configuration.EngineConfigurationFactoryFinder;
import org.apache.axis.configuration.SimpleProvider;
import org.apache.axis.message.SOAPHeaderElement;
import org.apache.axis.transport.http.CommonsHTTPSender;
import org.apache.axis.wsdl.gen.Parser;
import org.apache.axis.wsdl.symbolTable.BindingEntry;
import org.apache.axis.wsdl.symbolTable.ElementDecl;
import org.apache.axis.wsdl.symbolTable.Parameter;
import org.apache.axis.wsdl.symbolTable.Parameters;
import org.apache.axis.wsdl.symbolTable.ServiceEntry;
import org.apache.axis.wsdl.symbolTable.SymTabEntry;
import org.apache.axis.wsdl.symbolTable.SymbolTable;
import org.apache.axis.wsdl.symbolTable.TypeEntry;
import org.apache.axis.wsdl.toJava.Utils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import railo.commons.lang.ClassUtil;
import railo.commons.lang.StringUtil;
import railo.runtime.PageContext;
import railo.runtime.PageContextImpl;
import railo.runtime.config.Config;
import railo.runtime.dump.DumpData;
import railo.runtime.dump.DumpProperties;
import railo.runtime.dump.DumpTable;
import railo.runtime.dump.SimpleDumpData;
import railo.runtime.engine.ThreadLocalPageContext;
import railo.runtime.exp.ExpressionException;
import railo.runtime.exp.PageException;
import railo.runtime.net.proxy.Proxy;
import railo.runtime.net.proxy.ProxyData;
import railo.runtime.net.rpc.AxisCaster;
import railo.runtime.net.rpc.Pojo;
import railo.runtime.net.rpc.RPCException;
import railo.runtime.net.rpc.TypeMappingUtil;
import railo.runtime.op.Caster;
import railo.runtime.text.xml.XMLUtil;
import railo.runtime.type.Collection;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.Iteratorable;
import railo.runtime.type.KeyImpl;
import railo.runtime.type.Objects;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.dt.DateTime;
import railo.runtime.type.it.KeyAsStringIterator;
import railo.runtime.type.it.KeyIterator;
import railo.runtime.type.it.ObjectsEntryIterator;
import railo.runtime.type.it.ObjectsIterator;
import railo.runtime.type.util.ArrayUtil;
import railo.runtime.type.util.CollectionUtil;
import railo.runtime.type.util.ComponentUtil;
import railo.runtime.type.util.UDFUtil;
import railo.transformer.bytecode.util.ASMProperty;
import railo.transformer.bytecode.util.ASMPropertyImpl;
/**
* Wrapper for a Webservice
*/
public final class RPCClient implements Objects, Iteratorable{
private static final long serialVersionUID = 1L;
private Parser parser = new Parser();
//private Map properties=new HashTable();
private String wsdlUrl;
private ProxyData proxyData;
private String username;
private String password;
private Call last;
private List<SOAPHeaderElement> headers;
static {
EngineConfiguration engine = EngineConfigurationFactoryFinder.newFactory().getClientEngineConfig();
SimpleProvider provider = new SimpleProvider(engine);
provider.deployTransport("http", new CommonsHTTPSender());
}
/**
* @param wsdlUrl
* @param username
* @param password
* @throws PageException
*/
public RPCClient( String wsdlUrl, String username, String password) throws PageException {
this(wsdlUrl,username,password,null);
}
public RPCClient( String wsdlUrl) throws PageException {
this(wsdlUrl,null,null,null);
}
public RPCClient(String wsdlUrl, ProxyData proxyData) throws PageException {
this(wsdlUrl,null,null,proxyData);
}
public RPCClient(String wsdlUrl, String username, String password, ProxyData proxyData) throws PageException {
if(!StringUtil.isEmpty(username)) {
if(password==null)password="";
parser.setUsername(username);
parser.setPassword(password);
//parser.setTimeout(1000);
this.username=username;
this.password=password;
}
this.proxyData=proxyData;
run(wsdlUrl);
}
private void run(String wsdlUrl) throws PageException {
this.wsdlUrl=wsdlUrl;
try {
parser.run(wsdlUrl);
}
catch(Throwable e) {
throw Caster.toPageException(e);
}
}
public Object callWithNamedValues(PageContext pc, String methodName, Struct arguments) throws PageException {
try {
return (_callMethod(pc,pc.getConfig(),methodName,arguments,null));
}
catch (Exception e) {
throw Caster.toPageException(e);
}
}
public Object callWithNamedValues(Config config, String methodName, Struct arguments) throws PageException {
try {
return (_callMethod(null,config,methodName,arguments,null));
}
catch (Exception e) {
throw Caster.toPageException(e);
}
}
@Override
public Object callWithNamedValues(PageContext pc, Collection.Key methodName, Struct args) throws PageException {
return callWithNamedValues(pc, methodName.getString(), args);
}
public Object call(PageContext pc, String methodName,Object[] arguments) throws PageException {
try {
return _callMethod(pc,pc.getConfig(),methodName,null,arguments);
}
catch (Throwable t) {
throw Caster.toPageException(t);
}
}
/*public Object call(Config config, String methodName,Object[] arguments) throws PageException {
try {
return (_callMethod(ThreadLocalPageContext.get(config),methodName,null,arguments));
}
catch (Exception e) {
throw Caster.toPageException(e);
}
}*/
@Override
public Object call(PageContext pc, Collection.Key methodName, Object[] arguments) throws PageException {
return call(pc, methodName.getString(), arguments);
}
private Object _callMethod(PageContext pc,Config secondChanceConfig,String methodName, Struct namedArguments,Object[] arguments) throws PageException, ServiceException, RemoteException {
javax.wsdl.Service service = getWSDLService();
Service axisService = null;
axisService = new Service(parser, service.getQName());
TypeMappingUtil.registerDefaults(axisService.getTypeMappingRegistry());
Port port = getWSDLPort(service);
Binding binding = port.getBinding();
Parameters parameters = null;
Parameter p = null;
SymbolTable symbolTable = parser.getSymbolTable();
BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
Iterator itr = bEntry.getParameters().keySet().iterator();
Operation tmpOp = null;
Operation operation = null;
while(itr.hasNext()) {
tmpOp = (Operation)itr.next();
if(tmpOp.getName().equalsIgnoreCase(methodName)) {
operation = tmpOp;
parameters = (Parameters)bEntry.getParameters().get(tmpOp);
break;
}
}
if(operation == null || parameters == null)
throw new RPCException("Cannot locate method " + methodName + " in webservice " + wsdlUrl);
org.apache.axis.client.Call call = (Call)axisService.createCall(QName.valueOf(port.getName()), QName.valueOf(tmpOp.getName()));
if(!StringUtil.isEmpty(username,true)){
call.setUsername(username);
call.setPassword(password);
}
org.apache.axis.encoding.TypeMapping tm = (org.apache.axis.encoding.TypeMapping)
axisService.getTypeMappingRegistry().getDefaultTypeMapping();
//TypeMappingRegistry reg=(TypeMappingRegistry) axisService.getTypeMappingRegistry();
//tm=reg.getOrMakeTypeMapping("http://schemas.xmlsoap.org/soap/encoding/");
tm=call.getMessageContext().getTypeMapping();
Vector<String> inNames = new Vector<String>();
Vector<Parameter> inTypes = new Vector<Parameter>();
Vector<String> outNames = new Vector<String>();
Vector<Parameter> outTypes = new Vector<Parameter>();
for(int j = 0; j < parameters.list.size(); j++) {
p = (Parameter)parameters.list.get(j);
map(pc,secondChanceConfig,call,tm,p.getType());
switch(p.getMode()) {
case Parameter.IN:
inNames.add(p.getQName().getLocalPart());
inTypes.add(p);
break;
case Parameter.OUT:
outNames.add(p.getQName().getLocalPart());
outTypes.add(p);
break;
case Parameter.INOUT:
inNames.add(p.getQName().getLocalPart());
inTypes.add(p);
outNames.add(p.getQName().getLocalPart());
outTypes.add(p);
break;
}
}
// set output type
if (parameters.returnParam != null) {
QName rtnQName = parameters.returnParam.getQName();
TypeEntry rtnType = parameters.returnParam.getType();
map(pc,secondChanceConfig,call,tm,rtnType);
outNames.add(rtnQName.getLocalPart());
outTypes.add(parameters.returnParam);
}
//Iterator it = outTypes.iterator();
// check arguments
Object[] inputs = new Object[inNames.size()];
TimeZone tz;
if(pc==null)tz=ThreadLocalPageContext.getTimeZone(secondChanceConfig);
else tz=ThreadLocalPageContext.getTimeZone(pc);
if(arguments!=null) {
if(inNames.size() != arguments.length)
throw new RPCException("Invalid arguments count for operation " + methodName+" ("+arguments.length+" instead of "+inNames.size()+")");
for(int pos = 0; pos < inNames.size(); pos++) {
p = inTypes.get(pos);
inputs[pos]=getArgumentData(tm,tz, p, arguments[pos]);
}
}
else {
UDFUtil.argumentCollection(namedArguments);
if(inNames.size() != namedArguments.size())
throw new RPCException("Invalid arguments count for operation " + methodName+" ("+namedArguments.size()+" instead of "+inNames.size()+")");
Object arg;
for(int pos = 0; pos < inNames.size(); pos++) {
p = inTypes.get(pos);
arg=namedArguments.get(KeyImpl.init(p.getName()),null);
if(arg==null) {
throw new RPCException("Invalid arguments for operation " + methodName,
getErrorDetailForArguments(inNames.toArray(new String[inNames.size()]),CollectionUtil.keysAsString(namedArguments)));
}
inputs[pos]=getArgumentData(tm,tz, p, arg);
}
}
Object ret=null;
// add header
if(headers!=null && !headers.isEmpty()) {
Iterator<SOAPHeaderElement> it = headers.iterator();
while(it.hasNext()){
call.addHeader(it.next());
}
}
if(proxyData!=null && !StringUtil.isEmpty(proxyData.getServer(),true)) {
try {
Proxy.start(proxyData);
ret = call.invoke(inputs);
//ret = invoke(call,inputs);
}
finally {
Proxy.end();
}
}
else {
ret = call.invoke(inputs);
}
last=call;
if(outNames.size()<=1) return AxisCaster.toRailoType(null,ret);
//getParamData((org.apache.axis.client.Call)call,parameters.returnParam,ret);
Map outputs = call.getOutputParams();
Struct sct = new StructImpl();
for(int pos = 0; pos < outNames.size(); pos++) {
String name = outNames.get(pos);
//print.ln(name);
Object value = outputs.get(name);
if(value == null && pos == 0) {
sct.setEL(name, AxisCaster.toRailoType(null,ret));
}
else {
sct.setEL(name, AxisCaster.toRailoType(null,value));
}
}
return sct;
}
private void map(PageContext pc, Config secondChanceConfig,Call call, org.apache.axis.encoding.TypeMapping tm, TypeEntry type) throws PageException {
Vector els = type.getContainedElements();
if(els==null) mapSimple(tm, type);
else {
// class is already registed
Class rtnClass=tm.getClassForQName(type.getQName());
if(rtnClass!=null && rtnClass.getName().equals(getClientClassName(type))) return;
ClassLoader cl=null;
try {
if(pc==null)cl = secondChanceConfig.getRPCClassLoader(false);
else cl = ((PageContextImpl)pc).getRPCClassLoader(false);
} catch (IOException e) {}
Class cls = mapComplex(pc,secondChanceConfig,call,tm, type);
// TODO make a better impl; this is not the fastest way to make sure all pojos use the same classloader
if(cls!=null && cl!=cls.getClassLoader()){
mapComplex(pc,secondChanceConfig,call,tm, type);
}
}
}
private Class mapComplex(PageContext pc,Config secondChanceConfig,Call call, org.apache.axis.encoding.TypeMapping tm, TypeEntry type) throws PageException {
Vector children = type.getContainedElements();
TypeEntry ref=type.getRefType();
if(ref==null) return _mapComplex(pc,secondChanceConfig, call, tm, type);
children = ref.getContainedElements();
if(children==null) {
mapSimple(tm, ref);
return null;
}
Class clazz = mapComplex(pc,secondChanceConfig, call, tm, ref);
if(clazz==null) return null;
Class arr = ClassUtil.toArrayClass(clazz);
TypeMappingUtil.registerBeanTypeMapping(tm, arr, type.getQName());
return arr;
}
private Class _mapComplex(PageContext pc,Config secondChanceConfig,Call call, org.apache.axis.encoding.TypeMapping tm, TypeEntry type) throws PageException {
Vector children = type.getContainedElements();
ArrayList<ASMPropertyImpl> properties=new ArrayList<ASMPropertyImpl>();
if(children!=null) {
Iterator it = children.iterator();
ElementDecl el;
Class clazz;
TypeEntry t;
String name;
while(it.hasNext()){
clazz=null;
el=(ElementDecl) it.next();
t=el.getType();
Vector els = t.getContainedElements();
if(els!=null) {
clazz=mapComplex(pc,secondChanceConfig, call, tm, t);
}
name=railo.runtime.type.util.ListUtil.last(el.getQName().getLocalPart(), '>');
if(clazz==null)clazz=tm.getClassForQName(t.getQName());
if(clazz==null)clazz=Object.class;
properties.add(new ASMPropertyImpl(clazz,name));
}
}
ASMProperty[] props = properties.toArray(new ASMProperty[properties.size()]);
String clientClassName=getClientClassName(type);
Pojo pojo;
if(pc==null)pojo = (Pojo) ComponentUtil.getClientComponentPropertiesObject(secondChanceConfig,clientClassName,props);
else pojo = (Pojo) ComponentUtil.getClientComponentPropertiesObject(pc,clientClassName,props);
TypeMappingUtil.registerBeanTypeMapping(tm,
pojo.getClass(),
type.getQName());
return pojo.getClass();
}
private String getClientClassName(TypeEntry type) {
String className=StringUtil.toVariableName(type.getQName().getLocalPart());
String url=urlToClass(wsdlUrl);
String ns = type.getQName().getNamespaceURI();
//if(props!=null){String p = ASMUtil.createMD5(props);
//print.e("p:"+p);}
// has namespace
if(ns!=null && !"http://DefaultNamespace".equalsIgnoreCase(ns)){
ns=StringUtil.replace(ns, "http://", "", true);
ns=toClassName(ns,true);
if(!StringUtil.isEmpty(ns)) return ns+"."+className;
}
return url+"."+className;
}
private static String urlToClass(String wsdlUrl) {
StringBuffer sb=new StringBuffer();
try {
URL url = new URL(wsdlUrl);
// protocol
if("http".equalsIgnoreCase(url.getProtocol())){}
else{
sb.append(toClassName(url.getProtocol(), false));
sb.append('.');
}
// host
sb.append(toClassName(url.getHost(), true));
// port
if(url.getPort()>0 && url.getPort()!=80){
sb.append(".p");
sb.append(url.getPort());
}
// path
if(!StringUtil.isEmpty(url.getPath())){
sb.append('.');
sb.append(toClassName(url.getPath(), false));
}
// query
if(!StringUtil.isEmpty(url.getQuery()) && !"wsdl".equals(url.getQuery())){
sb.append('.');
sb.append(toClassName(url.getQuery(), false));
}
return sb.toString();
}
catch (MalformedURLException e) {
return StringUtil.toVariableName(wsdlUrl);
}
}
private static String toClassName(String raw,boolean reverse) {
raw=raw.trim();
if(raw.endsWith("/"))raw=raw.substring(0,raw.length()-1);
StringBuffer sb=new StringBuffer();
String[] arr=null;
try {
arr = railo.runtime.type.util.ListUtil.toStringArray(railo.runtime.type.util.ListUtil.listToArray(raw, "./&="));
} catch (PageException e) {}
String el;
for(int i=0;i<arr.length;i++){
el=arr[i].trim();
if(el.length()==0)continue;
if(reverse){
if(sb.length()>0)sb.insert(0,'.');
sb.insert(0,StringUtil.lcFirst(StringUtil.toVariableName(arr[i])));
}
else {
if(sb.length()>0)sb.append('.');
sb.append(StringUtil.lcFirst(StringUtil.toVariableName(arr[i])));
}
}
return sb.toString();
}
private void mapSimple(org.apache.axis.encoding.TypeMapping tm, TypeEntry type) {
//print.out("simple");
//print.out(tm);
//print.out(type);
}
private String getErrorDetailForArguments(String[] names, String[] argKeys) {
String name;
boolean found;
for(int i=0;i<names.length;i++) {
name=names[i];
found=false;
for(int y=0;y<argKeys.length;y++) {
if(name.equalsIgnoreCase(argKeys[y]))found=true;
}
if(!found) {
if(names.length>1)
return "missing argument with name ["+name+"], needed argument are ["+railo.runtime.type.util.ListUtil.arrayToList(names,", ")+"]";
return "missing argument with name ["+name+"]";
}
}
return "";
}
/**
* returns the WSDL Service for this Object
* @return WSDL Service
* @throws RPCException
*/
public javax.wsdl.Service getWSDLService() throws RPCException {
SymTabEntry symTabEntry = null;
Map.Entry entry = null;
Vector v = null;
for(Iterator iterator = parser.getSymbolTable().getHashMap().entrySet().iterator(); iterator.hasNext();) {
entry = (Map.Entry)iterator.next();
v = (Vector)entry.getValue();
for(int i = 0; i < v.size(); i++) {
if(!(org.apache.axis.wsdl.symbolTable.ServiceEntry.class).isInstance(v.elementAt(i)))
continue;
symTabEntry = (SymTabEntry)v.elementAt(i);
break;
}
}
if(symTabEntry == null)
throw new RPCException("Can't locate service entry in WSDL");
return ((ServiceEntry)symTabEntry).getService();
}
/**
* returns the WSDL Port
* @param service
* @return WSDL Port
* @throws RPCException
*/
public Port getWSDLPort(javax.wsdl.Service service) throws RPCException {
String name = null;
Port port = null;
List list = null;
Map ports = service.getPorts();
for(Iterator itr = ports.keySet().iterator(); itr.hasNext();) {
name = (String)itr.next();
port = (Port)ports.get(name);
list = port.getExtensibilityElements();
if(list != null) {
for(int i = 0; i < list.size(); i++)
if(list.get(i) instanceof SOAPAddress)
return port;
}
}
throw new RPCException("Can't locate port entry for service " + service.getQName().toString() + " WSDL");
}
private Object getArgumentData(TypeMapping tm,TimeZone tz, Parameter p, Object arg) throws PageException {
QName paramType = Utils.getXSIType(p);
Object o = AxisCaster.toAxisType(tm,tz,paramType,arg,null);
return o;
}
@Override
public Object get(PageContext pc, Collection.Key key) throws PageException {
return call(pc,"get"+key.getString(), ArrayUtil.OBJECT_EMPTY);
}
@Override
public Object get(PageContext pc, Collection.Key key, Object defaultValue) {
try {
return call(pc,"get"+StringUtil.ucFirst(key.getString()), ArrayUtil.OBJECT_EMPTY);
} catch (PageException e) {
return defaultValue;
}
}
@Override
public Object set(PageContext pc, Collection.Key propertyName, Object value) throws PageException {
return call(pc,"set"+propertyName.getString(), new Object[]{value});
}
@Override
public Object setEL(PageContext pc, Collection.Key propertyName, Object value) {
try {
return call(pc,"set"+propertyName.getString(), new Object[]{value});
} catch (PageException e) {
return null;
}
}
public boolean isInitalized() {
return true;
}
@Override
public DumpData toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) {
try {
return _toDumpData(pageContext,maxlevel,dp);
} catch (Exception e) {
DumpTable table = new DumpTable("webservice","#ccccff","#cccc00","#000000");
table.appendRow(1,new SimpleDumpData("webservice"),new SimpleDumpData(wsdlUrl));
return table;
}
}
private DumpData _toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) throws RPCException {
DumpTable functions = new DumpTable("webservice","#ccccff","#cccc00","#000000");
functions.setTitle("Web Service (WSDL/Soap)");
if(dp.getMetainfo())functions.setComment(wsdlUrl);
//DumpTable functions = new DumpTable("#ccccff","#cccc00","#000000");
javax.wsdl.Service service = getWSDLService();
Port port = getWSDLPort(service);
Binding binding = port.getBinding();
//Parameters parameters = null;
//Parameter p = null;
SymbolTable symbolTable = parser.getSymbolTable();
BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
Iterator itr = bEntry.getParameters().keySet().iterator();
Operation tmpOp = null;
//Operation operation = null;
while(itr.hasNext()) {
tmpOp = (Operation)itr.next();
Element el = tmpOp.getDocumentationElement();
StringBuffer doc=new StringBuffer();
if(el!=null){
NodeList children = XMLUtil.getChildNodes(el, Node.TEXT_NODE);
int len=children.getLength();
Text text;
for(int i=0;i<len;i++){
text=(Text) children.item(i);
doc.append(text.getData());
}
}
//parameters = (Parameters)bEntry.getParameters().get(tmpOp);
functions.appendRow(1,
new SimpleDumpData(tmpOp.getName()),
_toHTMLOperation(doc.toString(),(Parameters)bEntry.getParameters().get(tmpOp)));
}
//box.appendRow(1,new SimpleDumpData(""),functions);
return functions;
}
private DumpData _toHTMLOperation(String doc, Parameters parameters) {
DumpTable table = new DumpTable("#ccccff","#ccff66","#000000");
DumpTable attributes = new DumpTable("#ccccff","#ccff66","#000000");
String returns = "void";
attributes.appendRow(3,new SimpleDumpData("name"),new SimpleDumpData("type"));
for(int j = 0; j < parameters.list.size(); j++) {
Parameter p = (Parameter)parameters.list.get(j);
QName paramType = org.apache.axis.wsdl.toJava.Utils.getXSIType(p);
String strType=paramType.getLocalPart();
switch(p.getMode()) {
case Parameter.IN:
attributes.appendRow(0,new SimpleDumpData(p.getName()),new SimpleDumpData(toRailoType(strType)));
break;
case Parameter.OUT:
returns=toRailoType(strType);
break;
case Parameter.INOUT:
attributes.appendRow(0,new SimpleDumpData(p.getName()),new SimpleDumpData(toRailoType(strType)));
returns=toRailoType(strType);
break;
}
}
Parameter rtn = parameters.returnParam;
if(rtn!=null) {
QName paramType = org.apache.axis.wsdl.toJava.Utils.getXSIType(rtn);
String strType=paramType.getLocalPart();
returns=toRailoType(strType);
}
table.appendRow(1,new SimpleDumpData("arguments"),attributes);
table.appendRow(1,new SimpleDumpData("return type"),new SimpleDumpData(returns));
if(doc.length()>0)table.appendRow(1,new SimpleDumpData("hint"),new SimpleDumpData(doc));
return table;
}
private String toRailoType(String strType) {
strType=strType.toLowerCase();
if(strType.startsWith("array"))strType="array";
else if(strType.equals("map"))strType="struct";
else if(strType.startsWith("query"))strType="query";
else if(strType.equals("double"))strType="numeric";
else if(strType.startsWith("any"))strType="any";
else if(strType.equals("date"))strType="date";
return strType;
}
@Override
public String castToString() throws ExpressionException {
throw new RPCException("can't cast Webservice to a string");
}
@Override
public String castToString(String defaultValue) {
return defaultValue;
}
@Override
public boolean castToBooleanValue() throws ExpressionException {
throw new RPCException("can't cast Webservice to a boolean");
}
@Override
public Boolean castToBoolean(Boolean defaultValue) {
return defaultValue;
}
@Override
public double castToDoubleValue() throws ExpressionException {
throw new RPCException("can't cast Webservice to a number");
}
@Override
public double castToDoubleValue(double defaultValue) {
return defaultValue;
}
@Override
public DateTime castToDateTime() throws RPCException {
throw new RPCException("can't cast Webservice to a Date Object");
}
@Override
public DateTime castToDateTime(DateTime defaultValue) {
return defaultValue;
}
@Override
public int compareTo(boolean b) throws ExpressionException {
throw new ExpressionException("can't compare Webservice Object with a boolean value");
}
@Override
public int compareTo(DateTime dt) throws PageException {
throw new ExpressionException("can't compare Webservice Object with a DateTime Object");
}
@Override
public int compareTo(double d) throws PageException {
throw new ExpressionException("can't compare Webservice Object with a numeric value");
}
@Override
public int compareTo(String str) throws PageException {
throw new ExpressionException("can't compare Webservice Object with a String");
}
@Override
public Iterator<Collection.Key> keyIterator() {
List<Collection.Key> list=new ArrayList<Collection.Key>();
javax.wsdl.Service service = null;
Port port = null;
try {
service = getWSDLService();
port = getWSDLPort(service);
}
catch(Exception e) {
return new KeyIterator(new Collection.Key[0]);
}
Binding binding = port.getBinding();
SymbolTable symbolTable = parser.getSymbolTable();
BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
Iterator itr = bEntry.getParameters().keySet().iterator();
Operation tmpOp = null;
//Operation operation = null;
while(itr.hasNext()) {
tmpOp = (Operation)itr.next();
//Parameters p = (Parameters)bEntry.getParameters().get(tmpOp);
list.add(KeyImpl.init(tmpOp.getName()));
}
return new KeyIterator(list.toArray(new Collection.Key[list.size()]));
}
@Override
public Iterator<String> keysAsStringIterator() {
return new KeyAsStringIterator(keyIterator());
}
@Override
public Iterator<Object> valueIterator() {
return new ObjectsIterator(keyIterator(),this);
}
@Override
public Iterator<Entry<Key, Object>> entryIterator() {
return new ObjectsEntryIterator(keyIterator(), this);
}
public Call getLastCall() {
return last;
}
public void addHeader(SOAPHeaderElement header) {
if(headers==null)headers=new ArrayList<SOAPHeaderElement>();
headers.add(header);
}
}