Coverage Report - org.argouml.application.helpers.ResourceLoaderWrapper
 
Classes in this File Line Coverage Branch Coverage Complexity
ResourceLoaderWrapper
86%
195/225
38%
14/36
2.917
 
 1  
 /* $Id: ResourceLoaderWrapper.java 18324 2010-04-22 11:33:25Z bobtarling $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009-2010 Contributors - see below
 4  
  * All rights reserved. This program and the accompanying materials
 5  
  * are made available under the terms of the Eclipse Public License v1.0
 6  
  * which accompanies this distribution, and is available at
 7  
  * http://www.eclipse.org/legal/epl-v10.html
 8  
  *
 9  
  * Contributors:
 10  
  *    Thomas Neustupny
 11  
  *    Bob Tarling
 12  
  *    
 13  
  *****************************************************************************
 14  
  *
 15  
  * Some portions of this file was previously release using the BSD License:
 16  
  */
 17  
 
 18  
 // Copyright (c) 1996-2008 The Regents of the University of California. All
 19  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 20  
 // software and its documentation without fee, and without a written
 21  
 // agreement is hereby granted, provided that the above copyright notice
 22  
 // and this paragraph appear in all copies. This software program and
 23  
 // documentation are copyrighted by The Regents of the University of
 24  
 // California. The software program and documentation are supplied "AS
 25  
 // IS", without any accompanying services from The Regents. The Regents
 26  
 // does not warrant that the operation of the program will be
 27  
 // uninterrupted or error-free. The end-user understands that the program
 28  
 // was developed for research purposes and is advised not to rely
 29  
 // exclusively on the program for any reason. IN NO EVENT SHALL THE
 30  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 31  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 32  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 33  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 34  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 35  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 36  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 37  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 38  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 39  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 40  
 
 41  
 package org.argouml.application.helpers;
 42  
 
 43  
 import java.net.URL;
 44  
 import java.util.HashMap;
 45  
 import java.util.Hashtable;
 46  
 import java.util.Map;
 47  
 
 48  
 import javax.swing.Icon;
 49  
 import javax.swing.ImageIcon;
 50  
 import javax.swing.UIManager;
 51  
 
 52  
 import org.apache.log4j.Logger;
 53  
 import org.argouml.i18n.Translator;
 54  
 import org.argouml.model.DataTypesHelper;
 55  
 import org.argouml.model.InvalidElementException;
 56  
 import org.argouml.model.Model;
 57  
 
 58  
 
 59  
 /**
 60  
  * Wrapper around org.tigris.gef.util.ResourceLoader.<p>
 61  
  *
 62  
  * Necessary since ArgoUML needs some extra init.
 63  
  *
 64  
  * @since Nov 24, 2002
 65  
  * @author jaap.branderhorst@xs4all.nl 
 66  
  * @stereotype singleton
 67  
  */
 68  
 public final class ResourceLoaderWrapper {
 69  
 
 70  
     /**
 71  
      * Logger.
 72  
      */
 73  900
     private static final Logger LOG =
 74  
         Logger.getLogger(ResourceLoaderWrapper.class);
 75  
 
 76  
     private static ImageIcon initialStateIcon;
 77  
     private static ImageIcon deepIcon;
 78  
     private static ImageIcon shallowIcon;
 79  
     private static ImageIcon forkIcon;
 80  
     private static ImageIcon joinIcon;
 81  
     private static ImageIcon branchIcon;
 82  
     private static ImageIcon junctionIcon;
 83  
     private static ImageIcon realizeIcon;
 84  
     private static ImageIcon signalIcon;
 85  
     private static ImageIcon exceptionIcon;
 86  
     private static ImageIcon commentIcon;
 87  
 
 88  900
     private Hashtable<Class, Icon> iconCache = new Hashtable<Class, Icon>();
 89  
 
 90  
     /**
 91  
      * Singleton implementation.
 92  
      */
 93  900
     private static ResourceLoaderWrapper instance = new ResourceLoaderWrapper();
 94  
 
 95  
 
 96  
     /**
 97  
      * Returns the singleton instance.
 98  
      *
 99  
      * @return ResourceLoaderWrapper
 100  
      */
 101  
     public static ResourceLoaderWrapper getInstance() {
 102  67339
         return instance;
 103  
     }
 104  
 
 105  
     /**
 106  
      * Constructor for ResourceLoaderWrapper.
 107  
      */
 108  900
     private ResourceLoaderWrapper() {
 109  900
         initResourceLoader();
 110  900
     }
 111  
 
 112  
     /**
 113  
      * Calculate the path to a look and feel object.
 114  
      *
 115  
      * @param classname
 116  
      *            The look and feel classname
 117  
      * @param element
 118  
      *            The en part of the path.
 119  
      * @return the complete path.
 120  
      */
 121  
     private static String lookAndFeelPath(String classname, String element) {
 122  4500
         return "/org/argouml/Images/plaf/"
 123  
             + classname.replace('.', '/')
 124  
             + "/toolbarButtonGraphics/"
 125  
             + element;
 126  
     }
 127  
 
 128  
     /**
 129  
      * Initializes the resourceloader.
 130  
      *
 131  
      * LookupIconResource checks if there are locations and extensions known.
 132  
      * If there are none, this method is called to initialize the resource
 133  
      * loader. Originally, this method was placed within Main but this coupled
 134  
      * Main and the resourceLoader too much.
 135  
      */
 136  
     private static void initResourceLoader() {
 137  
         String lookAndFeelClassName;
 138  900
         if ("true".equals(System.getProperty("force.nativelaf", "false"))) {
 139  0
             lookAndFeelClassName = UIManager.getSystemLookAndFeelClassName();
 140  
         } else {
 141  900
             lookAndFeelClassName = "javax.swing.plaf.metal.MetalLookAndFeel";
 142  
         }
 143  900
         String lookAndFeelGeneralImagePath =
 144  
             lookAndFeelPath(lookAndFeelClassName, "general");
 145  900
         String lookAndFeelNavigationImagePath =
 146  
             lookAndFeelPath(lookAndFeelClassName, "navigation");
 147  900
         String lookAndFeelDiagramImagePath =
 148  
             lookAndFeelPath(lookAndFeelClassName, "argouml/diagrams");
 149  900
         String lookAndFeelElementImagePath =
 150  
             lookAndFeelPath(lookAndFeelClassName, "argouml/elements");
 151  900
         String lookAndFeelArgoUmlImagePath =
 152  
             lookAndFeelPath(lookAndFeelClassName, "argouml");
 153  900
         ResourceLoader.addResourceExtension("gif");
 154  900
         ResourceLoader.addResourceExtension("png");
 155  900
         ResourceLoader.addResourceLocation(lookAndFeelGeneralImagePath);
 156  900
         ResourceLoader.addResourceLocation(lookAndFeelNavigationImagePath);
 157  900
         ResourceLoader.addResourceLocation(lookAndFeelDiagramImagePath);
 158  900
         ResourceLoader.addResourceLocation(lookAndFeelElementImagePath);
 159  900
         ResourceLoader.addResourceLocation(lookAndFeelArgoUmlImagePath);
 160  900
         ResourceLoader.addResourceLocation("/org/argouml/Images");
 161  900
         ResourceLoader.addResourceLocation("/org/tigris/gef/Images");
 162  
 
 163  
         // Initialze GEF's version of the loader too
 164  
         // TODO: We should probably be passing icons that we loaded ourselves
 165  
         // but there doesn't seem to be a way to do that with GEF - tfm
 166  900
         org.tigris.gef.util.ResourceLoader.addResourceExtension("gif");
 167  900
         org.tigris.gef.util.ResourceLoader.addResourceExtension("png");
 168  900
         org.tigris.gef.util.ResourceLoader
 169  
                 .addResourceLocation(lookAndFeelGeneralImagePath);
 170  900
         org.tigris.gef.util.ResourceLoader
 171  
                 .addResourceLocation(lookAndFeelNavigationImagePath);
 172  900
         org.tigris.gef.util.ResourceLoader
 173  
                 .addResourceLocation(lookAndFeelDiagramImagePath);
 174  900
         org.tigris.gef.util.ResourceLoader
 175  
                 .addResourceLocation(lookAndFeelElementImagePath);
 176  900
         org.tigris.gef.util.ResourceLoader
 177  
                 .addResourceLocation(lookAndFeelArgoUmlImagePath);
 178  900
         org.tigris.gef.util.ResourceLoader
 179  
                 .addResourceLocation("/org/argouml/Images");
 180  900
         org.tigris.gef.util.ResourceLoader
 181  
                 .addResourceLocation("/org/tigris/gef/Images");
 182  
         
 183  900
         initialStateIcon = ResourceLoader.lookupIconResource("Initial");
 184  900
         deepIcon = ResourceLoader.lookupIconResource("DeepHistory");
 185  900
         shallowIcon = ResourceLoader.lookupIconResource("ShallowHistory");
 186  900
         forkIcon = ResourceLoader.lookupIconResource("Fork");
 187  900
         joinIcon = ResourceLoader.lookupIconResource("Join");
 188  900
         branchIcon = ResourceLoader.lookupIconResource("Choice");
 189  900
         junctionIcon = ResourceLoader.lookupIconResource("Junction");
 190  900
         realizeIcon = ResourceLoader.lookupIconResource("Realization");
 191  900
         signalIcon = ResourceLoader.lookupIconResource("SignalSending");
 192  900
         exceptionIcon = ResourceLoader.lookupIconResource("Exception");
 193  900
         commentIcon = ResourceLoader.lookupIconResource("Note");
 194  900
     }
 195  
 
 196  
     /**
 197  
      * This public operation is needed 
 198  
      * to allow modules to add their own images.
 199  
      * 
 200  
      * @param location the path were the images are
 201  
      */
 202  
     public static void addResourceLocation(String location) {
 203  0
         ResourceLoader.addResourceLocation(location);
 204  0
     }
 205  
 
 206  
     /**
 207  
      * Find the correct icon for a key.
 208  
      *
 209  
      * @param resource The name of the resource to look up.
 210  
      * @return The ImageIcon.
 211  
      */
 212  
     public static ImageIcon lookupIconResource(String resource) {
 213  37287
         return ResourceLoader.lookupIconResource(resource);
 214  
     }
 215  
 
 216  
     /**
 217  
      * Find the correct icon for a key.
 218  
      *
 219  
      * @param resource The name of the resource to look up.
 220  
      * @param desc The description for the icon.
 221  
      * @return The ImageIcon.
 222  
      */
 223  
     public static ImageIcon lookupIconResource(String resource, String desc) {
 224  127555
         return ResourceLoader.lookupIconResource(resource, desc);
 225  
     }
 226  
 
 227  
     /**
 228  
      * Look up the Icon for a key.
 229  
      *
 230  
      * @param key The key to find.
 231  
      * @return The found Icon.
 232  
      */
 233  
     public static ImageIcon lookupIcon(String key) {
 234  126636
         return lookupIconResource(getImageBinding(key),
 235  
                                   Translator.localize(key));
 236  
     }
 237  
 
 238  
     /**
 239  
      * Find the Icon for a given model element.
 240  
      *
 241  
      * @return The Icon or <code>null</code> if there is no Icon.
 242  
      * @param value The model element.
 243  
      *
 244  
      * TODO: This should not use string matching on classnames to do this
 245  
      *       since this means that we have knowledge about how the model
 246  
      *       elements are implemented outside of the Model component.
 247  
      */
 248  
     public Icon lookupIcon(Object value) {
 249  67339
         if (value == null) {
 250  0
             throw new IllegalArgumentException(
 251  
                     "Attempted to get an icon given a null key");
 252  
         }
 253  
 
 254  67339
         if (value instanceof String) {
 255  25200
             return null;
 256  
         }
 257  
 
 258  42139
         Icon icon = iconCache.get(value.getClass());
 259  
         
 260  
         try {
 261  42139
             if (Model.getFacade().isAPseudostate(value)) {
 262  
                 
 263  0
                 Object kind = Model.getFacade().getKind(value);
 264  0
                 DataTypesHelper helper = Model.getDataTypesHelper();
 265  0
                 if (helper.equalsINITIALKind(kind)) {
 266  0
                     icon = initialStateIcon;
 267  
                 }
 268  0
                 if (helper.equalsDeepHistoryKind(kind)) {
 269  0
                     icon = deepIcon;
 270  
                 }
 271  0
                 if (helper.equalsShallowHistoryKind(kind)) {
 272  0
                     icon = shallowIcon;
 273  
                 }
 274  0
                 if (helper.equalsFORKKind(kind)) {
 275  0
                     icon = forkIcon;
 276  
                 }
 277  0
                 if (helper.equalsJOINKind(kind)) {
 278  0
                     icon = joinIcon;
 279  
                 }
 280  0
                 if (helper.equalsCHOICEKind(kind)) {
 281  0
                     icon = branchIcon;
 282  
                 }
 283  0
                 if (helper.equalsJUNCTIONKind(kind)) {
 284  0
                     icon = junctionIcon;
 285  
                 }
 286  
                 // if (MPseudostateKind.FINAL.equals(kind))
 287  
                 // icon = _FinalStateIcon;
 288  
             }
 289  
             
 290  42139
             if (Model.getFacade().isAAbstraction(value)) {
 291  0
                 icon = realizeIcon;
 292  
             }
 293  42139
             if (Model.getFacade().isAException(value)) {
 294  0
                 icon = exceptionIcon;
 295  
             } else {
 296  
                 // needs more work: sending and receiving icons
 297  42139
                 if (Model.getFacade().isASignal(value)) {
 298  0
                     icon = signalIcon;
 299  
                 }
 300  
             }
 301  
             
 302  42139
             if (Model.getFacade().isAComment(value)) {
 303  0
                 icon = commentIcon;
 304  
             }
 305  
             
 306  42139
             if (icon == null) {
 307  
                 
 308  3863
                 String cName = Model.getMetaTypes().getName(value);
 309  
                 
 310  3863
                 icon = lookupIconResource(cName);
 311  3863
                 if (icon == null) {
 312  0
                     LOG.debug("Can't find icon for " + cName);
 313  
                 } else {
 314  3863
                     synchronized (iconCache) {
 315  3863
                         iconCache.put(value.getClass(), icon);
 316  3863
                     }
 317  
                 }
 318  
                 
 319  
             }
 320  0
         } catch (InvalidElementException e) {
 321  0
             LOG.debug("Attempted to get icon for deleted element");
 322  0
             return null;
 323  42139
         }
 324  42139
         return icon;
 325  
     }
 326  
 
 327  
     /**
 328  
      * Map to convert tokens into file names.
 329  
      */
 330  900
     private static Map<String, String> images = new HashMap<String, String>();
 331  
     static {
 332  900
         images.put("action.about-argouml", "AboutArgoUML");
 333  900
         images.put("action.activity-diagram", "Activity Diagram");
 334  900
         images.put("action.class-diagram", "Class Diagram");
 335  900
         images.put("action.collaboration-diagram", "Collaboration Diagram");
 336  900
         images.put("action.deployment-diagram", "Deployment Diagram");
 337  900
         images.put("action.sequence-diagram", "Sequence Diagram");
 338  900
         images.put("action.state-diagram", "State Diagram");
 339  900
         images.put("action.usecase-diagram", "Use Case Diagram");
 340  
     }
 341  
 
 342  
     static {
 343  900
         images.put("action.add-concurrent-region", "Add Concurrent Region");
 344  900
         images.put("action.add-message", "Add Message");
 345  900
         images.put("action.configure-perspectives", "ConfigurePerspectives");
 346  900
         images.put("action.copy", "Copy");
 347  900
         images.put("action.cut", "Cut");
 348  900
         images.put("action.delete-concurrent-region", "DeleteConcurrentRegion");
 349  900
         images.put("action.delete-from-model", "DeleteFromModel");
 350  900
         images.put("action.find", "Find...");
 351  900
         images.put("action.import-sources", "Import Sources...");
 352  900
         images.put("action.more-info", "More Info...");
 353  900
         images.put("action.navigate-back", "NavigateBack");
 354  900
         images.put("action.navigate-forward", "NavigateForward");
 355  900
         images.put("action.navigate-up", "NavigateUp");
 356  900
         images.put("action.new", "New");
 357  900
         images.put("action.new-profile", "NewProfile");
 358  900
         images.put("action.new-todo-item", "New To Do Item...");
 359  900
         images.put("action.open-project", "Open Project...");
 360  900
         images.put("action.page-setup", "Page Setup...");
 361  900
         images.put("action.paste", "Paste");
 362  900
         images.put("action.print", "Print...");
 363  900
         images.put("action.properties", "Properties");
 364  900
         images.put("action.remove-from-diagram", "Remove From Diagram");
 365  900
         images.put("action.resolve-item", "Resolve Item...");
 366  900
         images.put("action.save-project", "Save Project");
 367  900
         images.put("action.save-project-as", "Save Project As...");
 368  900
         images.put("action.settings", "Settings...");
 369  900
         images.put("action.snooze-critic", "Snooze Critic");
 370  900
         images.put("action.system-information", "System Information");
 371  
     }
 372  
 
 373  
     static {
 374  900
         images.put("button.broom", "Broom");
 375  900
         images.put("button.new-actionstate", "ActionState");
 376  900
         images.put("button.new-actor", "Actor");
 377  900
         images.put("button.new-aggregation", "Aggregation");
 378  900
         images.put("button.new-association", "Association");
 379  900
         images.put("button.new-associationclass", "AssociationClass");
 380  900
         images.put("button.new-association-end", "AssociationEnd");
 381  900
         images.put("button.new-associationrole", "AssociationRole");
 382  900
         images.put("button.new-attribute", "New Attribute");
 383  900
         images.put("button.new-callaction", "CallAction");
 384  900
         images.put("button.new-terminateaction", "TerminateAction");
 385  900
         images.put("button.new-uninterpretedaction", "UninterpretedAction");
 386  900
         images.put("button.new-actionsequence", "ActionSequence");
 387  900
         images.put("button.new-callaction", "CallAction");
 388  900
         images.put("button.new-callevent", "CallEvent");
 389  900
         images.put("button.new-callstate", "CallState");
 390  900
         images.put("button.new-changeevent", "ChangeEvent");
 391  900
         images.put("button.new-choice", "Choice");
 392  900
         images.put("button.new-class", "Class");
 393  900
         images.put("button.new-classifierrole", "ClassifierRole");
 394  900
         images.put("button.new-commentlink", "CommentLink");
 395  900
         images.put("button.new-component", "Component");
 396  900
         images.put("button.new-componentinstance", "ComponentInstance");
 397  900
         images.put("button.new-compositestate", "CompositeState");
 398  900
         images.put("button.new-composition", "Composition");
 399  900
         images.put("button.new-createaction", "CreateAction");
 400  900
         images.put("button.new-datatype", "DataType");
 401  900
         images.put("button.new-deephistory", "DeepHistory");
 402  900
         images.put("button.new-dependency", "Dependency");
 403  900
         images.put("button.new-destroyaction", "DestroyAction");
 404  900
         images.put("button.new-enumeration", "Enumeration");
 405  900
         images.put("button.new-enumerationliteral", "EnumerationLiteral");
 406  900
         images.put("button.new-extension-point", "New Extension Point");
 407  900
         images.put("button.new-extend", "Extend");
 408  900
         images.put("button.new-exception", "Exception");
 409  900
         images.put("button.new-extensionpoint", "ExtensionPoint");
 410  900
         images.put("button.new-guard", "Guard");
 411  900
         images.put("button.new-method", "Method");
 412  900
         images.put("button.new-message", "Message");
 413  900
         images.put("button.new-argument", "Argument");
 414  900
         images.put("button.new-property", "Property");
 415  900
         images.put("button.new-templateparameter", "TemplateParameter");
 416  
     }
 417  
 
 418  
     static {
 419  900
         images.put("button.new-finalstate", "FinalState");
 420  900
         images.put("button.new-fork", "Fork");
 421  900
         images.put("button.new-generalization", "Generalization");
 422  900
         images.put("button.new-include", "Include");
 423  900
         images.put("button.new-initial", "Initial");
 424  
     }
 425  
 
 426  
     static {
 427  900
         images.put("button.new-inner-class", "Inner Class");
 428  900
         images.put("button.new-interface", "Interface");
 429  900
         images.put("button.new-join", "Join");
 430  900
         images.put("button.new-junction", "Junction");
 431  900
         images.put("button.new-link", "Link");
 432  900
         images.put("button.new-node", "Node");
 433  900
         images.put("button.new-nodeinstance", "NodeInstance");
 434  900
         images.put("button.new-object", "Object");
 435  900
         images.put("button.new-objectflowstate", "ObjectFlowState");
 436  
     }
 437  
 
 438  
     static {
 439  900
         images.put("button.new-operation", "New Operation");
 440  900
         images.put("button.new-package", "Package");
 441  900
         images.put("button.new-parameter", "New Parameter");
 442  900
         images.put("button.new-partition", "Partition");
 443  900
         images.put("button.new-permission", "Permission");
 444  900
         images.put("button.new-profile-package", "ProfilePackage");
 445  900
         images.put("button.new-raised-signal", "New Raised Signal");
 446  900
         images.put("button.new-reception", "New Reception");
 447  900
         images.put("button.new-realization", "Realization");
 448  900
         images.put("button.new-returnaction", "ReturnAction");
 449  900
         images.put("button.new-sendaction", "SendAction");
 450  900
         images.put("button.new-shallowhistory", "ShallowHistory");
 451  900
         images.put("button.new-signal", "Signal");
 452  900
         images.put("button.new-signalevent", "SignalEvent");
 453  900
         images.put("button.new-simplestate", "SimpleState");
 454  900
         images.put("button.new-stereotype", "Stereotype");
 455  900
         images.put("button.new-stubstate", "StubState");
 456  900
         images.put("button.new-subactivitystate", "SubactivityState");
 457  900
         images.put("button.new-submachinestate", "SubmachineState");
 458  900
         images.put("button.new-synchstate", "SynchState");
 459  900
         images.put("button.new-timeevent", "TimeEvent");
 460  900
         images.put("button.new-tagdefinition", "TagDefinition");
 461  900
         images.put("button.new-transition", "Transition");
 462  900
         images.put("button.new-uniaggregation", "UniAggregation");
 463  900
         images.put("button.new-uniassociation", "UniAssociation");
 464  900
         images.put("button.new-unicomposition", "UniComposition");
 465  900
         images.put("button.new-usage", "Usage");
 466  900
         images.put("button.new-usecase", "UseCase");
 467  
     }
 468  
 
 469  
     static {
 470  900
         images.put("button.select", "Select");
 471  900
         images.put("button.sequence-expand", "SequenceExpand");
 472  900
         images.put("button.sequence-contract", "SequenceContract");
 473  900
     }
 474  
 
 475  
     /**
 476  
      * Convert the key to the image file name.
 477  
      *
 478  
      * @param name the new i18n key
 479  
      * @return the file name (base part only).
 480  
      */
 481  
     public static String getImageBinding(String name) {
 482  135779
         String found = images.get(name);
 483  135779
         if (found == null) {
 484  34708
             return name;
 485  
         }
 486  101071
         return found;
 487  
     }
 488  
     
 489  
     /**
 490  
      * Find the path to a given icon and return it as a URL.
 491  
      * 
 492  
      * @param name base name of the icon to search for
 493  
      * @param loader class loader to use or null to use the default class loader
 494  
      * @return the URL where the icon was found
 495  
      */
 496  
     public static URL lookupIconUrl(String name, ClassLoader loader) {
 497  0
         return ResourceLoader.lookupIconUrl(name, loader);
 498  
     }
 499  
     
 500  
     /**
 501  
      * Find the path to a given icon and return it as a URL.
 502  
      * 
 503  
      * @param name base name of the icon to search for
 504  
      * @return the URL where the icon was found
 505  
      */
 506  
     public static URL lookupIconUrl(String name) {
 507  0
         return lookupIconUrl(name, null);
 508  
     }
 509  
 }