// Module : $RCSfile: AbstractDefaultGUIElement.java,v $ // Version : $Revision: 0.0 $ $Author: Patrick $ $Date: 27.11.2011 17:21:28 $ // Project : TaskTreePerformanceTest // Creation : 2011 by Patrick // Copyright : Patrick Harms, 2011 package de.ugoe.cs.quest.eventcore.guimodel; import java.util.IdentityHashMap; import java.util.LinkedList; import java.util.List; /** * TODO comment * * @version $Revision: $ $Date: $ * @author 2011, last modified by $Author: $ */ public abstract class AbstractDefaultGUIElement implements IGUIElement { /** */ public static final long serialVersionUID = 1L; /** the reference to equal GUI element manager (needed to preserve singleton behavior) */ private static final EqualGUIElementManager equalGUIElementManager = new EqualGUIElementManager(); /** the specification of the GUI element */ private IGUIElementSpec specification; /** the reference to the parent element */ private IGUIElement parent; /** *

* TODO: comment *

* * @param specification */ public AbstractDefaultGUIElement(IGUIElementSpec specification, IGUIElement parent) { this.specification = specification; this.parent = parent; } /* * (non-Javadoc) * * @see de.ugoe.cs.tasktree.guimodel.GUIElement#getSpecification() */ @Override public IGUIElementSpec getSpecification() { return specification; } /* (non-Javadoc) * @see de.ugoe.cs.quest.eventcore.guimodel.IGUIElement#getParent() */ @Override public IGUIElement getParent() { return parent; } /* (non-Javadoc) * @see de.ugoe.cs.quest.eventcore.guimodel.IGUIElement#addEqualGUIElement(IGUIElement) */ @Override public void addEqualGUIElement(IGUIElement equalElement) { equalGUIElementManager.addEqualGUIElements(this, equalElement); } /* * (non-Javadoc) * * @see GUIElement#equals(GUIElement) */ public final boolean equals(Object other) { // implement final, as GUI elements are all singletons and they equal only if they are the // same object or if they are in the list of equal GUI elements return super.equals(other) || equalGUIElementManager.equals(this, other); } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public final int hashCode() { // implement final, as GUI elements are all singletons and they equal only if they are the // same object. If there are several GUI element objects that represent the same GUI element // then they are stored in the list of equal elements. In this case, the hash code of the // list is unique within the system return equalGUIElementManager.hashCode(this); } /** *

* TODO comment *

* * @version $Revision: $ $Date: 24.08.2012$ * @author 2012, last modified by $Author: pharms$ */ private static class EqualGUIElementManager { /** *

* the internal map of GUI elements mapping each registered element to its equal variants. * We use the {@link IdentityHashMap} as a normal hash map would not work because of the * changing of the hash code of GUI elements at runtime. *

*/ private IdentityHashMap> identityHashMap = new IdentityHashMap>(); /** *

* TODO: comment *

* * @param abstractDefaultGUIElement * @param equalElement */ private synchronized void addEqualGUIElements(IGUIElement guiElement1, IGUIElement guiElement2) { List list1 = identityHashMap.get(guiElement1); List list2 = identityHashMap.get(guiElement2); if (list1 == null) { if (list2 == null) { list2 = new LinkedList(); list2.add(guiElement1); list2.add(guiElement2); identityHashMap.put(guiElement1, list2); identityHashMap.put(guiElement2, list2); } else { addIfNotContained(list2, guiElement1); identityHashMap.put(guiElement1, list2); } } else { if (list2 == null) { addIfNotContained(list1, guiElement2); identityHashMap.put(guiElement2, list1); } else if (list1 != list2) { list1.addAll(list2); identityHashMap.put(guiElement2, list1); } // else // in this case, both GUI elements should already be registered with the same // lists. } } /** *

* TODO: comment *

* * @param abstractDefaultGUIElement * @return */ private synchronized int hashCode(IGUIElement guiElement) { return System.identityHashCode(getEqualElementsList(guiElement)); } /** *

* TODO: comment *

* * @param abstractDefaultGUIElement * @param other * @return */ private synchronized boolean equals(IGUIElement guiElement, Object other) { if (other instanceof IGUIElement) { for (IGUIElement candidate : getEqualElementsList(guiElement)) { if (candidate == other) { return true; } } } return false; } /** *

* TODO: comment *

* * @param guiElement * @return */ private List getEqualElementsList(IGUIElement guiElement) { List returnValue = identityHashMap.get(guiElement); if (returnValue == null) { returnValue = new LinkedList(); returnValue.add(guiElement); identityHashMap.put(guiElement, returnValue); } return returnValue; } /** *

* TODO: comment *

* * @param resultingList * @param guiElement1 */ private void addIfNotContained(List equalElementsList, IGUIElement guiElement) { for (IGUIElement candidate : equalElementsList) { if (candidate == guiElement) { return; } } equalElementsList.add(guiElement); } } }