Coverage Report - org.argouml.uml.ui.TabTaggedValuesModel
 
Classes in this File Line Coverage Branch Coverage Complexity
TabTaggedValuesModel
11%
16/142
6%
7/112
6.067
 
 1  
 /* $Id: TabTaggedValuesModel.java 19082 2011-02-28 09:56:30Z thn $
 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  
  *    Thomas Neustupny
 12  
  *****************************************************************************
 13  
  *
 14  
  * Some portions of this file was previously release using the BSD License:
 15  
  */
 16  
 
 17  
 // Copyright (c) 2005-2008 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.beans.PropertyChangeEvent;
 43  
 import java.beans.PropertyChangeListener;
 44  
 import java.beans.VetoableChangeListener;
 45  
 import java.util.ArrayList;
 46  
 import java.util.Collection;
 47  
 import java.util.Iterator;
 48  
 import java.util.List;
 49  
 
 50  
 import javax.swing.SwingUtilities;
 51  
 import javax.swing.event.TableModelEvent;
 52  
 import javax.swing.table.AbstractTableModel;
 53  
 
 54  
 import org.apache.log4j.Logger;
 55  
 import org.argouml.i18n.Translator;
 56  
 import org.argouml.kernel.DelayedChangeNotify;
 57  
 import org.argouml.kernel.DelayedVChangeListener;
 58  
 import org.argouml.model.DeleteInstanceEvent;
 59  
 import org.argouml.model.InvalidElementException;
 60  
 import org.argouml.model.Model;
 61  
 
 62  
 /**
 63  
  * The model for the table with the tagged values. Implementation for UML 1.4
 64  
  * and TagDefinitions.
 65  
  * 
 66  
  * TODO: This currently only supports TaggedValues with a TagDefinition which
 67  
  * has a type of String.
 68  
  */
 69  
 public class TabTaggedValuesModel extends AbstractTableModel implements
 70  
         VetoableChangeListener, DelayedVChangeListener, PropertyChangeListener {
 71  
 
 72  900
     private static final Logger LOG = Logger
 73  
             .getLogger(TabTaggedValuesModel.class);
 74  
 
 75  
     /**
 76  
      * The ModelElement that is the current target.
 77  
      */
 78  
     private Object target;
 79  
 
 80  
     /**
 81  
      * Construct a model to be used by a JTable containing TaggedValues.
 82  
      */
 83  900
     public TabTaggedValuesModel() {
 84  900
     }
 85  
 
 86  
     /**
 87  
      * Set the current target to the given model element.
 88  
      * 
 89  
      * @param t the target modelelement
 90  
      */
 91  
     public void setTarget(Object t) {
 92  900
         if (LOG.isDebugEnabled()) {
 93  900
             LOG.debug("Set target to " + t);
 94  
         }
 95  900
         if (t != null && !Model.getFacade().isAModelElement(t)) {
 96  0
             throw new IllegalArgumentException();
 97  
         }
 98  900
         if (target != t) {
 99  0
             if (target != null) {
 100  0
                 Model.getPump().removeModelEventListener(this, target);
 101  
             }
 102  0
             target = t;
 103  0
             if (t != null) {
 104  0
                 Model.getPump().addModelEventListener(this, t,
 105  
                         new String[] {"taggedValue", "referenceTag"});
 106  
             }
 107  
         }
 108  
         // always fire changes in the case something has changed in the
 109  
         // composition of the taggedValues collection.
 110  900
         fireTableDataChanged();
 111  900
     }
 112  
 
 113  
     /*
 114  
      * @see javax.swing.table.TableModel#getColumnCount()
 115  
      */
 116  
     public int getColumnCount() {
 117  2700
         return 2;
 118  
     }
 119  
 
 120  
     /*
 121  
      * @see javax.swing.table.TableModel#getColumnName(int)
 122  
      */
 123  
     @Override
 124  
     public String getColumnName(int c) {
 125  1800
         if (c == 0) {
 126  900
             return Translator.localize("label.taggedvaluespane.tag");
 127  
         }
 128  900
         if (c == 1) {
 129  900
             return Translator.localize("label.taggedvaluespane.value");
 130  
         }
 131  0
         return "XXX";
 132  
     }
 133  
 
 134  
     /*
 135  
      * @see javax.swing.table.TableModel#getColumnClass(int)
 136  
      */
 137  
     @Override
 138  
     public Class getColumnClass(int c) {
 139  0
         if (c == 0) {
 140  0
             return (Class) Model.getMetaTypes().getTagDefinition();
 141  
         }
 142  0
         if (c == 1) {
 143  
             // TODO: This will vary based on the type of the TagDefinition
 144  0
             return String.class;
 145  
         }
 146  0
         return null;
 147  
     }
 148  
 
 149  
     /*
 150  
      * @see javax.swing.table.TableModel#isCellEditable(int, int)
 151  
      */
 152  
     @Override
 153  
     public boolean isCellEditable(int row, int col) {
 154  0
         return true;
 155  
     }
 156  
 
 157  
     /*
 158  
      * @see javax.swing.table.TableModel#getRowCount()
 159  
      */
 160  
     public int getRowCount() {
 161  9557
         if (target == null) {
 162  9557
             return 0;
 163  
         }
 164  
         try {
 165  0
             Collection tvs = Model.getFacade()
 166  
                     .getTaggedValuesCollection(target);
 167  
             // if (tvs == null) return 1;
 168  0
             return tvs.size() + 1;
 169  0
         } catch (InvalidElementException e) {
 170  
             // Target has been deleted
 171  0
             return 0;
 172  
         }
 173  
     }
 174  
 
 175  
     /*
 176  
      * @see javax.swing.table.TableModel#getValueAt(int, int)
 177  
      */
 178  
     public Object getValueAt(int row, int col) {
 179  0
         Collection tvs = Model.getFacade().getTaggedValuesCollection(target);
 180  0
         if (row > tvs.size() || col > 1) {
 181  0
             throw new IllegalArgumentException();
 182  
         }
 183  
         // If the row is past the end of our current collection,
 184  
         // return an empty string so they can add a new value
 185  0
         if (row == tvs.size()) {
 186  0
             return "";
 187  
         }
 188  0
         Object[] tva = tvs.toArray();
 189  0
         Object tv = tva[row];
 190  0
         if (col == 0) {
 191  0
             Object n = Model.getFacade().getTagDefinition(tv);
 192  0
             if (n == null) {
 193  0
                 return "";
 194  
             }
 195  0
             return n;
 196  
         }
 197  0
         if (col == 1) {
 198  0
             if (Model.getFacade().getUmlVersion().charAt(0) == '1') {
 199  0
                 String be = Model.getFacade().getValueOfTag(tv);
 200  0
                 if (be == null) {
 201  0
                     return "";
 202  
                 }
 203  0
                 return be;
 204  
             } else {
 205  0
                 Object value = Model.getFacade().getValueOfTag(target, tv);
 206  0
                 if (value instanceof Collection) {
 207  
                     // handle multivalued tagged value
 208  0
                     int n = -1;
 209  0
                     for (int i = 0; i <= row; i++) {
 210  0
                         if (tva[i] == tv) {
 211  0
                             n++;
 212  
                         }
 213  
                     }
 214  0
                     if (n != -1) {
 215  0
                         value = ((Collection) value).toArray()[n];
 216  
                     } else {
 217  0
                         value = "";
 218  
                     }
 219  
                 }
 220  0
                 return value.toString();
 221  
             }
 222  
         }
 223  0
         return "TV-" + row * 2 + col; // for debugging
 224  
     }
 225  
 
 226  
     /*
 227  
      * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int)
 228  
      */
 229  
     @Override
 230  
     public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
 231  0
         if (columnIndex != 0 && columnIndex != 1) {
 232  0
             return;
 233  
         }
 234  0
         if (columnIndex == 1 && aValue == null) {
 235  
             // TODO: Use default value of appropriate type here
 236  0
             aValue = "";
 237  
         }
 238  
 
 239  0
         if ((aValue == null || "".equals(aValue)) && columnIndex == 0) {
 240  0
             removeRow(rowIndex);
 241  0
             return;
 242  
         }
 243  
 
 244  0
         Collection tvs = Model.getFacade().getTaggedValuesCollection(target);
 245  0
         if (tvs.size() <= rowIndex) {
 246  0
             if (columnIndex == 0) {
 247  0
                 addRow(new Object[] {aValue, null});
 248  
             }
 249  0
             if (columnIndex == 1) {
 250  0
                 addRow(new Object[] {null, aValue});
 251  
             }
 252  
         } else {
 253  0
             Object tv = getFromCollection(tvs, rowIndex);
 254  0
             if (columnIndex == 0) {
 255  0
                 Model.getExtensionMechanismsHelper().setType(tv, aValue);
 256  0
             } else if (columnIndex == 1) {
 257  0
                 if (Model.getFacade().getUmlVersion().charAt(0) == '1') {
 258  0
                     Model.getExtensionMechanismsHelper().setDataValues(tv,
 259  
                             new String[] {(String) aValue});
 260  
                 } else {
 261  0
                     Object[] tva = tvs.toArray();
 262  0
                     Object value = Model.getFacade().getValueOfTag(target, tv);
 263  0
                     if (value instanceof Collection) {
 264  
                         // handle multivalued tagged value
 265  0
                         Iterator iter = ((Collection) value).iterator();
 266  0
                         Collection values = new ArrayList();
 267  0
                         for (int i = 0; i < tva.length; i++) {
 268  0
                             if (tva[i] == tva[rowIndex]) {
 269  0
                                 if (i == rowIndex) {
 270  0
                                     values.add(aValue);
 271  0
                                     if (iter.hasNext()) {
 272  0
                                         iter.next();
 273  
                                     }
 274  0
                                 } else if (iter.hasNext()) {
 275  0
                                     values.add(iter.next());
 276  
                                 }
 277  
                             }
 278  0
                             value = values;
 279  
                         }
 280  0
                     } else {
 281  0
                         value = aValue;
 282  
                     }
 283  0
                     Model.getExtensionMechanismsHelper().setTaggedValue(
 284  
                             target, tv, value);
 285  
                 }
 286  
             }
 287  0
             fireTableChanged(new TableModelEvent(this, rowIndex, rowIndex,
 288  
                     columnIndex));
 289  
         }
 290  0
     }
 291  
 
 292  
     /**
 293  
      * Add a tagged value to the model with the given type and value.
 294  
      * 
 295  
      * @param values values for the columns: values[0] contains type for new
 296  
      *            TaggedValue values[1] contains value for new TaggedValue
 297  
      */
 298  
     public void addRow(Object[] values) {
 299  0
         Object tagType = values[0];
 300  
 
 301  0
         if (Model.getFacade().getUmlVersion().charAt(0) == '1') {
 302  0
             if (tagType == null) {
 303  0
                 tagType = "";
 304  
             }
 305  0
             String tagValue = (String) values[1];
 306  0
             if (tagValue == null) {
 307  
                 // TODO: Use default value of appropriate type for TD
 308  0
                 tagValue = "";
 309  
                 // tagValue = true;
 310  
             }
 311  0
             Object tv = Model.getExtensionMechanismsFactory()
 312  
                     .createTaggedValue();
 313  
 
 314  
             // We really shouldn't add it until after it is set up, but we
 315  
             // need it to have an owner for the following method calls
 316  0
             Model.getExtensionMechanismsHelper().addTaggedValue(target, tv);
 317  
 
 318  0
             Model.getExtensionMechanismsHelper().setType(tv, tagType);
 319  0
             Model.getExtensionMechanismsHelper().setDataValues(tv,
 320  
                     new String[] {tagValue});
 321  0
         } else {
 322  0
             if (tagType == null) {
 323  0
                 return;
 324  
             }
 325  0
             Object tagValue = values[1];
 326  0
             Model.getExtensionMechanismsHelper()
 327  
                     .addTaggedValue(target, tagType);
 328  
         }
 329  
 
 330  
         // Since we aren't sure of ordering, fire event for whole table
 331  0
         fireTableChanged(new TableModelEvent(this));
 332  0
     }
 333  
 
 334  
     /**
 335  
      * Remove the TaggedValue at the given row from the ModelElement.
 336  
      * 
 337  
      * @param row row containing TaggedValue to be removed.
 338  
      */
 339  
     public void removeRow(int row) {
 340  0
         Collection c = Model.getFacade().getTaggedValuesCollection(target);
 341  0
         if ((row >= 0) && (row < c.size())) {
 342  0
             Object element = getFromCollection(c, row);
 343  0
             Model.getUmlFactory().delete(element);
 344  0
             fireTableChanged(new TableModelEvent(this));
 345  
         }
 346  0
     }
 347  
 
 348  
     /*
 349  
      * Return the ith element from a Collection.
 350  
      * 
 351  
      * @param collection collection to get element from
 352  
      * 
 353  
      * @param index index of the element to be returned
 354  
      * 
 355  
      * @return the object
 356  
      */
 357  
     static Object getFromCollection(Collection collection, int index) {
 358  0
         if (collection instanceof List) {
 359  0
             return ((List) collection).get(index);
 360  
         }
 361  0
         if (index >= collection.size() || index < 0) {
 362  0
             throw new IndexOutOfBoundsException();
 363  
         }
 364  0
         Iterator it = collection.iterator();
 365  0
         for (int i = 0; i < index; i++) {
 366  0
             it.next();
 367  
         }
 368  0
         return it.next();
 369  
     }
 370  
 
 371  
     /*
 372  
      * @see java.beans.PropertyChangeListener#propertyChange(java.beans.
 373  
      * PropertyChangeEvent)
 374  
      */
 375  
     public void propertyChange(PropertyChangeEvent evt) {
 376  0
         if ("taggedValue".equals(evt.getPropertyName())
 377  
                 || "referenceTag".equals(evt.getPropertyName())) {
 378  0
             fireTableChanged(new TableModelEvent(this));
 379  
         }
 380  0
         if (evt instanceof DeleteInstanceEvent && evt.getSource() == target) {
 381  0
             setTarget(null);
 382  
         }
 383  0
     }
 384  
 
 385  
     /*
 386  
      * @see java.beans.VetoableChangeListener#vetoableChange(java.beans.
 387  
      * PropertyChangeEvent)
 388  
      */
 389  
     public void vetoableChange(PropertyChangeEvent pce) {
 390  0
         DelayedChangeNotify delayedNotify = new DelayedChangeNotify(this, pce);
 391  0
         SwingUtilities.invokeLater(delayedNotify);
 392  0
     }
 393  
 
 394  
     /*
 395  
      * @see
 396  
      * org.argouml.kernel.DelayedVChangeListener#delayedVetoableChange(java.
 397  
      * beans.PropertyChangeEvent)
 398  
      */
 399  
     public void delayedVetoableChange(PropertyChangeEvent pce) {
 400  0
         fireTableDataChanged();
 401  0
     }
 402  
 
 403  
     /**
 404  
      * The UID.
 405  
      */
 406  
     private static final long serialVersionUID = -5711005901444956345L;
 407  
 }