/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.ui.favorites; import java.util.AbstractSet; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.core.runtime.IStatus; import org.eclipse.emf.ecore.EObject; import org.teiid.core.designer.event.EventSourceException; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.ui.IModelerCacheListener; import org.teiid.designer.ui.ModelerCacheEvent; import org.teiid.designer.ui.UiConstants; import org.teiid.designer.ui.UiPlugin; import org.teiid.designer.ui.event.ModelResourceEvent; import org.teiid.designer.ui.viewsupport.ModelUtilities; /** * @since 8.0 */ public final class EObjectModelerCache extends AbstractSet implements UiConstants { /////////////////////////////////////////////////////////////////////////////////////////////// // FIELDS /////////////////////////////////////////////////////////////////////////////////////////////// /** The delegate cache. */ private HashSet cache; /** ModelerCacheEventManager for notifications and resource changes. */ private ModelerCacheEventManager eventMgr; /////////////////////////////////////////////////////////////////////////////////////////////// // CONSTRUCTORS /////////////////////////////////////////////////////////////////////////////////////////////// /** * Constructs an <code>EObjectModelerCache</code>. */ public EObjectModelerCache() { this.cache = new HashSet(); this.eventMgr = new ModelerCacheEventManager(this); // hook up listener ModelUtilities.addNotifyChangedListener(this.eventMgr); ModelerCore.getWorkspace().addResourceChangeListener(this.eventMgr); try { UiPlugin.getDefault().getEventBroker().addListener(ModelResourceEvent.class, this.eventMgr); } catch (EventSourceException e) { UiConstants.Util.log(IStatus.ERROR, e, e.getMessage()); } } /////////////////////////////////////////////////////////////////////////////////////////////// // METHODS /////////////////////////////////////////////////////////////////////////////////////////////// /** * @see java.util.Collection#add(java.lang.Object) * @throws IllegalArgumentException if input is <code>null</code> or not an {@link EObject} * @since 4.2 */ @Override public boolean add(Object theEObject) { CoreArgCheck.isNotNull(theEObject); CoreArgCheck.isInstanceOf(EObject.class, theEObject); boolean result = this.cache.add(theEObject); if (result) { this.eventMgr.fireCacheEvent(new ModelerCacheEvent(ModelerCacheEvent.ADD, theEObject)); } return result; } /** * @see java.util.Set#addAll(java.util.Collection) * @throws IllegalArgumentException if the collection contains an element that is not an {@link EObject} * @since 4.2 */ @Override public boolean addAll(Collection theEObjects) { CoreArgCheck.isNotNull(theEObjects); boolean result = false; if (!theEObjects.isEmpty()) { Collection addedObjs = new ArrayList(theEObjects.size()); Iterator itr = theEObjects.iterator(); while (itr.hasNext()) { Object obj = itr.next(); CoreArgCheck.isInstanceOf(EObject.class, obj); if (this.cache.add(obj)) { addedObjs.add(obj); if (!result) { result = true; } } } if (result) { this.eventMgr.fireCacheEvent(new ModelerCacheEvent(ModelerCacheEvent.ADD, addedObjs)); } } return result; } /** * Adds the specified listener to the collection of listeners receiving {@link ModelerCacheEvent}s. Listeners * already registered will not be added again. * @param theListener the listener being added * @since 4.2 */ public void addCacheListener(IModelerCacheListener theListener) { this.eventMgr.addListener(theListener); } /** * @see java.util.Collection#clear() * @since 4.2 */ @Override public void clear() { if (!isEmpty()) { this.cache.clear(); this.eventMgr.fireCacheEvent(ModelerCacheEvent.CLEAR_CACHE_EVENT); } } /** * @see java.util.Collection#contains(java.lang.Object) * @since 4.2 */ @Override public boolean contains(Object theEObject) { return this.cache.contains(theEObject); } /** * Gets all cache items that are descendants of the specified object. * @param theAncestor the object whose descendants are being requested * @return the descendants or an empty collection * @since 4.2 */ public Collection getCachedDescendants(EObject theAncestor) { Set result = Collections.EMPTY_SET; // only search if cache is not empty if (!isEmpty()) { List kids = theAncestor.eContents(); // only look at cache if object has children if ((kids != null) && !kids.isEmpty()) { for (int size = kids.size(), i = 0; i < size; i++) { EObject kid = (EObject)kids.get(i); // first see if kid is in cache if (contains(kid)) { // add to list if (result.isEmpty()) { result = new HashSet(); } result.add(kid); } // now see if any descendants in cache Collection temp = getCachedDescendants(kid); if (!temp.isEmpty()) { if (result.isEmpty()) { result = new HashSet(); } result.addAll(temp); } } } } return result; } /** * @see java.util.Collection#isEmpty() * @since 4.2 */ @Override public boolean isEmpty() { return this.cache.isEmpty(); } /** * @see java.util.Collection#iterator() * @since 4.2 */ @Override public Iterator iterator() { return this.cache.iterator(); } /** * @see java.util.Collection#remove(java.lang.Object) * @since 4.2 */ @Override public boolean remove(Object theEObject) { boolean result = this.cache.remove(theEObject); if (result) { this.eventMgr.fireCacheEvent(new ModelerCacheEvent(ModelerCacheEvent.REMOVE, theEObject)); } return result; } /** * @see java.util.AbstractSet#removeAll(java.util.Collection) * @since 4.2 */ @Override public boolean removeAll(Collection theEObjects) { CoreArgCheck.isNotNull(theEObjects); boolean result = false; if (!theEObjects.isEmpty()) { Collection removedObjs = new ArrayList(theEObjects.size()); Iterator itr = theEObjects.iterator(); while (itr.hasNext()) { Object obj = itr.next(); if (this.cache.remove(obj)) { removedObjs.add(obj); if (!result) { result = true; } } } if (result) { this.eventMgr.fireCacheEvent(new ModelerCacheEvent(ModelerCacheEvent.REMOVE, removedObjs)); } } return result; } /** * Removes the specified listener from the collection of listeners receiving {@link ModelerCacheEvent}s. * @param theListener the listener being removed * @since 4.2 */ public void removeCacheListener(IModelerCacheListener theListener) { this.eventMgr.removeListener(theListener); } /** * @see java.util.Collection#retainAll(java.util.Collection) * @since 4.2 */ @Override public boolean retainAll(Collection theEObjects) { boolean result = false; if (!isEmpty()) { Collection removedObjs = new ArrayList(); Iterator itr = iterator(); while (itr.hasNext()) { Object obj = itr.next(); if (!theEObjects.contains(obj)) { itr.remove(); removedObjs.add(obj); result = true; } } if (result) { this.eventMgr.fireCacheEvent(new ModelerCacheEvent(ModelerCacheEvent.REMOVE, removedObjs)); } } return result; } /** * @see java.util.Collection#size() * @since 4.2 */ @Override public int size() { return this.cache.size(); } /** * @see java.util.Collection#toArray() * @since 4.2 */ @Override public Object[] toArray() { return this.cache.toArray(); } /** * @see java.util.Collection#toArray(java.lang.Object[]) * @since 4.2 */ @Override public Object[] toArray(Object[] theEObjects) { return this.cache.toArray(theEObjects); } }