001/* 002 * Copyright (c) 1997-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: crawl $' 006 * '$Date: 2013-03-27 18:47:49 +0000 (Wed, 27 Mar 2013) $' 007 * '$Revision: 31770 $' 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.icon; 031 032import java.io.IOException; 033import java.util.List; 034 035import org.apache.commons.logging.Log; 036import org.apache.commons.logging.LogFactory; 037import org.kepler.configuration.ConfigurationManager; 038import org.kepler.configuration.ConfigurationNamespace; 039import org.kepler.configuration.ConfigurationProperty; 040import org.kepler.moml.NamedObjId; 041import org.kepler.objectmanager.cache.CacheException; 042import org.kepler.objectmanager.cache.CacheManager; 043import org.kepler.objectmanager.lsid.KeplerLSID; 044import org.kepler.util.StaticResources; 045 046import ptolemy.actor.CompositeActor; 047import ptolemy.kernel.util.Attribute; 048import ptolemy.kernel.util.ConfigurableAttribute; 049import ptolemy.kernel.util.IllegalActionException; 050import ptolemy.kernel.util.NameDuplicationException; 051import ptolemy.kernel.util.NamedObj; 052import ptolemy.util.MessageHandler; 053 054////////////////////////////////////////////////////////////////////////// 055//// ComponentEntityConfig 056 057/** 058 * Configuration Utilities for ComponentEntity class, which is a base class for 059 * all actors. 060 * 061 * @author Matthew Brooke 062 * @version $Id: ComponentEntityConfig.java 31770 2013-03-27 18:47:49Z crawl $ 063 * @since Ptolemy II 0.2 064 * @Pt.ProposedRating 065 * @Pt.AcceptedRating 066 */ 067public class ComponentEntityConfig { 068 069 /** 070 * attribute name for attribute added to actors to describe 071 * (batik-renderable) SVG image file location 072 */ 073 public static final String SVG_ICON_ATTRIB_NAME = "_svgIcon"; 074 075 /** 076 * attribute name for attribute added to actors to describe raster thumbnail 077 * image file location 078 */ 079 public static final String RASTER_THUMB_ATTRIB_NAME = "_thumbnailRasterIcon"; 080 081 // ///////////////////////////////////////////////////////////////// 082 083 /** 084 * Key for finding default actor-icon name in resource bundle (example value 085 * associated with this key: "basic-actor") 086 */ 087 private static final String DEFAULT_ACTOR_ICON_KEY = "DEFAULT_ACTOR_ICON"; 088 089 /** 090 * Key for finding default director-icon name in resource bundle (example 091 * value associated with this key: "director") 092 */ 093 private static final String DEFAULT_DIRECTOR_ICON_KEY = "DEFAULT_DIRECTOR_ICON"; 094 095 private static String DEFAULT_ACTOR_ICON_BASENAME; 096 private static String DEFAULT_DIRECTOR_ICON_BASENAME; 097 098 private static Log log; 099 private static boolean isDebugging; 100 101 static { 102 // logging... 103 log = LogFactory.getLog("SVG." + ComponentEntityConfig.class.getName()); 104 isDebugging = log.isDebugEnabled(); 105 106 try { 107 DEFAULT_ACTOR_ICON_BASENAME = StaticResources.getSettingsString( 108 DEFAULT_ACTOR_ICON_KEY, null); 109 } catch (Exception ex) { 110 if (isDebugging) { 111 log.debug("EXCEPTION GETTING DEFAULT_ACTOR_ICON_BASENAME: " 112 + ex.getMessage()); 113 } 114 } 115 try { 116 DEFAULT_DIRECTOR_ICON_BASENAME = StaticResources.getSettingsString( 117 DEFAULT_DIRECTOR_ICON_KEY, null); 118 } catch (Exception ex) { 119 if (isDebugging) { 120 log.debug("EXCEPTION GETTING DEFAULT_DIRECTOR_ICON_BASENAME: " 121 + ex.getMessage()); 122 } 123 } 124 } 125 126 private static final String PERIOD = "."; 127 128 // ///////////////////////////////////////////////////////////////// 129 // // public methods //// 130 // ///////////////////////////////////////////////////////////////// 131 132 public static synchronized void addSVGIconTo(NamedObj namedObj) 133 throws IOException, IllegalArgumentException, 134 NameDuplicationException, IllegalActionException { 135 if (isDebugging) 136 log.debug("addSVGIconTo(" + namedObj + ")"); 137 138 if (StaticResources.getUISettingsProperty() == null) { 139 throw new IOException("Could not access actor icon mappings."); 140 } 141 if (namedObj == null) { 142 throw new IllegalArgumentException( 143 "addSVGIconTo() received NULL arg"); 144 } 145 146 // try to assign an icon to this object based on it's LSID 147 boolean assigned = tryToAssignIconByLSID(namedObj); 148 if (assigned) { 149 return; 150 } 151 152 // try to get a generic icon definition from byClass resourcebundle: 153 String iconBaseName = tryToAssignIconByClass(namedObj); 154 155 // if we could not find an icon using the lsid or class, try 156 // the semantic type 157 if (iconBaseName == null || iconBaseName.trim().length() < 1) { 158 iconBaseName = tryToAssignIconBySemanticType(namedObj); 159 } 160 161 // get a default icon 162 if (iconBaseName == null || iconBaseName.trim().length() < 1) { 163 iconBaseName = getDefaultIconBaseName(namedObj); 164 } 165 166 if (iconBaseName == null) { 167 if (isDebugging) { 168 log.warn("Couldn't assign batik icon for: " 169 + namedObj.getClassName()); 170 } 171 return; 172 } 173 addRasterAndSVGAttributes(namedObj, iconBaseName); 174 } 175 176 /** 177 * Look for an LSID in an Attribute, and if it exists, try to find an icon 178 * mapping in the appropriate resource bundle 179 * 180 * @param container 181 * NamedObj 182 * @throws IOException 183 * @throws NameDuplicationException 184 * @throws IllegalActionException 185 */ 186 public static boolean tryToAssignIconByLSID(NamedObj container) 187 throws IOException, NameDuplicationException, 188 IllegalActionException { 189 boolean success = false; 190 191 if (container == null) { 192 return success; 193 } 194 195 NamedObjId lsid = NamedObjId.getIdAttributeFor(container); 196 String iconBaseName = null; 197 if (lsid != null) { 198 199 if (isDebugging) { 200 log.debug("\n\n*** FOUND LSID (" + lsid.getExpression() 201 + ") for: " + container.getClassName()); 202 } 203 try { 204 205 iconBaseName = StaticResources.getValueFromName( 206 getByLSIDResBundle(), lsid.getExpression()); 207 if (isDebugging) { 208 log.debug("*** icon (" + iconBaseName 209 + ") selected by LSID (" + lsid.getExpression() 210 + ") for: " + container.getClassName()); 211 } 212 } catch (Exception ex) { 213 log.debug(ex.getMessage()); 214 iconBaseName = null; 215 } 216 } 217 218 if (iconBaseName == null) { 219 return success; 220 } 221 222 addRasterAndSVGAttributes(container, iconBaseName); 223 return success; 224 } 225 226 /** 227 * Try to find an icon by class using mapping in the appropriate resource 228 * bundle 229 * 230 * @param container 231 * NamedObj 232 * @throws IOException 233 * @throws NameDuplicationException 234 * @throws IllegalActionException 235 */ 236 public static String tryToAssignIconByClass(NamedObj namedObj) 237 throws IOException { 238 239 return tryToAssignIconByClassName(namedObj, namedObj.getClassName()); 240 241 } 242 243 public static String tryToAssignIconByClassName(NamedObj namedObj, 244 String className) throws IOException { 245 String iconBaseName = null; 246 if (getByClassResBundle() != null) { 247 try { 248 iconBaseName = StaticResources.getValueFromName( 249 getByClassResBundle(), className); 250 addRasterAndSVGAttributes(namedObj, iconBaseName); 251 if (isDebugging) { 252 log.debug("icon (" + iconBaseName 253 + ") selected by ClassName for: " 254 + namedObj.getClassName()); 255 } 256 } catch (Exception ex1) { 257 //ex1.printStackTrace(); 258 log.debug(ex1.getMessage()); 259 iconBaseName = null; 260 } 261 } 262 return iconBaseName; 263 } 264 265 /** Try to assign the icon based on the semantic type. */ 266 public static String tryToAssignIconBySemanticType(NamedObj namedObj) { 267 268 if (_iconForSemanticTypeProp == null) { 269 ConfigurationNamespace ns = new ConfigurationNamespace( 270 "uiSVGIconMappingsBySemanticType"); 271 _iconForSemanticTypeProp = ConfigurationManager.getInstance() 272 .getProperty(ConfigurationManager.getModule("gui"), ns); 273 if(_iconForSemanticTypeProp == null) { 274 MessageHandler.error("Could not find uiSVGIconMappingsBySemanticType.xml."); 275 return null; 276 } 277 } 278 279 String iconBaseName = null; 280 281 CacheManager cacheManager = null; 282 try { 283 cacheManager = CacheManager.getInstance(); 284 } catch(CacheException e) { 285 MessageHandler.error("Error accessing cache manager.", e); 286 return null; 287 } 288 289 KeplerLSID lsid = null; 290 // try to get the lsid from the object 291 NamedObjId namedObjId = NamedObjId.getIdAttributeFor(namedObj); 292 if(namedObjId == null) { 293 // try to get the lsid from the cache based on the class name 294 List<KeplerLSID> lsids = null; 295 try { 296 lsids = cacheManager.getCachedLsidsForClass(namedObj.getClassName()); 297 } catch (Exception e) { 298 System.err.println("Exception query cache for LSIDs of " + namedObj.getClassName()); 299 return null; 300 } 301 if(lsids != null && !lsids.isEmpty()) { 302 lsid = lsids.get(0); 303 } 304 } else { 305 lsid = namedObjId.getId(); 306 } 307 308 // if we found the lsid, get the semantic types 309 if(lsid != null) { 310 List<KeplerLSID> semanticTypes = cacheManager.getSemanticTypesFor(lsid); 311 for(KeplerLSID semanticType : semanticTypes) { 312 iconBaseName = StaticResources.getValueFromName(_iconForSemanticTypeProp, semanticType.toString()); 313 if(iconBaseName != null) { 314 return iconBaseName; 315 } 316 } 317 } 318 return null; 319 } 320 321 // ///////////////////////////////////////////////////////////////// 322 // // private methods //// 323 // ///////////////////////////////////////////////////////////////// 324 325 private static void addRasterAndSVGAttributes(NamedObj namedObj, 326 String iconBaseName) throws IllegalActionException, 327 NameDuplicationException, IOException { 328 329 // If iconBaseName is null or empty, just abort; either a previously- 330 // assigned icon, or default icon from Ptolemy base classes will be 331 // used. 332 if (iconBaseName == null || iconBaseName.trim().length() < 1) { 333 if (isDebugging) { 334 log.debug("Using base class default icon for: " 335 + namedObj.getClassName()); 336 } 337 return; 338 } else { 339 if (isDebugging) { 340 log.debug("*** FOUND ICON MAPPING (" + iconBaseName + ") FOR: " 341 + namedObj.getClassName()); 342 } 343 } 344 345 // gets here only if iconBaseName is not null or empty... 346 347 // add base SVG icon 348 _addIconAttributeToNamedObj(namedObj, SVG_ICON_ATTRIB_NAME, 349 "SVG_ICON_BASE_PATH", iconBaseName, "SVG_BASE_ICON_EXT"); 350 351 // now add raster thumbnail icon 352 _addIconAttributeToNamedObj(namedObj, RASTER_THUMB_ATTRIB_NAME, 353 "RASTER_THUMBNAIL_BASE_PATH", iconBaseName, 354 "RASTER_THUMBNAIL_EXT"); 355 } 356 357 private static String getDefaultIconBaseName(NamedObj namedObj) { 358 359 String iconBaseName = null; 360 361 //System.out.println("using default icon for " + namedObj.getFullName()); 362 363 if (namedObj instanceof ptolemy.actor.Director) { 364 if (isDebugging) { 365 log.debug("getDefaultIconBaseName() found a DIRECTOR: " 366 + namedObj.getClassName()); 367 } 368 iconBaseName = DEFAULT_DIRECTOR_ICON_BASENAME; 369 } else if (namedObj instanceof CompositeActor) { 370 iconBaseName = "composite"; 371 } else if (!(namedObj instanceof Attribute)) { 372 if (isDebugging) { 373 log.debug("getDefaultIconBaseName() found an ACTOR: " 374 + namedObj.getClassName()); 375 } 376 iconBaseName = DEFAULT_ACTOR_ICON_BASENAME; 377 } 378 return iconBaseName; 379 } 380 381 private static void _addIconAttributeToNamedObj(NamedObj namedObj, 382 String attribName, String iconBasePathKey, String iconBaseName, 383 String iconExtensionKey) throws IOException, 384 NameDuplicationException, IllegalActionException { 385 386 if (isDebugging) { 387 log.debug("_addIconAttributeToNamedObj() received: " 388 + "\n namedObj:" + namedObj.getClassName() 389 + "\n attribName:" + attribName + "\n iconBasePathKey:" 390 + iconBasePathKey + "\n iconBaseName:" + iconBaseName 391 + "\n iconExtensionKey:" + iconExtensionKey); 392 } 393 394 String iconBasePath = StaticResources.getSettingsString( 395 iconBasePathKey, null); 396 if (iconBasePath == null) { 397 throw new IOException("Could not get icon base path (key = " 398 + iconBasePathKey + ") from configuration file"); 399 } 400 String iconExtension = StaticResources.getSettingsString( 401 iconExtensionKey, null); 402 if (iconExtension == null) { 403 throw new IOException("Could not get icon extension (key = " 404 + iconExtensionKey + ") from configuration file"); 405 } 406 407 // make sure we haven't already got an attribute with this name; if we 408 // have, get it instead of trying to create a new one 409 ConfigurableAttribute svgIconAttrib = getExistingOrNewAttribute( 410 namedObj, attribName); 411 412 StringBuffer buff = new StringBuffer(iconBasePath); 413 414 // ensure last char of iconBasePath is a slash: 415 if (!iconBasePath.endsWith("/")) { 416 buff.append("/"); 417 } 418 419 buff.append(iconBaseName.trim()); 420 421 // ensure iconExtension contains a ".": 422 if (iconExtension.indexOf(PERIOD) < 0) { 423 buff.append(PERIOD); 424 } 425 426 buff.append(iconExtension); 427 if (isDebugging) { 428 log.debug("_addIconAttributeToNamedObj(): " + "\n actor is: " 429 + namedObj.getClassName() + "\n attribute name: " 430 + attribName + "\n setExpression:" + buff.toString()); 431 } 432 svgIconAttrib.setExpression(buff.toString()); 433 434 // set non-persistent so it doesn't get saved in MOML 435 svgIconAttrib.setPersistent(false); 436 437 if (isDebugging) { 438 log.debug("from actual svgIconAttrib: " 439 + "\n svgIconAttrib.getExpression() = " 440 + svgIconAttrib.getExpression() 441 + "\n svgIconAttrib.getContainer() = " 442 + svgIconAttrib.getContainer().getClass().getName()); 443 } 444 } 445 446 private static ConfigurableAttribute getExistingOrNewAttribute( 447 NamedObj namedObj, String attribName) { 448 449 ConfigurableAttribute attrib = null; 450 try { 451 attrib = (ConfigurableAttribute) namedObj.getAttribute(attribName); 452 } catch (Exception ex) { 453 ex.printStackTrace(); 454 if (isDebugging) { 455 log.warn(namedObj.getClass().getName() 456 + ") : exception getting svgIcon attribute: " 457 + attribName + "; exception was: " + ex.getMessage() 458 + "\n\n"); 459 } 460 attrib = null; 461 } 462 if (attrib != null) { 463 return attrib; 464 } 465 466 try { 467 // the Attribute is automatically added to namedObj as an attribute, 468 // simply by passing namedObj to the constructor 469 attrib = new ConfigurableAttribute(namedObj, attribName); 470 } catch (Exception ex) { 471 ex.printStackTrace(); 472 if (isDebugging) { 473 log.warn(namedObj.getClass().getName() 474 + ") : exception getting svgIcon attribute: " 475 + attribName + "; exception was: " + ex.getMessage() 476 + "\n\n"); 477 } 478 attrib = null; 479 } 480 return attrib; 481 } 482 483 private static ConfigurationProperty getByClassResBundle() 484 throws IOException { 485 486 //System.out.println("byClassProperty: " + byClassProperty); 487 if (byClassProperty == null) { 488 byClassProperty = StaticResources.getUiSVGIconMappingsByClass(); 489 } 490 return byClassProperty; 491 } 492 493 private static ConfigurationProperty getByLSIDResBundle() 494 throws IOException { 495 496 if (byLSIDProperty == null) { 497 byLSIDProperty = StaticResources.getUiSVGIconMappingsByLSID(); 498 } 499 return byLSIDProperty; 500 } 501 502 // ///////////////////////////////////////////////////////////////// 503 // // private variables //// 504 // ///////////////////////////////////////////////////////////////// 505 506 private static ConfigurationProperty byClassProperty; 507 private static ConfigurationProperty byLSIDProperty; 508 private static ConfigurationProperty _iconForSemanticTypeProp; 509}