Author: bobtarling
Date: 2011-02-13 09:51:28-0800
New Revision: 19029

Added:
   
trunk/src/argouml-app/src/org/argouml/uml/ui/UMLModelElementStereotypeListModel.java
      - copied, changed from r19025, 
/trunk/src/argouml-app/src/org/argouml/uml/ui/foundation/core/UMLModelElementStereotypeListModel.java
   trunk/src/argouml-app/src/org/argouml/uml/ui/UMLStereotypeListModel.java
Removed:
   
trunk/src/argouml-app/src/org/argouml/uml/ui/foundation/core/UMLModelElementStereotypeListModel.java
Modified:
   trunk/src/argouml-app/src/org/argouml/uml/ui/TabStereotype.java

Log:
Introduce UMLStereotypeListModel so that there is no dependence on deprecated 
UMLModelElementListModel2

Modified: trunk/src/argouml-app/src/org/argouml/uml/ui/TabStereotype.java
Url: 
http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/ui/TabStereotype.java?view=diff&pathrev=19029&r1=19028&r2=19029
==============================================================================
--- trunk/src/argouml-app/src/org/argouml/uml/ui/TabStereotype.java     
(original)
+++ trunk/src/argouml-app/src/org/argouml/uml/ui/TabStereotype.java     
2011-02-13 09:51:28-0800
@@ -66,7 +66,6 @@
 import org.argouml.ui.TabModelTarget;
 import org.argouml.ui.targetmanager.TargetManager;
 import org.argouml.uml.StereotypeUtility;
-import org.argouml.uml.ui.foundation.core.UMLModelElementStereotypeListModel;
 import org.tigris.gef.presentation.Fig;
 import org.tigris.swidgets.Horizontal;
 import org.tigris.swidgets.Vertical;
@@ -262,7 +261,7 @@
      * the ones already applied.
      */
     private static class UMLModelStereotypeListModel
