/** * Copyright (c) 2002-2006 IBM Corporation and others. * 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: * IBM - Initial API and implementation */ package org.eclipse.emf.ecore.impl; import java.util.Collection; import java.util.Iterator; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.impl.AdapterImpl; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.common.util.UniqueEList; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EcorePackage; /** * An adapter implementation for maintaining {@link EClass}es */ public class ESuperAdapter extends AdapterImpl { public interface Holder { ESuperAdapter getESuperAdapter(); boolean isFrozen(); } /* * @deprecated */ public static ESuperAdapter getESuperAdapter(EClass eClass) { return ((Holder)eClass).getESuperAdapter(); } protected EList<EClass> subclasses; protected static final int ATTRIBUTES_MODIFIED = 0x0001; protected static final int REFERENCES_MODIFIED = 0x0002; protected static final int STRUCTURAL_FEATURES_MODIFIED = 0x0004; protected static final int CONTAINMENTS_MODIFIED = 0x0008; protected static final int OPERATIONS_MODIFIED = 0x0010; protected static final int SUPERS_MODIFIED = 0x0020; protected static final int LAST_ESUPER_ADAPTER_MODIFIED = SUPERS_MODIFIED; protected int modifiedState = 0x003F; protected final static int SUPERS = 0; protected final static int ATTRIBUTES = 1; protected final static int REFERENCES = 2; protected final static int OPERATIONS = 3; protected final static int STRUCTURAL_FEATURES = 4; protected static int getFeatureID(Notification notification) { int featureID = notification.getFeatureID(null); switch (featureID) { case EcorePackage.ECLASS__ESUPER_TYPES: return SUPERS; case EcorePackage.ECLASS__EATTRIBUTES: return ATTRIBUTES; case EcorePackage.ECLASS__EREFERENCES: return REFERENCES; case EcorePackage.ECLASS__EOPERATIONS: return OPERATIONS; case EcorePackage.ECLASS__ESTRUCTURAL_FEATURES: return STRUCTURAL_FEATURES; } return -1; } public ESuperAdapter() { super(); } public boolean isModified() { return modifiedState != 0; } @Override public boolean isAdapterForType(Object type) { return type == ESuperAdapter.class; } @Override public void notifyChanged(Notification notification) { int eventType = notification.getEventType(); if (eventType != Notification.REMOVING_ADAPTER) { int featureID = getFeatureID(notification); if (featureID == SUPERS) { switch (eventType) { case Notification.SET: { Object oldValue = notification.getOldValue(); if (oldValue != null) { ESuperAdapter eSuperAdapter = ((Holder)oldValue).getESuperAdapter(); eSuperAdapter.getSubclasses().remove(notification.getNotifier()); } Object newValue = notification.getNewValue(); if (newValue != null) { Holder holder = (Holder)newValue; if (!holder.isFrozen()) { ESuperAdapter eSuperAdapter = holder.getESuperAdapter(); eSuperAdapter.getSubclasses().add((EClass)notification.getNotifier()); } } break; } case Notification.RESOLVE: case Notification.ADD: { Object newValue = notification.getNewValue(); if (newValue != null) { Holder holder = (Holder)newValue; if (!holder.isFrozen()) { ESuperAdapter eSuperAdapter = holder.getESuperAdapter(); eSuperAdapter.getSubclasses().add((EClass)notification.getNotifier()); } } break; } case Notification.ADD_MANY: { Object newValue = notification.getNewValue(); if (newValue != null) { for (Iterator<?> i = ((Collection<?>)newValue).iterator(); i.hasNext(); ) { Holder holder = (Holder)i.next(); if (!holder.isFrozen()) { ESuperAdapter eSuperAdapter = holder.getESuperAdapter(); eSuperAdapter.getSubclasses().add((EClass)notification.getNotifier()); } } } break; } case Notification.REMOVE: { Object oldValue = notification.getOldValue(); if (oldValue != null) { Holder holder = (Holder)oldValue; if (!holder.isFrozen()) { ESuperAdapter eSuperAdapter = holder.getESuperAdapter(); eSuperAdapter.getSubclasses().remove(notification.getNotifier()); } } break; } case Notification.REMOVE_MANY: { Object oldValue = notification.getOldValue(); if (oldValue != null) { for (Iterator<?> i = ((Collection<?>)oldValue).iterator(); i.hasNext(); ) { Holder holder = (Holder)i.next(); if (!holder.isFrozen()) { ESuperAdapter eSuperAdapter = holder.getESuperAdapter(); eSuperAdapter.getSubclasses().remove(notification.getNotifier()); } } } break; } } } setFlags(featureID); } } public boolean isAllAttributesCollectionModified() { return (modifiedState & ATTRIBUTES_MODIFIED) != 0; } public void setAllAttributesCollectionModified(boolean set) { if (set) { modifiedState |= ATTRIBUTES_MODIFIED; } else { modifiedState &= ~ATTRIBUTES_MODIFIED; } } public boolean isAllContainmentsCollectionModified() { return (modifiedState & CONTAINMENTS_MODIFIED) != 0; } public void setAllContainmentsCollectionModified(boolean set) { if (set) { modifiedState |= CONTAINMENTS_MODIFIED; } else { modifiedState &= ~CONTAINMENTS_MODIFIED; } } public boolean isAllReferencesCollectionModified() { return (modifiedState & REFERENCES_MODIFIED) != 0; } public void setAllReferencesCollectionModified(boolean set) { if (set) { modifiedState |= REFERENCES_MODIFIED; } else { modifiedState &= ~REFERENCES_MODIFIED; } } public boolean isAllOperationsCollectionModified() { return (modifiedState & OPERATIONS_MODIFIED) != 0; } public void setAllOperationsCollectionModified(boolean set) { if (set) { modifiedState |= OPERATIONS_MODIFIED; } else { modifiedState &= ~OPERATIONS_MODIFIED; } } public boolean isAllStructuralFeaturesCollectionModified() { return (modifiedState & STRUCTURAL_FEATURES_MODIFIED) != 0; } public void setAllStructuralFeaturesCollectionModified(boolean set) { if (set) { modifiedState |= STRUCTURAL_FEATURES_MODIFIED; } else { modifiedState &= ~STRUCTURAL_FEATURES_MODIFIED; } } public boolean isAllSuperCollectionModified() { return (modifiedState & SUPERS_MODIFIED) != 0; } public void setAllSuperCollectionModified(boolean set) { if (set) { modifiedState |= SUPERS_MODIFIED; } else { modifiedState &= ~SUPERS_MODIFIED; } } public EList<EClass> getSubclasses() { if (subclasses == null) { subclasses = new UniqueEList<EClass>() { private static final long serialVersionUID = 1L; @Override protected Object [] newData(int capacity) { return new EClass [capacity]; } @Override protected boolean useEquals() { return false; } }; } return subclasses; } void setFlags(int featureId) { int oldModifiedState = modifiedState; switch (featureId) { case ATTRIBUTES: { setAllAttributesCollectionModified(true); setAllStructuralFeaturesCollectionModified(true); setAllContainmentsCollectionModified(true); break; } case REFERENCES: { setAllReferencesCollectionModified(true); setAllStructuralFeaturesCollectionModified(true); setAllContainmentsCollectionModified(true); break; } case STRUCTURAL_FEATURES: { setAllAttributesCollectionModified(true); setAllReferencesCollectionModified(true); setAllStructuralFeaturesCollectionModified(true); setAllContainmentsCollectionModified(true); break; } case OPERATIONS: { setAllOperationsCollectionModified(true); setAllContainmentsCollectionModified(true); break; } case SUPERS: { setAllSuperCollectionModified(true); setAllOperationsCollectionModified(true); setAllContainmentsCollectionModified(true); setAllAttributesCollectionModified(true); setAllReferencesCollectionModified(true); setAllStructuralFeaturesCollectionModified(true); break; } } if (modifiedState != oldModifiedState && subclasses != null) { for (Iterator<?> i = subclasses.iterator(); i.hasNext(); ) { Holder subclass = (Holder)i.next(); ESuperAdapter eSuperAdapter = subclass.getESuperAdapter(); eSuperAdapter.setFlags(featureId); } } } }