001/* 002 * Copyright (c) 1998-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2012-11-26 22:19:36 +0000 (Mon, 26 Nov 2012) $' 007 * '$Revision: 31113 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.sdm.spa; 031 032import java.util.Iterator; 033import java.util.List; 034import java.util.Vector; 035 036import ptolemy.actor.IOPort; 037import ptolemy.actor.TypedAtomicActor; 038import ptolemy.actor.TypedIOPort; 039import ptolemy.data.ArrayToken; 040import ptolemy.data.ObjectToken; 041import ptolemy.data.Token; 042import ptolemy.data.expr.StringParameter; 043import ptolemy.data.type.ArrayType; 044import ptolemy.data.type.BaseType; 045import ptolemy.data.type.BaseType.BooleanType; 046import ptolemy.data.type.BaseType.DoubleType; 047import ptolemy.data.type.BaseType.IntType; 048import ptolemy.data.type.BaseType.LongType; 049import ptolemy.data.type.BaseType.StringType; 050import ptolemy.data.type.BaseType.UnsignedByteType; 051import ptolemy.data.type.Type; 052import ptolemy.gui.GraphicalMessageHandler; 053import ptolemy.kernel.CompositeEntity; 054import ptolemy.kernel.util.Attribute; 055import ptolemy.kernel.util.IllegalActionException; 056import ptolemy.kernel.util.NameDuplicationException; 057 058/////////////////////////////////////////////////////////////// 059////SoaplabChooseOperation 060/** 061 * <p> 062 * The following actor is for choosing set_<name> operations for executing 063 * any derived web service registered at EBI. The following actor takes in an 064 * input values to serve as parameters for the set_<name> web service 065 * operation. The actor asks the user to choose the desired set_<name> 066 * operation. The inputValues and set_<name> operation name are further 067 * forwarded to the next actor SoaplabServiceStarter. 068 * </p> 069 * 070 * @author Nandita Mangal 071 * @version $Id: SoaplabChooseOperation.java, v 1.0 2005/19/07 072 * @category.name web 073 * @category.name external execution 074 */ 075 076public class SoaplabChooseOperation extends TypedAtomicActor { 077 078 /** 079 * Construct a SoaplabChooseOperation actor with given container and name. 080 * 081 * @param container 082 * The container. 083 * @param name 084 * The name of this actor. 085 * @exception NameDuplicationException 086 * If the container already has an actor with this name 087 */ 088 089 public SoaplabChooseOperation(CompositeEntity container, String name) 090 throws NameDuplicationException, IllegalActionException { 091 super(container, name); 092 093 wsdlUrl = new StringParameter(this, "wsdlUrl"); 094 selectInputSetMethods = new StringParameter(this, "inputSetMethods"); 095 096 input = new TypedIOPort(this, "input", true, false); 097 input.setTypeEquals(BaseType.UNKNOWN); // type of input value expected 098 // is not known yet 099 100 output = new TypedIOPort(this, "output", false, true); 101 output.setTypeEquals(BaseType.OBJECT); 102 103 _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" " 104 + "width=\"60\" height=\"30\" " + "style=\"fill:white\"/>\n" 105 + "</svg>\n"); 106 } 107 108 // ////////////////////////////////////////////////////////////////////////////// 109 // // Ports and Parameters //// 110 111 /** 112 * The web service URL which is registered at EBI 113 */ 114 public StringParameter wsdlUrl = null; 115 116 /** 117 * The standard "set_<name>" method choices for SoaplabServices 118 */ 119 public StringParameter selectInputSetMethods = null; 120 121 /** 122 * Outputs the username and input values to next actor namely 123 * "SoaplabServiceStarter" 124 */ 125 public TypedIOPort output; 126 127 /** 128 * The parameters for the "set_<name>" operations 129 */ 130 public TypedIOPort input; 131 132 // ////////////////////////////////////////////////////////////////////////////// 133 // // public Methods //// 134 135 /** 136 * Callback for changes in attribute values Get the WSDL from the given URL. 137 * 138 * @param at 139 * The attribute that changed. 140 * @exception IllegalActionException 141 */ 142 public void attributeChanged(Attribute at) throws IllegalActionException { 143 144 if (at == wsdlUrl) { 145 146 if (wsdlUrl.getExpression().equals("")) { 147 selectInputSetMethods.removeAllChoices(); 148 } else { 149 selectInputSetMethods.removeAllChoices(); 150 try { 151 152 // NOTE:- The following client is just created for geting 153 // the WSDL input methods 154 // in the very first stage of the workflow beforehand.The 155 // client created at this 156 // stage is not utilized after getting the required 157 // inputMethods. 158 159 SoaplabServiceClient client = new SoaplabServiceClient( 160 wsdlUrl.getExpression()); 161 client.setJobId(); // create Job in order to be able to 162 // generate input method names 163 client.generateInputMethods(); // get the set_<name> 164 // operations 165 Vector inputMethods = client.getInputMethods(); 166 for (int i = 0; i < inputMethods.size(); i++) { 167 selectInputSetMethods.addChoice("set_" 168 + (String) (inputMethods.elementAt(i))); 169 } 170 171 } catch (Exception ex) { 172 _debug("<EXCEPTION> There was an error while parsing the WSDL. " 173 + ex + ". </EXCEPTION>"); 174 // GraphicalMessageHandler.message( 175 _confErrorStr += "\n" 176 + ex.getMessage() 177 + "There was an error while parsing the WSDL in the actor: " 178 + this.getName();// ); 179 } 180 181 if (!(_confErrorStr.equals(""))) { 182 GraphicalMessageHandler.message(_confErrorStr); 183 184 } 185 } 186 187 } 188 189 } // end of attributeChanged 190 191 /** 192 * Gets a list of input ports configured with the actor and finally outputs 193 * an object containing all the inputValues for the set_<name> 194 * operation as well as name of operation itself. 195 * 196 * @exception IllegalActionException 197 * If there is no director. 198 */ 199 200 public void fire() throws IllegalActionException { 201 202 super.fire(); 203 204 // a vector to contain all user input data such as operation 205 // name,operation input values 206 Vector userInputs = new Vector(); 207 208 List inPortList = this.inputPortList(); 209 Iterator ports = inPortList.iterator(); 210 211 while (ports.hasNext()) { 212 213 IOPort p = (IOPort) ports.next(); 214 List connections = p.connectedPortList(); 215 if (!(connections.isEmpty())) { 216 217 if (wsdlUrl.getExpression().equals("")) 218 GraphicalMessageHandler.message("\nWSDL is empty in actor:" 219 + this.getName()); 220 else if (selectInputSetMethods.getExpression().equals("")) 221 GraphicalMessageHandler 222 .message("\nSet Method is empty in actor:" 223 + this.getName()); 224 225 Token originalToken = p.get(0); // getInputVaulue 226 Object tokenObjectForm = _getTokenConvertedObject(originalToken); // get 227 // the 228 // Java 229 // object 230 // form 231 // of 232 // input 233 // Token 234 userInputs.add(tokenObjectForm); 235 236 } 237 238 } 239 userInputs.add(selectInputSetMethods.getExpression()); // add the 240 // set_<name> 241 // operation 242 // name 243 output.broadcast(new ObjectToken(userInputs)); // braodcast the object 244 // consisting of input 245 // values + operation 246 // name. 247 248 }// end of fire 249 250 /** 251 * Before executing the actor, delete any unconnected input ports to the 252 * actor done in order to prevent possible SDF disconnected graphs problem 253 * for users. 254 */ 255 public boolean prefire() throws IllegalActionException { 256 257 List inPortList = this.inputPortList(); 258 Iterator ports = inPortList.iterator(); 259 260 while (ports.hasNext()) { 261 262 IOPort p = (IOPort) ports.next(); 263 List connections = p.connectedPortList(); 264 if (connections.isEmpty()) { 265 // delete the empty/unconnected port 266 try { 267 p.setContainer(null); 268 } catch (Exception ex) { 269 // Exceptions: IllegalAction or NameDuplicationException 270 _debug("<EXCEPTION> There was an error while attempting to delete unused ports " 271 + ex + ". </EXCEPTION>"); 272 _confErrorStr += "\n" 273 + ex.getMessage() 274 + "There was an error while deleting the unused input ports of the actor." 275 + this.getName();// ); 276 } 277 } 278 } 279 280 return super.prefire(); 281 282 } // end of prefire 283 284 // ////////////////////////////////////////////////////////////////// 285 // // private Methods /// 286 287 /** 288 * Given a token recieved from the input ports, the following attempts to 289 * get the token Value and convert it to a java Object form. 290 * 291 * @param portToken 292 * The input Token retrieved from the input port 293 */ 294 295 private Object _getTokenConvertedObject(Token portToken) { 296 297 if (portToken.getType() instanceof BooleanType) { 298 return new Boolean(portToken.toString()); 299 } else if (portToken.getType() instanceof IntType) { 300 return new Integer(portToken.toString()); 301 } else if (portToken.getType() instanceof LongType) { 302 return new Long(portToken.toString()); 303 } else if (portToken.getType() instanceof StringType) { 304 String returnValueStr = portToken.toString(); 305 String suffix = "\""; 306 // extra step to delete the "" quotation prefixes around the string 307 if (returnValueStr.endsWith(suffix) 308 && returnValueStr.startsWith(suffix)) { 309 return returnValueStr.substring(1, 310 (returnValueStr.length()) - 1); 311 } 312 } else if (portToken.getType() instanceof DoubleType) { 313 return new Double(portToken.toString()); 314 } else if (portToken.getType() instanceof UnsignedByteType) { 315 // ->There is no byte in Ptolemy type sys. cast the byte to INT. 316 return new Integer(portToken.toString()); 317 } else if (portToken.getType() instanceof ArrayType) { 318 319 // get the type of elements inside the ArrayToken 320 Type tokenType = ((ArrayToken) portToken).getElementType(); 321 322 if (tokenType instanceof BooleanType) { 323 324 Boolean arrayBool[] = new Boolean[((ArrayToken) portToken) 325 .length()]; 326 for (int i = 0; i < ((ArrayToken) portToken).length(); i++) { 327 arrayBool[i] = new Boolean((((ArrayToken) portToken) 328 .getElement(i)).toString()); 329 } 330 return arrayBool; 331 } else if (tokenType instanceof IntType) { 332 333 Integer arrayInt[] = new Integer[((ArrayToken) portToken) 334 .length()]; 335 for (int i = 0; i < ((ArrayToken) portToken).length(); i++) { 336 arrayInt[i] = new Integer((((ArrayToken) portToken) 337 .getElement(i)).toString()); 338 } 339 return arrayInt; 340 341 } else if (tokenType instanceof LongType) { 342 343 Long arrayLong[] = new Long[((ArrayToken) portToken).length()]; 344 for (int i = 0; i < ((ArrayToken) portToken).length(); i++) { 345 arrayLong[i] = new Long((((ArrayToken) portToken) 346 .getElement(i)).toString()); 347 } 348 return arrayLong; 349 350 } else if (tokenType instanceof StringType) { 351 352 String arrayString[] = new String[((ArrayToken) portToken) 353 .length()]; 354 for (int i = 0; i < ((ArrayToken) portToken).length(); i++) { 355 // extra step to delete the "" quotation prefixes around the 356 // string 357 String returnValueStr = (((ArrayToken) portToken) 358 .getElement(i)).toString(); 359 String suffix = "\""; 360 if (returnValueStr.endsWith(suffix) 361 && returnValueStr.startsWith(suffix)) { 362 arrayString[i] = returnValueStr.substring(1, 363 (returnValueStr.length()) - 1); 364 } 365 } 366 return arrayString; 367 368 } else if (tokenType instanceof DoubleType) { 369 370 Double arrayDouble[] = new Double[((ArrayToken) portToken) 371 .length()]; 372 for (int i = 0; i < ((ArrayToken) portToken).length(); i++) { 373 arrayDouble[i] = new Double((((ArrayToken) portToken) 374 .getElement(i)).toString()); 375 } 376 return arrayDouble; 377 378 } else if (tokenType instanceof UnsignedByteType) { 379 380 // ->There is no byte in Ptolemy type sys. cast the byte to INT. 381 Integer arrayInt[] = new Integer[((ArrayToken) portToken) 382 .length()]; 383 for (int i = 0; i < ((ArrayToken) portToken).length(); i++) { 384 arrayInt[i] = new Integer((((ArrayToken) portToken) 385 .getElement(i)).toString()); 386 } 387 return arrayInt; 388 389 } 390 } else { 391 _debug("<WARNING>Could not convert the token to appropriate java Object.Setting it to string. </WARNING>"); 392 } 393 394 return new String(portToken.toString()); 395 } // end of _getTokenConvertedObject 396 397 // //////////////////////////////////////////////////////////////////////////// 398 // // private variables //// 399 400 protected String _confErrorStr = ""; 401 402}// end of SoaplabChooseOperation