[kepler-dev] problem with type name mapping in WebService actor

Edward A. Lee eal at eecs.berkeley.edu
Thu May 24 15:13:56 PDT 2007


Actually, there is a much better solution.
The WebService actor does this:

  if (outPort.getType().toString().equals("arrayType(string)") {... }

Relying on string comparisons is both fragile and inefficient.
It should do this:

  if (outPort.getType().equals(new ArrayType(BaseType.STRING))) {... }

Or even better:

  static private _STRING_ARRAY = new ArrayType(BaseType.STRING);

  if (outPort.getType().equals(_STRING_ARRAY)) { ... }

This will be more efficient and less fragile.

Edward


At 09:57 AM 5/23/2007, Karen L Schuchardt wrote:
>I completely understand the difficulty of maintaining backwards compatibility.
>
>The old syntax was actually {unsignedByte}
>
>I did a quick search of the source code and found a number of bits of code that might be affected by this change.  I chose to search for {string} since it would probably be more commonly used.  
>
>find . -name \*.java -exec grep \{string\} {} \; -print
>                  (token_type_string.equals("{string}"))||
>            (token_type_string.equals("{string}"))||
>./src/org/ecoinformatics/seek/R/RExpression.java
>        if (outPort.getType().toString().equals("{string}")) {
>      else if (portPtr.getType().toString().equals("{string}")) {
>./src/org/sdm/spa/MessageBasedWebService.java
>        if (outPort.getType().toString().equals("{string}")) {
>      else if (portPtr.getType().toString().equals("{string}")) {
>./src/org/sdm/spa/WebService.java
>        if (outPort.getType().toString().equals("{string}")) {
>      else if (portPtr.getType().toString().equals("{string}")) {
>./src/org/sdm/spa/WebServiceStub.java
>        if (outPort.getType().toString().equals("{string}")) {
>      else if (portPtr.getType().toString().equals("{string}")) {
>
>The first of these RExpression already has a extra comparison on arrayType but I think the rest are all somewhat broken.  Maybe they are all due to be replaced like WebService.java?
>
>I've attached a revised WebService.java with all comparisons of {type} replace with a comparison of arrayType{thing}.  I only tested the byte array.  Could you please diff this with your current version and commit it if it looks ok to you?
>
>Karen
>
>
>Edward A. Lee wrote: 
>>
>>Some background here:
>>
>>The reason for the change in syntax for reporting array types
>>is that we now have dependent types for arrays, where the size of the
>>array can be part of the array type.  This is very helpful for our
>>code generation work, but if you consistently stick with unsized
>>arrays, shouldn't be a problem except that the text describing the
>>type has changed...  The syntax for the type of an array of unsigned
>>bytes used to be "[unsignedByte]" but this now specifies an array
>>of length one (the variable "unsignedByte" is actually just 0ub).
>>The new syntax for an array of unspecified size is
>>"arrayType(unsignedByte)".
>>
>>Sorry about that...  We try hard to avoid backward incompatibilities
>>when changing Ptolemy II, but sometimes they are hard to avoid.
>>
>>Edward
>>
>>At 10:27 AM 5/22/2007, Karen L Schuchardt wrote:
>>>Hi,
>>>
>>>I had an old workflow that used the WebService actor.  At one point I
>>>had added support for ports of type unsignedByte[].  The actor is not
>>>working correctly with the latest version of kepler.  I don't know when
>>>it broke as I have not updated in quite a long time.  Digging into the
>>>code a bit, I found that the methods
>>>_setObjectArray and _sendOutput no longer match on the web service types
>>>and quietly fail.
>>>
>>>For example, in _setObjecArray, the line of code
>>>else if (portPtr.getType().toString().equals("{unsignedByte}"))...
>>>
>>>fails to match because the type string is now actually
>>>"arrayType(unsignedByte)"
>>>The analogous error occurs in _sendOutput.
>>>
>>>The type appears to be supplied to the _createPort method and their are
>>>some notes in the vicinity indicating this code was changed:
>>>/* Original code
>>>           String baseTypeStr = _getArrayBaseType(arrTypeNode);
>>>           */
>>>           /* This code updated by Zhiming Zhao*/
>>>              String baseTypeStr =(String)(
>>>(org.apache.axis.wsdl.symbolTable.Parameter)parameters.returnParam).
>>>                                   
>>>getType().getRefType().getQName().getLocalPart()+"[]";
>>>            QName nodeQname= (
>>>(org.apache.axis.wsdl.symbolTable.Parameter)parameters.returnParam).getType().getRefType().getQName();
>>>
>>>              /* End */
>>>
>>>
>>>If I hack the code to also look for the new type name, the web service
>>>actor works for me.  I only have an example using the byte arrays but
>>>presumably all of the array types are affected by this.
>>>
>>>Has anybody else noticed this problem?  I am using java 1.5 and the same
>>>version of the axis client that is shipped with kepler.  I'd be willing
>>>to send fixed code but I'm not sure what the preferred fix would be. 
>>>Let me know if I can be of more help.
>>>
>>>Karen
>>>_______________________________________________
>>>Kepler-dev mailing list
>>><mailto:Kepler-dev at ecoinformatics.org>Kepler-dev at ecoinformatics.org
>>>http://mercury.nceas.ucsb.edu/ecoinformatics/mailman/listinfo/kepler-dev
>>
>>------------
>>Edward A. Lee
>>Chair of EECS and Robert S. Pepper Distinguished Professor
>>231 Cory Hall, UC Berkeley, Berkeley, CA 94720-1770
>>phone: 510-642-0253, fax: 510-642-2845
>><mailto:eal at eecs.Berkeley.EDU>eal at eecs.Berkeley.EDU, http://ptolemy.eecs.berkeley.edu/~eal 
>/** WebService actor is a dynamic web service client for WSDL-based
> * web services.
> *
> * Copyright (c) 2004 The Regents of the University of California.
> * All rights reserved.
> *
> * Permission is hereby granted, without written agreement and without
> * license or royalty fees, to use, copy, modify, and distribute this
> * software and its documentation for any purpose, provided that the
> * above copyright notice and the following two paragraphs appear in
> * all copies of this software.
> *
> * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
> * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
> * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
> * IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY
> * OF SUCH DAMAGE.
> *
> * THE UNIVERSITY OF CALIFORNIA SPECIFIALLY DISCLAIMS ANY WARRANTIES,
> * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
> * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
> * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY
> * OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT,
> * UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
> */
>
>package org.sdm.spa;
>
>import java.util.HashMap;
>import java.util.Iterator;
>import java.util.List;
>import java.util.Map;
>import java.util.Vector;
>
>import javax.wsdl.Binding;
>import javax.wsdl.Operation;
>import javax.wsdl.Port;
>import javax.wsdl.Service;
>import javax.wsdl.extensions.soap.SOAPAddress;
>import javax.xml.namespace.QName;
>import javax.xml.rpc.Call;
>import javax.xml.rpc.ServiceException;
>
>import org.apache.axis.wsdl.gen.Parser;
>import org.apache.axis.wsdl.symbolTable.BindingEntry;
>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.w3c.dom.Node;
>
>import ptolemy.actor.CompositeActor;
>import ptolemy.actor.IOPort;
>import ptolemy.actor.Manager;
>import ptolemy.actor.TypedAtomicActor;
>import ptolemy.actor.TypedIOPort;
>import ptolemy.data.ArrayToken;
>import ptolemy.data.BooleanToken;
>import ptolemy.data.DoubleToken;
>import ptolemy.data.IntToken;
>import ptolemy.data.LongToken;
>import ptolemy.data.StringToken;
>import ptolemy.data.Token;
>import ptolemy.data.expr.Parameter;
>import ptolemy.data.expr.SingletonParameter;
>import ptolemy.data.expr.StringParameter;
>import ptolemy.data.type.ArrayType;
>import ptolemy.data.type.BaseType;
>import ptolemy.data.UnsignedByteToken;
>import ptolemy.gui.GraphicalMessageHandler;
>import ptolemy.kernel.CompositeEntity;
>import ptolemy.kernel.util.Attribute;
>import ptolemy.kernel.util.IllegalActionException;
>import ptolemy.kernel.util.NameDuplicationException;
>import ptolemy.kernel.util.Nameable;
>
>//////////////////////////////////////////////////////////////////////////
>////WebService
>/**
><p>The WebService actor provides the user with
>a plug-in interface to execute any WSDL-defined web service. Given a URL
>for the WSDL of a web service and an operation name that is included in
>the WSDL,  this actor customizes itself to execute this web
>service operation.
></p><p>WSDL is an XML format for describing network services as a set of endpoints
>operating on messages containing either document-oriented or procedure-
>oriented information. The operations and messages are described abstractly,
>and then bound to a concrete network protocol and message format to define
>an endpoint. Related concrete endpoints are combined into abstract endpoints
>(services). WSDL is extensible to allow description of endpoints and their
>messages regardless of what message formats or network protocols are used
>to communicate. More information on WSDL and realted standard can be found
>at: http://www.w3.org/TR/wsdl
></p><p>The user can instantiate the generic web service actor by providing the
>WSDL URL and choosing the desired web service operation. The actor then a
>utomatically specializes itself and adds ports with the inputs and outputs
>as described by the WSDL. The so instantiated actor acts as a proxy for the
>web service being executed and links to the other actors through its ports.
></p><p>The WSDL is parsed to get the input, output and binding information.
>It dynamically generates ports for each input and output of the operation.
>This customization happens at the configuration time of a model.
>When the actor is fired at run time, it gets the binding information and
>creates a call object to run the model. Using this call object, it invokes
>the web service and broadcasts the response to the output ports.
></p><p><i><b>Notices to users:</b></i> <ul>
><li> Please double-click on the actor to start customization.
></li><li> To enter a WSDL URL which is not in the given list of WSDL URLs,
>   click on the "Preferences" button on the configuration interface and
>   change the type of the parameter to "Text". Then you can type in the
>   WSDL you would like to use.
></li><li> After you select the WSDL, "Commit" and double-click on the actor
>   again. This will reconfigure the list of available operations. Please
>   do this everytime you change the WSDL URL.
></li></ul>
></i>
></p>
>@author Ilkay Altintas, Updates by: Karen L. Schuchardt, Updated by Zhiming Zhao
>@version $Id: WebService.java,v 1.53 2007/02/01 20:18:02 berkley Exp $
>*/
>
>public class WebService
>    extends TypedAtomicActor {
>
>  /** Construct a WebService actor with the given container and name.
>   *  @param container The container.
>   *  @param name The name of this actor.
>   *  @exception IllegalActionException If the actor cannot be contained
>   *   by the proposed container.
>   *  @exception NameDuplicationException If the container already has an
>   *   actor with this name.
>   */
>  public WebService(CompositeEntity container, String name) throws
>      NameDuplicationException, IllegalActionException {
>
>    super(container, name);
>
>    wsdlUrl = new StringParameter(this, "wsdlUrl");
>    //    wsdlUrl.setExpression("http://xml.nig.ac.jp/wsdl/DDBJ.wsdl");
>    methodName = new StringParameter(this, "methodName");
>    userName = new StringParameter(this, "userName");
>    password = new StringParameter(this, "password");
>    timeout = new StringParameter(this, "timeout");
>    timeout.setExpression(""+600000);
>
>    startTrigger = new TypedIOPort(this, "startTrigger", true, false);
>    //new Attribute(startTrigger, "_showName");
>    //startTrigger.setContainer(null);
>      hide = new SingletonParameter(startTrigger, "_hide");
>      hide.setToken(BooleanToken.TRUE);
>    // Set the trigger Flag.
>    hasTrigger = new Parameter(this, "hasTrigger", new BooleanToken(false));
>    hasTrigger.setTypeEquals(BaseType.BOOLEAN);
>
>    clientExecErrors = new TypedIOPort(this, "clientExecErrors", false, true);
>    clientExecErrors.setTypeEquals(BaseType.STRING);
>
>    _attachText("_iconDescription",
>                "<svg>\n"
>                + "<rect x=\"0\" y=\"0\" "
>                + "width=\"60\" height=\"30\" "
>                + "style=\"fill:white\"/>\n"
>                + "</svg>\n");
>  }
>
>  ///////////////////////////////////////////////////////////////////
>  ////                     ports and parameters                  ////
>
>  /**
>   * The parameter for the URL of the web service WSDL.
>   */
>  public StringParameter wsdlUrl;
>  /**
>   * The parameter for the method name.
>   */
>  public StringParameter methodName;
>  /**
>   * The userName to invoke the web service if necessary.
>   */
>  public StringParameter userName;
>  /**
>   * The password to invoke the web service if necessary.
>   */
>  public StringParameter password;
>  /**
>   * The timeout duration in web service call.
>   */
>  public StringParameter timeout;
>  /**
>   * This is an parameter to activate the optional
>   *  startTrigger port. Please activate it <i>ONLY</i> when the actor
>   *  has no input and it is required for scheduling of the actor.
>   */
>  public Parameter hasTrigger;
>  /**
>   * This is an optional input port that can be used to
>   * help the scheduling of the actor.
>   *
>   * <p>This port is activated by the hasTrigger parameter. Double-click on
>   * the actor to enable. Please enable it <i>ONLY</i> when the actor has
>   * no input and it is required for scheduling of the actor.</p>
>   */
>  public TypedIOPort startTrigger;
>  /**
>   * It outputs the errors if any occured when actor is
>   *    executing. It outputs "NO ERRORS." if there are no exceptional cases.
>   *
>   */
>  public TypedIOPort clientExecErrors;
>
>  public SingletonParameter hide;
>  
>  ///////////////////////////////////////////////////////////////////
>  ////                        public methods                     ////
>
>  /** Callback for changes in attribute values
>   *  Get the WSDL from the given URL.
>   *
>   *  @param at The attribute that changed.
>   *  @exception IllegalActionException
>   */
>  public void attributeChanged(Attribute at) throws IllegalActionException {
>    if (at == hasTrigger) {
>      _triggerFlag = ( (BooleanToken) hasTrigger.getToken()).booleanValue();
>      _debug("<TRIGGER_FLAG>" + _triggerFlag + "</TRIGGER_FLAG>");
>      if (_triggerFlag) {
>        try {
>          //startTrigger.setContainer(this);
>          hide.setToken(BooleanToken.FALSE);
>        } catch (Exception ex) {
>          _debug("111: " + ex.getMessage());
>          GraphicalMessageHandler.message(this.getFullName() +
>          ": Could not create the trigger port--'" + ex.getMessage() + "'.");
>        }
>      }
>      else {
>        List inPortList = this.inputPortList();
>        Iterator ports = inPortList.iterator();
>        while (ports.hasNext()) {
>          IOPort p = (IOPort) ports.next();
>          if (p.isInput()) {
>            try {
>              if (p.getName().equals("startTrigger")) {
>                //p.setContainer(null);
>        hide.setToken(BooleanToken.TRUE);
>              }
>            }
>            catch (Exception e) {
>              GraphicalMessageHandler.message(this.getFullName() +
>                ": Could not delete the trigger port--'" + e.getMessage() + "'.");
>            }
>          }
>        }
>      }
>    }
>    else if (at == wsdlUrl) {
>
>      List inPortList = this.inputPortList();
>      int numInPorts = inPortList.size();
>      List outPortList = this.outputPortList();
>      int numOutPorts = outPortList.size();
>
>      if (wsdlUrl.getExpression().equals("")) {
>        //System.out.println("WSD url is empty string");
>        //do nothing
>      }
>      else if ((_urlStr.equals("")) &&
>               (methodName.getExpression().equals("")) &&
>               (numInPorts == 0) && (numOutPorts == 0))
>      {
>        //System.out.println("WSDL url before getExpression: " + _urlStr);
>        _urlStr = wsdlUrl.getExpression();
>        //System.out.println("Method name before removeAllChoice: " + _methodNameStr);
>        methodName.removeAllChoices();
>        //System.out.println("Method name after removeAllChoice: " + _methodNameStr);
>        //System.out.println("WSDL url after getExpression: " + _urlStr);
>        _wsdlParser = new Parser();
>        _confErrorStr = "";
>        //Parse the wsdl for the web service.
>        try {
>          _wsdlParser.run(_urlStr);
>          configureOperationNames();
>        }
>        catch (Exception ex) {
>          _debug("<EXCEPTION> There was an error while parsing the WSDL. "
>                 + ex + ". </EXCEPTION>");
>          _confErrorStr += "\n" + this.getFullName() +
>                ": Could not parse WSDL--'" + ex.getMessage() + "'.";//);
>        }
>        if (!(_confErrorStr.equals(""))) {
>             GraphicalMessageHandler.message(_confErrorStr);
>        }
>      }
>      else if ((_urlStr.equals("")) &&
>               (!(methodName.getExpression().equals(""))) &&
>               ((numInPorts != 0) && (numOutPorts != 0))) //The actor has at least one port
>      {
>        //System.out.println("WSDL url before getExpression: " + _urlStr);
>        _urlStr = wsdlUrl.getExpression();
>        //System.out.println("Method name before removeAllChoice: " + _methodNameStr);
>        //System.out.println("Method name after removeAllChoice: " + _methodNameStr);
>        //System.out.println("WSDL url after getExpression: " + _urlStr);
>      }
>      else if (! (this._urlStr.equals(wsdlUrl.getExpression()))) { // If the value has really changed.
>        _confErrorStr = "";
>        //System.out.println("WSDL url before getExpression: " + _urlStr);
>        _urlStr = wsdlUrl.getExpression();
>        //System.out.println("Method name before removeAllChoice: " + _methodNameStr);
>        methodName.removeAllChoices();
>        //System.out.println("Method name after removeAllChoice: " + _methodNameStr);
>        //System.out.println("WSDL url after getExpression: " + _urlStr);
>        deletePorts();
>        _wsdlParser = new Parser();
>        //Parse the wsdl for the web service.
>        try {
>          _wsdlParser.run(_urlStr);
>          configureOperationNames();
>        }
>        catch (Exception ex) {
>          _debug("<EXCEPTION> There was an error while parsing the WSDL. "
>                 + ex + ". </EXCEPTION>");
>          //GraphicalMessageHandler.message(
>          _confErrorStr += "\n" + ex.getMessage()
>                 + "There was an error while parsing the WSDL in the actor: "
>                 + this.getName();//);
>        }
>      }
>      else {
>        _debug("The " + _urlStr + " was the same. Ports left unchanged.");
>      }
>      if (!(_confErrorStr.equals(""))) {
>        GraphicalMessageHandler.message(_confErrorStr);
>      }
>    }
>    else if (at == methodName) {
>
>      List inPortList = this.inputPortList();
>      int numInPorts = inPortList.size();
>      List outPortList = this.outputPortList();
>      int numOutPorts = outPortList.size();
>
>      if (methodName.getExpression().equals("")) {
>      //System.out.println("Method name is empty string.");
>       //do nothing
>     }
>     else if ((_methodNameStr.equals("")) && (numInPorts == 0) && (numOutPorts == 1))
>     {
>
>       _confErrorStr = "";
>       //System.out.println("Method name before get expression: " + _methodNameStr);
>       _methodNameStr = methodName.getExpression();
>       _debug("<METHOD_NAME>" + _methodNameStr + "</METHOD_NAME>");
>       //System.out.println("Method name after get expression: " + _methodNameStr);
>       int slashIndex = _urlStr.lastIndexOf('/');
>       _wsName = _urlStr.substring(slashIndex + 1, _urlStr.length() - 5);
>
>       _attachText("_iconDescription",
>                   "<svg>\n"
>                   + "<rect x=\"0\" y=\"0\" "
>                   + "width=\"160\" height=\"50\" "
>                   + "style=\"fill:white\"/>\n"
>                   + "<text x=\"20\" y=\"25\" "
>                   +
>                   "style=\"font-size:11; fill:red; font-family:SansSerif\">"
>                   + _wsName + "_" + _methodNameStr + "</text>\n"
>                   + "</svg>\n");
>       configureActor();
>       if (!(_confErrorStr.equals(""))) {
>        GraphicalMessageHandler.message(_confErrorStr);
>       }
>     }
>     else if ((_methodNameStr.equals("")) && ((numInPorts != 0) && (numOutPorts > 1))) //The actor has at least one port
>     {
>
>       //System.out.println("Method name before get expression: " + _methodNameStr);
>       _methodNameStr = methodName.getExpression();
>       _debug("<METHOD_NAME>" + _methodNameStr + "</METHOD_NAME>");
>       //System.out.println("Method name after get expression: " + _methodNameStr);
>       int slashIndex = _urlStr.lastIndexOf('/');
>       _wsName = _urlStr.substring(slashIndex + 1, _urlStr.length() - 5);
>       _attachText("_iconDescription",
>                   "<svg>\n"
>                   + "<rect x=\"0\" y=\"0\" "
>                   + "width=\"160\" height=\"50\" "
>                   + "style=\"fill:white\"/>\n"
>                   + "<text x=\"20\" y=\"25\" "
>                   +
>                   "style=\"font-size:11; fill:red; font-family:SansSerif\">"
>                   + _wsName + "_" + _methodNameStr + "</text>\n"
>                   + "</svg>\n");
>     }
>     else if (! (this._methodNameStr.equals(methodName.getExpression()))) { // if the methodName really changed.
>
>        _confErrorStr = "";
>        //System.out.println("Method name before get expression: " + _methodNameStr);
>        _methodNameStr = methodName.getExpression();
>        _debug("<METHOD_NAME>" + _methodNameStr + "</METHOD_NAME>");
>        //System.out.println("Method name after get expression: " + _methodNameStr);
>        int slashIndex = _urlStr.lastIndexOf('/');
>        _wsName = _urlStr.substring(slashIndex + 1, _urlStr.length() - 5);
>
>        _attachText("_iconDescription",
>                    "<svg>\n"
>                    + "<rect x=\"0\" y=\"0\" "
>                    + "width=\"160\" height=\"50\" "
>                    + "style=\"fill:white\"/>\n"
>                    + "<text x=\"20\" y=\"25\" "
>                    +
>                    "style=\"font-size:11; fill:red; font-family:SansSerif\">"
>                    + _wsName + "_" + _methodNameStr + "</text>\n"
>                    + "</svg>\n");
>
>        // Delete all the ports the actor has when the method name changes.
>        deletePorts();
>        configureActor();
>        if (!(_confErrorStr.equals(""))) {
>          GraphicalMessageHandler.message(_confErrorStr);
>        }
>      }
>      else {
>
>        _debug("The " + _methodNameStr + " was the same. " +
>               "Ports left unchanged.");
>      }
>    }
>  } // end of attributeChanged
>
>  /** Configure the actor for the entered operation of the given web service. */
>  public void configureOperationNames() {
>    try {
>      _service = null;
>
>      // Find the entry for the ServiceEntry class in the symbol table.
>      HashMap map = _wsdlParser.getSymbolTable().getHashMap();
>      Iterator entrySetIter = map.entrySet().iterator();
>      while (entrySetIter.hasNext()) {
>        Map.Entry currentEntry = (Map.Entry) entrySetIter.next();
>        Vector valueVector = (Vector) currentEntry.getValue();
>        int vecSize = valueVector.size();
>        for (int index = 0; index < vecSize; ++index) {
>          SymTabEntry symTabEntryObj = (SymTabEntry) valueVector.get(index);
>          if ( (ServiceEntry.class).isInstance(symTabEntryObj)) {
>            _service = ( (ServiceEntry) symTabEntryObj).getService();
>          }
>        }
>      }
>
>      Port port = _getSOAPAddress(_service.getPorts());
>      if (port == null) {
>        _debug("<ERROR> No port was returned by the _getSOAPAddress. </ERROR>");
>
>      }
>      _portName = "";
>      _portName = port.getName();
>      _binding = port.getBinding();
>      SymbolTable symbolTable = _wsdlParser.getSymbolTable();
>      BindingEntry bEntry = symbolTable.getBindingEntry(_binding.getQName());
>
>      Operation operation = null;
>      Parameters parameters = null;
>      Iterator iter = bEntry.getParameters().keySet().iterator();
>      for (; iter.hasNext(); ) {
>        Operation oper = (Operation) iter.next();
>        methodName.addChoice(oper.getName());
>      }
>    }
>    catch (Exception ex) {
>      _debug("<EXCEPTION> There was an error when configuring the actor: " + ex +
>             ". </EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      _confErrorStr += "\n" +this.getFullName() +
>      ": Could not configure actor--'" + ex.getMessage() + "'.";//);
>    }
>  } // end-of-configureOperationNames
>
>      /** Configure the actor for the entered operation of the given web service. */
>  public void configureActor() {
>    try {
>      _service = null;
>
>      // Find the entry for the ServiceEntry class in the symbol table.
>      HashMap map = _wsdlParser.getSymbolTable().getHashMap();
>      Iterator entrySetIter = map.entrySet().iterator();
>      while (entrySetIter.hasNext()) {
>        Map.Entry currentEntry = (Map.Entry) entrySetIter.next();
>        Vector valueVector = (Vector) currentEntry.getValue();
>        int vecSize = valueVector.size();
>        for (int index = 0; index < vecSize; ++index) {
>          SymTabEntry symTabEntryObj = (SymTabEntry) valueVector.get(index);
>          if ( (ServiceEntry.class).isInstance(symTabEntryObj)) {
>            _service = ( (ServiceEntry) symTabEntryObj).getService();
>          }
>        }
>      }
>
>      Port port = _getSOAPAddress(_service.getPorts());
>      if (port == null) {
>        _debug("<ERROR> No port was returned by the _getSOAPAddress. </ERROR>");
>      }
>      _portName = "";
>      _portName = port.getName();
>      _binding = port.getBinding();
>      SymbolTable symbolTable = _wsdlParser.getSymbolTable();
>      BindingEntry bEntry = symbolTable.getBindingEntry(_binding.getQName());
>
>      Operation operation = null;
>      Parameters parameters = null;
>      Iterator iter = bEntry.getParameters().keySet().iterator();
>      for (; iter.hasNext(); ) {
>        Operation oper = (Operation) iter.next();
>        if (oper.getName().equals(_methodNameStr)) {
>          operation = oper;
>          parameters = (Parameters) bEntry.getParameters().get(oper);
>          createPorts(parameters);
>
>          // Set output type
>          if (parameters.returnParam == null) {
>            _returnMode = 1; //Get outputs into a map object!
>          }
>          else if (parameters.returnParam != null) {
>            _returnMode = 2; //Get the invoke result value as a single value.
>            // Get the QName for the return Type
>            QName returnQName = parameters.returnParam.getQName();
>            if ( ( (org.apache.axis.wsdl.symbolTable.Parameter)
>                  parameters.returnParam).getType().getDimensions().equals("[]")) {
>              Node arrTypeNode = ( (org.apache.axis.wsdl.symbolTable.Parameter)
>                                  parameters.returnParam).getType().getNode();
>              
>                          /* Original code
>                          String baseTypeStr = _getArrayBaseType(arrTypeNode);
>                          */
>                          /* This code updated by Zhiming Zhao*/
>              String baseTypeStr =(String)( (org.apache.axis.wsdl.symbolTable.Parameter)parameters.returnParam).
>                                    getType().getRefType().getQName().getLocalPart()+"[]";
>            QName nodeQname= ( (org.apache.axis.wsdl.symbolTable.Parameter)parameters.returnParam).getType().getRefType().getQName();
>
>              /* End */
>
>              _debug("ARRAY PARAM BASE TYPE: " + baseTypeStr);
>
>              _createPort( (
>                  (org.apache.axis.wsdl.symbolTable.Parameter)
>                  parameters.returnParam).getMode(), baseTypeStr,
>                          (String) returnQName.getLocalPart());
>            }
>            else {
>              _createPort( ( (org.apache.axis.wsdl.symbolTable.Parameter)
>                            parameters.returnParam).getMode(),
>                          ( (org.apache.axis.wsdl.symbolTable.Parameter)
>                           parameters.returnParam).getType().getQName().
>                          getLocalPart(),
>                          (String) returnQName.getLocalPart());
>            }
>            _debug("<RETURN_QNAME>" + returnQName.getLocalPart() +
>                   "</RETURN_QNAME>");
>          }
>          // Break out of the loop
>          break;
>        }
>      }
>    }
>    catch (Exception ex) {
>      _debug("<EXCEPTION> There was an error when configuring the actor: " + ex +
>             ". </EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      _confErrorStr += "\n" + ex.getMessage()
>             + "There was an error when configuring the actor:" + this.getName();//);
>    }
>  } // end-of-configureActor
>
>  /**
>   * Query the base type of the array type specified in the given dom node.
>   * @param arrayTypeNode
>   * @return
>   */
>  private String _getArrayBaseType(Node arrayTypeNode) {
>    _debug("TYPE NAME: " + arrayTypeNode.getAttributes().getNamedItem("name"));
>    String baseTStr = arrayTypeNode.getFirstChild().getFirstChild().
>        getFirstChild().getAttributes().getNamedItem("wsdl:arrayType").
>        getNodeValue();
>    String[] result = baseTStr.split(":");
>    baseTStr = result[1];
>    return baseTStr;
>  } //end-of-getArrayBaseType
>
>  /** Creates ports for the web service operation */
>
>  public void createPorts(Parameters params) {
>    try {
>      // Create ports using the input and output part descriptions
>      for (int j = 0; j < params.list.size(); j++) {
>        org.apache.axis.wsdl.symbolTable.Parameter param =
>            (org.apache.axis.wsdl.symbolTable.Parameter)
>            params.list.get(j);
>        _debug("PARAM DIMENSION: " + param.getType().getDimensions());
>        _debug("PARAM TYPE: " + param.getType().getQName().getLocalPart());
>        if (param.getType().getDimensions().equals("[]")) {
>
>          Node arrTypeNode = param.getType().getNode();
>          _debug("TYPE NAME: " +
>                 arrTypeNode.getAttributes().getNamedItem("name"));
>          /*
>          String baseTypeStr = arrTypeNode.getFirstChild().getFirstChild().
>              getFirstChild().getAttributes().getNamedItem("wsdl:arrayType").
>              getNodeValue();
>          String[] result = baseTypeStr.split(":");
>          baseTypeStr = result[1];
>                  */
>                  /* Updated by Zhiming */
>          String baseTypeStr=param.getType().getRefType().getQName().getLocalPart()+"[]";
>                  /* Updated by Zhiming End */
>
>          _debug("ARRAY PARAM BASE TYPE: " + baseTypeStr);
>          _createPort(param.getMode(), baseTypeStr,
>                      (String) param.getQName().getLocalPart());
>        }
>        else { // if (param.getType().getDimension() != null) {
>          _createPort(param.getMode(), param.getType().getQName().getLocalPart(),
>                      (String) param.getQName().getLocalPart());
>        }
>      }
>    }
>    catch (Exception ex) {
>      _debug("<EXCEPTION> There was an error when creating the TypedIOPorts: "
>             + ex + "</EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      _errorsStr += "\n" + this.getFullName() +
>        ": Could not create ports--'" + ex.getMessage() + "'.";//);
>    }
>  }
>
>  private void _createPort(int mode, String portTypeStr, String portNameStr) {
>    try {
>      if (mode == 1) { // input
>        TypedIOPort pin = new TypedIOPort(this, portNameStr, true, false);
>        new Attribute(pin, "_showName");
>        _setPortType(pin, portTypeStr);
>        _debug("<INPUT>" + portNameStr + "</INPUT>");
>      }
>      else if (mode == 2) { // output
>        TypedIOPort pout = new TypedIOPort(this, portNameStr, false, true);
>        new Attribute(pout, "_showName");
>        _setPortType(pout, portTypeStr);
>        _debug("<OUTPUT>" + portNameStr + "</OUTPUT>");
>      }
>      else if (mode == 3) { // input/output
>        TypedIOPort pin = new TypedIOPort(this, portNameStr, true, false);
>        new Attribute(pin, "_showName");
>        _setPortType(pin, portTypeStr);
>        _debug("<INPUT>" + portNameStr + "</INPUT>");
>        TypedIOPort pout = new TypedIOPort(this, portNameStr, false, true);
>        new Attribute(pout , "_showName");
>        _setPortType(pout, portTypeStr);
>        _debug("<OUTPUT>" + portNameStr + "</OUTPUT>");
>      }
>    }
>    catch (ptolemy.kernel.util.IllegalActionException iae) {
>      _debug(
>          "<EXCEPTION> There was an IllegalActionException when creating the TypedIOPorts in _createPort: "
>          + iae + "</EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      _errorsStr += "\n" + iae.getMessage()
>          + "There was an error when creating the TypedIOPorts in actor: "
>          + this.getName();//);
>    }
>    catch (ptolemy.kernel.util.NameDuplicationException nde) {
>      //GraphicalMessageHandler.message(
>          _errorsStr += "\n" + nde.getMessage()
>          + "\nThere was a NameDuplicationException when creating the "
>          + "TypedIOPorts in the actor: " + this.getName();// );
>      _debug(
>          "<EXCEPTION> There was a NameDuplicationException when creating the TypedIOPorts in _createPort: "
>          + nde + "</EXCEPTION>");
>    }
>  } //end-of-createPort
>
>  /** Deletes all the ports of this actor. */
>  public void deletePorts() {
>    List inPortList = this.inputPortList();
>    Iterator ports = inPortList.iterator();
>    while (ports.hasNext()) {
>      IOPort p = (IOPort) ports.next();
>      if (p.isInput()) {
>        try {
>          if (!(p.getName().equals("startTrigger"))){
>            p.setContainer(null);
>          }
>        }
>        catch (Exception e) {
>          //GraphicalMessageHandler.message(
>              _confErrorStr += "\n" + e.getMessage()
>                + "Could not delete the input port: "
>                + p.getName() + " in the actor: "
>                + this.getName();//);
>        }
>      }
>    }
>
>    List outPortList = this.outputPortList();
>    int numOutPorts = outPortList.size();
>    Iterator oports = outPortList.iterator();
>    while (oports.hasNext()) {
>      IOPort outp = (IOPort) oports.next();
>      if (outp.isOutput()) {
>        try {
>                if (!(outp.getName().equals("clientExecErrors"))){
>                outp.setContainer(null);
>                }
>        }
>        catch (Exception e) {
>          //GraphicalMessageHandler.message(
>              _confErrorStr += "\n" + e.getMessage()
>              + "Could not delete the output port:"
>              + outp.getName() + " in the actor: "
>              + this.getName();//);
>        }
>      }
>    }
>  } // end of deletePorts
>
>  /** Get the URL address of the the location of the web service defined by
>   *  the given WSDL. Get the the namespace and binding information of the
>   *  web service using the given WSDL and methodName. Add a parameter to the
>   *  call object for each input part.Fill these parameters with the input
>   *  values on channels on the ports that correspond to them.
>   *  Invoke the web service using all the gathered information.
>   *  Send the response of the call to the result port.
>   *
>   *  @exception IllegalActionException If there is no director.
>   */
>  public void fire() throws IllegalActionException {
>
>    super.fire();
>
>    // triggerring the actor..
>      if (startTrigger.getWidth() > 0) {
>        for (int i=0; i<startTrigger.getWidth(); i++)
>            startTrigger.get(i);
>      }
>
>      _urlStr = wsdlUrl.getExpression();
>      _methodNameStr = methodName.getExpression();
>
>      _wsdlParser = new Parser();
>
>      try {
>        _wsdlParser.run(new String(_urlStr));
>      }
>      catch (Exception ex) {
>        _debug("<EXCEPTION> There was an error while parsing the WSDL in fire for URL: "
>               + _urlStr + " .\n" + ex + ". </EXCEPTION>");
>        //GraphicalMessageHandler.message(
>            _errorsStr += "\n" + ex.getMessage()
>           +"Error in fire: There was an error while parsing the WSDL in the actor: "
>           + this.getName();//);
>
>    /* The following exception is thrown and for the case when the
>    web service's server is down. The director SDF4WS catches the
>    exception thrown below and re-tries to get web service access.After
>    three re-trials the director finally switches over to the same service
>    but at a different server (if second server is available)*/
>
>    GraphicalMessageHandler.message("\nWebService WSDL:" + _urlStr + " Not Responding");
>    throw new IllegalActionException("\nWebService WSDL Not Responding.");
>
>
>      }
>      getServiceBinding();
>      try {
>        SymbolTable symbolTable = _wsdlParser.getSymbolTable();
>        BindingEntry bEntry = symbolTable.getBindingEntry(_binding.getQName());
>        Operation operation = null;
>        Parameters parameters = null;
>        Iterator iter = bEntry.getParameters().keySet().iterator();
>        for (; iter.hasNext(); ) {
>          Operation oper = (Operation) iter.next();
>          if (oper.getName().equals(_methodNameStr)) {
>            operation = oper;
>            parameters = (Parameters) bEntry.getParameters().get(oper);
>            // Set output type
>            if (parameters.returnParam == null) {
>              _returnMode = 1; //Get outputs into a map object!
>            }
>            else if (parameters.returnParam != null) {
>              _returnMode = 2; //Get the invoke result value as a single value.
>            }
>            // Break out of the loop
>            break;
>          }
>        }
>      }
>      catch (Exception ex) {
>        _debug("<EXCEPTION>In fire when setting the return mode: " + ex +
>               ". </EXCEPTION>");
>        //GraphicalMessageHandler.message(
>        _errorsStr += "\n" + ex.getMessage()
>                + "There was an error when setting up the return mode of the web "
>             + "service at: " + this.getName();//);
>      }
>
>    try {
>      org.apache.axis.client.Service myServiceClient =
>          new org.apache.axis.client.Service(_wsdlParser, _service.getQName());
>      _call = myServiceClient.createCall(QName.valueOf(_portName),
>                                         QName.valueOf(_methodNameStr));
>      _debug (_call.getClass().getName() + "Call implementation");
>
>      //KLS((org.apache.axis.client.Call) _call).setTimeout(new Integer(600000));
>      ((org.apache.axis.client.Call) _call).setTimeout(new Integer(timeout.stringValue()));
>
>      // Add a parameter to the call object for each input part.
>      List inPortList = this.inputPortList();
>      int numInPorts = inPortList.size();
>      //_debug("<TRIGGER_FLAG_BEFORE_OBJECT_ARR>" + _triggerFlag + "</TRIGGER_FLAG_BEFORE_OBJECT_ARR>");
>      //if (_triggerFlag) {
>      _objArr = new Object[numInPorts - 1];
>      //}
>      //else {
>      //  _objArr = new Object[numInPorts];
>      //}
>      Iterator ports = inPortList.iterator();
>      int i = 0;
>      while (ports.hasNext()) {
>        // Fill these parameters with the input values on channels on the
>        // ports that correspond to them.
>        TypedIOPort p = (TypedIOPort) ports.next();
>        _debug("<INPUT_PORT>" + p.getName() + "</INPUT_PORT>");
>        if (p.getName().equals("startTrigger")) {
>          _debug("Skipped the value of the trigger port in fire.");
>        }
>        else if (p.hasToken(0)) {
>          _setObjectArray(p, i);
>          i++;
>        }
>      }
>      for (int j = 0; j < i; j++) {
>        _debug("_objArr[" + j + "]=" + _objArr[j]);
>      }
>
>      _debug("<OBJ_ARR_LENGTH> " + (new Integer(_objArr.length)).toString() + " </OBJ_ARR_LENGTH>");
>      _debug("<USERNAME> " + userName.stringValue() + " </USERNAME>");
>      _call.setProperty(Call.USERNAME_PROPERTY, userName.stringValue());
>      _debug("<PASSWORD> " + password.stringValue() + " </PASSWORD>");
>      _call.setProperty(Call.PASSWORD_PROPERTY, password.stringValue());
>
>      _debug("Starting the invoke!");
>      //Element invokeResult = (Element) call.invoke(objArr);
>      Object invokeResult = _call.invoke(_objArr);
>      _debug("Got results from the invoke...");
>      List outPortList = this.outputPortList();
>      Iterator oports = outPortList.iterator();
>      _debug("<RETURN_MODE> " + new Integer(_returnMode).toString() +
>             " </RETURN_MODE>");
>      if (_returnMode == 2) {
>        while (oports.hasNext()) {
>            TypedIOPort po = (TypedIOPort) oports.next();
>            if (!(po.getName().equals("clientExecErrors"))){
>              _sendOutput(po, invokeResult);
>            }
>        }
>      }
>      else if (_returnMode == 1) {
>        Map outParams = _call.getOutputParams();
>        while (oports.hasNext()) {
>          // Fill these parameters with the input values on
>          // channels on the ports that correspond to them.
>          TypedIOPort po = (TypedIOPort) oports.next();
>          _debug("<OUTPUT_PORT>" + po.getName() + ", " +
>                 po.getType().toString() + "</OUTPUT_PORT>");
>          try {
>            if (!(po.getName().equals("clientExecErrors"))){
>              _sendOutput(po, outParams.get(new QName("", po.getName())));
>            }
>          }
>          catch (Exception ex) {
>            _debug(
>                "<EXCEPTION> There was an exception when sending the outputs."
>                + " OutValue: " +
>                (String) org.apache.axis.utils.JavaUtils.convert(
>                outParams.get(new QName("", po.getName())), java.lang.String.class)
>                + ". </EXCEPTION>");
>            //GraphicalMessageHandler.message(
>            _errorsStr += "\n" + ex.getMessage()
>                + "\nThe error occured in the actor: " + this.getName()
>                + "\n Please look at the debugging details for this actor for "
>                + "more information.";//);
>          }
>        }
>      }
>    }
>    catch (ServiceException se) {
>      _debug("<EXCEPTION> Service exception in fire() method: "
>             + se.getMessage() + ". </EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      _errorsStr += "\n" + se.getMessage()
>             + "\nThe service exception error occured in the actor: "
>             + this.getName();//);
>    }
>    catch (java.rmi.RemoteException rex) {
>      _debug("<EXCEPTION> Remote exception in fire() method: "
>             + rex.getMessage() + ". </EXCEPTION>");
>           //get rmi.getCause() and print it here.
>      //GraphicalMessageHandler.message(
>      _errorsStr += "\n" + rex.getMessage()
>              + "\nThe remote exception error occured in the actor: "
>              + this.getName();//);
>
>      //FIX ME: Don't stop the model here but pause and let the user refine it!
>/*
>      // NOTE: We need to consume data on all channels that have data.
>      // If we don't then DE will go into an infinite loop.
>      for (int i = 0; i < input.getWidth(); i++) {
>          if (input.hasToken(i)) {
>              if (((BooleanToken)input.get(i)).booleanValue()) {
>                  result = true;
>              }
>          }
>      }*/
>          Nameable container = getContainer();
>          if (container instanceof CompositeActor) {
>              Manager manager = ((CompositeActor)container).getManager();
>              if (manager != null) {
>                  manager.finish();
>              } else {
>                  throw new IllegalActionException(this,
>                          "Cannot stop without a Manager.");
>              }
>          } else {
>              throw new IllegalActionException(this,
>                      "Cannot stop without a container that is a CompositeActor.");
>          }
>    }
>
>    System.out.println(_errorsStr);
>    if (!(_errorsStr.equals(""))) {
>          clientExecErrors.broadcast(new StringToken(_errorsStr));
>    } else {
>      clientExecErrors.broadcast(new StringToken("NO ERRORS."));
>    }
>  } // end of fire
>
>  /** Configure the service, port and binding info. */
>  public void getServiceBinding() {
>    try {
>      _service = null;
>
>      // Find the entry for the ServiceEntry class in the symbol table.
>      HashMap map = _wsdlParser.getSymbolTable().getHashMap();
>      Iterator entrySetIter = map.entrySet().iterator();
>      while (entrySetIter.hasNext()) {
>        Map.Entry currentEntry = (Map.Entry) entrySetIter.next();
>        Vector valueVector = (Vector) currentEntry.getValue();
>        int vecSize = valueVector.size();
>        for (int index = 0; index < vecSize; ++index) {
>          SymTabEntry symTabEntryObj = (SymTabEntry) valueVector.get(index);
>          if ( (ServiceEntry.class).isInstance(symTabEntryObj)) {
>            _service = ( (ServiceEntry) symTabEntryObj).getService();
>          }
>        }
>      }
>
>      Port port = _getSOAPAddress(_service.getPorts());
>      if (port == null) {
>        _debug("<ERROR> No port was returned by the _getSOAPAddress. </ERROR>");
>      }
>      _portName = "";
>      _portName = port.getName();
>      _binding = port.getBinding();
>    }
>    catch (Exception ex) {
>      _debug("<EXCEPTION> There was an error when configuring the actor: " + ex +
>             ". </EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      _errorsStr += "\n" + ex.getMessage()
>        +"There was an error when configuring the actor:" + this.getName();//);
>    }
>  } // end-of-getServiceBinding
>
>
>  /** Pre fire the actor.
>   *  Calls the super class's prefire in case something is set there.
>   */
>  public boolean prefire() throws IllegalActionException {
>    return super.prefire();
>  } // end of prefire
>
>  //////////////////////////////////////////////////////////////////////
>  ////                         private methods                      ////
>
>  /**
>   * Returns a port with a SOAPAddress extensibility element.
>   */
>  private Port _getSOAPAddress(Map ports) {
>    Iterator nameIter = ports.keySet().iterator();
>    while (nameIter.hasNext()) {
>      String portName = (String) nameIter.next();
>      Port port = (Port) ports.get(portName);
>      List extElemList = port.getExtensibilityElements();
>      for (int i = 0; (extElemList != null) && (i < extElemList.size()); i++) {
>        Object extEl = extElemList.get(i);
>        if (extEl instanceof SOAPAddress) {
>          return port;
>        }
>      }
>    }
>    return null;
>  } //end-of-getSOAPAddress
>
>  /** _sendOutput
>   * Send the output ports from the given port with the right type casting.
>   * @param outPort
>   * @param res
>   */
>  private void _sendOutput(TypedIOPort outPort, Object res) {
>    _debug("<RES_CLASS_NAME>" + res.getClass().getName() + "</RES_CLASS_NAME>");
>    try {
>      if (res instanceof String) {
>        if (outPort.getType().toString().equals("string")) {
>          outPort.broadcast(new StringToken( (String) res));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(String) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof Integer) {
>        if (outPort.getType().toString().equals("int")) {
>          outPort.broadcast(new IntToken( ( (Integer) res).intValue()));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(Integer) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof Double) {
>        if (outPort.getType().toString().equals("double")) {
>          outPort.broadcast(new DoubleToken( ( (Double) res).doubleValue()));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(Double) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof Long) {
>        if (outPort.getType().toString().equals("long")) {
>          outPort.broadcast(new LongToken( ( (Long) res).longValue()));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(Long) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof Boolean) {
>        if (outPort.getType().toString().equals("boolean")) {
>          outPort.broadcast(new BooleanToken( ( (Boolean) res).booleanValue()));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(Boolean) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof String[]) {
>        if (outPort.getType().toString().equals("arrayType(string)")) {
>          String[] resultArr = (String[]) res;
>          int xxx = resultArr.length;
>          
>         /* Original code 
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>            
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>                  */
>          /* code updated by zhiming */
>          
>         
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            
>            /*
>             * Check if '"' is included in the string array. 
>             * */
>            if(((resultArr[resCount].getBytes())[0]==(resultArr[resCount].getBytes())[resultArr[resCount].length()-1])&&
>                        (resultArr[resCount].getBytes()[0]==34))
>            {
>                resultArrStr += resultArr[resCount] + ",";
>                //System.out.println("Without adding \"");;
>                
>            }else {
>                resultArrStr +="\""+ resultArr[resCount] + "\",";
>                //System.out.println("add \"");;
>            }
>          }
>          if(((resultArr[xxx-1].getBytes())[0]==(resultArr[xxx-1].getBytes())[resultArr[xxx-1].length()-1])&&
>                          ((resultArr[xxx-1].getBytes())[0]==34))
>          {
>                resultArrStr += resultArr[xxx-1] + "}";
>                //System.out.println("Without adding \"");;
>          }else {
>                resultArrStr +="\""+ resultArr[xxx-1] + "\"}";
>                //System.out.println("add \"");;
>          }          
>                  //System.out.println("stringArrayB: "+resultArrStr);;
>                  /*End Zhiming*/
>
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(String[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if ( (res instanceof Integer[])) {
>        _debug("IN Integer[]");
>        if (outPort.getType().toString().equals("arrayType(int)")) {
>          Integer[] resultArr = (Integer[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(String[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof int[]) {
>        _debug("IN int[]");
>        if (outPort.getType().toString().equals("arrayType(int)")) {
>          int[] resultArr = (int[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          _debug(resultArrStr);
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(String[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof Double[]) {
>        _debug("IN Double[]");
>        if (outPort.getType().toString().equals("arrayType(double)")) {
>          Double[] resultArr = (Double[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          _debug(resultArrStr);
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(Double[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof double[]) {
>        _debug("IN double[]");
>        if (outPort.getType().toString().equals("arrayType(double)")) {
>          double[] resultArr = (double[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          _debug(resultArrStr);
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(double[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof Float[]) {
>        _debug("IN Float[]");
>        if (outPort.getType().toString().equals("arrayType(double)")) {
>          Float[] resultArr = (Float[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          _debug(resultArrStr);
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(Float[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>
>      else if (res instanceof float[]) {
>        _debug("IN float[]");
>        if (outPort.getType().toString().equals("arrayType(double)")) {
>          float[] resultArr = (float[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          _debug(resultArrStr);
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(float[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>      else if (res instanceof Boolean[]) {
>        _debug("IN Boolean[]");
>        if (outPort.getType().toString().equals("arrayType(boolean)")) {
>          Boolean[] resultArr = (Boolean[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          _debug(resultArrStr);
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(Boolean[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>
>      else if (res instanceof boolean[]) {
>        _debug("IN boolean[]");
>        if (outPort.getType().toString().equals("arrayType(boolean)")) {
>          boolean[] resultArr = (boolean[]) res;
>          int xxx = resultArr.length;
>          String resultArrStr = "{";
>          for (int resCount = 0; resCount < xxx - 1; resCount++) {
>            _debug("resultArr[" + resCount + "] = " + resultArr[resCount]);
>            resultArrStr += resultArr[resCount] + ", ";
>          }
>          resultArrStr += resultArr[xxx - 1] + "}";
>          _debug(resultArrStr);
>          outPort.broadcast(new ArrayToken(resultArrStr));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(boolean[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>
>      else if (res instanceof byte[]) {
>        _debug("IN byte[]");
>        if (outPort.getType().toString().equals("arrayType(unsignedByte}")) {
>           byte[] resultArr = (byte[]) res;
>           int bytesAvailable = resultArr.length;
>           Token[] dataTokens = new Token[bytesAvailable];
>
>           for (int j = 0; j < bytesAvailable; j++) {
>              dataTokens[j] = new UnsignedByteToken(resultArr[j]);
>           }
>
>           outPort.broadcast(new ArrayToken(dataTokens));
>        }
>        else {
>          _debug("<ERROR> The outPort type (" + outPort.getType().toString() +
>              ") and the res type(boolean[]) do not match in _sendOutput(). <ERROR>");
>        }
>      }
>
>      else
>        outPort.broadcast(new StringToken(
>            "Cannot identify the type instance of the result!"));
>    }
>    catch (IllegalActionException iae) {
>      _debug("<EXCEPTION> There was an exception in _sendOutput(): " +
>             iae.toString() + ". </EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      _errorsStr += "\n" + iae.getMessage()
>             + "There was an exception when sending the outputs in actor: "
>             + this.getName() + iae.toString();//);
>    }
>  } //end-of-sendOutput
>
>  /** _setObjectArray
>   * Set the values of the arguments (_objArr) to pass to call.
>   * @param portPtr
>   * @param index
>   */
>  private void _setObjectArray(TypedIOPort portPtr, int index) throws java.rmi.RemoteException {
>    try {
>      System.out.println("PORT TYPE in PTOLEMY ACTOR: " + portPtr.getType().toString());
>      _debug("PORT TYPE in PTOLEMY ACTOR: " + portPtr.getType().toString());
>      if (portPtr.getType().toString().equals("int")) {
>        _objArr[index] = new Integer( ( (IntToken) (portPtr.get(0))).intValue());
>      }
>      else if (portPtr.getType().toString().equals("double")) {
>        _objArr[index] = new Double( ( (DoubleToken) (portPtr.get(0))).
>                                    doubleValue());
>      }
>      else if (portPtr.getType().toString().equals("string")) {
>        _objArr[index] = new String( ( (StringToken) portPtr.get(0)).
>                                    stringValue());
>      }
>      else if (portPtr.getType().toString().equals("long")) {
>        _objArr[index] = new Long( ( (LongToken) (portPtr.get(0))).longValue());
>      }
>      else if (portPtr.getType().toString().equals("boolean")) {
>        _objArr[index] = new Boolean( ( (BooleanToken) (portPtr.get(0))).
>                                     booleanValue());
>      }
>      else if (portPtr.getType().toString().equals("arrayType(int)")) {
>        Token[] tempTokenArr = ( (ArrayToken) (portPtr.get(0))).arrayValue();
>        int numTokens = tempTokenArr.length;
>        Integer[] tempStrArr = new Integer[numTokens];
>        for (int ind = 0; ind < numTokens; ind++)
>          tempStrArr[ind] = new Integer(tempTokenArr[ind].toString());
>        _objArr[index] = tempStrArr;
>      }
>      else if (portPtr.getType().toString().equals("arrayType(string)")) {
>        Token[] tempTokenArr = ( (ArrayToken) (portPtr.get(0))).arrayValue();
>        int numTokens = tempTokenArr.length;
>        String[] tempStrArr = new String[numTokens];
>        for (int ind = 0; ind < numTokens; ind++)
>          tempStrArr[ind] = tempTokenArr[ind].toString();
>        _objArr[index] = tempStrArr;
>      }
>      else if (portPtr.getType().toString().equals("arrayType(long)")) {
>        Token[] tempTokenArr = ( (ArrayToken) (portPtr.get(0))).arrayValue();
>        int numTokens = tempTokenArr.length;
>        Long[] tempStrArr = new Long[numTokens];
>        for (int ind = 0; ind < numTokens; ind++)
>          tempStrArr[ind] = new Long(tempTokenArr[ind].toString());
>        _objArr[index] = tempStrArr;
>      }
>      else if (portPtr.getType().toString().equals("arrayType(boolean)")) {
>        Token[] tempTokenArr = ( (ArrayToken) (portPtr.get(0))).arrayValue();
>        int numTokens = tempTokenArr.length;
>        Boolean[] tempStrArr = new Boolean[numTokens];
>        for (int ind = 0; ind < numTokens; ind++)
>          tempStrArr[ind] = new Boolean(tempTokenArr[ind].toString());
>        _objArr[index] = tempStrArr;
>      }
>      else if (portPtr.getType().toString().equals("arrayType(double)")) {
>        Token[] tempTokenArr = ( (ArrayToken) (portPtr.get(0))).arrayValue();
>        int numTokens = tempTokenArr.length;
>        Double[] tempStrArr = new Double[numTokens];
>        for (int ind = 0; ind < numTokens; ind++)
>          tempStrArr[ind] = new Double(tempTokenArr[ind].toString());
>        _objArr[index] = tempStrArr;
>      }
>      else if (portPtr.getType().toString().equals("arrayType(unsignedByte)")) {
>        Token[] tempTokenArr = ( (ArrayToken) (portPtr.get(0))).arrayValue();
>        int numTokens = tempTokenArr.length;
>        byte[] tempArr = new byte[numTokens];
>        for (int ind = 0; ind < numTokens; ind++) {
>           UnsignedByteToken bt = (UnsignedByteToken)tempTokenArr[ind];
>           tempArr[ind] = (bt.byteValue());
>        }
>        _objArr[index] = tempArr;
>      }
>      else {
>        _debug("Could not: specify the type of the port and set object arr.");
>      }
>    }
>    catch (Exception ex) {
>      _debug("<EXCEPTION> There was an exception in setObjectArray method: " +
>             ex + ". </EXCEPTION>");
>      //GraphicalMessageHandler.message(
>      throw new java.rmi.RemoteException(ex.getMessage());
>
>    }
>  } // end-of-setObjectArray
>
>  /**
>   * Set the type of a port based on a string representation of that type
>   * that was extracted from the WSDL description.
>   *
>   * @param arrayTypes a hash of defined array types by name
>   * @param port the port whose type is to be set
>   * @param typeStr the string representation of the type to be set
>   */
>  private void _setPortType(TypedIOPort port,
>                            String typeStr) {
>    /* NOTE TO SELF:
>         I used:
>     http://www-106.ibm.com/developerworks/webservices/library/ws-soapmap1/
>         as reference for the Apache->SOAP type mapping.
>         Haven't got to the special "object encoding" and
>                                    "Sending blobs" parts of the doc.
>         Need to consider them seperately if we wanna do it.
>     */
>    if (typeStr.equals("int")) {
>      port.setTypeEquals(BaseType.INT);
>    }
>    else if (typeStr.equals("boolean")) {
>      port.setTypeEquals(BaseType.BOOLEAN);
>    }
>    else if (typeStr.equals("long")) {
>      port.setTypeEquals(BaseType.LONG);
>    }
>    else if (typeStr.equals("double")) {
>      port.setTypeEquals(BaseType.DOUBLE);
>    }
>    else if (typeStr.equals("float")) { //There is no float in Ptolemy type sys.
>      port.setTypeEquals(BaseType.DOUBLE);
>    }
>    else if (typeStr.equals("byte")) {
>      //->There is no byte in Ptolemy type sys. So I cast the byte to INT.
>      port.setTypeEquals(BaseType.INT);
>    }
>    else if (typeStr.equals("short")) {
>      //->There is no short in Ptolemy type sys. So again cast it to INT
>      port.setTypeEquals(BaseType.INT);
>    }
>    else if (typeStr.equals("string")) {
>      port.setTypeEquals(BaseType.STRING);
>    }
>    else if (typeStr.equals("string[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.STRING));
>    }
>    else if (typeStr.equals("byte[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.INT));
>    }
>    else if (typeStr.equals("short[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.INT));
>    }
>    else if (typeStr.equals("int[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.INT));
>    }
>    else if (typeStr.equals("long[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.LONG));
>    }
>    else if (typeStr.equals("double[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.DOUBLE));
>    }
>    else if (typeStr.equals("float[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.DOUBLE));
>    }
>    else if (typeStr.equals("boolean[]")) {
>      port.setTypeEquals(new ArrayType(BaseType.BOOLEAN));
>    }
>    else {
>      _debug(
>          "<WARNING>Could not specify the type. Setting it to string. </WARNING>");
>      port.setTypeEquals(BaseType.STRING);
>    }
>  }
>
>  //////////////////////////////////////////////////////////////////////
>  ////                         private variables                    ////
>
>  private Binding _binding = null;
>  // The main service call object
>  private Call _call = null;
>  // The name of the method that this web service actor binds to
>  //static private String _methodNameStr = "";
>  private String _methodNameStr = "";
>  // The input values to be sent when invoking the web service call.
>  private Object[] _objArr;
>  // The name of the port...
>  private String _portName = null;
>  private int _returnMode = 0; // 1--multiple output 2--single output param
>  private Service _service = null;
>  // The URL of the WSDL that describes the web service
>  // static private String _urlStr = new String();
>  private String _urlStr = new String();
>  private String _wsName = "";
>  // The parser for the WSDL. Will be initiated by the _urlStr.
>  private Parser _wsdlParser = null;
>  private String _errorsStr = "";
>  protected String _confErrorStr = "";
>  private boolean _triggerFlag = false;
>
>} // end of WebService

------------ 
Edward A. Lee
Chair of EECS and Robert S. Pepper Distinguished Professor
231 Cory Hall, UC Berkeley, Berkeley, CA 94720-1770
phone: 510-642-0253, fax: 510-642-2845
eal at eecs.Berkeley.EDU, http://ptolemy.eecs.berkeley.edu/~eal  



More information about the Kepler-dev mailing list