001/* 002 * Copyright (c) 2003-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: welker $' 006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 007 * '$Revision: 24234 $' 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.kepler.dataproxy.datasource.geon; 031 032import java.net.URL; 033import java.util.Iterator; 034import java.util.List; 035import java.util.Map; 036import java.util.TreeMap; 037 038import org.apache.commons.logging.Log; 039import org.apache.commons.logging.LogFactory; 040import org.kepler.dataproxy.datasource.DataSourceInterface; 041import org.kepler.dataproxy.metadata.ADN.ADNMetadataSpecification; 042import org.kepler.objectmanager.cache.DataCacheListener; 043import org.kepler.objectmanager.cache.DataCacheObject; 044import org.kepler.objectmanager.data.DataSourceControllerFactory; 045import org.sdm.spa.WebService; 046 047import ptolemy.actor.IOPort; 048import ptolemy.actor.TypedIOPort; 049import ptolemy.actor.gui.style.TextStyle; 050import ptolemy.data.BooleanToken; 051import ptolemy.data.StringToken; 052import ptolemy.data.expr.SingletonParameter; 053import ptolemy.data.expr.StringParameter; 054import ptolemy.data.type.BaseType; 055import ptolemy.kernel.CompositeEntity; 056import ptolemy.kernel.util.IllegalActionException; 057import ptolemy.kernel.util.NameDuplicationException; 058import ptolemy.kernel.util.Settable; 059import ptolemy.kernel.util.StringAttribute; 060 061/** 062 * A GEON shapefile resource. 063 */ 064public class GEONShpResource extends WebService implements DataCacheListener, 065 DataSourceInterface { 066 067 private DataSourceControllerFactory _nodeController = null; 068 069 // Constants used for more efficient execution. 070 071 private static final int _VIEWMD = 0; 072 private static final int _DOWNLOADDATA = 1; 073 private static final int _VIEWDATA = 2; 074 private static final int _FORWARDID = 3; 075 076 private static final String _VIEWMDSTR = "view metadata"; 077 private static final String _DOWNLOADDATASTR = "download data"; 078 private static final String _VIEWDATASTR = "view data"; 079 private static final String _FORWARDIDSTR = "forward geon id"; 080 081 int _procType = 0; 082 083 private final static Map processMap = new TreeMap(); 084 085 static { 086 processMap.put(_VIEWMDSTR, new Integer(_VIEWMD)); 087 processMap.put(_DOWNLOADDATASTR, new Integer(_DOWNLOADDATA)); 088 processMap.put(_VIEWDATASTR, new Integer(_VIEWDATA)); 089 processMap.put(_FORWARDIDSTR, new Integer(_FORWARDID)); 090 } 091 092 protected final static Log log; 093 static { 094 log = LogFactory 095 .getLog("org.kepler.dataproxy.datasource.geon.GEONShpResource"); 096 } 097 098 // private static final String ENDPOINT = "endpoint"; 099 // private static final String RECORDID = "recordid"; 100 // private static final String NAMESPACE = "namespace"; 101 102 // protected static final String YELLOW = "{1.0, 1.0, 0.0, 1.0}"; 103 // protected static final String RED = "{1.0, 0.0, 0.0, 1.0}"; 104 // protected static final String BLACK = "{0.0, 0.0, 0.0, 1.0}"; 105 // protected static final String MAGENTA = "{1.0, 0.0, 1.0, 1.0}"; 106 // protected static final String TITLE_BINARY = "0101"; 107 // protected static final String TITLE_BUSY = "BUSY"; 108 // protected static final String TITLE_ERROR = "ERROR"; 109 110 // ///////////////////////////////////////////////////////////////// 111 // // ports and parameters //// 112 113 public StringParameter _process = null; 114 115 public StringAttribute _idAtt = null; 116 117 public StringAttribute _endpointAtt = null; 118 119 public StringAttribute _namespaceAtt = null; 120 121 public StringAttribute _descriptionAtt = null; 122 123 public SingletonParameter _hideOutput; 124 125 public SingletonParameter _hideErrorPort; 126 127 public TypedIOPort _forwardGEONId; 128 129 /** 130 * Construct an actor with the given container and name. 131 * 132 * @param container 133 * The container. 134 * @param name 135 * The name of this actor. 136 * @exception IllegalActionException 137 * If the actor cannot be contained by the proposed 138 * container. 139 * @exception NameDuplicationException 140 * If the container already has an actor with this name. 141 * @since 142 */ 143 public GEONShpResource(CompositeEntity container, String name) 144 throws NameDuplicationException, IllegalActionException { 145 super(container, name); 146 147 _forwardGEONId = new TypedIOPort(this, "forwardGEONId", false, true); 148 _forwardGEONId.setTypeEquals(BaseType.STRING); 149 150 _process = new StringParameter(this, "process"); 151 // _process.setExpression(_VIEWMDSTR); 152 _process.setExpression(_FORWARDIDSTR); 153 // _process.addChoice(_VIEWMDSTR); 154 // _process.addChoice(_DOWNLOADDATASTR); 155 // _process.addChoice(_VIEWDATASTR); 156 _process.addChoice(_FORWARDIDSTR); // requires component to integrate 157 // several services. 158 159 _idAtt = new StringAttribute(this, RECORDID); 160 _idAtt.setVisibility(Settable.NOT_EDITABLE); 161 162 _endpointAtt = new StringAttribute(this, ENDPOINT); 163 _endpointAtt.setVisibility(Settable.NOT_EDITABLE); 164 165 _namespaceAtt = new StringAttribute(this, NAMESPACE); 166 _namespaceAtt.setVisibility(Settable.NONE); 167 168 _descriptionAtt = new StringAttribute(this, "description"); 169 TextStyle descTSatt = new TextStyle(_descriptionAtt, "descriptionTS"); 170 171 _hideOutput = new SingletonParameter(_forwardGEONId, "_hide"); 172 _hideOutput.setToken(BooleanToken.FALSE); 173 174 _hideErrorPort = new SingletonParameter(clientExecErrors, "_hide"); 175 // _hideErrorPort.setToken(BooleanToken.TRUE); 176 177 wsdlUrl.setVisibility(Settable.NONE); 178 methodName.setVisibility(Settable.NONE); 179 userName.setVisibility(Settable.NONE); 180 password.setVisibility(Settable.NONE); 181 182 hasTrigger.moveToLast(); 183 184 // Create a node controller to control the context menu 185 _nodeController = new DataSourceControllerFactory(this, 186 "_controllerFactory"); 187 188 _attachText("_iconDescription", "<svg>\n" + "<rect x=\"0\" y=\"0\" " 189 + "width=\"85\" height=\"30\" " + "style=\"fill:white\"/>\n" 190 + "<text x=\"9\" y=\"22\"" 191 + "style=\"font-size:16; fill:blue; font-family:SansSerif\">" 192 + "Shapefile</text>\n" + "</svg>\n"); 193 194 } 195 196 /** 197 * Callback for changes in attribute values. 198 */ 199 public void attributeChanged(ptolemy.kernel.util.Attribute attribute) 200 throws ptolemy.kernel.util.IllegalActionException { 201 202 if (attribute.getName().equals("process")) { 203 if (_process != null) { 204 String proc = ((StringParameter) attribute).getExpression(); 205 if (!proc.equals("")) { 206 _procType = ((Integer) processMap.get(proc)).intValue(); 207 208 if (proc.equals(_VIEWMDSTR) 209 || proc.equals(_DOWNLOADDATASTR) 210 || proc.equals(_FORWARDIDSTR)) { 211 212 // Reset wsdlUrl and methodName 213 wsdlUrl.setExpression(""); 214 methodName.setExpression(""); 215 216 // delete all other service ports 217 _deletePorts(); 218 219 if (proc.equals(_FORWARDIDSTR)) { 220 // expose output port 221 _hideOutput.setToken(BooleanToken.FALSE); 222 _forwardGEONId.moveToFirst(); 223 } else { 224 // hide output port 225 _hideOutput.setToken(BooleanToken.TRUE); 226 _forwardGEONId.moveToLast(); 227 } 228 // hide clientErrorPort 229 _hideErrorPort.setToken(BooleanToken.TRUE); 230 } 231 232 else if (proc.equals(_VIEWDATASTR)) { 233 234 // hide clientErrorPort and expose output port 235 _hideErrorPort.setToken(BooleanToken.FALSE); 236 // _hideOutput.setToken(BooleanToken.TRUE); 237 238 // Point wsdlUrl and methodName to the mapping service 239 // URL. 240 // This should call the web service actor's 241 // attributeChanged method!!! 242 // wsdlUrl.setExpression("??"); // TODO: ADD URL + 243 // modify config file 244 // methodName.setExpression("??"); 245 } 246 } 247 } 248 } else 249 super.attributeChanged(attribute); 250 } 251 252 /** 253 * Get the identifier of this record. 254 * 255 * @return the String that uniquely identifies the record 256 */ 257 public String getRecordId() { 258 String value = null; 259 try { 260 StringAttribute attribute = (StringAttribute) this 261 .getAttribute(RECORDID); 262 value = attribute.getExpression(); 263 } catch (Exception e) { 264 System.err.println("getRecordId - RECORDID attr is null."); 265 } 266 return value; 267 } 268 269 /** 270 * Get the endpoint of this record. The endpoint indicates where the service 271 * generating the record can be accessed. 272 * 273 * @return endpoint the URL of the service that contains the record 274 */ 275 public String getEndpoint() { 276 String value = null; 277 try { 278 StringAttribute attribute = (StringAttribute) this 279 .getAttribute(ENDPOINT); 280 value = attribute.getExpression(); 281 } catch (Exception e) { 282 System.err.println("getEndpoint - ENDPOINT attr is null."); 283 } 284 return value; 285 } 286 287 /** 288 * Get the namespace of this record. 289 * 290 * @return namespace the URL of the service that contains the record 291 */ 292 public String getNamespace() { 293 String value = null; 294 try { 295 StringAttribute attribute = (StringAttribute) this 296 .getAttribute(NAMESPACE); 297 value = attribute.getExpression(); 298 } catch (Exception e) { 299 System.err.println("getNamespace - NAMESPACE attr is null."); 300 } 301 return value; 302 } 303 304 /** 305 * Get a URL pointer to the ADN documentation for this data source. 306 * 307 * @return URL the URL of the HTML file containing the documentation 308 */ 309 public URL getDocumentation() { 310 try { 311 URL htmlDoc = ADNMetadataSpecification 312 .getDocumentation(getRecordId()); 313 return htmlDoc; 314 } catch (Exception ex) { 315 return null; 316 } 317 } 318 319 public void fire() throws IllegalActionException { 320 switch (_procType) { 321 case _VIEWMD: 322 viewMD(); 323 break; 324 case _DOWNLOADDATA: 325 downloadData(); 326 break; 327 case _VIEWDATA: 328 super.fire(); 329 break; 330 case _FORWARDID: 331 _forwardGEONId.broadcast(new StringToken(getRecordId())); 332 break; 333 default: 334 throw new IllegalActionException(this, 335 "Unrecognized process type: " + _procType); 336 337 } 338 } 339 340 /** 341 * postfire the actor. Return false if the command is not invoking the web 342 * service client and there is no trigger. 343 */ 344 public boolean postfire() throws IllegalActionException { 345 if (_procType != _VIEWDATA && startTrigger.getWidth() == 0) { 346 return false; 347 } 348 return super.postfire(); 349 } 350 351 /** Deletes all the ports of this actor. */ 352 protected void _deletePorts() throws IllegalActionException { 353 List inPortList = this.inputPortList(); 354 Iterator ports = inPortList.iterator(); 355 while (ports.hasNext()) { 356 IOPort p = (IOPort) ports.next(); 357 if (p.isInput()) { 358 try { 359 if (!(p.getName().equals("startTrigger"))) { 360 p.setContainer(null); 361 } 362 } catch (NameDuplicationException e) { 363 throw new IllegalActionException(this, e, 364 "Could not delete the input port: " + p.getName()); 365 } 366 } 367 } 368 369 List outPortList = this.outputPortList(); 370 Iterator oports = outPortList.iterator(); 371 while (oports.hasNext()) { 372 IOPort outp = (IOPort) oports.next(); 373 if (outp.isOutput()) { 374 try { 375 if (!(outp.getName().equals("clientExecErrors")) 376 && !(outp.getName().equals("forwardGEONId"))) { 377 outp.setContainer(null); 378 } 379 } catch (NameDuplicationException e) { 380 throw new IllegalActionException(this, e, 381 "Could not delete the output port:" + outp.getName()); 382 } 383 } 384 } 385 } // end of deletePorts 386 387 /** 388 * download shapefile from the GEON portal to the client machine. 389 */ 390 private void downloadData() { 391 // add implementation here.. 392 } 393 394 /** 395 * View ADN metadata (could be also exposed by getMetadata in the actor's 396 * context menu). 397 */ 398 private void viewMD() { 399 // add implementation here.. 400 } 401 402 // ------------------------------------------------------------------------ 403 // -- DataCacheListener 404 // ------------------------------------------------------------------------ 405 406 public void complete(DataCacheObject aItem) { 407 log.debug("complete: " + this); 408 409 aItem.removeListener(this); 410 411 /* 412 * if (aItem.isReady()) { // } 413 */} 414 415}