-        extends UMLModelElementListModel2 {
+        extends UMLStereotypeListModel {
 
         /**
          * Constructor for UMLModelElementNamespaceListModel.

Copied: 
trunk/src/argouml-app/src/org/argouml/uml/ui/UMLModelElementStereotypeListModel.java
 (from r19025, 
/trunk/src/argouml-app/src/org/argouml/uml/ui/foundation/core/UMLModelElementStereotypeListModel.java)
Url: 
http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/ui/UMLModelElementStereotypeListModel.java?view=diff&pathrev=19029&r1=19025&r2=19029
==============================================================================
--- 
/trunk/src/argouml-app/src/org/argouml/uml/ui/foundation/core/UMLModelElementStereotypeListModel.java
       (original)
+++ 
trunk/src/argouml-app/src/org/argouml/uml/ui/UMLModelElementStereotypeListModel.java
        2011-02-13 09:51:28-0800
@@ -36,7 +36,7 @@
 // CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
 // UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 
-package org.argouml.uml.ui.foundation.core;
+package org.argouml.uml.ui;
 
 import javax.swing.Action;
 import javax.swing.Icon;
@@ -46,15 +46,14 @@
 
 import org.argouml.model.Model;
 import org.argouml.uml.StereotypeUtility;
-import org.argouml.uml.ui.UMLModelElementListModel2;
 
 /**
  * The swing List Model for displaying stereotypes.
  * @since Oct 24, 2005
  * @author Bob Tarling
  */
-public class UMLModelElementStereotypeListModel
-    extends UMLModelElementListModel2 {
+class UMLModelElementStereotypeListModel
+    extends UMLStereotypeListModel {
 
     /**
      * Constructor for UMLModelElementNamespaceListModel.

Added: trunk/src/argouml-app/src/org/argouml/uml/ui/UMLStereotypeListModel.java
Url: 
http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/ui/UMLStereotypeListModel.java?view=markup&pathrev=19029
==============================================================================
--- (empty file)
+++ trunk/src/argouml-app/src/org/argouml/uml/ui/UMLStereotypeListModel.java    
2011-02-13 09:51:28-0800
@@ -0,0 +1,557 @@
+/* $Id: UMLStereotypeListModel.java 18588 2010-07-28 21:30:25Z bobtarling $
+ *****************************************************************************
+ * Copyright (c) 2009 Contributors - see below
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *    mvw
+ *****************************************************************************
+ *
+ * Some portions of this file was previously release using the BSD License:
+ */
+
+// Copyright (c) 2002-2008 The Regents of the University of California. All
+// Rights Reserved. Permission to use, copy, modify, and distribute this
+// software and its documentation without fee, and without a written
+// agreement is hereby granted, provided that the above copyright notice
+// and this paragraph appear in all copies.  This software program and
+// documentation are copyrighted by The Regents of the University of
+// California. The software program and documentation are supplied "AS
+// IS", without any accompanying services from The Regents. The Regents
+// does not warrant that the operation of the program will be
+// uninterrupted or error-free. The end-user understands that the program
+// was developed for research purposes and is advised not to rely
+// exclusively on the program for any reason.  IN NO EVENT SHALL THE
+// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
+// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS,
+// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
+// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
+// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
+// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
+// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
+// UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+
+package org.argouml.uml.ui;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JPopupMenu;
+
+import org.apache.log4j.Logger;
+import org.argouml.model.AddAssociationEvent;
+import org.argouml.model.AssociationChangeEvent;
+import org.argouml.model.AttributeChangeEvent;
+import org.argouml.model.InvalidElementException;
+import org.argouml.model.Model;
+import org.argouml.model.RemoveAssociationEvent;
+import org.argouml.ui.targetmanager.TargetEvent;
+import org.argouml.ui.targetmanager.TargetListener;
+import org.tigris.gef.base.Diagram;
+import org.tigris.gef.presentation.Fig;
+
+/**
+ * The model for a list that contains ModelElements. The state of the Element 
is
+ * still kept in the model subsystem itself. This list is only to be used as 
the
+ * model for some GUI element like UMLLinkedList.
+ *
+ * @since Oct 2, 2002
+ * @author [email protected]
+ */
+abstract class UMLStereotypeListModel extends DefaultListModel
+        implements TargetListener, PropertyChangeListener {
+
+    private static final Logger LOG = 
+        Logger.getLogger(UMLStereotypeListModel.class);
+    
+    private String eventName = null;
+    private Object listTarget = null;
+
+    /**
+     * Flag to indicate wether list events should be fired
+     */
+    private boolean fireListEvents = true;
+
+    /**
+     * Flag to indicate wether the model is being build
+     */
+    private boolean buildingModel = false;
+
+    /**
+     * The type of model elements this list model is designed to hold.
+     */
+    private Object metaType;
+    
+    /**
+     * Indicates that drops onto this list should connect in the opposite
+     * way to standard.
+     */
+    private boolean reverseDropConnection;
+
+    /**
+     * Constructor to be used if the subclass does not depend on the
+     * MELementListener methods and setTarget method implemented in this
+     * class.
+     */
+    public UMLStereotypeListModel() {
+        super();
+    }
+
+    /**
+     * Constructor for UMLModelElementListModel2.
+     *
+     * @param name the name of the event to listen to, which triggers us
+     *             to update the list model from the UML data
+     */
+    public UMLStereotypeListModel(String name) {
+        super();
+        eventName = name;
+    }
+    
+    /**
+     * Constructor for UMLModelElementListModel2.
+     *
+     * @param name the name of the event to listen to, which triggers us
+     *             to update the list model from the UML data
+     * @param theMetaType the type of model element that the list model
+     *                 is designed to contain.
+     */
+    public UMLStereotypeListModel(String name, Object theMetaType) {
+        super();
+        this.metaType = theMetaType;
+        eventName = name;
+    }
+    
+    /**
+     * Constructor for UMLModelElementListModel2.
+     *
+     * @param name the name of the event to listen to, which triggers us
+     *             to update the list model from the UML data
+     * @param theMetaType the type of model element that the list model
+     *                 is designed to contain.
+     * @param reverseTheDropConnection tells the JList to reverse the
+     *              connection made and drop during dnd.
+     */
+    public UMLStereotypeListModel(
+           String name, 
+           Object theMetaType, 
+           boolean reverseTheDropConnection) {
+        super();
+        this.metaType = theMetaType;
+        eventName = name;
+        this.reverseDropConnection = reverseTheDropConnection;
+    }
+    
+    /**
+     * Get the type of objects that this list model is designed to contain.
+     * @return metaType the meta type.
+     */
+    public Object getMetaType() {
+       return metaType;
+    }
+    
+    public boolean isReverseDropConnection() {
+       return reverseDropConnection;
+    }
+
+    /**
+     * @param building The buildingModel to set.
+     */
+    protected void setBuildingModel(boolean building) {
+        this.buildingModel = building;
+    }
+
+    /**
+     * @param t the list target to set
+     */
+    protected void setListTarget(Object t) {
+        this.listTarget = t;
+    }
+
+    /*
+     * @see 
java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
+     * 
+     * TODO: This should be reviewed to see if it can be improved with a view
+     * towards removing some of the overrriding methods used as workarounds 
for 
+     * differences between NSUML and MDR - tfm - 20060302
+     */
+    public void propertyChange(PropertyChangeEvent e) {
+        if (e instanceof AttributeChangeEvent) {
+            try {
+                if (isValidEvent(e)) {
+                    rebuildModelList();
+                }
+            } catch (InvalidElementException iee) {
+                return;
+            }
+        } else if (e instanceof AddAssociationEvent) {
+            if (isValidEvent(e)) {
+                Object o = getChangedElement(e);
+                if (o instanceof Collection) {
+                    ArrayList tempList = new ArrayList((Collection) o);
+                    Iterator it = tempList.iterator();
+                    while (it.hasNext()) {
+                        Object o2 = it.next();
+                        addElement(o2);
+                    }
+                } else {
+                    /* TODO: If this is an ordered list, then you have to 
+                        add in the right location! */
+                    addElement(o); 
+                }
+            }
+        } else if (e instanceof RemoveAssociationEvent) {
+            boolean valid = false;
+            if (!(getChangedElement(e) instanceof Collection)) {
+                valid = contains(getChangedElement(e));
+            } else {
+                Collection col = (Collection) getChangedElement(e);
+                Iterator it = col.iterator();
+                valid = true;
+                while (it.hasNext()) {
+                    Object o = it.next();
+                    if (!contains(o)) {
+                        valid = false;
+                        break;
+                    }
+                }
+            }
+            if (valid) {
+                Object o = getChangedElement(e);
+                if (o instanceof Collection) {
+                    Iterator it = ((Collection) o).iterator();
+                    while (it.hasNext()) {
+                        Object o3 = it.next();
+                        removeElement(o3);
+                    }
+                } else {
+                    removeElement(o);
+                }
+            }
+        }
+    }
+
+    /**
+     * Delete and rebuild the model list from scratch.
+     */
+    private void rebuildModelList() {
+        removeAllElements();
+        buildingModel = true;
+        try {
+            buildModelList();
+        } catch (InvalidElementException exception) {
+            /*
+             * This can throw an exception if the target has been
+             * deleted. We don't want to try locking the repository
+             * because this is called from the event delivery thread and
+             * could cause a deadlock. Instead catch the exception and
+             * leave the model empty.
+             */
+            LOG.debug("buildModelList threw exception for target " 
+                    + getTarget() + ": "
+                    + exception);
+        } finally {
+            buildingModel = false;
+        }
+        if (getSize() > 0) {
+            fireIntervalAdded(this, 0, getSize() - 1);
+        }
+    }
+
+    /**
+     * Builds the list of elements. Called from targetChanged every time the
+     * target of the proppanel is changed. Usually the method setAllElements is
+     * called with the result.
+     */
+    protected abstract void buildModelList();
+
+    /**
+     * Utility method to set the elements of this list to the contents of the
+     * given collection.
+     * @param col the given collection
+     */
+    protected void setAllElements(Collection col) {
+        if (!isEmpty())
+            removeAllElements();
+        addAll(col);
+    }
+
+    /**
+     * Utility method to add a collection of elements to the model
+     * @param col the given collection
+     */
+    protected void addAll(Collection col) {
+        if (col.size() == 0) return;
+        Iterator it = col.iterator();
+        fireListEvents = false;
+        int intervalStart = getSize() == 0 ? 0 : getSize() - 1;
+        while (it.hasNext()) {
+            Object o = it.next();
+            addElement(o);
+        }
+        fireListEvents = true;
+        fireIntervalAdded(this, intervalStart, getSize() - 1);
+    }
+
+    /**
+     * Utility method to get the target. Sets the target if the target is null
+     * via the method setTarget().
+     * @return MModelElement
+     */
+    public Object getTarget() {
+        return listTarget;
+    }
+
+    /**
+     * Utility method to get the changed element from some event e
+     * @param e the event
+     * @return Object the changed element
+     */
+    protected Object getChangedElement(PropertyChangeEvent e) {
+        if (e instanceof AssociationChangeEvent) {
+            return ((AssociationChangeEvent) e).getChangedValue();
+        }
+        if (e instanceof AttributeChangeEvent) {
+            return ((AttributeChangeEvent) e).getSource();
+        }
+        return e.getNewValue();
+    }
+
+    /*
+     * @see javax.swing.DefaultListModel#contains(java.lang.Object)
+     */
+    public boolean contains(Object elem) {
+        if (super.contains(elem)) {
+            return true;
+        }
+        if (elem instanceof Collection) {
+            Iterator it = ((Collection) elem).iterator();
+            while (it.hasNext()) {
+                if (!super.contains(it.next())) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets the target. If the old target is a ModelElement, it also removes
+     * the model from the element listener list of the target. If the new 
target
+     * is instanceof ModelElement, the model is added as element listener to 
the
+     * new target. <p>
+     *      
+     * This function is called when the user changes the target. 
+     * Hence, this shall not result in any UML model changes.
+     * Hence, we block firing list events completely by setting 
+     * buildingModel to true for the duration of this function. <p>
+     * 
+     * This function looks a lot like the one in UMLComboBoxModel2.
+     * 
+     * @param theNewTarget the new target
+     */
+    public void setTarget(Object theNewTarget) {
+        theNewTarget = theNewTarget instanceof Fig
+            ? ((Fig) theNewTarget).getOwner() : theNewTarget;
+        if (Model.getFacade().isAUMLElement(theNewTarget)
+                || theNewTarget instanceof Diagram) {
+            if (Model.getFacade().isAUMLElement(listTarget)) {
+                Model.getPump().removeModelEventListener(this, listTarget,
+                        eventName);
+                // Allow listening to other elements:
+                removeOtherModelEventListeners(listTarget);
+            }
+
+            if (Model.getFacade().isAUMLElement(theNewTarget)) {
+                listTarget = theNewTarget;
+                Model.getPump().addModelEventListener(this, listTarget,
+                        eventName);
+                // Allow listening to other elements:
+                addOtherModelEventListeners(listTarget);
+
+                rebuildModelList();
+
+            } else {
+                listTarget = null;
+                removeAllElements();
+            }
+        }
+    }
+
+    /**
+     * This function allows subclasses to listen to more modelelements.
+     * The given target is guaranteed to be a UML modelelement.
+     * 
+     * @param oldTarget the UML modelelement
+     */
+    protected void removeOtherModelEventListeners(Object oldTarget) {
+        /* Do nothing by default. */
+    }
+
+    /**
+     * This function allows subclasses to listen to more modelelements.
+     * The given target is guaranteed to be a UML modelelement.
+     * 
+     * @param newTarget the UML modelelement
+     */
+    protected void addOtherModelEventListeners(Object newTarget) {
+        /* Do nothing by default. */
+    }
+
+    /**
+     * Returns true if the given element is valid, i.e. it may be added to the
+     * list of elements.
+     *
+     * @param element the element to be tested
+     * @return true if valid
+     */
+    protected abstract boolean isValidElement(Object element);
+
+    /**
+     * Returns true if some event is valid. An event is valid if the
+     * element changed in the event is valid. This is determined via a
+     * call to isValidElement.  This method can be overriden by
+     * subclasses if they cannot determine if it is a valid event just
+     * by checking the changed element.
+     *
+     * @param e the event
+     * @return boolean true if valid
+     */
+    protected boolean isValidEvent(PropertyChangeEvent e) {
+        boolean valid = false;
+        if (!(getChangedElement(e) instanceof Collection)) {
+            // TODO: Considering all delete events to be valid like below
+            // is going to cause lots of unecessary work and some problems
+            if ((e.getNewValue() == null && e.getOldValue() != null)
+                    // Don't test changed element if it was deleted
+                    || isValidElement(getChangedElement(e))) {
+                valid = true; // we tried to remove a value
+            }
+        } else {
+            Collection col = (Collection) getChangedElement(e);
+            Iterator it = col.iterator();
+            if (!col.isEmpty()) {
+                valid = true;
+                while (it.hasNext()) {
+                    Object o = it.next();
+                    if (!isValidElement(o)) {
+                        valid = false;
+                        break;
+                    }
+                }
+            } else {
+                if (e.getOldValue() instanceof Collection
+                    && !((Collection) e.getOldValue()).isEmpty()) {
+                    valid = true;
+                }
+            }
+        }
+        return valid;
+    }
+
+    /*
+     * @see javax.swing.DefaultListModel#addElement(java.lang.Object)
+     */
+    public void addElement(Object obj) {
+        if (obj != null && !contains(obj)) {
+            super.addElement(obj);
+        }
+    }
+
+    /**
+     * Returns the eventName. This method is only here for testing goals.
+     * @return String
+     */
+    String getEventName() {
+        return eventName;
+    }
+
+    /**
+     * Sets the eventName. The eventName is the name of the
+     * MElementEvent to which the list should listen. The list is
+     * registred with UMLModelEventPump and only gets events that have
+     * a name like eventName.  This method should be called in the
+     * constructor of every subclass.
+     *
+     * @param theEventName The eventName to set
+     */
+    protected void setEventName(String theEventName) {
+        eventName = theEventName;
+    }
+
+    /*
+     * @see TargetListener#targetAdded(TargetEvent)
+     */
+    public void targetAdded(TargetEvent e) {
+        setTarget(e.getNewTarget());
+    }
+
+    /*
+     * @see TargetListener#targetRemoved(TargetEvent)
+     */
+    public void targetRemoved(TargetEvent e) {
+        setTarget(e.getNewTarget());
+    }
+
+    /*
+     * @see TargetListener#targetSet(TargetEvent)
+     */
+    public void targetSet(TargetEvent e) {
+        setTarget(e.getNewTarget());
+    }
+
+    /*
+     * @see javax.swing.AbstractListModel#fireContentsChanged(
+     *          Object, int, int)
+     */
+    protected void fireContentsChanged(Object source, int index0, int index1) {
+        if (fireListEvents && !buildingModel)
+            super.fireContentsChanged(source, index0, index1);
+    }
+
+    /*
+     * @see javax.swing.AbstractListModel#fireIntervalAdded(
+     *          Object, int, int)
+     */
+    protected void fireIntervalAdded(Object source, int index0, int index1) {
+        if (fireListEvents && !buildingModel)
+            super.fireIntervalAdded(source, index0, index1);
+    }
+
+    /*
+     * @see javax.swing.AbstractListModel#fireIntervalRemoved(
+     *          Object, int, int)
+     */
+    protected void fireIntervalRemoved(Object source, int index0, int index1) {
+        if (fireListEvents && !buildingModel)
+            super.fireIntervalRemoved(source, index0, index1);
+    }
+
+    /**
+     * Override this if you want a popup menu.
+     * See for an example UMLModelElementOrderedListModel2.
+     *
+     * @param popup the popup menu
+     * @param index the selected item in the list at the moment
+     *              the mouse was clicked
+     * @return true if a popup menu is created, and needs to be shown
+     */
+    public boolean buildPopup(JPopupMenu popup, int index) {
+        return false;
+    }
+    
+    protected boolean hasPopup() {
+        return false;
+    }
+
+}

Removed: 
trunk/src/argouml-app/src/org/argouml/uml/ui/foundation/core/UMLModelElementStereotypeListModel.java
Url: 
http://argouml.tigris.org/source/browse/argouml/trunk/src/argouml-app/src/org/argouml/uml/ui/foundation/core/UMLModelElementStereotypeListModel.java?view=markup&pathrev=19028

------------------------------------------------------
http://argouml.tigris.org/ds/viewMessage.do?dsForumId=5905&dsMessageId=2703702

To unsubscribe from this discussion, e-mail: 
[[email protected]].

Reply via email to