Coverage Report - org.argouml.uml.ui.TabConstraints
 
Classes in this File Line Coverage Branch Coverage Complexity
TabConstraints
50%
23/46
25%
4/16
2.914
TabConstraints$ConstraintModel
0%
0/67
0%
0/54
2.914
TabConstraints$ConstraintModel$CR
0%
0/92
0%
0/26
2.914
TabConstraints$ConstraintModel$CR$1
0%
0/7
0%
0/2
2.914
 
 1  
 /* $Id: TabConstraints.java 17881 2010-01-12 21:09:28Z 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  
  *    tfmorris
 11  
  *****************************************************************************
 12  
  *
 13  
  * Some portions of this file was previously release using the BSD License:
 14  
  */
 15  
 
 16  
 // Copyright (c) 1996-2007 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.uml.ui;
 40  
 
 41  
 import java.awt.BorderLayout;
 42  
 import java.awt.event.ComponentEvent;
 43  
 import java.awt.event.ComponentListener;
 44  
 import java.io.IOException;
 45  
 import java.util.ArrayList;
 46  
 import java.util.Iterator;
 47  
 import java.util.List;
 48  
 
 49  
 import javax.swing.JOptionPane;
 50  
 import javax.swing.JToolBar;
 51  
 import javax.swing.event.EventListenerList;
 52  
 
 53  
 import org.apache.log4j.Logger;
 54  
 import org.argouml.application.api.AbstractArgoJPanel;
 55  
 import org.argouml.model.Model;
 56  
 import org.argouml.ocl.ArgoFacade;
 57  
 import org.argouml.ocl.OCLUtil;
 58  
 import org.argouml.swingext.UpArrowIcon;
 59  
 import org.argouml.ui.TabModelTarget;
 60  
 import org.argouml.ui.targetmanager.TargetEvent;
 61  
 import org.tigris.gef.presentation.Fig;
 62  
 import org.tigris.toolbar.ToolBarManager;
 63  
 
 64  
 import tudresden.ocl.OclException;
 65  
 import tudresden.ocl.OclTree;
 66  
 import tudresden.ocl.check.OclTypeException;
 67  
 import tudresden.ocl.gui.ConstraintRepresentation;
 68  
 import tudresden.ocl.gui.EditingUtilities;
 69  
 import tudresden.ocl.gui.OCLEditor;
 70  
 import tudresden.ocl.gui.OCLEditorModel;
 71  
 import tudresden.ocl.gui.events.ConstraintChangeEvent;
 72  
 import tudresden.ocl.gui.events.ConstraintChangeListener;
 73  
 import tudresden.ocl.parser.OclParserException;
 74  
 import tudresden.ocl.parser.analysis.DepthFirstAdapter;
 75  
 import tudresden.ocl.parser.node.AConstraintBody;
 76  
 import tudresden.ocl.parser.node.TName;
 77  
 
 78  
 /**
 79  
   * Tab for OCL constraint editing.
 80  
   *
 81  
   * @author v1.0: Falk Finger
 82  
   * @author v2.0: Steffen Zschaler
 83  
   */
 84  0
 public class TabConstraints extends AbstractArgoJPanel
 85  
     implements TabModelTarget, ComponentListener {
 86  
 
 87  900
     private static final Logger LOG = Logger.getLogger(TabConstraints.class);
 88  
 
 89  
     /**
 90  
      * The actual editor pane.
 91  
      */
 92  
     private OCLEditor mOcleEditor;
 93  
 
 94  
     /**
 95  
      * The current target element.
 96  
      */
 97  
     private Object mMmeiTarget;
 98  
 
 99  
     /**
 100  
      * The constructor.
 101  
      */
 102  
     public TabConstraints() {
 103  900
         super("tab.constraints");
 104  
 
 105  900
         setIcon(new UpArrowIcon());
 106  900
         setLayout(new BorderLayout(0, 0));
 107  
 
 108  900
         mOcleEditor = new OCLEditor();
 109  900
         mOcleEditor.setOptionMask(OCLEditor.OPTIONMASK_TYPECHECK
 110  
                    /*|  //removed to workaround problems with autosplit
 111  
                      OCLEditor.OPTIONMASK_AUTOSPLIT*/);
 112  900
         mOcleEditor.setDoAutoSplit(false);
 113  900
         setToolbarRollover(true);
 114  900
         setToolbarFloatable(false);
 115  900
         getOclToolbar().setName("misc.toolbar.constraints");
 116  
 
 117  900
         add(mOcleEditor);
 118  
         
 119  900
         addComponentListener(this);
 120  900
     }
 121  
 
 122  
     /**
 123  
      * Set the toolbar rollover style.
 124  
      *
 125  
      * @param enable If true then button borders do not become visible
 126  
      * until mouse rolls over button.
 127  
      */
 128  
     private void setToolbarRollover(boolean enable) {
 129  900
         if (!ToolBarManager.alwaysUseStandardRollover()) {
 130  0
             getOclToolbar().putClientProperty(
 131  
                     "JToolBar.isRollover", Boolean.TRUE);
 132  
         }
 133  900
     }
 134  
 
 135  
     /**
 136  
      * Set the toolbar floating style.
 137  
      *
 138  
      * @param enable If true then the toolbar can be floated and docked
 139  
      */
 140  
     private void setToolbarFloatable(boolean enable) {
 141  900
         getOclToolbar().setFloatable(false);
 142  900
     }
 143  
 
 144  
     /**
 145  
      * Get a reference to the toolbar object contained in the
 146  
      * OCLEditor component.  This is currently a nasty hack. We really
 147  
      * require an interface method on OCLEditor (Bob Tarling 8 Feb
 148  
      * 2003).
 149  
      *
 150  
      * @return The toolbar
 151  
      */
 152  
     private JToolBar getOclToolbar() {
 153  1800
         return (JToolBar) mOcleEditor.getComponent(0);
 154  
     }
 155  
 
 156  
     //TabModelTarget interface methods
 157  
 
 158  
     /**
 159  
      * Should this tab be activated for the current target element?<p>
 160  
      *
 161  
      * Argo only supports constraints for Classes and Features
 162  
      * (eg. Attributes and Operations) currently.
 163  
      *
 164  
      * {@inheritDoc}
 165  
      */
 166  
     public boolean shouldBeEnabled(Object target) {
 167  1327
         target = (target instanceof Fig) ? ((Fig) target).getOwner() : target;
 168  1327
         return (Model.getFacade().isAClass(target)
 169  
                 || Model.getFacade().isAFeature(target));
 170  
     }
 171  
 
 172  
     /*
 173  
      * @see org.argouml.ui.TabTarget#getTarget()
 174  
      */
 175  
     public Object getTarget() {
 176  0
         return mMmeiTarget;
 177  
     }
 178  
 
 179  
     /**
 180  
      * Refresh the tab because the target has changed.
 181  
      */
 182  
     public void refresh() {
 183  0
         setTarget(mMmeiTarget);
 184  0
     }
 185  
 
 186  
     /**
 187  
      * Set the target element to be displayed in this tab. Only model elements
 188  
      * will be accepted by the constraint tab.
 189  
      *
 190  
      * {@inheritDoc}
 191  
      */
 192  
     public void setTarget(Object oTarget) {
 193  0
         oTarget =
 194  
             (oTarget instanceof Fig) ? ((Fig) oTarget).getOwner() : oTarget;
 195  0
         if (!(Model.getFacade().isAModelElement(oTarget))) {
 196  0
             mMmeiTarget = null;
 197  0
             return;
 198  
         }
 199  
 
 200  0
         mMmeiTarget = oTarget;
 201  
 
 202  0
         if (isVisible()) {
 203  0
             setTargetInternal(mMmeiTarget);
 204  
         }
 205  0
     }
 206  
 
 207  
     private void setTargetInternal(Object oTarget) {
 208  
         // Set editor's model
 209  0
         if (oTarget != null) {
 210  0
             mOcleEditor.setModel(new ConstraintModel(oTarget));
 211  
         }
 212  0
     }
 213  
 
 214  
     /**
 215  
      * Adapter to provide information and a manipulation interface for a
 216  
      * target element's set of constraints to the constraint editor.
 217  
      */
 218  0
     private static class ConstraintModel implements OCLEditorModel {
 219  
 
 220  
         /**
 221  
          * The target element being edited.
 222  
          */
 223  
         private Object theMMmeiTarget;
 224  
 
 225  
         /**
 226  
          * A list of all the constraints in m_nmeiTarget. This is necessary to
 227  
          * induce a consistent order on the constraints.
 228  
          */
 229  
         private ArrayList theMAlConstraints;
 230  
 
 231  
         /**
 232  
          * List of listeners.
 233  
          */
 234  0
         private EventListenerList theMEllListeners = new EventListenerList();
 235  
 
 236  
         /**
 237  
          * Construct a new ConstraintModel.
 238  
          */
 239  
         public ConstraintModel(Object mmeiTarget) {
 240  0
             super();
 241  
 
 242  0
             theMMmeiTarget = mmeiTarget;
 243  
 
 244  0
             theMAlConstraints =
 245  
                 new ArrayList(Model.getFacade().getConstraints(theMMmeiTarget));
 246  0
         }
 247  
 
 248  
         /**
 249  
          * Return the number of constraints in this model.
 250  
          */
 251  
         public int getConstraintCount() {
 252  0
             return theMAlConstraints.size();
 253  
         }
 254  
 
 255  
         /**
 256  
          * Return the constraint with the specified index.
 257  
          *
 258  
          * @param nIdx the index of the constraint to be returned.
 259  
          *             0 <= nIdx < {@link #getConstraintCount}
 260  
          */
 261  
         public ConstraintRepresentation getConstraintAt(int nIdx) {
 262  0
             return representationFor(nIdx);
 263  
         }
 264  
 
 265  
         /**
 266  
          * Remove the specified constraint from the model.
 267  
          *
 268  
          * @param nIdx the index of the constraint to be removed.
 269  
          *             0 <= nIdx < {@link #getConstraintCount}
 270  
          */
 271  
         public void removeConstraintAt(int nIdx) {
 272  0
             if ((nIdx < 0) || (nIdx > theMAlConstraints.size())) {
 273  0
                 return;
 274  
             }
 275  
 
 276  0
             Object mc = theMAlConstraints.remove(nIdx);
 277  
 
 278  0
             if (mc != null) {
 279  0
                 Model.getCoreHelper().removeConstraint(theMMmeiTarget, mc);
 280  
             }
 281  
 
 282  0
             fireConstraintRemoved(mc, nIdx);
 283  0
         }
 284  
 
 285  
         /**
 286  
          * Add a fresh constraint to the model.<p>
 287  
          *
 288  
          * There are 2 restrictions on what can be parsed, given
 289  
          * the current OCL grammar:
 290  
          * <ol>
 291  
          *   <li>Class names must have a capital first letter.
 292  
          *   <li>Feature name must have a lower case first letter.
 293  
          * </ol>
 294  
          */
 295  
         public void addConstraint() {
 296  
 
 297  
             // check ocl parsing constraints
 298  0
             Object mmeContext = OCLUtil
 299  
                     .getInnerMostEnclosingNamespace(theMMmeiTarget);
 300  0
             String contextName = Model.getFacade().getName(mmeContext);
 301  0
             String targetName = Model.getFacade().getName(theMMmeiTarget);
 302  0
             if ((contextName == null
 303  
                  || contextName.equals (""))
 304  
                 ||  // this is to fix issue #2056
 305  
                 (targetName == null
 306  
                  || targetName.equals (""))
 307  
                 ||   // this is to fix issue #2056
 308  
                 !Character.isUpperCase(contextName.charAt(0))
 309  
                 || (Model.getFacade().isAClass (theMMmeiTarget)
 310  
                     && !Character.isUpperCase(targetName.charAt(0)))
 311  
                 || (Model.getFacade().isAFeature(theMMmeiTarget)
 312  
                     && !Character.isLowerCase(targetName.charAt(0)))) {
 313  
                 // TODO: I18n
 314  0
                 JOptionPane.showMessageDialog(
 315  
                     null,
 316  
                     "The OCL Toolkit requires that:\n\n"
 317  
                     + "Class names have a capital first letter and\n"
 318  
                     + "Attribute or Operation names have "
 319  
                     + "a lower case first letter.",
 320  
                     "Require Correct name convention:",
 321  
                     JOptionPane.ERROR_MESSAGE);
 322  
                 // do not create a constraint:
 323  0
                 return;
 324  
             }
 325  
 
 326  
             // null elements represent new constraints, which will be
 327  
             // added to the target the first time any actual editing
 328  
             // takes place.  This is done to ensure syntactical
 329  
             // correctness of constraints stored with the target.
 330  0
             theMAlConstraints.add(null);
 331  
 
 332  0
             fireConstraintAdded();
 333  0
         }
 334  
 
 335  
         // TODO: - please add some javadoc - ugly classname also
 336  
         private class CR implements ConstraintRepresentation {
 337  
             /**
 338  
              * The constraint being represented.
 339  
              */
 340  
             private Object theMMcConstraint;
 341  
 
 342  
             /**
 343  
              * The constraint's index in the list of
 344  
              * constraints. Necessary only for new constraints, where
 345  
              * m_mcConstraint is still <tt>null</tt>.
 346  
              */
 347  0
             private int theMNIdx = -1;
 348  
 
 349  0
             public CR(Object mcConstraint, int nIdx) {
 350  0
                 super();
 351  
 
 352  0
                 theMMcConstraint = mcConstraint;
 353  0
                 theMNIdx = nIdx;
 354  0
             }
 355  
 
 356  
             public CR(int nIdx) {
 357  0
                 this(null, nIdx);
 358  0
             }
 359  
 
 360  
             /**
 361  
              * Get the name of the constraint.
 362  
              */
 363  
             public String getName() {
 364  0
                 if (theMMcConstraint == null) {
 365  0
                     return "newConstraint";
 366  
                 }
 367  0
                 return Model.getFacade().getName(theMMcConstraint);
 368  
             }
 369  
 
 370  
             /**
 371  
              * Get the constraint's body.
 372  
              */
 373  
             public String getData() {
 374  0
                 if (theMMcConstraint == null) {
 375  0
                     return OCLUtil.getContextString(theMMmeiTarget);
 376  
                 }
 377  0
                 return (String) Model.getFacade().getBody(
 378  
                         Model.getFacade().getBody(theMMcConstraint));
 379  
             }
 380  
 
 381  
             /**
 382  
              * Set the constraint's body text. For the exceptions the
 383  
              * detailed message must be human readable.
 384  
              *
 385  
              * @param sData the new body of the constraint
 386  
              *
 387  
              * @exception IllegalStateException if the constraint is
 388  
              *            not in a state to accept body changes.
 389  
              * @exception OclParserException if the specified constraint is not
 390  
              *     syntactically correct.
 391  
              * @exception OclTypeException if the specified constraint
 392  
              *            does not adhere by OCL type rules.
 393  
              */
 394  
             public void setData(String sData, EditingUtilities euHelper)
 395  
                 throws OclParserException, OclTypeException {
 396  
                 // Parse and check specified constraint.
 397  0
                 OclTree tree = null;
 398  
 
 399  
                 try {
 400  0
                     Object mmeContext = OCLUtil
 401  
                             .getInnerMostEnclosingNamespace(theMMmeiTarget);
 402  
 
 403  
                     try {
 404  0
                         tree =
 405  
                             euHelper.parseAndCheckConstraint(
 406  
                                 sData,
 407  
                                 new ArgoFacade(mmeContext));
 408  0
                     } catch (IOException ioe) {
 409  
                         // Ignored: Highly unlikely, and what would we
 410  
                         // do anyway?  log it
 411  0
                         LOG.error("problem parsing And Checking Constraints",
 412  
                                    ioe);
 413  0
                         return;
 414  0
                     }
 415  
 
 416  
                     // Split constraint body, if user wants us to
 417  0
                     if (euHelper.getDoAutoSplit()) {
 418  0
                         List lConstraints = euHelper.splitConstraint(tree);
 419  
 
 420  0
                         if (lConstraints.size() > 0) {
 421  0
                             removeConstraintAt(theMNIdx);
 422  
 
 423  0
                             for (Iterator i = lConstraints.iterator();
 424  0
                                  i.hasNext();) {
 425  0
                                 OclTree ocltCurrent = (OclTree) i.next();
 426  
 
 427  0
                                 Object mc =
 428  
                                     Model.getCoreFactory()
 429  
                                         .createConstraint();
 430  0
                                 Model.getCoreHelper().setName(mc, ocltCurrent
 431  
                                     .getConstraintName());
 432  0
                                 Model.getCoreHelper().setBody(mc,
 433  
                                         Model.getDataTypesFactory()
 434  
                                                 .createBooleanExpression(
 435  
                                                         "OCL",
 436  
                                                         ocltCurrent
 437  
                                                         .getExpression()));
 438  0
                                 Model.getCoreHelper().addConstraint(
 439  
                                         theMMmeiTarget,
 440  
                                         mc);
 441  
 
 442  
                                 // the constraint _must_ be owned by a namespace
 443  0
                                 if (Model.getFacade().getNamespace(
 444  
                                         theMMmeiTarget)
 445  
                                         != null) {
 446  0
                                     Model.getCoreHelper().addOwnedElement(
 447  
                                             Model.getFacade().getNamespace(
 448  
                                                     theMMmeiTarget),
 449  
                                             mc);
 450  0
                                 } else if (Model.getFacade().getNamespace(
 451  
                                         mmeContext) != null) {
 452  0
                                     Model.getCoreHelper().addOwnedElement(
 453  
                                             Model.getFacade().getNamespace(
 454  
                                                     mmeContext),
 455  
                                             theMMcConstraint);
 456  
                                 }
 457  
 
 458  0
                                 theMAlConstraints.add(mc);
 459  0
                                 fireConstraintAdded();
 460  0
                             }
 461  
 
 462  0
                             return;
 463  
                         }
 464  
                     }
 465  
 
 466  
                     // Store constraint body
 467  0
                     Object mcOld = null;
 468  
 
 469  0
                     if (theMMcConstraint == null) {
 470  
                         // New constraint, first time setData is called
 471  0
                         theMMcConstraint =
 472  
                             Model.getCoreFactory().createConstraint();
 473  
 
 474  0
                         Model.getCoreHelper().setName(
 475  
                                 theMMcConstraint,
 476  
                                 "newConstraint");
 477  0
                         Model.getCoreHelper().setBody(
 478  
                                 theMMcConstraint,
 479  
                                 Model.getDataTypesFactory()
 480  
                                         .createBooleanExpression("OCL", sData));
 481  
 
 482  0
                         Model.getCoreHelper().addConstraint(theMMmeiTarget,
 483  
                                 theMMcConstraint);
 484  
 
 485  
                         // the constraint _must_ be owned by a namespace
 486  0
                         Object targetNamespace =
 487  
                             Model.getFacade().getNamespace(theMMmeiTarget);
 488  0
                         Object contextNamespace =
 489  
                             Model.getFacade().getNamespace(mmeContext);
 490  0
                         if (targetNamespace != null) {
 491  0
                             Model.getCoreHelper().addOwnedElement(
 492  
                                     targetNamespace,
 493  
                                     theMMcConstraint);
 494  0
                         } else if (contextNamespace != null) {
 495  0
                             Model.getCoreHelper().addOwnedElement(
 496  
                                     contextNamespace,
 497  
                                     theMMcConstraint);
 498  
                         }
 499  
 
 500  0
                         theMAlConstraints.set(theMNIdx, theMMcConstraint);
 501  0
                     } else {
 502  0
                         mcOld = Model.getCoreFactory().createConstraint();
 503  0
                         Model.getCoreHelper().setName(
 504  
                                 mcOld,
 505  
                                 Model.getFacade().getName(theMMcConstraint));
 506  0
                         Model.getCoreHelper().setBody(
 507  
                                 mcOld,
 508  
                                 Model.getDataTypesFactory()
 509  
                                         .createBooleanExpression("OCL",
 510  
                                                 (String) Model.getFacade()
 511  
                                                         .getBody(
 512  
                                                 Model.getFacade().getBody(
 513  
                                                         theMMcConstraint))));
 514  0
                         Model.getCoreHelper().setBody(theMMcConstraint,
 515  
                                 Model.getDataTypesFactory()
 516  
                                         .createBooleanExpression("OCL", sData));
 517  
                     }
 518  
 
 519  0
                     fireConstraintDataChanged(theMNIdx, mcOld,
 520  
                             theMMcConstraint);
 521  
 
 522  0
                 } catch (OclTypeException pe) {
 523  0
                     LOG.warn("There was some sort of OCL Type problem", pe);
 524  0
                     throw pe;
 525  0
                 } catch (OclParserException pe1) {
 526  0
                     LOG.warn("Could not parse the constraint", pe1);
 527  0
                     throw pe1;
 528  0
                 } catch (OclException oclExc) {
 529  
                     // a runtime exception that occurs when some
 530  
                     // internal test fails
 531  0
                     LOG.warn("There was some unidentified problem");
 532  0
                     throw oclExc;
 533  0
                 }
 534  0
             }
 535  
 
 536  
             /**
 537  
              * Set the constraint's name.
 538  
              */
 539  
             public void setName(
 540  
                 final String sName,
 541  
                 final EditingUtilities euHelper) {
 542  0
                 if (theMMcConstraint != null) {
 543  
                     // Check name for consistency with spec
 544  0
                     if (!euHelper.isValidConstraintName(sName)) {
 545  0
                         throw new IllegalArgumentException(
 546  
                                 "Please specify a valid name.");
 547  
                     }
 548  
 
 549  
                     // Set name
 550  0
                     Object mcOld =
 551  
                         Model.getCoreFactory().createConstraint();
 552  0
                     Model.getCoreHelper().setName(mcOld,
 553  
                             Model.getFacade().getName(theMMcConstraint));
 554  0
                     Object constraintBody =
 555  
                         Model.getFacade().getBody(theMMcConstraint);
 556  0
                     Model.getCoreHelper().setBody(mcOld,
 557  
                             Model.getDataTypesFactory()
 558  
                                 .createBooleanExpression(
 559  
                                         "OCL",
 560  
                                         (String) Model.getFacade().getBody(
 561  
                                                 constraintBody)));
 562  
 
 563  0
                     Model.getCoreHelper().setName(theMMcConstraint, sName);
 564  
 
 565  0
                     fireConstraintNameChanged(theMNIdx, mcOld,
 566  
                             theMMcConstraint);
 567  
 
 568  
                     // Also set name in constraint body -- Added 03/14/2001
 569  
                     try {
 570  0
                         OclTree tree = null;
 571  0
                         Object mmeContext = OCLUtil
 572  
                                 .getInnerMostEnclosingNamespace(theMMmeiTarget);
 573  
 
 574  0
                         constraintBody =
 575  
                             Model.getFacade().getBody(theMMcConstraint);
 576  0
                         tree =
 577  
                             euHelper.parseAndCheckConstraint(
 578  
                                 (String) Model.getFacade().getBody(
 579  
                                         constraintBody),
 580  
                                 new ArgoFacade(mmeContext));
 581  
 
 582  0
                         if (tree != null) {
 583  0
                             tree.apply(new DepthFirstAdapter() {
 584  0
                                 private int nameID = 0;
 585  
                                 public void caseAConstraintBody(
 586  
                                         AConstraintBody node) {
 587  
                                     // replace name
 588  0
                                     if (nameID == 0) {
 589  0
                                         node.setName(new TName(sName));
 590  
                                     } else {
 591  0
                                         node.setName(new TName(
 592  
                                                 sName + "_" + nameID));
 593  
                                     }
 594  0
                                     nameID++;
 595  0
                                 }
 596  
                             });
 597  
 
 598  0
                             setData(tree.getExpression(), euHelper);
 599  
                         }
 600  0
                     } catch (Throwable t) {
 601  
                         // OK, so that didn't work out... Just ignore
 602  
                         // any problems and don't set the name in the
 603  
                         // constraint body better had log it.
 604  0
                         LOG.error("some unidentified problem", t);
 605  0
                     }
 606  0
                 } else {
 607  0
                     throw new IllegalStateException(
 608  
                         "Please define and submit a constraint body first.");
 609  
                 }
 610  0
             }
 611  
         }
 612  
 
 613  
         /**
 614  
          * Create a representation adapter for the given constraint.
 615  
          */
 616  
         private CR representationFor(int nIdx) {
 617  0
             if ((nIdx < 0) || (nIdx >= theMAlConstraints.size())) {
 618  0
                 return null;
 619  
             }
 620  
 
 621  0
             Object mc = theMAlConstraints.get(nIdx);
 622  
 
 623  0
             if (mc != null) {
 624  0
                 return new CR(mc, nIdx);
 625  
             }
 626  0
             return new CR(nIdx);
 627  
         }
 628  
 
 629  
         /**
 630  
          * Add a listener to be informed of changes in the model.
 631  
          *
 632  
          * @param ccl the new listener
 633  
          */
 634  
         public void addConstraintChangeListener(ConstraintChangeListener ccl) {
 635  0
             theMEllListeners.add(ConstraintChangeListener.class, ccl);
 636  0
         }
 637  
 
 638  
         /**
 639  
          * Remove a listener to be informed of changes in the model.
 640  
          *
 641  
          * @param ccl the listener to be removed
 642  
          */
 643  
         public void removeConstraintChangeListener(
 644  
                 ConstraintChangeListener ccl) {
 645  0
             theMEllListeners.remove(ConstraintChangeListener.class, ccl);
 646  0
         }
 647  
 
 648  
         protected void fireConstraintRemoved(
 649  
                 Object mc, int nIdx) {
 650  
             // Guaranteed to return a non-null array
 651  0
             Object[] listeners = theMEllListeners.getListenerList();
 652  
 
 653  0
             ConstraintChangeEvent cce = null;
 654  
 
 655  
             // Process the listeners last to first, notifying
 656  
             // those that are interested in this event
 657  0
             for (int i = listeners.length - 2; i >= 0; i -= 2) {
 658  0
                 if (listeners[i] == ConstraintChangeListener.class) {
 659  
                     // Lazily create the event:
 660  0
                     if (cce == null) {
 661  0
                         cce = new ConstraintChangeEvent(
 662  
                             this,
 663  
                             nIdx,
 664  
                             new CR(mc, nIdx),
 665  
                             null);
 666  
                     }
 667  0
                     ((ConstraintChangeListener) listeners[i + 1])
 668  
                         .constraintRemoved(cce);
 669  
                 }
 670  
             }
 671  0
         }
 672  
 
 673  
         protected void fireConstraintAdded() {
 674  
             // Guaranteed to return a non-null array
 675  0
             Object[] listeners = theMEllListeners.getListenerList();
 676  
 
 677  0
             ConstraintChangeEvent cce = null;
 678  
 
 679  
             // Process the listeners last to first, notifying
 680  
             // those that are interested in this event
 681  0
             for (int i = listeners.length - 2; i >= 0; i -= 2) {
 682  0
                 if (listeners[i] == ConstraintChangeListener.class) {
 683  
                     // Lazily create the event:
 684  0
                     if (cce == null) {
 685  0
                         int nIdx = theMAlConstraints.size() - 1;
 686  0
                         cce =
 687  
                             new ConstraintChangeEvent(
 688  
                                     this,
 689  
                                     nIdx,
 690  
                                     null,
 691  
                                     representationFor(nIdx));
 692  
                     }
 693  0
                     ((ConstraintChangeListener) listeners[i + 1])
 694  
                         .constraintAdded(cce);
 695  
                 }
 696  
             }
 697  0
         }
 698  
 
 699  
         protected void fireConstraintDataChanged(
 700  
                          int nIdx,
 701  
                          Object mcOld,
 702  
                          Object mcNew) {
 703  
             // Guaranteed to return a non-null array
 704  0
             Object[] listeners = theMEllListeners.getListenerList();
 705  
 
 706  0
             ConstraintChangeEvent cce = null;
 707  
 
 708  
             // Process the listeners last to first, notifying
 709  
             // those that are interested in this event
 710  0
             for (int i = listeners.length - 2; i >= 0; i -= 2) {
 711  0
                 if (listeners[i] == ConstraintChangeListener.class) {
 712  
                     // Lazily create the event:
 713  0
                     if (cce == null) {
 714  0
                         cce = new ConstraintChangeEvent(
 715  
                             this,
 716  
                             nIdx,
 717  
                             new CR(mcOld, nIdx),
 718  
                             new CR(mcNew, nIdx));
 719  
                     }
 720  
 
 721  0
                     ((ConstraintChangeListener) listeners[i + 1])
 722  
                         .constraintDataChanged(cce);
 723  
                 }
 724  
             }
 725  0
         }
 726  
 
 727  
         protected void fireConstraintNameChanged(
 728  
                          int nIdx,
 729  
                          Object mcOld,
 730  
                          Object mcNew) {
 731  
             // Guaranteed to return a non-null array
 732  0
             Object[] listeners = theMEllListeners.getListenerList();
 733  
 
 734  0
             ConstraintChangeEvent cce = null;
 735  
 
 736  
             // Process the listeners last to first, notifying
 737  
             // those that are interested in this event
 738  0
             for (int i = listeners.length - 2; i >= 0; i -= 2) {
 739  0
                 if (listeners[i] == ConstraintChangeListener.class) {
 740  
                     // Lazily create the event:
 741  0
                     if (cce == null) {
 742  0
                         cce = new ConstraintChangeEvent(
 743  
                             this,
 744  
                             nIdx,
 745  
                             new CR(mcOld, nIdx),
 746  
                             new CR(mcNew, nIdx));
 747  
                     }
 748  
 
 749  0
                     ((ConstraintChangeListener) listeners[i + 1])
 750  
                         .constraintNameChanged(cce);
 751  
                 }
 752  
             }
 753  0
         }
 754  
     }
 755  
 
 756  
     /*
 757  
      * @see org.argouml.ui.targetmanager.TargetListener#targetAdded(
 758  
      *         org.argouml.ui.targetmanager.TargetEvent)
 759  
      */
 760  
     public void targetAdded(TargetEvent e) {
 761  
         // TODO: Why is this ignored? - tfm - 20070110
 762  0
     }
 763  
 
 764  
     /*
 765  
      * @see org.argouml.ui.targetmanager.TargetListener#targetRemoved(
 766  
      *         org.argouml.ui.targetmanager.TargetEvent)
 767  
      */
 768  
     public void targetRemoved(TargetEvent e) {
 769  0
         setTarget(e.getNewTarget());
 770  0
     }
 771  
 
 772  
     /*
 773  
      * @see org.argouml.ui.targetmanager.TargetListener#targetSet(
 774  
      *         org.argouml.ui.targetmanager.TargetEvent)
 775  
      */
 776  
     public void targetSet(TargetEvent e) {
 777  0
         setTarget(e.getNewTarget());
 778  0
     }
 779  
     
 780  
     /*
 781  
      * @see java.awt.event.ComponentListener#componentShown(java.awt.event.ComponentEvent)
 782  
      */
 783  
     public void componentShown(ComponentEvent e) {
 784  
         // Update our model with our saved target
 785  0
         setTargetInternal(mMmeiTarget);
 786  0
     }
 787  
     
 788  
     /*
 789  
      * @see java.awt.event.ComponentListener#componentHidden(java.awt.event.ComponentEvent)
 790  
      */
 791  
     public void componentHidden(ComponentEvent e) {
 792  
         // We have no model event listeners, so no need to do anything
 793  900
     }
 794  
 
 795  
     public void componentMoved(ComponentEvent e) {
 796  
         // ignored
 797  900
     }
 798  
 
 799  
     public void componentResized(ComponentEvent e) {
 800  
         // ignored
 801  900
     }
 802  
 
 803  
 
 804  
 }