/** * Copyright (c) 2014, the Railo Company Ltd. * Copyright (c) 2015, Lucee Assosication Switzerland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see <http://www.gnu.org/licenses/>. * */ package lucee.runtime.net.rpc.client; import java.io.IOException; import java.io.StringReader; 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.Set; import java.util.TimeZone; import java.util.Vector; import javax.wsdl.Binding; import javax.wsdl.Operation; import javax.wsdl.Port; import javax.xml.namespace.QName; import javax.xml.rpc.ServiceException; import javax.xml.rpc.encoding.TypeMapping; import lucee.commons.digest.HashUtil; import lucee.commons.lang.ClassUtil; import lucee.commons.lang.ExceptionUtil; import lucee.commons.lang.StringUtil; import lucee.runtime.PageContext; import lucee.runtime.PageContextImpl; import lucee.runtime.cache.tag.CacheHandler; import lucee.runtime.cache.tag.CacheHandlerCollectionImpl; import lucee.runtime.cache.tag.CacheItem; import lucee.runtime.cache.tag.webservice.WebserviceCacheItem; import lucee.runtime.config.Config; import lucee.runtime.dump.DumpData; import lucee.runtime.dump.DumpProperties; import lucee.runtime.dump.DumpTable; import lucee.runtime.dump.DumpUtil; import lucee.runtime.dump.SimpleDumpData; import lucee.runtime.engine.ThreadLocalPageContext; import lucee.runtime.exp.ExpressionException; import lucee.runtime.exp.PageException; import lucee.runtime.net.proxy.Proxy; import lucee.runtime.net.proxy.ProxyData; import lucee.runtime.net.rpc.AxisCaster; import lucee.runtime.net.rpc.RPCException; import lucee.runtime.net.rpc.TypeMappingUtil; import lucee.runtime.op.Caster; import lucee.runtime.text.xml.XMLUtil; import lucee.runtime.type.Collection; import lucee.runtime.type.Collection.Key; import lucee.runtime.type.KeyImpl; import lucee.runtime.type.Struct; import lucee.runtime.type.StructImpl; import lucee.runtime.type.dt.DateTime; import lucee.runtime.type.it.KeyAsStringIterator; import lucee.runtime.type.it.KeyIterator; import lucee.runtime.type.it.ObjectsEntryIterator; import lucee.runtime.type.it.ObjectsIterator; import lucee.runtime.type.util.ArrayUtil; import lucee.runtime.type.util.CollectionUtil; import lucee.runtime.type.util.ComponentUtil; import lucee.runtime.type.util.UDFUtil; import lucee.transformer.bytecode.util.ASMProperty; import lucee.transformer.bytecode.util.ASMPropertyImpl; import org.apache.axis.AxisFault; 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.DefinedType; 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.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.InputSource; /** * Wrapper for a Webservice */ final class Axis1Client extends WSClient { 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; private boolean wsdlExecuted; 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 Axis1Client( String wsdlUrl, String username, String password) throws PageException { this(wsdlUrl,username,password,null); } public Axis1Client(String wsdlUrl, String username, String password, ProxyData proxyData) { 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; this.wsdlUrl=wsdlUrl; } public Object callWithNamedValues(PageContext pc, String methodName, Struct arguments) throws PageException { try { if(hasCachedWithin(pc)) return _callCachedWithin(pc, pc.getConfig(), methodName, arguments, null); return _call(pc,pc.getConfig(),methodName,arguments,null); } catch (Exception e) { throw Caster.toPageException(e); } } @Override public Object callWithNamedValues(Config config, Collection.Key methodName, Struct arguments) throws PageException { try { return (_call(null,config,methodName.getString(),arguments,null)); } catch (Exception e) { throw Caster.toPageException(e); } } public Object call(PageContext pc, String methodName,Object[] arguments) throws PageException { try { if(hasCachedWithin(pc)) return _callCachedWithin(pc, null, methodName, null, arguments); return _call(pc,pc.getConfig(),methodName,null,arguments); } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); throw Caster.toPageException(t); } } @Override public Object callWithNamedValues(PageContext pc, Collection.Key methodName, Struct args) throws PageException { return callWithNamedValues(pc, methodName.getString(), args); } @Override public Object call(PageContext pc, Collection.Key methodName, Object[] arguments) throws PageException { return call(pc, methodName.getString(), arguments); } private boolean hasCachedWithin(PageContext pc) { return pc.getCachedWithin(Config.CACHEDWITHIN_WEBSERVICE)!=null; } private Object getCachedWithin(PageContext pc) { //if(this.properties.cachedWithin!=null) return this.properties.cachedWithin; return pc.getCachedWithin(Config.CACHEDWITHIN_WEBSERVICE); } private Object _callCachedWithin(PageContext pc,Config secondChanceConfig,String methodName, Struct namedArguments,Object[] arguments) throws PageException, RemoteException, ServiceException { // no pc no cache! if(pc==null) return _call(pc, secondChanceConfig, methodName, namedArguments, arguments); String id=CacheHandlerCollectionImpl.createId(wsdlUrl,username,password,proxyData,methodName,arguments,namedArguments); CacheHandler ch = pc.getConfig().getCacheHandlerCollection(Config.CACHE_TYPE_WEBSERVICE,null).getInstanceMatchingObject( getCachedWithin(pc),null); CacheItem ci=ch!=null?ch.get(pc, id):null; // get from cache if(ci instanceof WebserviceCacheItem ) { WebserviceCacheItem entry = (WebserviceCacheItem)ci; return entry.getData(); } long start = System.nanoTime(); Object rtn = _call(pc, secondChanceConfig, methodName, namedArguments, arguments); if(ch!=null)ch.set(pc, id,getCachedWithin(pc),new WebserviceCacheItem(rtn,wsdlUrl,methodName,System.nanoTime()-start)); return rtn; } private Object _call(PageContext pc,Config secondChanceConfig,String methodName, Struct namedArguments,Object[] arguments) throws PageException, ServiceException, RemoteException { javax.wsdl.Service service = getWSDLService(); Service axisService = new Service(parser, service.getQName()); //TypeMappingRegistry tmr = axisService.getTypeMappingRegistry(); //TypeMappingDelegate dtm = (TypeMappingDelegate) tmr.getDefaultTypeMapping(); //dtm.setDoAutoTypes(true); TypeMappingUtil.registerDefaults(axisService.getTypeMappingRegistry()); Port port = WSUtil.getSoapPort(service); Binding binding = port.getBinding(); SymbolTable symbolTable = parser.getSymbolTable(); BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName()); // get matching operation/method Iterator<Entry<Operation,Parameters>> itr = bEntry.getParameters().entrySet().iterator(); Operation operation = null; Entry<Operation,Parameters> e; Parameters parameters = null; while(itr.hasNext()) { e=itr.next(); if(e.getKey().getName().equalsIgnoreCase(methodName)) { operation = e.getKey(); parameters = e.getValue(); break; } } // no operation found! if(operation == null || parameters == null) { // get array of existing methods Set<Operation> set = bEntry.getParameters().keySet(); Iterator<Operation> it = set.iterator(); Collection.Key[] keys=new Collection.Key[set.size()]; int index=0; while(it.hasNext()) { keys[index++]=KeyImpl.init(it.next().getName()); } throw new RPCException(ExceptionUtil.similarKeyMessage(keys, methodName, "method/operation", "methods/operations",null, true) +" Webservice: " + wsdlUrl); } org.apache.axis.client.Call call = (Call)axisService.createCall(QName.valueOf(port.getName()), QName.valueOf(operation.getName())); if(!StringUtil.isEmpty(username,true)){ call.setUsername(username); call.setPassword(password); } org.apache.axis.encoding.TypeMapping tm=call.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>(); Parameter p = null; for(int j = 0; j < parameters.list.size(); j++) { p = (Parameter)parameters.list.get(j); map(pc,symbolTable,secondChanceConfig,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,symbolTable,secondChanceConfig,tm,parameters.returnParam.getType()); outNames.add(rtnQName.getLocalPart()); outTypes.add(parameters.returnParam); } // get timezone TimeZone tz; if(pc==null)tz=ThreadLocalPageContext.getTimeZone(secondChanceConfig); else tz=ThreadLocalPageContext.getTimeZone(pc); // check arguments Object[] inputs = new Object[inNames.size()]; 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()); } } try{ ret = invoke(call,inputs); } catch(AxisFault af){ boolean rethrow=true; Throwable cause = af.getCause(); if(cause!=null) { /* // first check if that missing type is around String[] notFound=new String[]{"could not find deserializer for type","No deserializer for"}; int index; if(msg!=null)for(int i=0; i<notFound.length;i++) { if((index=msg.indexOf(notFound[i]))==-1)continue;; String raw=msg.substring(index+notFound[i].length()+1).trim(); QName qn = QName.valueOf(raw); print.e(qn.getLocalPart()); print.e(qn.getNamespaceURI()); Type type = symbolTable.getType(qn); if(type!=null) { map(pc,secondChanceConfig,call.getTypeMapping(),type); ret = invoke(call,inputs); rethrow=false; } }*/ // get the missing types from the SOAP Body, if possible String msg = cause.getMessage(); //if(StringUtil.indexOfIgnoreCase(msg, "deserializer")!=-1) { try { InputSource is = new InputSource(new StringReader(call.getResponseMessage().getSOAPPartAsString())); Document doc = XMLUtil.parse(is, null, false); Element body = XMLUtil.getChildWithName("soapenv:Body", doc.getDocumentElement()); Vector types = SOAPUtil.getTypes(body, symbolTable); map(pc,symbolTable,secondChanceConfig,(org.apache.axis.encoding.TypeMapping) (axisService.getTypeMappingRegistry().getDefaultTypeMapping()),types); ret = invoke(call,inputs); rethrow=false; } catch(Throwable t) {ExceptionUtil.rethrowIfNecessary(t);} //} } if(rethrow) throw af; } last=call; if(outNames.size()<=1) return AxisCaster.toLuceeType(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.toLuceeType(null,ret)); } else { sct.setEL(name, AxisCaster.toLuceeType(null,value)); } } return sct; } private Object invoke(Call call, Object[] inputs) throws RemoteException { if(proxyData!=null && !StringUtil.isEmpty(proxyData.getServer(),true)) { try { Proxy.start(proxyData); return call.invoke(inputs); } finally { Proxy.end(); } } return call.invoke(inputs); } private void map(PageContext pc,SymbolTable symbolTable, Config secondChanceConfig,org.apache.axis.encoding.TypeMapping tm, Vector types) throws PageException { Iterator it = types.iterator(); while(it.hasNext()){ map(pc,symbolTable, secondChanceConfig, tm, (TypeEntry)it.next()); } } private Class map(PageContext pc,SymbolTable symbolTable, Config secondChanceConfig,org.apache.axis.encoding.TypeMapping tm, TypeEntry type) throws PageException { //print.e("MAP"); //print.e(type.getQName()); // Simple Type if(type.getContainedElements()==null) return null; // is class already registered! //Class clazz=tm.getClassForQName(type.getQName()); //if(clazz!=null && clazz.getName().equals(getClientClassName(type))) return clazz; Class clazz = mapComplex(pc,symbolTable,secondChanceConfig,tm, type); // TODO make a better impl; this is not the fastest way to make sure all pojos use the same classloader if(clazz!=null && getClassLoader(pc,secondChanceConfig)!=clazz.getClassLoader()){ clazz=mapComplex(pc,symbolTable,secondChanceConfig,tm, type); } return clazz; } private Class mapComplex(PageContext pc,SymbolTable symbolTable,Config secondChanceConfig,org.apache.axis.encoding.TypeMapping tm, TypeEntry type) throws PageException { TypeEntry ref=type.getRefType(); if(ref==null) return _mapComplex(pc,symbolTable,secondChanceConfig, tm, type); // Array if(ref.getContainedElements()==null) return null; Class clazz = mapComplex(pc,symbolTable,secondChanceConfig, 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,SymbolTable symbolTable,Config secondChanceConfig, org.apache.axis.encoding.TypeMapping tm, TypeEntry type) throws PageException { // extension Class ex=null; if(type instanceof DefinedType) { DefinedType dt=(DefinedType) type; TypeEntry exType = dt.getComplexTypeExtensionBase(symbolTable); if(exType!=null)ex=map(pc, symbolTable, secondChanceConfig, tm, exType); } 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(); // again handle children if(els!=null) { clazz=mapComplex(pc,symbolTable,secondChanceConfig, tm, t); } name=lucee.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,props); Class pojo; if(pc==null)pojo = ComponentUtil.getComponentPropertiesClass(secondChanceConfig,clientClassName,props,ex); else pojo = ComponentUtil.getClientComponentPropertiesClass(pc,clientClassName,props,ex); TypeMappingUtil.registerBeanTypeMapping(tm,pojo, type.getQName()); return pojo; } private ClassLoader getClassLoader(PageContext pc, Config secondChanceConfig) { ClassLoader cl=null; try { if(pc==null)cl = secondChanceConfig.getRPCClassLoader(false); else cl = ((PageContextImpl)pc).getRPCClassLoader(false); } catch (IOException e) {} return cl; } private String getClientClassName(TypeEntry type, ASMProperty[] props) { // properties StringBuilder sb=new StringBuilder(); if(props!=null)for(int i=0;i<props.length;i++){ sb.append(props[i].toString()).append(';'); } String className=StringUtil.toJavaClassName(type.getQName().getLocalPart()); String url=urlToClass(wsdlUrl); String ns = type.getQName().getNamespaceURI(); String prefix = Long.toString(HashUtil.create64BitHash(sb.append(url).append(':').append(ns)),Character.MAX_RADIX); char c=prefix.charAt(0); if(c>='0' && c<='9') prefix="a"+prefix; return prefix+"."+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 = lucee.runtime.type.util.ListUtil.toStringArray(lucee.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 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 ["+lucee.runtime.type.util.ListUtil.arrayToList(names,", ")+"]"; return "missing argument with name ["+name+"]"; } } return ""; } /** * returns the WSDL Service for this Object * @return * @return WSDL Service * @throws RPCException * @throws PageException */ public Port getPort() throws RPCException, PageException { return WSUtil.getSoapPort(getWSDLService()); } public javax.wsdl.Service getWSDLService() throws PageException { if(!wsdlExecuted) { try { parser.run(wsdlUrl); wsdlExecuted=true; } catch(Throwable t) { ExceptionUtil.rethrowIfNecessary(t); throw Caster.toPageException(t); } } SymTabEntry symTabEntry = null; Map.Entry entry = null; Vector v = null; Iterator<Map.Entry> it = parser.getSymbolTable().getHashMap().entrySet().iterator(); while(it.hasNext()) { entry = it.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 */ private Object getArgumentData(TypeMapping tm,TimeZone tz, Parameter p, Object arg) throws PageException { //print.e("ArgumentData"); QName paramType = Utils.getXSIType(p); Object res = AxisCaster.toAxisType(tm,tz,p.getType(),paramType,arg); //print.e(res); return res; } @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","#99cccc","#ccffff","#000000"); table.appendRow(1,new SimpleDumpData("webservice"),new SimpleDumpData(wsdlUrl)); table.appendRow(1,new SimpleDumpData("error"),DumpUtil.toDumpData(e, pageContext, maxlevel, dp)); return table; } } private DumpData _toDumpData(PageContext pageContext, int maxlevel, DumpProperties dp) throws PageException { DumpTable functions = new DumpTable("webservice","#99cccc","#ccffff","#000000"); functions.setTitle("Web Service (Axis 1)"); if(dp.getMetainfo())functions.setComment(wsdlUrl); //DumpTable functions = new DumpTable("#ccccff","#cccc00","#000000"); Port port = getPort(); 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(tmpOp.getName(),doc.toString(),(Parameters)bEntry.getParameters().get(tmpOp))); } //box.appendRow(1,new SimpleDumpData(""),functions); return functions; } private DumpData _toHTMLOperation(String title,String doc, Parameters parameters) { DumpTable table = new DumpTable("#99cccc","#ccffff","#000000"); table.setTitle(title); if(doc.length()>0)table.setComment(doc); DumpTable attributes = new DumpTable("#99cccc","#ccffff","#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(toLuceeType(strType))); break; case Parameter.OUT: returns=toLuceeType(strType); break; case Parameter.INOUT: attributes.appendRow(0,new SimpleDumpData(p.getName()),new SimpleDumpData(toLuceeType(strType))); returns=toLuceeType(strType); break; } } Parameter rtn = parameters.returnParam; if(rtn!=null) { QName paramType = org.apache.axis.wsdl.toJava.Utils.getXSIType(rtn); String strType=paramType.getLocalPart(); returns=toLuceeType(strType); } table.appendRow(1,new SimpleDumpData("arguments"),attributes); table.appendRow(1,new SimpleDumpData("return type"),new SimpleDumpData(returns)); return table; } private String toLuceeType(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>(); Port port = null; try { port = getPort(); } 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); } @Override public Call getLastCall() { return last; } @Override public void addHeader(SOAPHeaderElement header) { if(headers==null)headers=new ArrayList<SOAPHeaderElement>(); headers.add(header); } }