Coverage Report - org.argouml.notation.providers.uml.OperationNotationUml
 
Classes in this File Line Coverage Branch Coverage Complexity
OperationNotationUml
0%
0/262
0%
0/206
9.429
 
 1  
 /* $Id: OperationNotationUml.java 17828 2010-01-12 18:55:12Z linus $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009 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.Collection;
 44  
 import java.util.Iterator;
 45  
 import java.util.List;
 46  
 import java.util.NoSuchElementException;
 47  
 
 48  
 import org.argouml.application.events.ArgoEventPump;
 49  
 import org.argouml.application.events.ArgoEventTypes;
 50  
 import org.argouml.application.events.ArgoHelpEvent;
 51  
 import org.argouml.i18n.Translator;
 52  
 import org.argouml.kernel.Project;
 53  
 import org.argouml.kernel.ProjectManager;
 54  
 import org.argouml.model.InvalidElementException;
 55  
 import org.argouml.model.Model;
 56  
 import org.argouml.notation.NotationSettings;
 57  
 import org.argouml.notation.providers.OperationNotation;
 58  
 import org.argouml.uml.StereotypeUtility;
 59  
 import org.argouml.util.MyTokenizer;
 60  
 
 61  
 /**
 62  
  * The UML notation for an Operation or a Reception.
 63  
  * 
 64  
  * @author mvw@tigris.org
 65  
  */
 66  
 public class OperationNotationUml extends OperationNotation {
 67  
 
 68  
     private static final String RECEPTION_KEYWORD = "signal";
 69  
     
 70  
     /**
 71  
      * The constructor.
 72  
      *
 73  
      * @param operation the operation that is represented
 74  
      */
 75  
     public OperationNotationUml(Object operation) {
 76  0
         super(operation);
 77  0
     }
 78  
 
 79  
     /*
 80  
      * @see org.argouml.notation.providers.NotationProvider#parse(java.lang.Object, java.lang.String)
 81  
      */
 82  
     public void parse(Object modelElement, String text) {
 83  
         try {
 84  0
             parseOperationFig(Model.getFacade().getOwner(modelElement), 
 85  
                     modelElement, text);
 86  0
         } catch (ParseException pe) {
 87  0
             String msg = "statusmsg.bar.error.parsing.operation";
 88  0
             Object[] args = {
 89  
                 pe.getLocalizedMessage(),
 90  
                 Integer.valueOf(pe.getErrorOffset()),
 91  
             };
 92  0
             ArgoEventPump.fireEvent(new ArgoHelpEvent(
 93  
                     ArgoEventTypes.HELP_CHANGED, this,
 94  
                     Translator.messageFormat(msg, args)));
 95  0
         }
 96  0
     }
 97  
 
 98  
     /**
 99  
      * Parse a string representing one ore more ';' separated operations. The
 100  
      * case that a String or char contains a ';' (e.g. in an initializer) is
 101  
      * handled, but not other occurences of ';'.
 102  
      *
 103  
      * @param classifier  Classifier The classifier the operation(s) belong to
 104  
      * @param operation   Operation The operation on which the editing happened
 105  
      * @param text The string to parse
 106  
      * @throws ParseException for invalid input
 107  
      */
 108  
     public void parseOperationFig(
 109  
             Object classifier,
 110  
             Object operation,
 111  
             String text) throws ParseException {
 112  
 
 113  0
         if (classifier == null || operation == null) {
 114  0
             return;
 115  
         }
 116  0
         ParseException pex = null;
 117  0
         int start = 0;
 118  0
         int end = NotationUtilityUml.indexOfNextCheckedSemicolon(text, start);
 119  0
         Project currentProject =
 120  
             ProjectManager.getManager().getCurrentProject();
 121  0
         if (end == -1) {
 122  
             //no text? remove op!
 123  0
             currentProject.moveToTrash(operation);
 124  0
             return;
 125  
         }
 126  0
         String s = text.substring(start, end).trim();
 127  0
         if (s.length() == 0) {
 128  
             //no non-whitechars in text? remove op!
 129  0
             currentProject.moveToTrash(operation);
 130  0
             return;
 131  
         }
 132  0
         parseOperation(s, operation);
 133  0
         int i = Model.getFacade().getFeatures(classifier).indexOf(operation);
 134  
         // check for more operations (';' separated):
 135  0
         start = end + 1;
 136  0
         end = NotationUtilityUml.indexOfNextCheckedSemicolon(text, start);
 137  0
         while (end > start && end <= text.length()) {
 138  0
             s = text.substring(start, end).trim();
 139  0
             if (s.length() > 0) {
 140  
                 // yes, there are more:
 141  0
                 Object returnType = currentProject.getDefaultReturnType();
 142  0
                 Object newOp =
 143  
                     Model.getCoreFactory()
 144  
                         .buildOperation(classifier, returnType);
 145  0
                 if (newOp != null) {
 146  
                     try {
 147  0
                         parseOperation(s, newOp);
 148  
                         //newOp.setOwnerScope(op.getOwnerScope()); //
 149  
                         //not needed in case of operation
 150  0
                         if (i != -1) {
 151  0
                             Model.getCoreHelper().addFeature(
 152  
                                     classifier, ++i, newOp);
 153  
                         } else {
 154  0
                             Model.getCoreHelper().addFeature(
 155  
                                     classifier, newOp);
 156  
                         }
 157  0
                     } catch (ParseException ex) {
 158  0
                         if (pex == null) {
 159  0
                             pex = ex;
 160  
                         }
 161  0
                     }
 162  
                 }
 163  
             }
 164  0
             start = end + 1;
 165  0
             end = NotationUtilityUml.indexOfNextCheckedSemicolon(text, start);
 166  
         }
 167  0
         if (pex != null) {
 168  0
             throw pex;
 169  
         }
 170  0
     }
 171  
 
 172  
 
 173  
     /**
 174  
      * Parse a line of text and aligns the Operation to the specification
 175  
      * given. The line should be on the following form:<ul>
 176  
      * <li> visibility name (parameter list) : return-type-expression
 177  
      * {property-string}
 178  
      * </ul>
 179  
      *
 180  
      * All elements are optional and, if left unspecified, will preserve their
 181  
      * old values.<p>
 182  
      *
 183  
      * <em>Stereotypes</em> can be given between any element in the line on the
 184  
      * form: &lt;&lt;stereotype1,stereotype2,stereotype3&gt;&gt;<p>
 185  
      *
 186  
      * The following properties are recognized to have special meaning:
 187  
      * abstract, concurrency, concurrent, guarded, leaf, query, root and
 188  
      * sequential.<p>
 189  
      *
 190  
      * This syntax is compatible with the UML 1.3 spec.<p>
 191  
      *
 192  
      * (formerly visibility name (parameter list) : return-type-expression
 193  
      * {property-string} ) (formerly 2nd: [visibility] [keywords] returntype
 194  
      * name(params)[;] )
 195  
      *
 196  
      * @param s   The String to parse.
 197  
      * @param op  The Operation to adjust to the specification in s.
 198  
      * @throws ParseException
 199  
      *             when it detects an error in the attribute string. See also
 200  
      *             ParseError.getErrorOffset().
 201  
      */
 202  
     public void parseOperation(String s, Object op) throws ParseException {
 203  
         MyTokenizer st;
 204  0
         boolean hasColon = false;
 205  0
         String name = null;
 206  0
         String parameterlist = null;
 207  0
         StringBuilder stereotype = null;
 208  
         String token;
 209  0
         String type = null;
 210  0
         String visibility = null;
 211  0
         List<String> properties = null;
 212  0
         int paramOffset = 0;
 213  
 
 214  0
         s = s.trim();
 215  
 
 216  0
         if (s.length() > 0 
 217  
                 && NotationUtilityUml.VISIBILITYCHARS.indexOf(s.charAt(0)) 
 218  
                     >= 0) {
 219  0
             visibility = s.substring(0, 1);
 220  0
             s = s.substring(1);
 221  
         }
 222  
 
 223  
         try {
 224  0
             st = new MyTokenizer(s, " ,\t,<<,\u00AB,\u00BB,>>,:,=,{,},\\,",
 225  
                     NotationUtilityUml.operationCustomSep);
 226  0
             while (st.hasMoreTokens()) {
 227  0
                 token = st.nextToken();
 228  0
                 if (" ".equals(token) || "\t".equals(token)
 229  
                         || ",".equals(token)) {
 230  0
                     continue; // Do nothing
 231  0
                 } else if ("<<".equals(token) || "\u00AB".equals(token)) {
 232  0
                     if (stereotype != null) {
 233  0
                         parseError("operation.stereotypes", 
 234  
                                 st.getTokenIndex());
 235  
                     }
 236  0
                     stereotype = new StringBuilder();
 237  
                     while (true) {
 238  0
                         token = st.nextToken();
 239  0
                         if (">>".equals(token) || "\u00BB".equals(token)) {
 240  0
                             break;
 241  
                         }
 242  0
                         stereotype.append(token);
 243  
                     }
 244  0
                 } else if ("{".equals(token)) {
 245  0
                     properties = tokenOpenBrace(st, properties);
 246  0
                 } else if (":".equals(token)) {
 247  0
                     hasColon = true;
 248  0
                 } else if ("=".equals(token)) {
 249  0
                     parseError("operation.default-values", st.getTokenIndex());
 250  0
                 } else if (token.charAt(0) == '(' && !hasColon) {
 251  0
                     if (parameterlist != null) {
 252  0
                         parseError("operation.two-parameter-lists", 
 253  
                                 st.getTokenIndex());
 254  
                     }
 255  
 
 256  0
                     parameterlist = token;
 257  
                 } else {
 258  0
                     if (hasColon) {
 259  0
                         if (type != null) {
 260  0
                             parseError("operation.two-types", 
 261  
                                     st.getTokenIndex());
 262  
                         }
 263  
 
 264  0
                         if (token.length() > 0
 265  
                                 && (token.charAt(0) == '\"'
 266  
                                     || token.charAt(0) == '\'')) {
 267  0
                             parseError("operation.type-quoted",
 268  
                                     st.getTokenIndex());
 269  
                         }
 270  
 
 271  0
                         if (token.length() > 0 && token.charAt(0) == '(') {
 272  0
                             parseError("operation.type-expr", 
 273  
                                     st.getTokenIndex());
 274  
                         }
 275  
 
 276  0
                         type = token;
 277  
                     } else {
 278  0
                         if (name != null && visibility != null) {
 279  0
                             parseError("operation.extra-text",
 280  
                                     st.getTokenIndex());
 281  
                         }
 282  
 
 283  0
                         if (token.length() > 0
 284  
                                 && (token.charAt(0) == '\"'
 285  
                                     || token.charAt(0) == '\'')) {
 286  0
                             parseError("operation.name-quoted",
 287  
                                     st.getTokenIndex());
 288  
                         }
 289  
 
 290  0
                         if (token.length() > 0 && token.charAt(0) == '(') {
 291  0
                             parseError("operation.name-expr", 
 292  
                                     st.getTokenIndex());
 293  
                         }
 294  
 
 295  0
                         if (name == null
 296  
                                 && visibility == null
 297  
                                 && token.length() > 1
 298  
                                 && NotationUtilityUml.VISIBILITYCHARS.indexOf(
 299  
                                         token.charAt(0))
 300  
                                                     >= 0) {
 301  0
                             visibility = token.substring(0, 1);
 302  0
                             token = token.substring(1);
 303  
                         }
 304  
 
 305  0
                         if (name != null) {
 306  0
                             visibility = name;
 307  0
                             name = token;
 308  
                         } else {
 309  0
                             name = token;
 310  
                         }
 311  
                     }
 312  
                 }
 313  
             } // end while loop
 314  0
         } catch (NoSuchElementException nsee) {
 315  0
             parseError("operation.unexpected-end-operation", 
 316  
                     s.length());
 317  0
         } catch (ParseException pre) {
 318  0
             throw pre;
 319  0
         }
 320  
 
 321  0
         if (parameterlist != null) {
 322  
             // parameterlist is guaranteed to contain at least "("
 323  0
             if (parameterlist.charAt(parameterlist.length() - 1) != ')') {
 324  0
                 parseError("operation.parameter-list-incomplete",
 325  
                         paramOffset + parameterlist.length() - 1);
 326  
             }
 327  
 
 328  0
             paramOffset++;
 329  0
             parameterlist = parameterlist.substring(1,
 330  
                     parameterlist.length() - 1);
 331  0
             NotationUtilityUml.parseParamList(op, parameterlist, paramOffset);
 332  
         }
 333  
 
 334  0
         if (visibility != null) {
 335  0
             Model.getCoreHelper().setVisibility(op,
 336  
                     NotationUtilityUml.getVisibility(visibility.trim()));
 337  
         }
 338  
 
 339  0
         if (name != null) {
 340  0
             Model.getCoreHelper().setName(op, name.trim());
 341  0
         } else if (Model.getFacade().getName(op) == null
 342  
                 || "".equals(Model.getFacade().getName(op))) {
 343  0
             Model.getCoreHelper().setName(op, "anonymous");
 344  
         }
 345  
 
 346  0
         if (type != null) {
 347  0
             Object ow = Model.getFacade().getOwner(op);
 348  0
             Object ns = null;
 349  0
             if (ow != null && Model.getFacade().getNamespace(ow) != null) {
 350  0
                 ns = Model.getFacade().getNamespace(ow);
 351  
             } else {
 352  0
                 ns = Model.getFacade().getRoot(op);
 353  
             }
 354  0
             Object mtype = NotationUtilityUml.getType(type.trim(), ns);
 355  0
             setReturnParameter(op, mtype);
 356  
         }
 357  
 
 358  0
         if (properties != null) {
 359  0
             NotationUtilityUml.setProperties(op, properties, 
 360  
                     NotationUtilityUml.operationSpecialStrings);
 361  
         }
 362  
 
 363  
         // Don't create a stereotype for <<signal>> on a Reception
 364  
         // but create any other parsed stereotypes as needed
 365  0
         if (!Model.getFacade().isAReception(op) 
 366  
                 || !RECEPTION_KEYWORD.equals(stereotype.toString())) {
 367  0
             StereotypeUtility.dealWithStereotypes(op, stereotype, true);
 368  
         }
 369  0
     }
 370  
 
 371  
     /**
 372  
      * Convenience method to signal a parser error.
 373  
      * 
 374  
      * @param message
 375  
      *            string containing error message literal. It will be appended
 376  
      *            to the base "parser.error." and localized.
 377  
      * @param offset
 378  
      *            offset to where error occurred
 379  
      * @throws ParseException
 380  
      */
 381  
     private void parseError(String message, int offset)
 382  
         throws ParseException {
 383  
 
 384  0
         throw new ParseException(
 385  
                 Translator.localize("parsing.error." + message), 
 386  
                 offset);
 387  
     }
 388  
 
 389  
     /**
 390  
      * Parse tokens following an open brace (properties).
 391  
      * 
 392  
      * @param st tokenizer being used
 393  
      * @param properties current properties list
 394  
      * @return updated list of properties
 395  
      * @throws ParseException
 396  
      */
 397  
     private List<String> tokenOpenBrace(MyTokenizer st, List<String> properties)
 398  
         throws ParseException {
 399  
         String token;
 400  0
         StringBuilder propname = new StringBuilder();
 401  0
         String propvalue = null;
 402  
 
 403  0
         if (properties == null) {
 404  0
             properties = new ArrayList<String>();
 405  
         }
 406  
         while (true) {
 407  0
             token = st.nextToken();
 408  0
             if (",".equals(token) || "}".equals(token)) {
 409  0
                 if (propname.length() > 0) {
 410  0
                     properties.add(propname.toString());
 411  0
                     properties.add(propvalue);
 412  
                 }
 413  0
                 propname = new StringBuilder();
 414  0
                 propvalue = null;
 415  
 
 416  0
                 if ("}".equals(token)) {
 417  0
                     break;
 418  
                 }
 419  0
             } else if ("=".equals(token)) {
 420  0
                 if (propvalue != null) {
 421  0
                     String msg = 
 422  
                         "parsing.error.operation.prop-stereotypes";
 423  0
                     Object[] args = {propname};
 424  0
                     throw new ParseException(
 425  
                                     Translator.localize(msg, 
 426  
                             args), 
 427  
                             st.getTokenIndex());
 428  
                 }
 429  0
                 propvalue = "";
 430  0
             } else if (propvalue == null) {
 431  0
                 propname.append(token);
 432  
             } else {
 433  0
                 propvalue += token;
 434  
             }
 435  
         }
 436  0
         if (propname.length() > 0) {
 437  0
             properties.add(propname.toString());
 438  0
             properties.add(propvalue);
 439  
         }
 440  0
         return properties;
 441  
     }
 442  
 
 443  
 
 444  
     /**
 445  
      * Sets the return parameter of op to be of type type. If there is none, one
 446  
      * is created. If there are many, all but one are removed.
 447  
      *
 448  
      * @param op the operation
 449  
      * @param type the type of the return parameter
 450  
      */
 451  
     private void setReturnParameter(Object op, Object type) {
 452  0
         Object param = null;
 453  0
         Iterator it = Model.getFacade().getParameters(op).iterator();
 454  0
         while (it.hasNext()) {
 455  0
             Object p = it.next();
 456  0
             if (Model.getFacade().isReturn(p)) {
 457  0
                 param = p;
 458  0
                 break;
 459  
             }
 460  0
         }
 461  0
         while (it.hasNext()) {
 462  0
             Object p = it.next();
 463  0
             if (Model.getFacade().isReturn(p)) {
 464  0
                 ProjectManager.getManager().getCurrentProject().moveToTrash(p);
 465  
             }
 466  0
         }
 467  0
         if (param == null) {
 468  0
             Object returnType =
 469  
                 ProjectManager.getManager()
 470  
                         .getCurrentProject().getDefaultReturnType();
 471  0
             param = Model.getCoreFactory().buildParameter(op, returnType);
 472  
         }
 473  0
         Model.getCoreHelper().setType(param, type);
 474  0
     }
 475  
 
 476  
     /*
 477  
      * @see org.argouml.notation.providers.NotationProvider#getParsingHelp()
 478  
      */
 479  
     public String getParsingHelp() {
 480  0
         return "parsing.help.operation";
 481  
     }
 482  
 
 483  
     /**
 484  
      * Generate an operation according to the UML notation:
 485  
      * <pre>
 486  
      *         stereotype visibility name (parameter-list) :
 487  
      *                         return-type-expression {property-string}
 488  
      * </pre>
 489  
      * For the return-type-expression: only the types of the return parameters
 490  
      * are shown.  Depending on settings in Notation, visibility and
 491  
      * properties are shown/not shown.
 492  
      * 
 493  
      * @param modelElement UML Operation element
 494  
      * @param settings notation settings
 495  
      * @return a formatted text string
 496  
      * @see org.argouml.notation.NotationProvider#toString(java.lang.Object, org.argouml.notation.NotationSettings)
 497  
      */
 498  
     public String toString(Object modelElement, NotationSettings settings) {
 499  0
         return toString(modelElement, settings.isUseGuillemets(), 
 500  
                 settings.isShowVisibilities(), settings.isShowTypes(),
 501  
                 settings.isShowProperties());
 502  
     }
 503  
     
 504  
     /**
 505  
      * Generate an operation according to the UML notation:
 506  
      * <pre>
 507  
      *         stereotype visibility name (parameter-list) :
 508  
      *                         return-type-expression {property-string}
 509  
      * </pre>
 510  
      * For the return-type-expression: only the types of the return parameters
 511  
      * are shown.  Depending on settings in Notation, visibility and
 512  
      * properties are shown/not shown.
 513  
      *
 514  
      * @author jaap.branderhorst@xs4all.nl
 515  
      */
 516  
     private String toString(Object modelElement, boolean useGuillemets, 
 517  
             boolean showVisibility,
 518  
             boolean showTypes, boolean showProperties) {
 519  
         try {
 520  0
             String stereoStr = NotationUtilityUml.generateStereotype(
 521  
                     Model.getFacade().getStereotypes(modelElement), 
 522  
                     useGuillemets);
 523  0
             boolean isReception = Model.getFacade().isAReception(modelElement);
 524  
             // TODO: needs I18N
 525  0
             if (isReception) {
 526  0
                 stereoStr =
 527  
                         NotationUtilityUml
 528  
                                 .generateStereotype(RECEPTION_KEYWORD, 
 529  
                                         useGuillemets)
 530  
                                 + " " + stereoStr;
 531  
             }
 532  
 
 533  
             // Unused currently
 534  
 //            StringBuffer taggedValuesSb = getTaggedValues(modelElement);
 535  
             
 536  
             // lets concatenate it to the resulting string (genStr)
 537  0
             StringBuffer genStr = new StringBuffer(30);
 538  0
             if ((stereoStr != null) && (stereoStr.length() > 0)) {
 539  0
                 genStr.append(stereoStr).append(" ");
 540  
             }
 541  0
             if (showVisibility) {
 542  0
                 String visStr = NotationUtilityUml
 543  
                         .generateVisibility2(modelElement);
 544  0
                 if (visStr != null) {
 545  0
                     genStr.append(visStr);
 546  
                 }
 547  
             }
 548  
             
 549  0
             String nameStr = Model.getFacade().getName(modelElement);
 550  0
             if ((nameStr != null) && (nameStr.length() > 0)) {
 551  0
                 genStr.append(nameStr);
 552  
             }
 553  
             
 554  
             /* The "show types" defaults to TRUE, to stay compatible with older
 555  
              * ArgoUML versions that did not have this setting: */
 556  0
             if (showTypes) {
 557  
                 // the parameters
 558  0
                 StringBuffer parameterStr = new StringBuffer();
 559  0
                 parameterStr.append("(").append(getParameterList(modelElement))
 560  
                         .append(")");
 561  
 
 562  
                 // the returnparameters
 563  0
                 StringBuffer returnParasSb = getReturnParameters(modelElement,
 564  
                         isReception);
 565  0
                 genStr.append(parameterStr).append(" ");
 566  0
                 if ((returnParasSb != null) && (returnParasSb.length() > 0)) {
 567  0
                     genStr.append(returnParasSb).append(" ");
 568  
                 }
 569  0
             } else {
 570  0
                 genStr.append("()");
 571  
             }
 572  0
             if (showProperties) {
 573  0
                 StringBuffer propertySb = getProperties(modelElement,
 574  
                         isReception);
 575  0
                 if (propertySb.length() > 0) {
 576  0
                     genStr.append(propertySb);
 577  
                 }
 578  
             }
 579  0
             return genStr.toString().trim();
 580  0
         } catch (InvalidElementException e) {
 581  
             // The model element was deleted while we were working on it
 582  0
             return "";   
 583  
         }
 584  
 
 585  
     }
 586  
 
 587  
 
 588  
     private StringBuffer getParameterList(Object modelElement) {
 589  0
         StringBuffer parameterListBuffer = new StringBuffer();
 590  0
         Collection coll = Model.getFacade().getParameters(modelElement);
 591  0
         Iterator it = coll.iterator();
 592  0
         int counter = 0;
 593  0
         while (it.hasNext()) {
 594  0
             Object parameter = it.next();
 595  0
             if (!Model.getFacade().hasReturnParameterDirectionKind(
 596  
                     parameter)) {
 597  0
                 counter++;
 598  0
                 parameterListBuffer.append(
 599  
                         NotationUtilityUml.generateParameter(parameter));
 600  0
                 parameterListBuffer.append(",");
 601  
             }
 602  0
         }
 603  0
         if (counter > 0) {
 604  0
             parameterListBuffer.delete(
 605  
                     parameterListBuffer.length() - 1,
 606  
                     parameterListBuffer.length());
 607  
         }
 608  0
         return parameterListBuffer;
 609  
     }
 610  
 
 611  
     private StringBuffer getReturnParameters(Object modelElement,
 612  
             boolean isReception) {
 613  0
         StringBuffer returnParasSb = new StringBuffer();
 614  0
         if (!isReception) {
 615  0
             Collection coll = 
 616  
                 Model.getCoreHelper().getReturnParameters(modelElement);
 617  0
             if (coll != null && coll.size() > 0) {
 618  0
                 returnParasSb.append(": ");
 619  0
                 Iterator it2 = coll.iterator();
 620  0
                 while (it2.hasNext()) {
 621  0
                     Object type = Model.getFacade().getType(it2.next());
 622  0
                     if (type != null) {
 623  0
                         returnParasSb.append(Model.getFacade()
 624  
                                 .getName(type));
 625  
                     }
 626  0
                     returnParasSb.append(",");
 627  0
                 }
 628  
                 // if we have only one return value and without type,
 629  
                 // the return param string is ": ,", we remove it
 630  0
                 if (returnParasSb.length() == 3) {
 631  0
                     returnParasSb.delete(0, returnParasSb.length());
 632  
                 }
 633  
                 // else: we remove only the extra ","
 634  
                 else {
 635  0
                     returnParasSb.delete(
 636  
                             returnParasSb.length() - 1,
 637  
                             returnParasSb.length());
 638  
                 }
 639  
             }
 640  
         }
 641  0
         return returnParasSb;
 642  
     }
 643  
     
 644  
     
 645  
     private StringBuffer getProperties(Object modelElement, 
 646  
             boolean isReception) {
 647  0
         StringBuffer propertySb = new StringBuffer().append("{");
 648  
         // the query state
 649  0
         if (Model.getFacade().isQuery(modelElement)) {
 650  0
             propertySb.append("query,");
 651  
         }
 652  
         /*
 653  
          * Although Operation and Signal are peers in the UML type 
 654  
          * hierarchy they share the attributes isRoot, isLeaf, 
 655  
          * isAbstract, and  specification. Concurrency is *not* 
 656  
          * shared and is specific to Operation.
 657  
          */
 658  0
         if (Model.getFacade().isRoot(modelElement)) {
 659  0
             propertySb.append("root,");
 660  
         }
 661  0
         if (Model.getFacade().isLeaf(modelElement)) {
 662  0
             propertySb.append("leaf,");
 663  
         }
 664  0
         if (!isReception) {
 665  0
             if (Model.getFacade().getConcurrency(modelElement) != null) {
 666  0
                 propertySb.append(Model.getFacade().getName(
 667  
                         Model.getFacade().getConcurrency(modelElement)));
 668  0
                 propertySb.append(',');
 669  
             }
 670  
         }
 671  0
         if (propertySb.length() > 1) {
 672  0
             propertySb.delete(propertySb.length() - 1, propertySb.length());
 673  
             // remove last ,
 674  0
             propertySb.append("}");
 675  
         } else {
 676  0
             propertySb = new StringBuffer();
 677  
         }
 678  0
         return propertySb;
 679  
     }
 680  
 
 681  
 
 682  
     private StringBuffer getTaggedValues(Object modelElement) {
 683  0
         StringBuffer taggedValuesSb = new StringBuffer();
 684  0
         Iterator it3 = Model.getFacade().getTaggedValues(modelElement);
 685  0
         if (it3 != null && it3.hasNext()) {
 686  0
             while (it3.hasNext()) {
 687  0
                 taggedValuesSb.append(
 688  
                         NotationUtilityUml.generateTaggedValue(it3.next()));
 689  0
                 taggedValuesSb.append(",");
 690  
             }
 691  0
             taggedValuesSb.delete(
 692  
                     taggedValuesSb.length() - 1,
 693  
                     taggedValuesSb.length());
 694  
         }
 695  0
         return taggedValuesSb;
 696  
     }
 697  
 }