001/* An action that generates the Moml for a group of states to be used as a 002 design pattern. 003 004 Copyright (c) 2008-2014 The Regents of the University of California. 005 All rights reserved. 006 Permission is hereby granted, without written agreement and without 007 license or royalty fees, to use, copy, modify, and distribute this 008 software and its documentation for any purpose, provided that the above 009 copyright notice and the following two paragraphs appear in all copies 010 of this software. 011 012 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 013 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 014 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 015 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 016 SUCH DAMAGE. 017 018 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 019 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 020 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 021 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 022 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 023 ENHANCEMENTS, OR MODIFICATIONS. 024 025 PT_COPYRIGHT_VERSION_2 026 COPYRIGHTENDKEY 027 028 */ 029package ptolemy.actor; 030 031import java.io.StringWriter; 032import java.util.HashMap; 033import java.util.HashSet; 034import java.util.List; 035 036import ptolemy.data.BooleanToken; 037import ptolemy.data.expr.Parameter; 038import ptolemy.data.expr.StringParameter; 039import ptolemy.kernel.ComponentEntity; 040import ptolemy.kernel.ComponentRelation; 041import ptolemy.kernel.CompositeEntity; 042import ptolemy.kernel.Port; 043import ptolemy.kernel.util.Attribute; 044import ptolemy.kernel.util.InternalErrorException; 045import ptolemy.kernel.util.NamedObj; 046import ptolemy.util.StringUtilities; 047 048/** 049 An action that generates the Moml for a group of states to be used as a 050 design pattern. 051 052 @author Thomas Huining Feng 053 @version $Id$ 054 @since Ptolemy II 8.0 055 @Pt.ProposedRating Red (tfeng) 056 @Pt.AcceptedRating Red (tfeng) 057 */ 058public class DesignPatternGetMoMLAction { 059 060 /** Generate the Moml string for the given object. If the object is a group 061 * of states, then the contents of the group are generated; otherwise, the 062 * Moml of the object itself is generated with {@link 063 * NamedObj#exportMoML(String)}. 064 * 065 * @param object The object. 066 * @param name The name to be used for the object in the generated Moml. 067 * @return The Moml string. 068 */ 069 public String getMoml(NamedObj object, String name) { 070 CompositeEntity group = (CompositeEntity) object; 071 Attribute before = object.getAttribute("Before"); 072 Attribute after = object.getAttribute("After"); 073 StringWriter buffer = new StringWriter(); 074 int extraIndent = 0; 075 try { 076 buffer.write("<group>\n"); 077 078 if (before != null) { 079 String oldType = null; 080 StringParameter typeParameter = (StringParameter) before 081 .getAttribute("_type"); 082 if (typeParameter == null) { 083 typeParameter = new StringParameter(before, "_type"); 084 } else { 085 oldType = typeParameter.getExpression(); 086 } 087 typeParameter.setExpression("immediate"); 088 try { 089 buffer.write( 090 StringUtilities.getIndentPrefix(1) + "<group>\n"); 091 before.exportMoML(buffer, 2); 092 buffer.write( 093 StringUtilities.getIndentPrefix(1) + "</group>\n"); 094 } finally { 095 if (oldType == null) { 096 typeParameter.setContainer(null); 097 } else { 098 typeParameter.setExpression(oldType); 099 } 100 } 101 } 102 103 if (after != null || before != null) { 104 extraIndent++; 105 buffer.write(StringUtilities.getIndentPrefix(extraIndent) 106 + "<group>\n"); 107 } 108 109 List<Attribute> attributes = group.attributeList(); 110 for (Attribute attribute : attributes) { 111 if (!_IGNORED_ATTRIBUTES.contains(attribute.getName()) 112 && (after == null || attribute != after) 113 && (before == null || attribute != before)) { 114 attribute.exportMoML(buffer, extraIndent + 1); 115 if (attribute instanceof Parameter) { 116 String parameterName = attribute.getName(); 117 String expression = _overriddenParameters 118 .get(parameterName); 119 if (expression != null) { 120 buffer.write(StringUtilities 121 .getIndentPrefix(extraIndent + 1) 122 + "<property name=\"" + parameterName 123 + "\" value=\"" + expression + "\">\n"); 124 buffer.write(StringUtilities.getIndentPrefix( 125 extraIndent + 1) + "</property>\n"); 126 } 127 } 128 } 129 } 130 131 List<Port> ports = group.portList(); 132 for (Port port : ports) { 133 buffer.write(StringUtilities.getIndentPrefix(extraIndent + 1) 134 + "<port name=\"" + port.getName() + "\">\n"); 135 if (port instanceof IOPort) { 136 IOPort ioPort = (IOPort) port; 137 boolean isInput = ioPort.isInput(); 138 boolean isOutput = ioPort.isOutput(); 139 if (isInput) { 140 buffer.write( 141 StringUtilities.getIndentPrefix(extraIndent + 2) 142 + "<property name=\"input\"/>\n"); 143 } 144 if (isOutput) { 145 buffer.write( 146 StringUtilities.getIndentPrefix(extraIndent + 2) 147 + "<property name=\"output\"/>\n"); 148 } 149 if (ioPort.isMultiport()) { 150 buffer.write( 151 StringUtilities.getIndentPrefix(extraIndent + 2) 152 + "<property name=\"multiport\"/>\n"); 153 } 154 } 155 attributes = port.attributeList(); 156 for (Attribute attribute : attributes) { 157 if (!_IGNORED_ATTRIBUTES.contains(attribute.getName())) { 158 attribute.exportMoML(buffer, extraIndent + 2); 159 } 160 } 161 buffer.write(StringUtilities.getIndentPrefix(extraIndent + 1) 162 + "</port>\n"); 163 } 164 165 List<ComponentEntity> classes = group.classDefinitionList(); 166 for (ComponentEntity entity : classes) { 167 Attribute attribute = entity.getAttribute("_noAutonaming"); 168 if (attribute != null 169 && ((BooleanToken) ((Parameter) attribute).getToken()) 170 .booleanValue()) { 171 entity.exportMoML(buffer, extraIndent + 2); 172 } 173 } 174 175 List<ComponentEntity> entities = group.entityList(); 176 for (ComponentEntity entity : entities) { 177 Attribute attribute = entity.getAttribute("_noAutonaming"); 178 if (attribute != null 179 && ((BooleanToken) ((Parameter) attribute).getToken()) 180 .booleanValue()) { 181 entity.exportMoML(buffer, extraIndent + 2); 182 } 183 } 184 185 buffer.write(StringUtilities.getIndentPrefix(extraIndent + 1) 186 + "<group name=\"auto\">\n"); 187 188 classes = group.classDefinitionList(); 189 for (ComponentEntity entity : classes) { 190 Attribute attribute = entity.getAttribute("_noAutonaming"); 191 if (attribute == null 192 || !((BooleanToken) ((Parameter) attribute).getToken()) 193 .booleanValue()) { 194 entity.exportMoML(buffer, extraIndent + 2); 195 } 196 } 197 198 entities = group.entityList(); 199 for (ComponentEntity entity : entities) { 200 Attribute attribute = entity.getAttribute("_noAutonaming"); 201 if (attribute == null 202 || !((BooleanToken) ((Parameter) attribute).getToken()) 203 .booleanValue()) { 204 entity.exportMoML(buffer, extraIndent + 2); 205 } 206 } 207 208 List<ComponentRelation> relations = group.relationList(); 209 for (ComponentRelation relation : relations) { 210 relation.exportMoML(buffer, extraIndent + 2); 211 } 212 213 buffer.write(group.exportLinks(extraIndent + 2, null)); 214 buffer.write(StringUtilities.getIndentPrefix(extraIndent + 1) 215 + "</group>\n"); 216 if (after != null || before != null) { 217 buffer.write(StringUtilities.getIndentPrefix(extraIndent) 218 + "</group>\n"); 219 } 220 221 if (after != null) { 222 String oldType = null; 223 StringParameter typeParameter = (StringParameter) after 224 .getAttribute("_type"); 225 if (typeParameter == null) { 226 typeParameter = new StringParameter(after, "_type"); 227 } else { 228 oldType = typeParameter.getExpression(); 229 } 230 typeParameter.setExpression("delayed"); 231 try { 232 buffer.write( 233 StringUtilities.getIndentPrefix(1) + "<group>\n"); 234 after.exportMoML(buffer, 2); 235 buffer.write( 236 StringUtilities.getIndentPrefix(1) + "</group>\n"); 237 } finally { 238 if (oldType == null) { 239 typeParameter.setContainer(null); 240 } else { 241 typeParameter.setExpression(oldType); 242 } 243 } 244 } 245 246 buffer.write("</group>\n"); 247 248 return buffer.toString(); 249 } catch (Throwable throwable) { 250 // This should not occur. 251 throw new InternalErrorException(null, throwable, 252 "Unable to get the " + "Moml content for group " 253 + group.getName() + "."); 254 } 255 } 256 257 /** Add a parameter and expression to the map of parameters 258 * to override. 259 * @param name The name of the parameter. 260 * @param expression The expression of the parameter. 261 */ 262 public void overrideParameter(String name, String expression) { 263 _overriddenParameters.put(name, expression); 264 } 265 266 /** The set of attribute names that need to be ignored while generating 267 * the Moml. 268 */ 269 private static final HashSet<String> _IGNORED_ATTRIBUTES = new HashSet<String>(); 270 271 private HashMap<String, String> _overriddenParameters = new HashMap<String, String>(); 272 273 static { 274 _IGNORED_ATTRIBUTES.add("GroupIcon"); 275 _IGNORED_ATTRIBUTES.add("_alternateGetMomlAction"); 276 _IGNORED_ATTRIBUTES.add("_createdBy"); 277 _IGNORED_ATTRIBUTES.add("_designPatternIcon"); 278 _IGNORED_ATTRIBUTES.add("_hideName"); 279 _IGNORED_ATTRIBUTES.add("_vergilSize"); 280 _IGNORED_ATTRIBUTES.add("_vergilZoomFactor"); 281 _IGNORED_ATTRIBUTES.add("_vergilCenter"); 282 _IGNORED_ATTRIBUTES.add("_windowProperties"); 283 } 284}