Coverage Report - org.argouml.uml.ui.TabStereotype
 
Classes in this File Line Coverage Branch Coverage Complexity
TabStereotype
67%
53/79
18%
3/16
3.533
TabStereotype$1
N/A
N/A
3.533
TabStereotype$AddRemoveListener
14%
1/7
0%
0/4
3.533
TabStereotype$AvailableListSelectionListener
16%
1/6
0%
0/4
3.533
TabStereotype$SelectedListSelectionListener
16%
1/6
0%
0/4
3.533
TabStereotype$UMLModelStereotypeListModel
3%
2/63
0%
0/44
3.533
 
 1  
 /* $Id: TabStereotype.java 19037 2011-02-16 22:29:14Z bobtarling $
 2  
  *****************************************************************************
 3  
  * Copyright (c) 2009-2011 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  
  *    Michiel ven der Wulp
 11  
  *    Laurent Braud
 12  
  *****************************************************************************
 13  
  *
 14  
  * Some portions of this file was previously release using the BSD License:
 15  
  */
 16  
 
 17  
 // Copyright (c) 1996-2007 The Regents of the University of California. All
 18  
 // Rights Reserved. Permission to use, copy, modify, and distribute this
 19  
 // software and its documentation without fee, and without a written
 20  
 // agreement is hereby granted, provided that the above copyright notice
 21  
 // and this paragraph appear in all copies. This software program and
 22  
 // documentation are copyrighted by The Regents of the University of
 23  
 // California. The software program and documentation are supplied "AS
 24  
 // IS", without any accompanying services from The Regents. The Regents
 25  
 // does not warrant that the operation of the program will be
 26  
 // uninterrupted or error-free. The end-user understands that the program
 27  
 // was developed for research purposes and is advised not to rely
 28  
 // exclusively on the program for any reason. IN NO EVENT SHALL THE
 29  
 // UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
 30  
 // SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
 31  
 // ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
 32  
 // THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
 33  
 // SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
 34  
 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 35  
 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
 36  
 // PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
 37  
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 38  
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 39  
 
 40  
 package org.argouml.uml.ui;
 41  
 
 42  
 import java.awt.BorderLayout;
 43  
 import java.awt.Dimension;
 44  
 import java.awt.Insets;
 45  
 import java.awt.event.ActionEvent;
 46  
 import java.awt.event.ActionListener;
 47  
 import java.beans.PropertyChangeEvent;
 48  
 import java.util.ArrayList;
 49  
 import java.util.Collection;
 50  
 import java.util.Iterator;
 51  
 
 52  
 import javax.swing.BorderFactory;
 53  
 import javax.swing.Box;
 54  
 import javax.swing.BoxLayout;
 55  
 import javax.swing.ImageIcon;
 56  
 import javax.swing.JButton;
 57  
 import javax.swing.JLabel;
 58  
 import javax.swing.JList;
 59  
 import javax.swing.JPanel;
 60  
 import javax.swing.JScrollPane;
 61  
 import javax.swing.event.ListSelectionEvent;
 62  
 import javax.swing.event.ListSelectionListener;
 63  
 
 64  
 import org.argouml.configuration.Configuration;
 65  
 import org.argouml.i18n.Translator;
 66  
 import org.argouml.kernel.ProjectManager;
 67  
 import org.argouml.model.AddAssociationEvent;
 68  
 import org.argouml.model.AttributeChangeEvent;
 69  
 import org.argouml.model.Model;
 70  
 import org.argouml.model.RemoveAssociationEvent;
 71  
 import org.argouml.swingext.SpacerPanel;
 72  
 import org.argouml.swingext.UpArrowIcon;
 73  
 import org.argouml.ui.TabModelTarget;
 74  
 import org.argouml.ui.targetmanager.TargetManager;
 75  
 import org.argouml.uml.StereotypeUtility;
 76  
 import org.tigris.gef.presentation.Fig;
 77  
 import org.tigris.swidgets.Horizontal;
 78  
 import org.tigris.swidgets.Vertical;
 79  
 
 80  
 /**
 81  
  * This the tab in the details pane for displaying the stereotypes applied to a
 82  
  * model element and allowing adding and removal of stereotypes to that list.<p>
 83  
  *
 84  
  * The code for the 2 lists and the buttons to move items
 85  
  * from one side to the other is based on the PerspectiveConfigurator class.
 86  
  */
 87  0
 public class TabStereotype extends PropPanel implements TabModelTarget {
 88  
 
 89  
     /**
 90  
      * Insets in pixels.
 91  
      */
 92  
     private static final int INSET_PX = 3;
 93  
 
 94  900
     private static String orientation =
 95  
         Configuration.getString(Configuration
 96  
             .makeKey("layout", "tabstereotype"));
 97  
 
 98  
     private UMLModelElementStereotypeListModel selectedListModel;
 99  
     private UMLModelStereotypeListModel availableListModel;
 100  
 
 101  
     private JScrollPane selectedScroll;
 102  
     private JScrollPane availableScroll;
 103  
     private JPanel panel;
 104  
     private JButton addStButton;
 105  
     private JButton removeStButton;
 106  
     private JPanel xferButtons;
 107  
     private JList selectedList;
 108  
     private JList availableList;
 109  
 
 110  
     /**
 111  
      * Construct new Stereotype tab.
 112  
      */
 113  
     public TabStereotype() {
 114  900
         super(Translator.localize("tab.stereotype"), (ImageIcon) null);
 115  900
         setOrientation((orientation
 116  
                 .equals("West") || orientation.equals("East")) ? Vertical
 117  
                 .getInstance() : Horizontal.getInstance());
 118  900
         setIcon(new UpArrowIcon());
 119  900
         setLayout(new BorderLayout());
 120  900
         remove(getTitleLabel()); // no title looks better
 121  
 
 122  900
         panel = makePanel();
 123  900
         add(panel);
 124  900
     }
 125  
 
 126  
     /**
 127  
      * Create a JPanel with everything on it.
 128  
      *
 129  
      * @return a newly created JPanel.
 130  
      */
 131  
     private JPanel makePanel() {
 132  
         // make lists
 133  900
         selectedListModel = new UMLModelElementStereotypeListModel();
 134  900
         selectedList = new UMLStereotypeList(selectedListModel);
 135  900
         selectedScroll = new JScrollPane(selectedList);
 136  900
         selectedScroll.setBorder(BorderFactory.createEmptyBorder(
 137  
                 INSET_PX, INSET_PX, INSET_PX, INSET_PX));
 138  900
         selectedScroll.setColumnHeaderView(new JLabel(
 139  
                 Translator.localize("label.applied-stereotypes")));
 140  
 
 141  900
         availableListModel = new UMLModelStereotypeListModel();
 142  900
         availableList = new UMLStereotypeList(availableListModel);
 143  900
         availableScroll = new JScrollPane(availableList);
 144  900
         availableScroll.setBorder(BorderFactory.createEmptyBorder(
 145  
                 INSET_PX, INSET_PX, INSET_PX, INSET_PX));
 146  900
         availableScroll.setColumnHeaderView(new JLabel(
 147  
                 Translator.localize("label.available-stereotypes")));
 148  
 
 149  
         // make buttons
 150  900
         addStButton = new JButton(">>");
 151  900
         addStButton.setToolTipText(Translator.localize("button.add-stereo"));
 152  900
         removeStButton = new JButton("<<");
 153  900
         removeStButton.setToolTipText(Translator.localize(
 154  
                 "button.remove-stereo"));
 155  900
         addStButton.setEnabled(false);
 156  900
         removeStButton.setEnabled(false);
 157  900
         addStButton.setMargin(new Insets(2, 15, 2, 15));
 158  900
         removeStButton.setMargin(new Insets(2, 15, 2, 15));
 159  900
         addStButton.setPreferredSize(addStButton.getMinimumSize());
 160  900
         removeStButton.setPreferredSize(removeStButton.getMinimumSize());
 161  
 
 162  
         // make buttons layout
 163  
         BoxLayout box;
 164  900
         xferButtons = new JPanel();
 165  900
         box = new BoxLayout(xferButtons, BoxLayout.Y_AXIS);
 166  900
         xferButtons.setLayout(box);
 167  900
         xferButtons.add(new SpacerPanel());
 168  900
         xferButtons.add(addStButton);
 169  900
         xferButtons.add(new SpacerPanel());
 170  900
         xferButtons.add(removeStButton);
 171  900
         Dimension dmax = box.maximumLayoutSize(xferButtons);
 172  900
         Dimension dmin = box.minimumLayoutSize(xferButtons);
 173  900
         xferButtons.setMaximumSize(new Dimension(dmin.width, dmax.height));
 174  
 
 175  
         // make listeners
 176  900
         addStButton.addActionListener(new AddRemoveListener());
 177  900
         removeStButton.addActionListener(new AddRemoveListener());
 178  900
         availableList.addListSelectionListener(
 179  
                 new AvailableListSelectionListener());
 180  900
         selectedList.addListSelectionListener(
 181  
                 new SelectedListSelectionListener());
 182  
 
 183  
         // put everything together
 184  900
         JPanel thePanel = new JPanel();
 185  900
         thePanel.setLayout(new BoxLayout(thePanel, BoxLayout.X_AXIS));
 186  900
         thePanel.setBorder(BorderFactory.createEmptyBorder(
 187  
                 INSET_PX, INSET_PX, INSET_PX, INSET_PX));
 188  900
         thePanel.add(availableScroll);
 189  900
         thePanel.add(xferButtons);
 190  900
         thePanel.add(Box.createRigidArea(new Dimension(5, 1)));
 191  900
         thePanel.add(selectedScroll);
 192  
 
 193  900
         return thePanel;
 194  
     }
 195  
 
 196  
     /**
 197  
      * Checks if the tab should be enabled. Returns true if the target
 198  
      * returned by getTarget is a modelelement or if that target shows up as Fig
 199  
      * on the active diagram and has a modelelement as owner.
 200  
      *
 201  
      * @return true if this tab should be enabled, otherwise false.
 202  
      */
 203  
     public boolean shouldBeEnabled() {
 204  0
         Object target = getTarget();
 205  0
         return shouldBeEnabled(target);
 206  
     }
 207  
     
 208  
     /*
 209  
      * @see org.argouml.uml.ui.PropPanel#shouldBeEnabled(java.lang.Object)
 210  
      */
 211  
     @Override
 212  
     public boolean shouldBeEnabled(Object target) {
 213  1327
         if (target instanceof Fig) {
 214  0
             target = ((Fig) target).getOwner();
 215  
         }
 216  1327
         return Model.getFacade().isAModelElement(target);
 217  
     }
 218  
 
 219  
     /*
 220  
      * @see org.argouml.ui.TabTarget#setTarget(java.lang.Object)
 221  
      */
 222  
     @Override
 223  
     public void setTarget(Object theTarget) {
 224  0
         super.setTarget(theTarget);
 225  0
         if (isVisible()) {
 226  0
             Object me = getModelElement();
 227  0
             if (me != null) {
 228  0
                 selectedListModel.setTarget(me);
 229  0
                 validate();
 230  
             }
 231  
         }
 232  0
     }
 233  
 
 234  
     /**
 235  
      * Add the currently selected stereotype from the library
 236  
      * to the modelelement.
 237  
      */
 238  
     private void doAddStereotype() {
 239  0
         Object stereotype = availableList.getSelectedValue();
 240  0
         Object modelElement = TargetManager.getInstance().getModelTarget();
 241  0
         if (modelElement == null) {
 242  0
             return;
 243  
         }
 244  0
         Model.getCoreHelper().addStereotype(modelElement, stereotype);
 245  0
         ProjectManager.getManager().updateRoots();
 246  0
     }
 247  
 
 248  
     /**
 249  
      * Add the currently selected stereotype from the library
 250  
      * to the modelelement.
 251  
      */
 252  
     private void doRemoveStereotype() {
 253  0
         Object stereotype = selectedList.getSelectedValue();
 254  0
         Object modelElement = TargetManager.getInstance().getModelTarget();
 255  0
         if (modelElement == null) {
 256  0
             return;
 257  
         }
 258  
 
 259  0
         if (Model.getFacade().getStereotypes(modelElement)
 260  
                 .contains(stereotype)) {
 261  0
             Model.getCoreHelper().removeStereotype(modelElement, stereotype);
 262  0
             ProjectManager.getManager().updateRoots();
 263  
         }
 264  0
     }
 265  
 
 266  
     /**
 267  
      * The list model for all stereotypes available in all the models - except
 268  
      * the ones already applied.
 269  
      */
 270  
     private static class UMLModelStereotypeListModel
 271  
         extends UMLStereotypeListModel {
 272  
 
 273  
         /**
 274  
          * Constructor for UMLModelElementNamespaceListModel.
 275  
          */
 276  
         public UMLModelStereotypeListModel() {
 277  900
             super("stereotype");
 278  900
         }
 279  
 
 280  
         /*
 281  
          * @see org.argouml.uml.ui.UMLModelElementListModel2#buildModelList()
 282  
          */
 283  
         protected void buildModelList() {
 284  0
             removeAllElements();
 285  0
             if (Model.getFacade().isAModelElement(getTarget())) {
 286  
                 Collection s;
 287  0
                 s = StereotypeUtility.getAvailableStereotypes(getTarget());
 288  
                 // now remove the ones already applied.
 289  0
                 s.removeAll(Model.getFacade().getStereotypes(getTarget()));
 290  0
                 addAll(s);
 291  
             }
 292  0
         }
 293  
         
 294  
         
 295  
         /**
 296  
          * @param e
 297  
          * @return
 298  
          * @see org.argouml.uml.ui.UMLStereotypeListModel#isValidEvent(java.beans.PropertyChangeEvent)
 299  
          * @since 20110215
 300  
          */
 301  
         private boolean isValidEventRemove(PropertyChangeEvent e) {
 302  0
             boolean valid = false;
 303  0
             if (!(getChangedElement(e) instanceof Collection)) {
 304  
                
 305  0
                 if ((e.getNewValue() != null && e.getOldValue() == null) 
 306  
                         || isValidElement(getChangedElement(e))) {
 307  0
                     valid = true; // we tried to remove a value
 308  
                 }
 309  
             } else {
 310  0
                 Collection col = (Collection) getChangedElement(e);
 311  0
                 Iterator it = col.iterator();
 312  0
                 if (!col.isEmpty()) {
 313  0
                     valid = true;
 314  0
                     while (it.hasNext()) {
 315  0
                         Object o = it.next();
 316  0
                         if (!isValidElement(o)) {
 317  0
                             valid = false;
 318  0
                             break;
 319  
                         }
 320  0
                     }
 321  
                 } else {
 322  0
                     if (e.getOldValue() instanceof Collection
 323  
                         && !((Collection) e.getOldValue()).isEmpty()) {
 324  0
                         valid = true;
 325  
                     }
 326  
                 }
 327  
             }
 328  0
             return valid;
 329  
         }
 330  
         
 331  
         /**
 332  
          * Must be different from the extends class because 
 333  
          * when we add a sterotype=> remove from available
 334  
          *         remove a stereotype=> add to available
 335  
          * Called twices: with a AttributeChangeEvent, and with AddAssociationEvent or RemoveAssociationEvent
 336  
          * 
 337  
          * @param e
 338  
          * 
 339  
          * @see org.argouml.uml.ui.UMLStereotypeListModel#propertyChange(PropertyChangeEvent)
 340  
          * @since 20110215
 341  
          */
 342  
         public void propertyChange(PropertyChangeEvent e) {
 343  0
             if (e instanceof AttributeChangeEvent) {
 344  
                // ignored this event
 345  0
             } else if (e instanceof AddAssociationEvent) {
 346  
                 //Remove the element from Available List
 347  0
                 boolean valid = false;
 348  0
                 if (!(getChangedElement(e) instanceof Collection)) {
 349  0
                     valid = contains(getChangedElement(e));
 350  
                 } else {
 351  0
                     Collection col = (Collection) getChangedElement(e);
 352  0
                     Iterator it = col.iterator();
 353  0
                     valid = true;
 354  0
                     while (it.hasNext()) {
 355  0
                         Object o = it.next();
 356  0
                         if (!contains(o)) {
 357  0
                             valid = false;
 358  0
                             break;
 359  
                         }
 360  0
                     }
 361  
                 }
 362  0
                 if (valid) {
 363  0
                     Object o = getChangedElement(e);
 364  0
                     if (o instanceof Collection) {
 365  0
                         Iterator it = ((Collection) o).iterator();
 366  0
                         while (it.hasNext()) {
 367  0
                             Object o3 = it.next();
 368  0
                             removeElement(o3);
 369  0
                         }
 370  0
                     } else {
 371  0
                         removeElement(o);
 372  
                     }
 373  
                 }
 374  
                 
 375  
                
 376  
                 
 377  0
             } else if (e instanceof RemoveAssociationEvent) {
 378  0
                 if (isValidEventRemove(e)) {
 379  0
                     Object o = getChangedElement(e);
 380  0
                     if (o instanceof Collection) {
 381  0
                         ArrayList tempList = new ArrayList((Collection) o);
 382  0
                         Iterator it = tempList.iterator();
 383  0
                         while (it.hasNext()) {
 384  0
                             Object o2 = it.next();
 385  0
                             addElement(o2);
 386  0
                         }
 387  0
                     } else {
 388  0
                         addElement(o); 
 389  
                     }
 390  
                 }
 391  
                 
 392  
             }
 393  0
         }
 394  
 
 395  
         /*
 396  
          * @see org.argouml.uml.ui.UMLModelElementListModel2#isValidElement(Object)
 397  
          */
 398  
         protected boolean isValidElement(Object element) {
 399  0
             return Model.getFacade().isAStereotype(element);
 400  
         }
 401  
 
 402  
         /**
 403  
          * The UID.
 404  
          */
 405  
         private static final long serialVersionUID = 7247425177890724453L;
 406  
     }
 407  
 
 408  
     /**
 409  
      * Handles pressing the ">>" or "<<" buttons.
 410  
      */
 411  3600
     private class AddRemoveListener implements ActionListener {
 412  
         /*
 413  
          * @see java.awt.event.ActionListener#actionPerformed(
 414  
          *         java.awt.event.ActionEvent)
 415  
          */
 416  
         public void actionPerformed(ActionEvent e) {
 417  
 
 418  0
             Object src = e.getSource();
 419  0
             if (src == addStButton) {
 420  0
                 doAddStereotype();
 421  0
             } else if (src == removeStButton) {
 422  0
                 doRemoveStereotype();
 423  
             }
 424  0
         }
 425  
     }
 426  
 
 427  
     /**
 428  
      * Handles selection changes in the available stereotypes list.
 429  
      */
 430  1800
     private class AvailableListSelectionListener
 431  
         implements ListSelectionListener {
 432  
         /*
 433  
          * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
 434  
          */
 435  
         public void valueChanged(ListSelectionEvent lse) {
 436  0
             if (lse.getValueIsAdjusting()) {
 437  0
                 return;
 438  
             }
 439  
 
 440  0
             Object selRule = availableList.getSelectedValue();
 441  0
             addStButton.setEnabled(selRule != null);
 442  0
         }
 443  
     }
 444  
 
 445  
     /**
 446  
      * Handles selection changes in the stereotypes list.
 447  
      */
 448  1800
     private class SelectedListSelectionListener
 449  
         implements ListSelectionListener {
 450  
         /*
 451  
          * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent)
 452  
          */
 453  
         public void valueChanged(ListSelectionEvent lse) {
 454  0
             if (lse.getValueIsAdjusting()) {
 455  0
                 return;
 456  
             }
 457  
 
 458  0
             Object selRule = selectedList.getSelectedValue();
 459  0
             removeStButton.setEnabled(selRule != null);
 460  0
         }
 461  
     }
 462  
 
 463  
     /**
 464  
      * The UID.
 465  
      */
 466  
     private static final long serialVersionUID = -4741653225927138553L;
 467  
 }