Coverage Report - org.argouml.notation.providers.uml.AttributeNotationUml
 
Classes in this File Line Coverage Branch Coverage Complexity
AttributeNotationUml
0%
0/251
0%
0/200
10
 
 1  
 /* $Id: AttributeNotationUml.java 18760 2010-09-18 05:19:53Z tfmorris $
 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  
  *    mvw
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 2005-2009 The Regents of the University of California. All
 17  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 18  
 // software and its documentation without fee, and without a written
 19  
 // agreement is hereby granted, provided that the above copyright notice
 20  
 // and this paragraph appear in all copies.  This software program and
 21  
 // documentation are copyrighted by The Regents of the University of
 22  
 // California. The software program and documentation are supplied "AS
 23  
 // IS", without any accompanying services from The Regents. The Regents
 24  
 // does not warrant that the operation of the program will be
 25  
 // uninterrupted or error-free. The end-user understands that the program
 26  
 // was developed for research purposes and is advised not to rely
 27  
 // exclusively on the program for any reason.  IN NO EVENT SHALL THE
 28  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 29  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 30  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 31  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 32  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 33  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 34  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 35  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 36  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 37  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 38  
 
 39  
 package org.argouml.notation.providers.uml;
 40  
 
 41  
 import java.text.ParseException;
 42  
 import java.util.ArrayList;
 43  
 import java.util.List;
 44  
 import java.util.NoSuchElementException;
 45  
 
 46  
 import org.apache.log4j.Logger;
 47  
 import org.argouml.application.events.ArgoEventPump;
 48  
 import org.argouml.application.events.ArgoEventTypes;
 49  
 import org.argouml.application.events.ArgoHelpEvent;
 50  
 import org.argouml.i18n.Translator;
 51  
 import org.argouml.kernel.Project;
 52  
 import org.argouml.kernel.ProjectManager;
 53  
 import org.argouml.kernel.ProjectSettings;
 54  
 import org.argouml.model.InvalidElementException;
 55  
 import org.argouml.model.Model;
 56  
 import org.argouml.notation.NotationSettings;
 57  
 import org.argouml.notation.providers.AttributeNotation;
 58  
 import org.argouml.uml.StereotypeUtility;
 59  
 import org.argouml.util.MyTokenizer;
 60  
 
 61  
 /**
 62  
  * The notation for an attribute for UML.
 63  
  * 
 64  
  * @author Michiel
 65  
  */
 66  
 public class AttributeNotationUml extends AttributeNotation {
 67  
 
 68  
     /**
 69  
      * The standard error etc. logger
 70  
      */
 71  0
     private static final Logger LOG = 
 72  
         Logger.getLogger(AttributeNotationUml.class);
 73  
     
 74  
     /**
 75  
      * The constructor.
 76  
      * @param attribute the UML object
 77  
      */
 78  
     public AttributeNotationUml(Object attribute) {
 79  0
         super(attribute);
 80  0
     }
 81  
 
 82  
     /*
 83  
      * @see org.argouml.notation.providers.NotationProvider#parse(java.lang.Object, java.lang.String)
 84  
      */
 85  
     public void parse(Object modelElement, String text) {
 86  
         try {
 87  0
             parseAttributeFig(Model.getFacade().getOwner(modelElement), 
 88  
                     modelElement, text);
 89  0
         } catch (ParseException pe) {
 90  0
             String msg = "statusmsg.bar.error.parsing.attribute";
 91  0
             Object[] args = {
 92  
                 pe.getLocalizedMessage(),
 93  
                 Integer.valueOf(pe.getErrorOffset()),
 94  
             };
 95  0
             ArgoEventPump.fireEvent(new ArgoHelpEvent(
 96  
                     ArgoEventTypes.HELP_CHANGED, this, 
 97  
                     Translator.messageFormat(msg, args)));
 98  0
         }
 99  0
     }
 100  
 
 101  
     /**
 102  
      * Parse a string representing one ore more ';' separated attributes. The
 103  
      * case that a String or char contains a ';' (e.g. in an initializer) is
 104  
      * handled, but not other occurrences of ';'.
 105  
      *
 106  
      * @param classifier  Classifier The classifier the attribute(s) belong to
 107  
      * @param attribute   Attribute The attribute on which the editing happened
 108  
      * @param text The string to parse
 109  
      * @throws ParseException for invalid input
 110  
      */
 111  
     public void parseAttributeFig(
 112  
             Object classifier,
 113  
             Object attribute,
 114  
             String text) throws ParseException {
 115  
 
 116  0
         if (classifier == null || attribute == null) {
 117  0
             return;
 118  
         }
 119  
 
 120  
         /* TODO: We should have all the information that is required in the 
 121  
          * NotationSettings object */
 122  0
         Project project = ProjectManager.getManager().getCurrentProject();
 123  
 
 124  0
         ParseException pex = null;
 125  0
         int start = 0;
 126  0
         int end = NotationUtilityUml.indexOfNextCheckedSemicolon(text, start);
 127  0
         if (end == -1) {
 128  
             //no text? remove attr!
 129  0
             project.moveToTrash(attribute);
 130  0
             return;
 131  
         }
 132  0
         String s = text.substring(start, end).trim();
 133  0
         if (s.length() == 0) {
 134  
             //no non-whitechars in text? remove attr!
 135  0
             project.moveToTrash(attribute);
 136  0
             return;
 137  
         }
 138  0
         parseAttribute(s, attribute);
 139  0
         int i = Model.getFacade().getFeatures(classifier).indexOf(attribute);
 140  
         // check for more attributes (';' separated):
 141  0
         start = end + 1;
 142  0
         end = NotationUtilityUml.indexOfNextCheckedSemicolon(text, start);
 143  0
         while (end > start && end <= text.length()) {
 144  0
             s = text.substring(start, end).trim();
 145  0
             if (s.length() > 0) {
 146  
                 // yes, there are more:
 147  0
                 Object attrType = project.getDefaultAttributeType();
 148  
                 
 149  0
                 Object newAttribute = Model.getUmlFactory().buildNode(
 150  
                         Model.getMetaTypes().getAttribute());
 151  
                 
 152  0
                 Model.getCoreHelper().setType(newAttribute, attrType);
 153  
                 
 154  0
                 if (newAttribute != null) {
 155  
                     /* We need to set the namespace/owner 
 156  
                      * of the new attribute before parsing: */
 157  0
                     if (i != -1) {
 158  0
                         Model.getCoreHelper().addFeature(
 159  
                                 classifier, ++i, newAttribute);
 160  
                     } else {
 161  0
                         Model.getCoreHelper().addFeature(
 162  
                                 classifier, newAttribute);
 163  
                     }
 164  
                     try {
 165  0
                         parseAttribute(s, newAttribute);
 166  
                         /* If the 1st attribute is static, 
 167  
                          * then the new ones, too. */
 168  0
                         Model.getCoreHelper().setStatic(
 169  
                                 newAttribute,
 170  
                                 Model.getFacade().isStatic(attribute));
 171  0
                     } catch (ParseException ex) {
 172  0
                         if (pex == null) {
 173  0
                             pex = ex;
 174  
                         }
 175  0
                     }
 176  
                 }
 177  
             }
 178  0
             start = end + 1;
 179  0
             end = NotationUtilityUml.indexOfNextCheckedSemicolon(text, start);
 180  
         }
 181  0
         if (pex != null) {
 182  0
             throw pex;
 183  
         }
 184  0
     }
 185  
 
 186  
     /**
 187  
      * Parse a line on the form:<pre>
 188  
      *      visibility name [: type-expression] [= initial-value]
 189  
      * </pre>
 190  
      *
 191  
      * <ul>
 192  
      * <li>If only one of visibility and name is given, then it is assumed to
 193  
      * be the name and the visibility is left unchanged.
 194  
      * <li>Type and initial value can be given in any order.
 195  
      * <li>Properties can be given between any element in the form<pre>
 196  
      *      {[name] [= [value]] [, ...]}
 197  
      * </pre>
 198  
      * <li>Multiplicity can be given between any element except after the
 199  
      * initial-value and before the type or end (to allow java-style array
 200  
      * indexing in the initial value). It must be given on form [multiplicity]
 201  
      * with the square brackets included.
 202  
      * <li>Stereotypes can be given between any element except after the
 203  
      * initial-value and before the type or end (to allow java-style bit-shifts
 204  
      * in the initial value). It must be given on form
 205  
      * &lt;&lt;stereotype1,stereotype2,stereotype3&gt;&gt;.
 206  
      * </ul>
 207  
      *
 208  
      * The following properties are recognized to have special meaning:
 209  
      * frozen.<p>
 210  
      *
 211  
      * This syntax is compatible with the UML 1.3 spec.
 212  
      *
 213  
      * (formerly: visibility name [multiplicity] : type-expression =
 214  
      * initial-value {property-string} ) (2nd formerly: [visibility] [keywords]
 215  
      * type name [= init] [;] )
 216  
      *
 217  
      * @param text    The String to parse.
 218  
      * @param attribute The attribute to modify to comply 
 219  
      *                           with the instructions in s.
 220  
      * @throws ParseException
 221  
      *             when it detects an error in the attribute string. See also
 222  
      *             ParseError.getErrorOffset().
 223  
      */
 224  
     protected void parseAttribute(
 225  
             String text,
 226  
             Object attribute) throws ParseException {
 227  0
         StringBuilder multiplicity = null;
 228  0
         String name = null;
 229  0
         List<String> properties = null;
 230  0
         StringBuilder stereotype = null; // This is null as until
 231  
                                 // the first stereotype declaration is seen.
 232  
                                 // After that it is non-null.
 233  
         String token;
 234  0
         String type = null;
 235  0
         StringBuilder value = null;
 236  0
         String visibility = null;
 237  0
         boolean hasColon = false;
 238  0
         boolean hasEq = false;
 239  0
         int multindex = -1;
 240  
         MyTokenizer st;
 241  
 
 242  0
         text = text.trim();
 243  0
         if (text.length() > 0 
 244  
                 && NotationUtilityUml.VISIBILITYCHARS.indexOf(text.charAt(0)) 
 245  
                     >= 0) {
 246  0
             visibility = text.substring(0, 1);
 247  0
             text = text.substring(1);
 248  
         }
 249  
 
 250  
         try {
 251  0
             st = new MyTokenizer(text, 
 252  
                     " ,\t,<<,\u00AB,\u00BB,>>,[,],:,=,{,},\\,",
 253  
                     NotationUtilityUml.attributeCustomSep);
 254  0
             while (st.hasMoreTokens()) {
 255  0
                 token = st.nextToken();
 256  0
                 if (" ".equals(token) || "\t".equals(token)
 257  
                         || ",".equals(token)) {
 258  0
                     if (hasEq) {
 259  0
                         value.append(token);
 260  
                     }
 261  0
                 } else if ("<<".equals(token) || "\u00AB".equals(token)) {
 262  0
                     if (hasEq) {
 263  0
                         value.append(token);
 264  
                     } else {
 265  0
                         if (stereotype != null) {
 266  0
                             String msg = 
 267  
                                 "parsing.error.attribute.two-sets-stereotypes";
 268  0
                             throw new ParseException(Translator.localize(msg),
 269  
                                     st.getTokenIndex());
 270  
                         }
 271  0
                         stereotype = new StringBuilder();
 272  
                         while (true) {
 273  0
                             token = st.nextToken();
 274  0
                             if (">>".equals(token) || "\u00BB".equals(token)) {
 275  0
                                 break;
 276  
                             }
 277  0
                             stereotype.append(token);
 278  
                         }
 279  
                     }
 280  0
                 } else if ("[".equals(token)) {
 281  0
                     if (hasEq) {
 282  0
                         value.append(token);
 283  
                     } else {
 284  0
                         if (multiplicity != null) {
 285  0
                             String msg = 
 286  
                                 "parsing.error.attribute.two-multiplicities";
 287  0
                             throw new ParseException(Translator.localize(msg),
 288  
                                     st.getTokenIndex());
 289  
                         }
 290  0
                         multiplicity = new StringBuilder();
 291  0
                         multindex = st.getTokenIndex() + 1;
 292  
                         while (true) {
 293  0
                             token = st.nextToken();
 294  0
                             if ("]".equals(token)) {
 295  0
                                 break;
 296  
                             }
 297  0
                             multiplicity.append(token);
 298  
                         }
 299  
                     }
 300  0
                 } else if ("{".equals(token)) {
 301  0
                     StringBuilder propname = new StringBuilder();
 302  0
                     String propvalue = null;
 303  
 
 304  0
                     if (properties == null) {
 305  0
                         properties = new ArrayList<String>();
 306  
                     }
 307  
                     while (true) {
 308  0
                         token = st.nextToken();
 309  0
                         if (",".equals(token) || "}".equals(token)) {
 310  0
                             if (propname.length() > 0) {
 311  0
                                 properties.add(propname.toString());
 312  0
                                 properties.add(propvalue);
 313  
                             }
 314  0
                             propname = new StringBuilder();
 315  0
                             propvalue = null;
 316  
 
 317  0
                             if ("}".equals(token)) {
 318  0
                                 break;
 319  
                             }
 320  0
                         } else if ("=".equals(token)) {
 321  0
                             if (propvalue != null) {
 322  0
                                 String msg = 
 323  
                                     "parsing.error.attribute.prop-two-values";
 324  0
                                 Object[] args = {propvalue};
 325  
 
 326  0
                                 throw new ParseException(Translator.localize(
 327  
                                         msg, args), st.getTokenIndex());
 328  
                             }
 329  0
                             propvalue = "";
 330  0
                         } else if (propvalue == null) {
 331  0
                             propname.append(token);
 332  
                         } else {
 333  0
                             propvalue += token;
 334  
                         }
 335  
                     }
 336  0
                     if (propname.length() > 0) {
 337  0
                         properties.add(propname.toString());
 338  0
                         properties.add(propvalue);
 339  
                     }
 340  0
                 } else if (":".equals(token)) {
 341  0
                     hasColon = true;
 342  0
                     hasEq = false;
 343  0
                 } else if ("=".equals(token)) {
 344  0
                     if (value != null) {
 345  0
                         String msg = 
 346  
                             "parsing.error.attribute.two-default-values";
 347  0
                         throw new ParseException(Translator.localize(msg), st
 348  
                                 .getTokenIndex());
 349  
                     }
 350  0
                     value = new StringBuilder();
 351  0
                     hasColon = false;
 352  0
                     hasEq = true;
 353  
                 } else {
 354  0
                     if (hasColon) {
 355  0
                         if (type != null) {
 356  0
                             String msg = "parsing.error.attribute.two-types";
 357  0
                             throw new ParseException(Translator.localize(msg),
 358  
                                     st.getTokenIndex());
 359  
                         }
 360  0
                         if (token.length() > 0
 361  
                                 && (token.charAt(0) == '\"'
 362  
                                     || token.charAt(0) == '\'')) {
 363  0
                             String msg = "parsing.error.attribute.quoted";
 364  0
                             throw new ParseException(Translator.localize(msg),
 365  
                                     st.getTokenIndex());
 366  
                         }
 367  0
                         if (token.length() > 0 && token.charAt(0) == '(') {
 368  0
                             String msg = "parsing.error.attribute.is-expr";
 369  0
                             throw new ParseException(Translator.localize(msg),
 370  
                                     st.getTokenIndex());
 371  
                         }
 372  0
                         type = token;
 373  0
                     } else if (hasEq) {
 374  0
                         value.append(token);
 375  
                     } else {
 376  0
                         if (name != null && visibility != null) {
 377  0
                             String msg = "parsing.error.attribute.extra-text";
 378  0
                             throw new ParseException(Translator.localize(msg),
 379  
                                     st.getTokenIndex());
 380  
                         }
 381  0
                         if (token.length() > 0
 382  
                                 && (token.charAt(0) == '\"'
 383  
                                     || token.charAt(0) == '\'')) {
 384  0
                             String msg = "parsing.error.attribute.name-quoted";
 385  0
                             throw new ParseException(Translator.localize(msg),
 386  
                                     st.getTokenIndex());
 387  
                         }
 388  0
                         if (token.length() > 0 && token.charAt(0) == '(') {
 389  0
                             String msg = "parsing.error.attribute.name-expr";
 390  0
                             throw new ParseException(Translator.localize(msg),
 391  
                                     st.getTokenIndex());
 392  
                         }
 393  
 
 394  0
                         if (name == null
 395  
                                 && visibility == null
 396  
                                 && token.length() > 1
 397  
                                 && NotationUtilityUml.VISIBILITYCHARS
 398  
                                         .indexOf(token.charAt(0)) >= 0) {
 399  0
                             visibility = token.substring(0, 1);
 400  0
                             token = token.substring(1);
 401  
                         }
 402  
 
 403  0
                         if (name != null) {
 404  0
                             visibility = name;
 405  0
                             name = token;
 406  
                         } else {
 407  0
                             name = token;
 408  
                         }
 409  
                     }
 410  
                 }
 411  
             }
 412  0
         } catch (NoSuchElementException nsee) {
 413  0
             String msg = "parsing.error.attribute.unexpected-end-attribute";
 414  0
             throw new ParseException(Translator.localize(msg), text.length());
 415  0
         } 
 416  
         // catch & rethrow is not necessary if we don't do nothing (penyaskito)
 417  
         // catch (ParseException pre) {
 418  
         //      throw pre;
 419  
         // }
 420  
 
 421  0
         if (LOG.isDebugEnabled()) {
 422  0
             LOG.debug("ParseAttribute [name: " + name 
 423  
                     + " visibility: " + visibility 
 424  
                     + " type: " + type + " value: " + value 
 425  
                     + " stereo: " + stereotype
 426  
                     + " mult: " + multiplicity);
 427  0
             if (properties != null) {
 428  0
                 for (int i = 0; i + 1 < properties.size(); i += 2) {
 429  0
                     LOG.debug("\tProperty [name: " + properties.get(i) + " = "
 430  
                             + properties.get(i + 1) + "]");
 431  
                 }
 432  
             }
 433  
         }
 434  
 
 435  0
         dealWithVisibility(attribute, visibility);
 436  0
         dealWithName(attribute, name);
 437  0
         dealWithType(attribute, type);
 438  0
         dealWithValue(attribute, value);
 439  0
         dealWithMultiplicity(attribute, multiplicity, multindex);
 440  0
         dealWithProperties(attribute, properties);
 441  0
         StereotypeUtility.dealWithStereotypes(attribute, stereotype, true);
 442  0
     }
 443  
 
 444  
     private void dealWithProperties(Object attribute, List<String> properties) {
 445  0
         if (properties != null) {
 446  0
             NotationUtilityUml.setProperties(attribute, properties,
 447  
                     NotationUtilityUml.attributeSpecialStrings);
 448  
         }
 449  0
     }
 450  
 
 451  
     private void dealWithMultiplicity(Object attribute,
 452  
             StringBuilder multiplicity, int multindex) throws ParseException {
 453  0
         if (multiplicity != null) {
 454  
             try {
 455  0
                 Model.getCoreHelper().setMultiplicity(attribute, multiplicity.toString());
 456  0
             } catch (IllegalArgumentException iae) {
 457  0
                 String msg = "parsing.error.attribute.bad-multiplicity";
 458  0
                 Object[] args = {iae};
 459  
 
 460  0
                 throw new ParseException(Translator.localize(msg, args),
 461  
                         multindex);
 462  0
             }
 463  
         }
 464  0
     }
 465  
 
 466  
     private void dealWithValue(Object attribute, StringBuilder value) {
 467  0
         if (value != null) {
 468  0
             Project project = 
 469  
                 ProjectManager.getManager().getCurrentProject();
 470  0
             ProjectSettings ps = project.getProjectSettings();
 471  0
             Object initExpr = Model.getDataTypesFactory().createExpression(
 472  
                     ps.getNotationLanguage(), value.toString().trim());
 473  0
             Model.getCoreHelper().setInitialValue(attribute, initExpr);
 474  
         }
 475  0
     }
 476  
 
 477  
     private void dealWithType(Object attribute, String type) {
 478  0
         if (type != null) {
 479  0
             Object ow = Model.getFacade().getOwner(attribute);
 480  0
             Object ns = null;
 481  0
             if (ow != null && Model.getFacade().getNamespace(ow) != null) {
 482  0
                 ns = Model.getFacade().getNamespace(ow);
 483  
             } else {
 484  0
                 ns = Model.getFacade().getRoot(attribute);
 485  
             }
 486  0
             Model.getCoreHelper().setType(attribute, 
 487  
                     NotationUtilityUml.getType(type.trim(), ns));
 488  
         }
 489  0
     }
 490  
 
 491  
     private void dealWithName(Object attribute, String name) {
 492  0
         if (name != null) {
 493  0
             Model.getCoreHelper().setName(attribute, name.trim());
 494  0
         } else if (Model.getFacade().getName(attribute) == null
 495  
                 || "".equals(Model.getFacade().getName(attribute))) {
 496  0
             Model.getCoreHelper().setName(attribute, "anonymous");
 497  
         }
 498  0
     }
 499  
 
 500  
     private void dealWithVisibility(Object attribute, String visibility) {
 501  0
         if (visibility != null) {
 502  0
             Model.getCoreHelper().setVisibility(attribute,
 503  
                     NotationUtilityUml.getVisibility(visibility.trim()));
 504  
         }
 505  0
     }
 506  
 
 507  
     /*
 508  
      * @see org.argouml.notation.providers.NotationProvider#getParsingHelp()
 509  
      */
 510  
     public String getParsingHelp() {
 511  0
         return "parsing.help.attribute";
 512  
     }
 513  
 
 514  
     @Override
 515  
     public String toString(Object modelElement, NotationSettings settings) {
 516  0
         return toString(modelElement, settings.isUseGuillemets(), settings
 517  
                 .isShowVisibilities(), settings.isShowMultiplicities(), settings
 518  
                 .isShowTypes(), settings.isShowInitialValues(),
 519  
                 settings.isShowProperties());
 520  
     }
 521  
 
 522  
     /*
 523  
      * Generates a string representation for the provided
 524  
      * attribute. The string representation will be of the form:
 525  
      *          visibility name [multiplicity] : type-expression =
 526  
      *                          initial-value {property-string}
 527  
      * Depending on settings in Notation, visibility, multiplicity,
 528  
      * type-expression, initial value and properties are shown/not shown.
 529  
      */
 530  
     private String toString(Object modelElement, boolean useGuillemets, 
 531  
             boolean showVisibility, boolean showMultiplicity, boolean showTypes,
 532  
             boolean showInitialValues, boolean showProperties) {
 533  
         try {
 534  0
             String stereo = NotationUtilityUml.generateStereotype(modelElement, 
 535  
                     useGuillemets);
 536  0
             String name = Model.getFacade().getName(modelElement);
 537  0
             String multiplicity = generateMultiplicity(
 538  
                     Model.getFacade().getMultiplicity(modelElement));
 539  0
             String type = ""; // fix for loading bad projects
 540  0
             if (Model.getFacade().getType(modelElement) != null) {
 541  0
                 type = Model.getFacade().getName(
 542  
                         Model.getFacade().getType(modelElement));
 543  
             }
 544  
 
 545  0
             StringBuilder sb = new StringBuilder(20);
 546  0
             if ((stereo != null) && (stereo.length() > 0)) {
 547  0
                 sb.append(stereo).append(" ");
 548  
             }
 549  0
             if (showVisibility) {
 550  0
                 String visibility = NotationUtilityUml
 551  
                         .generateVisibility2(modelElement);
 552  0
                 if (visibility != null && visibility.length() > 0) {
 553  0
                     sb.append(visibility);
 554  
                 }
 555  
             }
 556  0
             if ((name != null) && (name.length() > 0)) {
 557  0
                 sb.append(name).append(" ");
 558  
             }
 559  0
             if ((multiplicity != null)
 560  
                     && (multiplicity.length() > 0)
 561  
                     && showMultiplicity) {
 562  0
                 sb.append("[").append(multiplicity).append("]").append(" ");
 563  
             }
 564  0
             if ((type != null) && (type.length() > 0)
 565  
                     /*
 566  
                      * The "show types" defaults to TRUE, to stay compatible
 567  
                      * with older ArgoUML versions that did not have this
 568  
                      * setting:
 569  
                      */
 570  
                     && showTypes) {
 571  0
                 sb.append(": ").append(type).append(" ");
 572  
             }
 573  0
             if (showInitialValues) {
 574  0
                 Object iv = Model.getFacade().getInitialValue(modelElement);
 575  0
                 if (iv != null) {
 576  0
                     String initialValue = 
 577  
                         (String) Model.getFacade().getBody(iv);
 578  0
                     if (initialValue != null && initialValue.length() > 0) {
 579  0
                         sb.append(" = ").append(initialValue).append(" ");
 580  
                     }
 581  
                 }
 582  
             }
 583  0
             if (showProperties) {
 584  0
                 String changeableKind = "";
 585  0
                 if (Model.getFacade().isReadOnly(modelElement)) {
 586  0
                     changeableKind = "frozen";
 587  
                 }
 588  0
                 if (Model.getFacade().getChangeability(modelElement) != null) {
 589  0
                     if (Model.getChangeableKind().getAddOnly().equals(
 590  
                             Model.getFacade().getChangeability(modelElement))) {
 591  0
                         changeableKind = "addOnly";
 592  
                     }
 593  
                 }
 594  0
                 StringBuilder properties = new StringBuilder();
 595  0
                 if (changeableKind.length() > 0) {
 596  0
                     properties.append("{ ").append(changeableKind).append(" }");
 597  
                 }
 598  
 
 599  0
                 if (properties.length() > 0) {
 600  0
                     sb.append(properties);
 601  
                 }
 602  
             }
 603  0
             return sb.toString().trim();
 604  0
         } catch (InvalidElementException e) {
 605  
             // The element was deleted while we were processing it
 606  0
             return "";
 607  
         }
 608  
     }
 609  
     
 610  
     private static String generateMultiplicity(Object m) {
 611  0
         if (m == null || "1".equals(Model.getFacade().toString(m))) {
 612  0
             return "";
 613  
         }
 614  0
         return Model.getFacade().toString(m);
 615  
     }
 616  
 
 617  
 }