/* * 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.core; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.resource.Resource; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.util.ModelVisitor; /** * This class finds all non-containment references to a specified EObject within a resource and removes or unsets those * references. This class is a simple visitor that examines all non-containment EReference features of the visited EObject looking * for references to the "refdObject". If one is found the reference is unset if the feature is single valued or the object is * removed if the feature is multivalued. This vistor will only clear references for the objects inside the resource being visited * and will not check the opposite end of any EReference for a reference to "refdObject". * * @since 8.0 */ public class ClearEObjectReferences implements ModelVisitor { private final EObject refdObject; private final Set affectedObjects; // ================================================================================== // C O N S T R U C T O R S // ================================================================================== /** * Construct an instance of ClearEObjectReferences. */ public ClearEObjectReferences( final EObject refdObject ) { CoreArgCheck.isNotNull(refdObject); this.refdObject = refdObject; this.affectedObjects = new HashSet(); } // ================================================================================== // I N T E R F A C E M E T H O D S // ================================================================================== /** * @see org.teiid.designer.core.util.ModelVisitor#visit(org.eclipse.emf.ecore.EObject) * @since 4.3 */ @Override public boolean visit( final EObject object ) { // Find all references ... final EClass eclass = object.eClass(); final Collection allRefs = eclass.getEAllReferences(); for (final Iterator i = allRefs.iterator(); i.hasNext();) { final EReference reference = (EReference)i.next(); // Process only non-containment references ... if (!reference.isContainment() && !reference.isContainer() && !reference.isVolatile()) { final Object value = object.eGet(reference, false); if (reference.isMany()) { // There may be many values ... boolean removeRefdValue = false; for (Iterator j = ((List)value).iterator(); j.hasNext();) { final Object valueInList = j.next(); if (valueInList instanceof EObject && valueInList == refdObject) { removeRefdValue = true; } } if (removeRefdValue && reference.isChangeable()) { ((List)value).remove(refdObject); this.affectedObjects.add(object); } } else { // There may be 0..1 value ... if (value instanceof EObject && value == refdObject) { if (reference.isChangeable()) { object.eUnset(reference); this.affectedObjects.add(object); } } } } } return true; } /** * @see org.teiid.designer.core.util.ModelVisitor#visit(org.eclipse.emf.ecore.resource.Resource) * @since 4.3 */ @Override public boolean visit( Resource resource ) { return resource != null; } // ================================================================================== // P U B L I C M E T H O D S // ================================================================================== /** * Return the collection of EObject instances that were affected by unsetting or removing one or more of their references to * the specified EObject * * @return Returns the affectedObjects. * @since 4.3 */ public Collection getAffectedObjects() { return this.affectedObjects; } }