001/* Remove graphical classes 002 003 Copyright (c) 1998-2016 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 */ 028package ptolemy.moml.filter; 029 030import java.util.HashMap; 031import java.util.Iterator; 032 033import ptolemy.kernel.util.NamedObj; 034import ptolemy.moml.MoMLParser; 035 036/////////////////////////////////////////////////////////////////// 037//// RemoveGraphicalClasses 038 039/** When this class is registered with the MoMLParser.setMoMLFilter() 040 method, it will cause MoMLParser to filter out graphical classes. 041 042 <p>This is very useful for running applets with out requiring files 043 like diva.jar to be downloaded. It is also used by the nightly build to 044 run tests when there is no graphical display present.</p> 045 046 <p> See ptolemy.moml.filter.RemoveGraphicalClassesApplication for 047 an application that will remove graphical classes from a file.</p> 048 049 @author Edward A. Lee, Christopher Hylands 050 @version $Id$ 051 @since Ptolemy II 2.0 052 @Pt.ProposedRating Red (cxh) 053 @Pt.AcceptedRating Red (cxh) 054 */ 055public class RemoveGraphicalClasses extends MoMLFilterSimple { 056 /** Construct a filter that removes graphical classes. 057 */ 058 public RemoveGraphicalClasses() { 059 if (_graphicalClasses == null) { 060 initialize(); 061 } 062 } 063 064 /** Clear the map of graphical classes to be removed. 065 */ 066 public static void clear() { 067 _graphicalClasses = new HashMap(); 068 } 069 070 /** Filter for graphical classes and return new values if 071 * a graphical class is found. 072 * An internal HashMap maps names of graphical entities to 073 * new names. The HashMap can also map a graphical entity 074 * to null, which means the entity is removed from the model. 075 * All class attributeValues that start with "ptolemy.domains.gr" 076 * are deemed to be graphical elements and null is always returned. 077 * For example, if the attributeValue is "ptolemy.vergil.icon.ValueIcon", 078 * or "ptolemy.vergil.basic.NodeControllerFactory" 079 * then return "ptolemy.kernel.util.Attribute"; if the attributeValue 080 * is "ptolemy.vergil.icon.AttributeValueIcon" or 081 * "ptolemy.vergil.icon.BoxedValueIcon" then return null, which 082 * will cause the MoMLParser to skip the rest of the element; 083 * otherwise return the original value of the attributeValue. 084 * 085 * @param container The container for this attribute, ignored 086 * in this method. 087 * @param element The XML element name. 088 * @param attributeName The name of the attribute, ignored 089 * in this method. 090 * @param attributeValue The value of the attribute. 091 * @param xmlFile The file currently being parsed. 092 * @return the filtered attributeValue. 093 */ 094 @Override 095 public String filterAttributeValue(NamedObj container, String element, 096 String attributeName, String attributeValue, String xmlFile) { 097 if (_graphicalClasses == null) { 098 initialize(); 099 } 100 // If the nightly build is failing with messages like: 101 // " X connection to foo:0 broken (explicit kill or server shutdown)." 102 // Try uncommenting the next lines to see what is being 103 // expanding before the error: 104 //System.out.println("filterAttributeValue: " + container + "\t" 105 // + attributeName + "\t" + attributeValue); 106 if (attributeValue == null) { 107 return null; 108 } else if (_graphicalClasses.containsKey(attributeValue)) { 109 MoMLParser.setModified(true); 110 return (String) _graphicalClasses.get(attributeValue); 111 } else if (_removeGR 112 && attributeValue.startsWith("ptolemy.domains.gr")) { 113 MoMLParser.setModified(true); 114 return null; 115 } 116 117 return attributeValue; 118 } 119 120 /** In this class, do nothing. 121 * @param container The object created by this element. 122 * @param elementName The element name. 123 * @param currentCharData The character data, which appears 124 * only in the doc and configure elements 125 * @param xmlFile The file currently being parsed. 126 * @exception Exception Not thrown in this base class. 127 */ 128 @Override 129 public void filterEndElement(NamedObj container, String elementName, 130 StringBuffer currentCharData, String xmlFile) throws Exception { 131 } 132 133 /** Initialize the set of classes to remove. */ 134 public static void initialize() { 135 _graphicalClasses = new HashMap(); 136 137 // Alphabetical by key class 138 // We can convert any graphical classes that have a port named "input" to 139 // a DiscardDoubles actor. However, classes like XYPlot have ports named "X" and Y", 140 // so XYPlot cannot be converted. 141 142 // We use DiscardDoublesArray here so that the types are preserved 143 // in case enableBackwardTypeInference is set. 144 _graphicalClasses.put("ptolemy.actor.lib.gui.ArrayPlotter", 145 "ptolemy.moml.filter.DiscardDoublesArray"); 146 _graphicalClasses.put("ptolemy.actor.lib.gui.BarGraph", 147 "ptolemy.moml.filter.DiscardDoublesArray"); 148 149 // Display's input port is of type General. 150 _graphicalClasses.put("ptolemy.actor.lib.gui.Display", 151 "ptolemy.actor.lib.Discard"); 152 // Classes that extend Display 153 _graphicalClasses.put("ptolemy.actor.lib.gui.TimedDisplay", 154 "ptolemy.actor.lib.Discard"); 155 _graphicalClasses.put("ptolemy.domains.taskpt.lib.gui.DisplayAll", 156 "ptolemy.actor.lib.Discard"); 157 158 // We use DiscardDoubles here so that the types are preserved 159 // in case enableBackwardTypeInference is set. 160 _graphicalClasses.put("ptolemy.actor.lib.gui.HistogramPlotter", 161 "ptolemy.moml.filter.DiscardDoubles"); 162 _graphicalClasses.put("ptolemy.actor.lib.gui.RealTimePlotter", 163 "ptolemy.moml.filter.DiscardDoubles"); 164 _graphicalClasses.put("ptolemy.actor.lib.gui.TimedPlotter", 165 "ptolemy.moml.filter.DiscardDoubles"); 166 _graphicalClasses.put("ptolemy.actor.lib.gui.SequencePlotter", 167 "ptolemy.moml.filter.DiscardDoubles"); 168 _graphicalClasses.put("ptolemy.vergil.actor.lib.LEDMatrix", 169 "ptolemy.moml.filter.DiscardDoubles"); 170 171 _graphicalClasses.put("ptolemy.data.properties.gui.PropertyHighlighter", 172 null); 173 174 _graphicalClasses.put("ptolemy.domains.sr.lib.gui.NonStrictDisplay", 175 "ptolemy.actor.lib.Discard"); 176 177 // Generated applet from moml/demo/modulation.xml 178 // fails to run if substitute Attribute for NodeControllerFactory 179 // so we set it to null instead. 180 _graphicalClasses.put("ptolemy.vergil.toolbox.AnnotationEditorFactory", 181 "ptolemy.kernel.util.Attribute"); 182 _graphicalClasses.put( 183 "ptolemy.vergil.toolbox.VisibleParameterEditorFactory", 184 "ptolemy.kernel.util.Attribute"); 185 _graphicalClasses.put( 186 "ptolemy.vergil.fsm.modal.HierarchicalStateControllerFactory", 187 "ptolemy.kernel.util.Attribute"); 188 _graphicalClasses.put( 189 "ptolemy.vergil.modal.modal.HierarchicalStateControllerFactory", 190 "ptolemy.kernel.util.Attribute"); 191 _graphicalClasses.put("ptolemy.vergil.fsm.modal.ModalTableauFactory", 192 "ptolemy.kernel.util.Attribute"); 193 _graphicalClasses.put("ptolemy.vergil.modal.modal.ModalTableauFactory", 194 "ptolemy.kernel.util.Attribute"); 195 _graphicalClasses.put("ptolemy.vergil.ptera.PteraGraphTableau$Factory", 196 "ptolemy.kernel.util.Attribute"); 197 _graphicalClasses.put( 198 "ptolemy.vergil.gt.TransformationAttributeEditorFactory", 199 "ptolemy.kernel.util.Attribute"); 200 _graphicalClasses.put("ptolemy.vergil.gt.MatchResultTableau$Factory", 201 "ptolemy.kernel.util.Attribute"); 202 _graphicalClasses.put("ptolemy.vergil.gt.GTTableau$Factory", 203 "ptolemy.kernel.util.Attribute"); 204 _graphicalClasses.put("ptolemy.vergil.gt.GTTableau$ModalTableauFactory", 205 "ptolemy.kernel.util.Attribute"); 206 207 // 4/04 BooleanSwitch uses EditorIcon 208 _graphicalClasses.put("ptolemy.vergil.icon.EditorIcon", null); 209 210 // 11/06 FSM uses StateIcon 211 _graphicalClasses.put("ptolemy.vergil.fsm.StateIcon", null); 212 213 _graphicalClasses.put("ptolemy.vergil.modal.StateIcon", null); 214 215 _graphicalClasses.put("ptolemy.vergil.fsm.fmv.FmvStateIcon", null); 216 217 _graphicalClasses.put("ptolemy.vergil.modal.fmv.FmvStateIcon", null); 218 219 _graphicalClasses.put("ptolemy.ontologies.ConceptIcon", null); 220 221 _graphicalClasses.put("ptolemy.vergil.kernel.attributes.ArcAttribute", 222 null); 223 224 _graphicalClasses 225 .put("ptolemy.vergil.kernel.attributes.EllipseAttribute", null); 226 227 _graphicalClasses.put( 228 "ptolemy.vergil.kernel.attributes.FilledShapeAttribute", null); 229 230 _graphicalClasses.put("ptolemy.vergil.kernel.attributes.IDAttribute", 231 null); 232 233 _graphicalClasses.put("ptolemy.vergil.kernel.attributes.ImageAttribute", 234 null); 235 236 _graphicalClasses.put("ptolemy.vergil.kernel.attributes.ArrowAttribute", 237 null); 238 239 _graphicalClasses.put("ptolemy.vergil.kernel.attributes.LineAttribute", 240 null); 241 242 _graphicalClasses.put("ptolemy.vergil.kernel.attributes.ShapeAttribute", 243 null); 244 245 _graphicalClasses.put( 246 "ptolemy.vergil.kernel.attributes.ResizablePolygonAttribute", 247 null); 248 249 _graphicalClasses.put( 250 "ptolemy.vergil.kernel.attributes.RectangleAttribute", null); 251 252 _graphicalClasses.put("ptolemy.vergil.kernel.attributes.TextAttribute", 253 null); 254 255 _graphicalClasses.put("ptolemy.vergil.basic.export.web.BasicJSPlotter", 256 null); 257 _graphicalClasses 258 .put("ptolemy.vergil.basic.export.web.DygraphsJSPlotter", null); 259 // Classes that import ptolemy.vergil.icon.ValueIcon 260 _graphicalClasses.put("ptolemy.vergil.basic.export.web.DefaultIconLink", 261 null); 262 _graphicalClasses 263 .put("ptolemy.vergil.basic.export.web.DefaultIconScript", null); 264 _graphicalClasses.put("ptolemy.vergil.basic.export.web.DefaultTitle", 265 null); 266 _graphicalClasses.put("ptolemy.vergil.basic.export.web.HTMLImage", 267 null); 268 // HTMLText extends WebContent which imports ValueIcon 269 _graphicalClasses.put("ptolemy.vergil.basic.export.web.HTMLText", null); 270 _graphicalClasses.put("ptolemy.vergil.basic.export.web.IconLink", null); 271 _graphicalClasses.put("ptolemy.vergil.basic.export.web.IconScript", 272 null); 273 _graphicalClasses.put( 274 "ptolemy.vergil.basic.export.web.LinkToOpenTableaux", null); 275 _graphicalClasses.put( 276 "ptolemy.vergil.basic.export.web.ParameterDisplayIconScript", 277 null); 278 _graphicalClasses.put("ptolemy.vergil.basic.export.web.Title", null); 279 _graphicalClasses.put("ptolemy.vergil.basic.export.web.WebContent", 280 null); 281 _graphicalClasses.put("ptolemy.vergil.basic.export.web.WebExportable", 282 null); 283 284 _graphicalClasses.put("ptolemy.vergil.basic.NodeControllerFactory", 285 null); 286 287 _graphicalClasses.put("ptolemy.vergil.ptera.EventIcon", null); 288 _graphicalClasses.put("ptolemy.vergil.ptera.OctagonEventIcon", null); 289 _graphicalClasses.put("ptolemy.vergil.ptera.TestIcon", null); 290 _graphicalClasses.put("ptolemy.vergil.ptera.TimeAdvanceEventIcon", 291 null); 292 293 _graphicalClasses.put("ptolemy.vergil.gt.IterativeParameterIcon", null); 294 _graphicalClasses.put("ptolemy.vergil.gt.StateMatcherIcon", null); 295 _graphicalClasses.put("ptolemy.vergil.gt.TransformationAttributeIcon", 296 null); 297 298 _graphicalClasses.put("ptolemy.vergil.ptera.TimeAdvanceEventIcon", 299 null); 300 301 _graphicalClasses.put("ptolemy.vergil.icon.AttributeValueIcon", null); 302 _graphicalClasses.put("ptolemy.vergil.icon.BoxedValueIcon", null); 303 _graphicalClasses.put("ptolemy.vergil.icon.DesignPatternIcon", null); 304 _graphicalClasses.put("ptolemy.vergil.icon.CopyCatIcon", null); 305 _graphicalClasses.put("ptolemy.vergil.icon.EditorIcon", null); 306 _graphicalClasses.put("ptolemy.vergil.icon.ShapeIcon", null); 307 _graphicalClasses.put("ptolemy.vergil.icon.XMLIcon", null); 308 309 // ptolemy/actor/lib/test/auto/StopSDF.xml has a MonitorValue actor, 310 // so remove the UpdatedValueIcon. 311 _graphicalClasses.put("ptolemy.vergil.icon.UpdatedValueIcon", null); 312 _graphicalClasses.put("ptolemy.vergil.icon.ValueIcon", 313 "ptolemy.kernel.util.Attribute"); 314 315 // Generated applet from moml/demo/modulation.xml 316 // fails to run if substitute Attribute for AnnotationEditorFactory 317 // so we set it to null instead. 318 //_graphicalClasses.put("ptolemy.vergil.toolbox.AnnotationEditorFactory", 319 // "ptolemy.kernel.util.Attribute"); 320 _graphicalClasses.put("ptolemy.vergil.toolbox.AnnotationEditorFactory", 321 null); 322 _graphicalClasses.put( 323 "ptolemy.vergil.toolbox" + ".VisibleParameterEditorFactory", 324 "ptolemy.kernel.util.Attribute"); 325 326 // Shallow CG of actor/lib/test/auto/URLDirectoryReader3.xml fails 327 // unless we remove CheckBoxStyle 328 _graphicalClasses.put("ptolemy.actor.gui.style.CheckBoxStyle", null); 329 _graphicalClasses.put("ptolemy.actor.gui.style.ChoiceStyle", null); 330 331 _graphicalClasses.put("ptolemy.actor.gui.LocationAttribute", null); 332 _graphicalClasses.put("ptolemy.actor.gui.SizeAttribute", null); 333 _graphicalClasses.put("ptolemy.actor.gui.PtolemyPreferences", 334 "ptolemy.data.expr.ScopeExtendingAttribute"); 335 _graphicalClasses.put("ptolemy.actor.gui.WindowPropertiesAttribute", 336 null); 337 338 // Sinewave has a DocViewerFactory, which we need to remove 339 _graphicalClasses.put("ptolemy.vergil.basic.DocViewerFactory", 340 "ptolemy.kernel.util.Attribute"); 341 // Sinewave has a DocAttribute, which we need to remove 342 _graphicalClasses.put("ptolemy.vergil.basic.DocAttribute", 343 "ptolemy.kernel.util.Attribute"); 344 345 _graphicalClasses.put("ptolemy.domains.wireless.lib.GraphicalLocator", 346 "ptolemy.domains.wireless.lib.Locator"); 347 348 _graphicalClasses.put("ptolemy.domains.wireless.lib.TerrainProperty", 349 null); 350 351 _graphicalClasses.put( 352 "ptolemy.domains.wireless.demo.EvaderAndPursuer.Sensor", null); 353 354 // Remove various graphical classes from curriculum 355 _graphicalClasses 356 .put("ptolemy.domains.curriculum.DependencyHighlighter", null); 357 _graphicalClasses.put("ptolemy.vergil.basic.DependencyHighlighter", 358 null); 359 _graphicalClasses.put("ptolemy.domains.curriculum.HighlightEntities", 360 "ptolemy.kernel.util.Attribute"); 361 _graphicalClasses.put("ptolemy.vergil.icon.NameIcon", null); 362 363 // Needed modal/demo/SystemLevelTypes/*.xml 364 _graphicalClasses.put("ptolemy.vergil.modal.StateIcon", null); 365 366 // Exclude DependencyHighlighter 367 _graphicalClasses.put("ptolemy.actor.gui.DependencyHighlighter", null); 368 369 // properties classes 370 _graphicalClasses.put( 371 "ptolemy.vergil.properties.ModelAttributeController", null); 372 373 _graphicalClasses.put("ptolemy.vergil.properties.LatticeElementIcon", 374 null); 375 376 _graphicalClasses 377 .put("ptolemy.vergil.actor.lib.MonitorReceiverContents", null); 378 379 _graphicalClasses.put("ptolemy.vergil.ontologies.ConceptIcon", null); 380 _graphicalClasses.put("ptolemy.vergil.ontologies.MultipleConceptIcon", 381 null); 382 383 _graphicalClasses.put( 384 "ptolemy.domains.petrinet.lib.gui.PetriNetDisplay", 385 "ptolemy.domains.petrinet.lib.PetriNetRecorder"); 386 387 _graphicalClasses.put( 388 "ptolemy.domains.ptides.demo.PtidesAirplaneFuelControl.Tank", 389 "ptolemy.domains.wireless.kernel.WirelessComposite"); 390 391 _graphicalClasses.put("ptolemy.actor.lib.image.ImageDisplay", 392 "ptolemy.moml.filter.DiscardGenerals"); 393 // Classes that extend ImageDisplay 394 _graphicalClasses.put("ptolemy.domains.sdf.lib.vq.ImageDisplay", 395 "ptolemy.moml.filter.DiscardGenerals"); 396 397 // FIXME: If this actors are used when enabledBackwardTypeInference 398 // is set, then the type of Discard is not the same as the type 399 // of MatrixViewer. 400 _graphicalClasses.put("ptolemy.actor.lib.gui.MatrixViewer", 401 "ptolemy.actor.lib.Discard"); 402 403 // org/ptolemy/qss/test/auto/RLC.xml 404 _graphicalClasses.put("ptolemy.vergil.pdfrenderer.PDFAttribute", null); 405 406 //note: kepler display related actors should not be added here. 407 //if the actor supports '-redirectgui', it should be put into file: $Kepler/common/configs/ptolemy/configs/kepler/KeplerDisplayActorWithRedirect.xml. 408 //if the actor does not support '-redirectgui', it should be put into file: $Kepler/common/configs/ptolemy/configs/kepler/KeplerDisplayActorNoRedirect.xml. 409 410 _graphicalClasses.put("ptolemy.vergil.actor.LayoutHint", null); 411 412 } 413 414 /** Remove a class to be filtered. 415 * @param className The name of the class to be filtered 416 * out, for example "ptolemy.copernicus.kernel.GeneratorAttribute". 417 * @see #put(String, String) 418 */ 419 public void remove(String className) { 420 // ptolemy.copernicus.kernel.MakefileGenerator 421 // so as to filter out the GeneratorAttribute 422 _graphicalClasses.remove(className); 423 } 424 425 /** Add a class to be filtered for and its replacement if the class 426 * is found. If the replacement is null, then the rest of the 427 * attribute is skipped. Note that if you add a class with 428 * this method, then you must remove it with {@link #remove(String)}, 429 * calling 'new RemoveGraphicalClasses' will not remove a class 430 * that was added with this method. 431 * @param className The name of the class to be filtered 432 * out, for example "ptolemy.copernicus.kernel.GeneratorAttribute". 433 * @param replacement The name of the class to be used if 434 * className is found. If this argument is null then the 435 * rest of the attribute is skipped. 436 * @see #remove(String) 437 */ 438 public void put(String className, String replacement) { 439 // ptolemy.copernicus.kernel.KernelMain call this method 440 // so as to filter out the GeneratorAttribute 441 _graphicalClasses.put(className, replacement); 442 } 443 444 /** Set to true if we should removed classes that start with 445 * ptolemy.domains.gr. 446 * @param removeGR True if we should remove classes that start 447 * with ptolemy.domains.gr. 448 */ 449 public void setRemoveGR(boolean removeGR) { 450 _removeGR = removeGR; 451 } 452 453 /** Return a string that describes what the filter does. 454 * @return the description of the filter that ends with a newline. 455 */ 456 @Override 457 public String toString() { 458 StringBuffer results = new StringBuffer(getClass().getName() 459 + ": Remove or replace classes that are graphical.\n" 460 + "This filter is used by the nightly build, and\n" 461 + "can be used to run applets so that files like\n" 462 + "diva.jar do not need to be downloaded.\n" 463 + "The following actors are affected:\n"); 464 Iterator classNames = _graphicalClasses.keySet().iterator(); 465 466 while (classNames.hasNext()) { 467 String oldClassName = (String) classNames.next(); 468 String newClassName = (String) _graphicalClasses.get(oldClassName); 469 470 if (newClassName == null) { 471 results.append(oldClassName + " will be removed\n"); 472 } else { 473 results.append(oldClassName + " will be replaced by " 474 + newClassName + "\n"); 475 } 476 } 477 478 return results.toString(); 479 } 480 481 /////////////////////////////////////////////////////////////////// 482 //// private variables //// 483 484 /** Map of actor names a HashMap of graphical classes to their 485 * non-graphical counterparts, usually either 486 * ptolemy.kernel.util.Attribute or null. 487 */ 488 private static HashMap _graphicalClasses; 489 490 /** True if we should remove the GR domain. */ 491 private boolean _removeGR = false; 492}