diff options
author | Eike Stepper | 2008-09-18 12:57:24 +0000 |
---|---|---|
committer | Eike Stepper | 2008-09-18 12:57:24 +0000 |
commit | 25059b9f4277a331568ced5198fc87177c97a0df (patch) | |
tree | 8b93331ef33c0e990b9d934aaa541544e6e78891 /plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo | |
parent | fc9b00dd988bddeb67ab89f6c077cb7eb8a5dcc6 (diff) | |
download | cdo-25059b9f4277a331568ced5198fc87177c97a0df.tar.gz cdo-25059b9f4277a331568ced5198fc87177c97a0df.tar.xz cdo-25059b9f4277a331568ced5198fc87177c97a0df.zip |
[247226] Transparently support legacy models
https://bugs.eclipse.org/bugs/show_bug.cgi?id=247226
Diffstat (limited to 'plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo')
20 files changed, 1079 insertions, 1327 deletions
diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOAdapterImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOAdapterImpl.java deleted file mode 100644 index 0fe204ed93..0000000000 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOAdapterImpl.java +++ /dev/null @@ -1,59 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2004 - 2008 Eike Stepper, Germany. - * 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: - * Eike Stepper - initial API and implementation - **************************************************************************/ -package org.eclipse.emf.internal.cdo; - -import org.eclipse.emf.internal.cdo.bundle.OM; - -import org.eclipse.emf.common.notify.Notification; - -/** - * @author Eike Stepper - */ -public class CDOAdapterImpl extends CDOLegacyImpl -{ - public CDOAdapterImpl() - { - } - - @Override - public boolean isAdapterForType(Object type) - { - return type == CDOAdapterImpl.class; - } - - public void notifyChanged(Notification msg) - { - try - { - if (msg.getNotifier() == instance) - { - switch (msg.getEventType()) - { - case Notification.ADD: - case Notification.ADD_MANY: - case Notification.REMOVE: - case Notification.REMOVE_MANY: - case Notification.MOVE: - case Notification.SET: - case Notification.UNSET: - if (!instance.eIsProxy()) - { - CDOStateMachine.INSTANCE.write(this); - } - } - } - } - catch (RuntimeException ex) - { - OM.LOG.error(ex); - } - } -} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java deleted file mode 100644 index fe83b1433f..0000000000 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOCallbackImpl.java +++ /dev/null @@ -1,174 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2004 - 2008 Eike Stepper, Germany. - * 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: - * Eike Stepper - initial API and implementation - **************************************************************************/ -package org.eclipse.emf.internal.cdo; - -import org.eclipse.emf.cdo.CDOView; - -import org.eclipse.emf.internal.cdo.bundle.OM; -import org.eclipse.emf.internal.cdo.util.FSMUtil; - -import org.eclipse.emf.common.notify.Notification; -import org.eclipse.emf.ecore.EReference; -import org.eclipse.emf.ecore.InternalEObject; -import org.eclipse.emf.ecore.impl.CDOAware; -import org.eclipse.emf.ecore.impl.CDOCallback; -import org.eclipse.emf.ecore.impl.EObjectImpl; -import org.eclipse.emf.ecore.util.EcoreUtil; - -import java.util.List; - -/** - * @author Eike Stepper - */ -public class CDOCallbackImpl extends CDOLegacyImpl implements CDOCallback -{ - public CDOCallbackImpl(InternalEObject instance) - { - this.instance = instance; - } - - public void beforeRead(EObjectImpl instance) - { - CDOStateMachine.INSTANCE.read(this); - } - - public void beforeWrite(EObjectImpl instance) - { - CDOStateMachine.INSTANCE.write(this); - } - - @Override - public boolean isAdapterForType(Object type) - { - return type == CDOCallbackImpl.class; - } - - public void notifyChanged(Notification msg) - { - try - { - if (msg.getNotifier() == instance) - { - Object feature = msg.getFeature(); - if (feature instanceof EReference) - { - EReference reference = (EReference)feature; - if (reference.isContainment() && !reference.isTransient()) - { - switch (msg.getEventType()) - { - case Notification.ADD: - notifyAdd(msg.getNewValue()); - break; - - case Notification.ADD_MANY: - notifyAddMany(msg); - break; - - case Notification.REMOVE: - notifyRemove(msg.getOldValue()); - break; - - case Notification.REMOVE_MANY: - notifyRemoveMany(msg); - break; - } - } - } - } - } - catch (RuntimeException ex) - { - OM.LOG.error(ex); - } - } - - @Override - protected void adjustEProxy() - { - // Do nothing - } - - private void notifyAddMany(Notification msg) - { - List<?> newValues = (List<?>)msg.getNewValue(); - List<?> oldValues = (List<?>)msg.getOldValue(); - for (Object newValue : newValues) - { - if (!oldValues.contains(newValue)) - { - notifyAdd(newValue); - } - } - } - - private void notifyAdd(Object instance) - { - if (instance instanceof InternalEObject) - { - if (((InternalEObject)instance).eDeliver()) - { - InternalCDOObject object = FSMUtil.adapt(instance, view); - CDOStateMachine.INSTANCE.attach(object, view.toTransaction()); - } - } - } - - private void notifyRemoveMany(Notification msg) - { - List<?> newValues = (List<?>)msg.getNewValue(); - List<?> oldValues = (List<?>)msg.getOldValue(); - for (Object oldValue : oldValues) - { - if (!newValues.contains(oldValue)) - { - notifyRemove(oldValue); - } - } - } - - private void notifyRemove(Object instance) - { - if (instance instanceof InternalEObject) - { - if (((InternalEObject)instance).eDeliver()) - { - InternalCDOObject object = FSMUtil.adapt(instance, view); - CDOStateMachine.INSTANCE.detach(object); - } - } - } - - public static InternalCDOObject adapt(Object object, CDOView view) throws Throwable - { - if (object instanceof CDOAware) - { - CDOAware aware = (CDOAware)object; - CDOCallbackImpl callback = (CDOCallbackImpl)aware.getCDOCallback(); - if (callback == null) - { - InternalEObject instance = (InternalEObject)aware; - if (instance.eIsProxy()) - { - instance = (InternalEObject)EcoreUtil.resolve(instance, view.getResourceSet()); - } - - callback = new CDOCallbackImpl(instance); - aware.setCDOCallback(callback); - instance.eAdapters().add(callback); - } - - return callback; - } - - return null; - } -} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java deleted file mode 100644 index 54c4a61176..0000000000 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyImpl.java +++ /dev/null @@ -1,559 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2004 - 2008 Eike Stepper, Germany. - * 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: - * Eike Stepper - initial API and implementation - * Simon McDuff - http://bugs.eclipse.org/201266 - **************************************************************************/ -package org.eclipse.emf.internal.cdo; - -import org.eclipse.emf.cdo.CDOState; -import org.eclipse.emf.cdo.common.CDOProtocolConstants; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.model.CDOClass; -import org.eclipse.emf.cdo.common.model.CDOFeature; -import org.eclipse.emf.cdo.common.model.CDOType; -import org.eclipse.emf.cdo.common.revision.CDORevision; -import org.eclipse.emf.cdo.eresource.CDOResource; -import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl; -import org.eclipse.emf.cdo.spi.common.InternalCDORevision; - -import org.eclipse.emf.internal.cdo.bundle.OM; -import org.eclipse.emf.internal.cdo.util.GenUtil; -import org.eclipse.emf.internal.cdo.util.ModelUtil; - -import org.eclipse.net4j.util.ImplementationError; -import org.eclipse.net4j.util.ReflectUtil; -import org.eclipse.net4j.util.om.trace.ContextTracer; - -import org.eclipse.emf.common.notify.Adapter; -import org.eclipse.emf.common.notify.Notifier; -import org.eclipse.emf.common.util.URI; -import org.eclipse.emf.ecore.EObject; -import org.eclipse.emf.ecore.EStructuralFeature; -import org.eclipse.emf.ecore.InternalEObject; -import org.eclipse.emf.ecore.impl.BasicEObjectImpl; -import org.eclipse.emf.ecore.impl.EAttributeImpl; -import org.eclipse.emf.ecore.impl.EClassImpl; -import org.eclipse.emf.ecore.impl.EDataTypeImpl; -import org.eclipse.emf.ecore.impl.EReferenceImpl; -import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl; -import org.eclipse.emf.ecore.impl.ETypedElementImpl; -import org.eclipse.emf.ecore.resource.Resource; -import org.eclipse.emf.ecore.util.InternalEList; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.Iterator; -import java.util.List; - -/** - * @author Eike Stepper - */ -public abstract class CDOLegacyImpl extends CDOWrapperImpl implements Adapter.Internal -{ - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOLegacyImpl.class); - - private CDOState state; - - private CDOResourceImpl resource; - - private InternalCDORevision revision; - - public CDOLegacyImpl() - { - state = CDOState.TRANSIENT; - } - - public CDOState cdoState() - { - return state; - } - - public InternalCDORevision cdoRevision() - { - return revision; - } - - public CDOResourceImpl cdoResource() - { - return resource; - } - - public CDOClass cdoClass() - { - return CDOObjectImpl.getCDOClass(this); - } - - public void cdoReload() - { - CDOStateMachine.INSTANCE.reload(this); - } - - public boolean isAdapterForType(Object type) - { - return false; - } - - public CDOState cdoInternalSetState(CDOState state) - { - if (this.state != state) - { - if (TRACER.isEnabled()) - { - TRACER.format("Setting state {0} for {1}", state, this); - } - - CDOState tmp = this.state; - this.state = state; - adjustEProxy(); - return tmp; - } - - // TODO Detect duplicate cdoInternalSetState() calls - return null; - } - - public void cdoInternalSetRevision(CDORevision revision) - { - if (TRACER.isEnabled()) - { - TRACER.format("Setting revision: {0}", revision); - } - - this.revision = (InternalCDORevision)revision; - } - - public void cdoInternalSetResource(CDOResource resource) - { - if (TRACER.isEnabled()) - { - TRACER.format("Setting resource: {0}", resource); - } - - this.resource = (CDOResourceImpl)resource; - // if (resource != null) - // { - // transferResourceToInstance(resource); - // } - } - - public void cdoInternalPostAttach() - { - // Do nothing - } - - public void cdoInternalPostDetach() - { - // Do nothing - } - - public void cdoInternalPreCommit() - { - transferInstanceToRevision(); - - CDORevisionManagerImpl revisionManager = view.getSession().getRevisionManager(); - InternalCDORevision revision = cdoRevision(); - InternalCDORevision originRevision = revisionManager.getRevisionByVersion(revision.getID(), CDORevision.UNCHUNKED, - revision.getVersion() - 1, false); - - CDOTransactionImpl transaction = cdoView().toTransaction(); - transaction.registerRevisionDelta(cdoRevision().compare(originRevision)); - } - - public void cdoInternalPostLoad() - { - transferRevisionToInstance(); - } - - @Override - public String toString() - { - if (id == null) - { - return eClass().getName() + "?"; - } - - return eClass().getName() + "@" + id; - } - - public InternalEObject getTarget() - { - return instance; - } - - public void setTarget(Notifier newTarget) - { - if (newTarget instanceof InternalEObject) - { - instance = (InternalEObject)newTarget; - } - else - { - throw new IllegalArgumentException("Not an InternalEObject: " + newTarget.getClass().getName()); - } - } - - public void unsetTarget(Notifier oldTarget) - { - if (oldTarget instanceof InternalEObject) - { - if (instance == oldTarget) - { - instance = null; - } - } - else - { - throw new IllegalArgumentException("Not an InternalEObject: " + oldTarget.getClass().getName()); - } - } - - protected void transferInstanceToRevision() - { - if (TRACER.isEnabled()) - { - TRACER.format("Transfering instance to revision: {0} --> {1}", instance, revision); - } - - CDOViewImpl view = cdoView(); - if (view == null) - { - throw new ImplementationError("view == null"); - } - - // Handle containment - EObject container = instance.eContainer(); - if (container != null) - { - if (container instanceof CDOResource) - { - revision.setResourceID(((CDOResource)container).cdoID()); - revision.setContainerID(CDOID.NULL); - revision.setContainingFeatureID(0); - } - else - { - revision.setResourceID(CDOID.NULL); - // TODO is as CDOIDProvider call ok here? - CDOID containerID = view.provideCDOID(container); - if (containerID.isNull()) - { - throw new ImplementationError("containerID.isNull()"); - } - - int containerFeatureID = instance.eContainerFeatureID();// containER??? - revision.setContainerID(containerID); - revision.setContainingFeatureID(containerFeatureID); - } - } - - // Handle values - CDOClass cdoClass = revision.getCDOClass(); - CDOFeature[] features = cdoClass.getAllFeatures(); - for (int i = 0; i < features.length; i++) - { - CDOFeature feature = features[i]; - Object instanceValue = getInstanceValue(instance, feature); - if (feature.isMany()) - { - List<Object> revisionList = revision.getList(feature); // TODO lazy? - revisionList.clear(); - - if (instanceValue != null) - { - if (instanceValue instanceof InternalEList) - { - InternalEList<?> instanceList = (InternalEList<?>)instanceValue; - if (instanceList != null) - { - for (Iterator<?> it = instanceList.basicIterator(); it.hasNext();) - { - Object instanceElement = it.next(); - if (instanceElement != null && feature.isReference()) - { - instanceElement = view.convertObjectToID(instanceElement); - } - - revisionList.add(instanceElement); - } - } - } - else - { - throw new ImplementationError("Not an InternalEList: " + instanceValue.getClass().getName()); - } - } - } - else - { - if (instanceValue != null && feature.isReference()) - { - instanceValue = view.convertObjectToID(instanceValue); - } - - revision.setValue(feature, instanceValue); - } - } - } - - protected void transferRevisionToInstance() - { - if (TRACER.isEnabled()) - { - TRACER.format("Transfering revision to instance: {0} --> {1}", revision, instance); - } - - CDOViewImpl view = cdoView(); - if (view == null) - { - throw new ImplementationError("view == null"); - } - - boolean deliver = instance.eDeliver(); - if (deliver) - { - instance.eSetDeliver(false); - } - - try - { - // Handle containment - transferContainmentToInstance(view); - - // Handle values - CDOClass cdoClass = revision.getCDOClass(); - CDOFeature[] features = cdoClass.getAllFeatures(); - for (CDOFeature feature : features) - { - transferFeatureToInstance(view, feature); - } - } - finally - { - if (deliver) - { - instance.eSetDeliver(true); - } - } - } - - protected void transferContainmentToInstance(CDOViewImpl view) - { - // Not supported anymore - // Object containerID = revision.getContainerID(); - // if (containerID.isNull()) - // { - // CDOID resourceID = revision.getResourceID(); - // Resource.Internal resource = (Resource.Internal)view.getObject(resourceID); - // transferResourceToInstance(resource); - // } - // else - // { - // int containingFeatureID = revision.getContainingFeatureID(); - // InternalEObject container = convertPotentialID(view, containerID); - // ((BasicEObjectImpl)instance).eBasicSetContainer(container, containingFeatureID, null); - // } - } - - public void transferResourceToInstance(Resource.Internal resource) - { - Method method = ReflectUtil.getMethod(BasicEObjectImpl.class, "eSetDirectResource", Resource.Internal.class); - ReflectUtil.invokeMethod(method, instance, resource); - } - - @SuppressWarnings("unchecked") - protected void transferFeatureToInstance(CDOViewImpl view, CDOFeature feature) - { - Object value = revision.getValue(feature); - if (feature.isMany()) - { - InternalEList<Object> instanceList = (InternalEList<Object>)getInstanceValue(instance, feature); - if (instanceList != null) - { - clearEList(instanceList); - if (value != null) - { - List<?> revisionList = (List<?>)value; - for (Object element : revisionList) - { - if (feature.isReference()) - { - element = convertPotentialID(view, element); - } - - instanceList.basicAdd(element, null); - } - } - } - } - else - { - if (feature.isReference()) - { - value = convertPotentialID(view, value); - } - - setInstanceValue(instance, feature, value); - } - } - - protected InternalEObject convertPotentialID(CDOViewImpl view, Object potentialID) - { - if (potentialID instanceof CDOID) - { - CDOID id = (CDOID)potentialID; - if (id.isNull()) - { - return null; - } - - potentialID = view.getObject(id, false); - } - - if (potentialID instanceof InternalCDOObject) - { - potentialID = ((InternalCDOObject)potentialID).cdoInternalInstance(); - } - - if (potentialID instanceof InternalEObject) - { - return (InternalEObject)potentialID; - } - - throw new ImplementationError(); - } - - protected Object getInstanceValue(InternalEObject instance, CDOFeature feature) - { - EStructuralFeature eFeature = ModelUtil.getEFeature(feature, cdoView().getSession().getPackageRegistry()); - return instance.eGet(eFeature); - } - - protected void setInstanceValue(InternalEObject instance, CDOFeature feature, Object value) - { - // TODO Don't use Java reflection - Class<?> instanceClass = instance.getClass(); - String featureName = feature.getName(); - String fieldName = featureName;// TODO safeName() - Field field = ReflectUtil.getField(instanceClass, fieldName); - if (field == null && feature.getType() == CDOType.BOOLEAN) - { - if (instanceClass.isAssignableFrom(EAttributeImpl.class) || instanceClass.isAssignableFrom(EClassImpl.class) - || instanceClass.isAssignableFrom(EDataTypeImpl.class) - || instanceClass.isAssignableFrom(EReferenceImpl.class) - || instanceClass.isAssignableFrom(EStructuralFeatureImpl.class) - || instanceClass.isAssignableFrom(ETypedElementImpl.class)) - { - // ******************************************* - // ID_EFLAG = 1 << 15; - // ******************************************* - // ABSTRACT_EFLAG = 1 << 8; - // INTERFACE_EFLAG = 1 << 9; - // ******************************************* - // SERIALIZABLE_EFLAG = 1 << 8; - // ******************************************* - // CONTAINMENT_EFLAG = 1 << 15; - // RESOLVE_PROXIES_EFLAG = 1 << 16; - // ******************************************* - // CHANGEABLE_EFLAG = 1 << 10; - // VOLATILE_EFLAG = 1 << 11; - // TRANSIENT_EFLAG = 1 << 12; - // UNSETTABLE_EFLAG = 1 << 13; - // DERIVED_EFLAG = 1 << 14; - // ******************************************* - // ORDERED_EFLAG = 1 << 8; - // UNIQUE_EFLAG = 1 << 9; - // ******************************************* - - String flagName = GenUtil.getFeatureUpperName(featureName) + "_EFLAG"; - int flagsMask = getEFlagMask(instanceClass, flagName); - - field = ReflectUtil.getField(instanceClass, "eFlags"); - int flags = (Integer)ReflectUtil.getValue(field, instance); - boolean on = (Boolean)value; - if (on) - { - flags |= flagsMask; // Add EFlag - } - else - { - flags &= ~flagsMask; // Remove EFlag - } - - ReflectUtil.setValue(field, instance, flags); - return; - } - } - - if (field == null) - { - throw new ImplementationError("Field not found: " + fieldName); - } - - ReflectUtil.setValue(field, instance, value); - } - - protected void adjustEProxy() - { - // Setting eProxyURI is necessary to prevent content adapters from - // loading the whole content tree. - // TODO Does not have the desired effect ;-( see CDOEditor.createModel() - if (state == CDOState.PROXY) - { - if (!instance.eIsProxy()) - { - URI uri = URI.createURI(CDOProtocolConstants.PROTOCOL_NAME + ":proxy#" + id); - if (TRACER.isEnabled()) - { - TRACER.format("Setting proxyURI {0} for {1}", uri, instance); - } - - instance.eSetProxyURI(uri); - } - } - else - { - if (instance.eIsProxy()) - { - if (TRACER.isEnabled()) - { - TRACER.format("Unsetting proxyURI for {0}", instance); - } - - instance.eSetProxyURI(null); - } - } - } - - protected void clearEList(InternalEList<Object> list) - { - while (!list.isEmpty()) - { - Object toBeRemoved = list.basicGet(0); - list.basicRemove(toBeRemoved, null); - } - } - - protected static int getEFlagMask(Class<?> instanceClass, String flagName) - { - Field field = ReflectUtil.getField(instanceClass, flagName); - if (!field.isAccessible()) - { - field.setAccessible(true); - } - - try - { - return (Integer)field.get(null); - } - catch (IllegalAccessException ex) - { - throw new ImplementationError(ex); - } - } -} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyWrapper.java new file mode 100644 index 0000000000..9815902d89 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyWrapper.java @@ -0,0 +1,783 @@ +/*************************************************************************** + * Copyright (c) 2004 - 2008 Eike Stepper, Germany. + * 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: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.emf.internal.cdo; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOState; +import org.eclipse.emf.cdo.common.CDOProtocolConstants; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.model.CDOClass; +import org.eclipse.emf.cdo.common.model.CDOFeature; +import org.eclipse.emf.cdo.common.model.CDOType; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; +import org.eclipse.emf.cdo.eresource.CDOResource; +import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl; +import org.eclipse.emf.cdo.spi.common.InternalCDORevision; +import org.eclipse.emf.cdo.util.CDOPackageRegistry; + +import org.eclipse.emf.internal.cdo.bundle.OM; +import org.eclipse.emf.internal.cdo.util.FSMUtil; +import org.eclipse.emf.internal.cdo.util.GenUtil; +import org.eclipse.emf.internal.cdo.util.ModelUtil; + +import org.eclipse.net4j.util.ImplementationError; +import org.eclipse.net4j.util.ReflectUtil; +import org.eclipse.net4j.util.om.trace.ContextTracer; + +import org.eclipse.emf.common.notify.Adapter; +import org.eclipse.emf.common.notify.impl.NotifyingListImpl; +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.impl.EAttributeImpl; +import org.eclipse.emf.ecore.impl.EClassImpl; +import org.eclipse.emf.ecore.impl.EDataTypeImpl; +import org.eclipse.emf.ecore.impl.EObjectImpl; +import org.eclipse.emf.ecore.impl.EReferenceImpl; +import org.eclipse.emf.ecore.impl.EStructuralFeatureImpl; +import org.eclipse.emf.ecore.impl.ETypedElementImpl; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.emf.ecore.util.InternalEList; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Iterator; +import java.util.List; + +/** + * @author Eike Stepper + * @since 2.0 + */ +/* + * IMPORTANT: Compile errors in this class might indicate an old version of EMF. Legacy support is only enabled for EMF + * with fixed bug #247130. These compile errors do not affect native models! + */ +public final class CDOLegacyWrapper extends CDOObjectWrapper implements InternalEObject.EReadListener, + InternalEObject.EWriteListener +{ + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOLegacyWrapper.class); + + private static final Method eSetDirectResourceMethod = ReflectUtil.getMethod(EObjectImpl.class, "eSetDirectResource", + Resource.Internal.class); + + private static final Method eBasicSetContainerMethod = ReflectUtil.getMethod(EObjectImpl.class, "eBasicSetContainer", + InternalEObject.class, int.class); + + private CDOState state; + + private CDOResourceImpl resource; + + private InternalCDORevision revision; + + private boolean allProxiesResolved; + + private boolean handlingCallback; + + public CDOLegacyWrapper(InternalEObject instance) + { + this.instance = instance; + state = CDOState.TRANSIENT; + } + + public CDOClass cdoClass() + { + return CDOObjectImpl.getCDOClass(this); + } + + public CDOState cdoState() + { + return state; + } + + public InternalCDORevision cdoRevision() + { + return revision; + } + + public CDOResourceImpl cdoResource() + { + return resource; + } + + public void cdoReload() + { + CDOStateMachine.INSTANCE.reload(this); + } + + public CDOState cdoInternalSetState(CDOState state) + { + if (this.state != state) + { + if (TRACER.isEnabled()) + { + TRACER.format("Setting state {0} for {1}", state, this); + } + + CDOState tmp = this.state; + this.state = state; + adjustEProxy(); + return tmp; + } + + // TODO Detect duplicate cdoInternalSetState() calls + return null; + } + + public void cdoInternalSetRevision(CDORevision revision) + { + if (TRACER.isEnabled()) + { + TRACER.format("Setting revision: {0}", revision); + } + + this.revision = (InternalCDORevision)revision; + } + + public void cdoInternalSetResource(CDOResource resource) + { + if (TRACER.isEnabled()) + { + TRACER.format("Setting resource: {0}", resource); + } + + this.resource = (CDOResourceImpl)resource; + } + + public void cdoInternalPostAttach() + { + // TODO Avoid if no adapters in list (eBasicAdapters?) + // TODO LEGACY Clarify how to intercept adapter addition in the legacy instance + for (Adapter adapter : eAdapters()) + { + view.subscribe(this, adapter); + } + } + + public void cdoInternalPostDetach() + { + // Do nothing + } + + public void cdoInternalPreCommit() + { + instanceToRevision(); + if (cdoState() == CDOState.DIRTY) // NEW is handled in PrepareTransition + { + CDORevisionManagerImpl revisionManager = (CDORevisionManagerImpl)revision.getRevisionResolver(); + InternalCDORevision originRevision = revisionManager.getRevisionByVersion(revision.getID(), + CDORevision.UNCHUNKED, revision.getVersion() - 1, false); + CDORevisionDelta delta = revision.compare(originRevision); + + // TODO LEGACY Consider to gather the deltas on the fly with noremal EMF change notifications + cdoView().toTransaction().registerRevisionDelta(delta); + } + } + + public void cdoInternalPostLoad() + { + // TODO Consider not remembering the revisin after copying it to the instance (spare 1/2 of the space) + revisionToInstance(); + } + + public synchronized void handleRead(InternalEObject object, int featureID) + { + if (!handlingCallback) + { + try + { + handlingCallback = true; + CDOStateMachine.INSTANCE.read(this); + + // TODO Optimize this when the list position index is added to the new callbacks + resolveAllProxies(); + } + finally + { + handlingCallback = false; + } + } + } + + public synchronized void handleWrite(InternalEObject object, int featureID) + { + if (!handlingCallback) + { + try + { + handlingCallback = true; + CDOStateMachine.INSTANCE.write(this); + + // TODO Optimize this when the list position index is added to the new callbacks + resolveAllProxies(); + } + finally + { + handlingCallback = false; + } + } + } + + @Override + public boolean equals(Object obj) + { + return obj == this || obj == instance; + } + + @Override + public int hashCode() + { + if (instance != null) + { + return instance.hashCode(); + } + + return super.hashCode(); + } + + @Override + public String toString() + { + return "CDOLegacyWrapper[" + id + "]"; + } + + private void instanceToRevision() + { + if (TRACER.isEnabled()) + { + TRACER.format("Transfering instance to revision: {0} --> {1}", instance, revision); + } + + // Handle containment + instanceToRevisionContainment(); + + // Handle values + CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); + CDOClass cdoClass = revision.getCDOClass(); + for (CDOFeature feature : cdoClass.getAllFeatures()) + { + instanceToRevisionFeature(feature, packageRegistry); + } + } + + private void instanceToRevisionContainment() + { + CDOResource resource = (CDOResource)getInstanceResource(instance); + revision.setResourceID(resource == null ? CDOID.NULL : resource.cdoID()); + + InternalEObject eContainer = getInstanceContainer(instance); + if (eContainer == null) + { + revision.setContainerID(CDOID.NULL); + revision.setContainingFeatureID(0); + } + else + { + CDOObject cdoContainer = FSMUtil.adapt(eContainer, view); + revision.setContainerID(cdoContainer.cdoID()); + revision.setContainingFeatureID(getInstanceContainerFeatureID(instance)); + } + } + + private void instanceToRevisionFeature(CDOFeature feature, CDOPackageRegistry packageRegistry) + { + Object instanceValue = getInstanceValue(instance, feature, packageRegistry); + if (feature.isMany()) + { + List<Object> revisionList = revision.getList(feature); // TODO lazy? + revisionList.clear(); + + if (instanceValue != null) + { + InternalEList<?> instanceList = (InternalEList<?>)instanceValue; + if (!instanceList.isEmpty()) + { + for (Iterator<?> it = instanceList.basicIterator(); it.hasNext();) + { + Object instanceElement = it.next(); + if (instanceElement != null && feature.isReference()) + { + instanceElement = view.convertObjectToID(instanceElement); + } + + revisionList.add(instanceElement); + } + } + } + } + else + { + if (instanceValue != null && feature.isReference()) + { + instanceValue = view.convertObjectToID(instanceValue); + } + + revision.setValue(feature, instanceValue); + } + } + + /** + * TODO Simon: Fix this whole mess ;-) + */ + private void revisionToInstance() + { + if (TRACER.isEnabled()) + { + TRACER.format("Transfering revision to instance: {0} --> {1}", revision, instance); + } + + boolean deliver = instance.eDeliver(); + if (deliver) + { + instance.eSetDeliver(false); + } + + try + { + // Handle containment + revisionToInstanceContainment(); + + // Handle values + CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); + CDOClass cdoClass = revision.getCDOClass(); + for (CDOFeature feature : cdoClass.getAllFeatures()) + { + revisionToInstanceFeature(feature, packageRegistry); + } + } + finally + { + if (deliver) + { + instance.eSetDeliver(true); + } + } + } + + private void revisionToInstanceContainment() + { + CDOID resourceID = revision.getResourceID(); + InternalEObject resource = getEObjectFromPotentialID(view, null, resourceID); + setInstanceResource((Resource.Internal)resource); + + Object containerID = revision.getContainerID(); + InternalEObject container = getEObjectFromPotentialID(view, null, containerID); + setInstanceContainer(container, revision.getContainingFeatureID()); + } + + @SuppressWarnings("unchecked") + private void revisionToInstanceFeature(CDOFeature feature, CDOPackageRegistry packageRegistry) + { + Object value = revision.getValue(feature); + if (feature.isMany()) + { + InternalEList<Object> instanceList = (InternalEList<Object>)getInstanceValue(instance, feature, packageRegistry); + if (instanceList != null) + { + clearEList(instanceList); + if (value != null) + { + List<?> revisionList = (List<?>)value; + if (feature.isReference()) + { + for (Object element : revisionList) + { + element = getEObjectFromPotentialID(view, feature, element); + instanceList.basicAdd(element, null); + } + } + else + { + // TODO Is this only for multi-valued attributes?? + for (Object element : revisionList) + { + instanceList.basicAdd(element, null); + } + } + } + } + } + else + { + if (feature.isReference()) + { + value = getEObjectFromPotentialID(view, feature, value); + } + + setInstanceValue(instance, feature, value); + } + } + + private Resource.Internal getInstanceResource(InternalEObject instance) + { + return instance.eDirectResource(); + } + + private InternalEObject getInstanceContainer(InternalEObject instance) + { + return instance.eInternalContainer(); + } + + private int getInstanceContainerFeatureID(InternalEObject instance) + { + return instance.eContainerFeatureID(); + } + + private Object getInstanceValue(InternalEObject instance, CDOFeature feature, CDOPackageRegistry packageRegistry) + { + EStructuralFeature eFeature = ModelUtil.getEFeature(feature, packageRegistry); + return instance.eGet(eFeature); + } + + private void setInstanceResource(Resource.Internal resource) + { + ReflectUtil.invokeMethod(eSetDirectResourceMethod, instance, resource); + } + + private void setInstanceContainer(InternalEObject container, int containerFeatureID) + { + ReflectUtil.invokeMethod(eBasicSetContainerMethod, instance, container, containerFeatureID); + } + + /** + * TODO Ed: Help to fix whole mess (avoid inverse updates) + */ + private void setInstanceValue(InternalEObject instance, CDOFeature feature, Object value) + { + // TODO Consider EStoreEObjectImpl based objects as well! + // TODO Don't use Java reflection + Class<?> instanceClass = instance.getClass(); + String featureName = feature.getName(); + String fieldName = featureName;// TODO safeName() + Field field = ReflectUtil.getField(instanceClass, fieldName); + if (field == null && feature.getType() == CDOType.BOOLEAN) + { + if (instanceClass.isAssignableFrom(EAttributeImpl.class) || instanceClass.isAssignableFrom(EClassImpl.class) + || instanceClass.isAssignableFrom(EDataTypeImpl.class) + || instanceClass.isAssignableFrom(EReferenceImpl.class) + || instanceClass.isAssignableFrom(EStructuralFeatureImpl.class) + || instanceClass.isAssignableFrom(ETypedElementImpl.class)) + { + // ******************************************* + // ID_EFLAG = 1 << 15; + // ******************************************* + // ABSTRACT_EFLAG = 1 << 8; + // INTERFACE_EFLAG = 1 << 9; + // ******************************************* + // SERIALIZABLE_EFLAG = 1 << 8; + // ******************************************* + // CONTAINMENT_EFLAG = 1 << 15; + // RESOLVE_PROXIES_EFLAG = 1 << 16; + // ******************************************* + // CHANGEABLE_EFLAG = 1 << 10; + // VOLATILE_EFLAG = 1 << 11; + // TRANSIENT_EFLAG = 1 << 12; + // UNSETTABLE_EFLAG = 1 << 13; + // DERIVED_EFLAG = 1 << 14; + // ******************************************* + // ORDERED_EFLAG = 1 << 8; + // UNIQUE_EFLAG = 1 << 9; + // ******************************************* + + String flagName = GenUtil.getFeatureUpperName(featureName) + "_EFLAG"; + int flagsMask = getEFlagMask(instanceClass, flagName); + + field = ReflectUtil.getField(instanceClass, "eFlags"); + int flags = (Integer)ReflectUtil.getValue(field, instance); + boolean on = (Boolean)value; + if (on) + { + flags |= flagsMask; // Add EFlag + } + else + { + flags &= ~flagsMask; // Remove EFlag + } + + ReflectUtil.setValue(field, instance, flags); + return; + } + } + + if (field == null) + { + throw new ImplementationError("Field not found: " + fieldName); + } + + ReflectUtil.setValue(field, instance, value); + } + + /** + * @param feature + * in case that a proxy has to be created the feature that will determine the interface type of the proxy and + * that will be used later to resolve the proxy. <code>null</code> indicates that proxy creation will be + * avoided! + */ + private InternalEObject getEObjectFromPotentialID(CDOViewImpl view, CDOFeature feature, Object potentialID) + { + if (potentialID instanceof CDOID) + { + CDOID id = (CDOID)potentialID; + if (id.isNull()) + { + return null; + } + + boolean loadOnDemand = feature == null; + potentialID = view.getObject(id, loadOnDemand); + if (potentialID == null && !loadOnDemand) + { + return createProxy(view, feature, id); + } + } + + if (potentialID instanceof InternalCDOObject) + { + return ((InternalCDOObject)potentialID).cdoInternalInstance(); + } + + return (InternalEObject)potentialID; + } + + /** + * Creates and returns a <em>proxy</em> object. The usage of a proxy object is strongly limited. The only guarantee + * that can be made is that the following methods are callable and will behave in the expected way: + * <ul> + * <li>{@link CDOObject#cdoID()} will return the {@link CDOID} of the target object + * <li>{@link CDOObject#cdoState()} will return {@link CDOState#PROXY PROXY} + * <li>{@link InternalEObject#eIsProxy()} will return <code>true</code> + * <li>{@link InternalEObject#eProxyURI()} will return the EMF proxy URI of the target object + * </ul> + * Calling any other method on the proxy object will result in an {@link UnsupportedOperationException} being thrown + * at runtime. Note also that the proxy object might even not be cast to the concrete type of the target object. The + * proxy can only guaranteed to be of <em>any</em> concrete subtype of the declared type of the given feature. + * <p> + * TODO {@link InternalEObject#eResolveProxy(InternalEObject) + */ + private InternalEObject createProxy(CDOViewImpl view, CDOFeature feature, CDOID id) + { + CDOPackageRegistry packageRegistry = view.getSession().getPackageRegistry(); + EStructuralFeature eFeature = ModelUtil.getEFeature(feature, packageRegistry); + EClassifier eType = eFeature.getEType(); + Class<?> instanceClass = eType.getInstanceClass(); + + Class<?>[] interfaces = { instanceClass, InternalEObject.class, LegacyProxy.class }; + ClassLoader classLoader = CDOLegacyWrapper.class.getClassLoader(); + LegacyProxyInvocationHandler handler = new LegacyProxyInvocationHandler(this, id); + return (InternalEObject)Proxy.newProxyInstance(classLoader, interfaces, handler); + } + + /** + * TODO Consider using only EMF concepts for resolving proxies! + */ + private void resolveAllProxies() + { + // if (!allProxiesResolved) + { + CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); + CDOClass cdoClass = revision.getCDOClass(); + for (CDOFeature feature : cdoClass.getAllFeatures()) + { + if (feature.isReference()) + { + resolveProxies(feature, packageRegistry); + } + } + + // allProxiesResolved = true; + } + } + + /* + * IMPORTANT: Compile errors in this method might indicate an old version of EMF. Legacy support is only enabled for + * EMF with fixed bug #247130. These compile errors do not affect native models! + */ + @SuppressWarnings("unchecked") + private void resolveProxies(CDOFeature feature, CDOPackageRegistry packageRegistry) + { + Object value = getInstanceValue(instance, feature, packageRegistry); + if (value != null) + { + if (feature.isMany()) + { + InternalEList<Object> list = (InternalEList<Object>)value; + int size = list.size(); + for (int i = 0; i < size; i++) + { + Object element = list.get(i); + if (element instanceof LegacyProxy) + { + CDOID id = ((LegacyProxy)element).getID(); + InternalCDOObject resolved = view.getObject(id); + InternalEObject instance = resolved.cdoInternalInstance(); + + // TODO Is InternalEList.basicSet() needed??? + if (list instanceof org.eclipse.emf.ecore.util.DelegatingInternalEList) + { + list = ((org.eclipse.emf.ecore.util.DelegatingInternalEList)list).getDelegateInternalEList(); + } + + if (list instanceof NotifyingListImpl) + { + ((NotifyingListImpl)list).basicSet(i, instance, null); + } + else + { + list.set(i, instance); + } + } + } + } + else + { + if (value instanceof LegacyProxy) + { + CDOID id = ((LegacyProxy)value).getID(); + InternalCDOObject resolved = view.getObject(id); + InternalEObject instance = resolved.cdoInternalInstance(); + setInstanceValue(instance, feature, instance); + } + } + } + } + + private void adjustEProxy() + { + // Setting eProxyURI is necessary to prevent content adapters from + // loading the whole content tree. + // TODO Does not have the desired effect ;-( see CDOEditor.createModel() + if (state == CDOState.PROXY) + { + if (!instance.eIsProxy()) + { + URI uri = URI.createURI(CDOProtocolConstants.PROTOCOL_NAME + ":proxy#" + id); + if (TRACER.isEnabled()) + { + TRACER.format("Setting proxyURI {0} for {1}", uri, instance); + } + + instance.eSetProxyURI(uri); + } + } + else + { + if (instance.eIsProxy()) + { + if (TRACER.isEnabled()) + { + TRACER.format("Unsetting proxyURI for {0}", instance); + } + + instance.eSetProxyURI(null); + } + } + } + + /** + * TODO Ed: Fix whole mess ;-) + */ + private void clearEList(InternalEList<Object> list) + { + while (!list.isEmpty()) + { + Object toBeRemoved = list.basicGet(0); + list.basicRemove(toBeRemoved, null); + } + } + + private static int getEFlagMask(Class<?> instanceClass, String flagName) + { + Field field = ReflectUtil.getField(instanceClass, flagName); + if (!field.isAccessible()) + { + field.setAccessible(true); + } + + try + { + return (Integer)field.get(null); + } + catch (IllegalAccessException ex) + { + throw new ImplementationError(ex); + } + } + + public static boolean isLegacyProxy(Object object) + { + return object instanceof LegacyProxy; + } + + /** + * @author Eike Stepper + */ + private static interface LegacyProxy + { + public CDOID getID(); + } + + /** + * @author Eike Stepper + */ + private static final class LegacyProxyInvocationHandler implements InvocationHandler, LegacyProxy + { + private static final Method getIDMethod = ReflectUtil.getMethod(LegacyProxy.class, "getID"); + + private static final Method eIsProxyMethod = ReflectUtil.getMethod(EObject.class, "eIsProxy"); + + private static final Method eProxyURIMethod = ReflectUtil.getMethod(InternalEObject.class, "eProxyURI"); + + private CDOLegacyWrapper wrapper; + + private CDOID id; + + public LegacyProxyInvocationHandler(CDOLegacyWrapper wrapper, CDOID id) + { + this.wrapper = wrapper; + this.id = id; + } + + public CDOID getID() + { + return id; + } + + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable + { + if (method.equals(getIDMethod)) + { + return id; + } + + if (method.equals(eIsProxyMethod)) + { + return true; + } + + if (method.equals(eProxyURIMethod)) + { + // Use the resource of the container because it's guaranteed to be in the same CDOView as the resource + // of the target! + Resource resource = wrapper.eResource(); + + // TODO Consider using a "fake" Resource implementation. See Resource.getEObject(...) + return resource.getURI().appendFragment(id.toURIFragment()); + } + + // A client must have invoked the proxy while being told not to do so! + throw new UnsupportedOperationException(method.getName()); + } + } +} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaWrapper.java index 4cef61cd57..228bcc93d6 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOMetaWrapper.java @@ -20,10 +20,11 @@ import org.eclipse.emf.ecore.InternalEObject; /** * @author Eike Stepper + * @since 2.0 */ -public class CDOMetaImpl extends CDOWrapperImpl +public class CDOMetaWrapper extends CDOObjectWrapper { - public CDOMetaImpl(CDOViewImpl view, InternalEObject instance, CDOID id) + public CDOMetaWrapper(CDOViewImpl view, InternalEObject instance, CDOID id) { this.view = view; this.instance = instance; diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java index 71fa09a4ab..9ad7301d23 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java @@ -36,6 +36,7 @@ import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.notify.Notification; import org.eclipse.emf.common.notify.NotificationChain; +import org.eclipse.emf.common.util.BasicEList; import org.eclipse.emf.common.util.BasicEMap; import org.eclipse.emf.common.util.ECollections; import org.eclipse.emf.common.util.EList; @@ -76,6 +77,8 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec private CDOViewImpl cdoView; + // TODO Consider removal because it's only an optimization (proof that revision.resourceID could be used in all cases + // as well) private CDOResourceImpl resource; private InternalCDORevision revision; @@ -231,9 +234,10 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec } } - if (eBasicAdapters() != null) + BasicEList<Adapter> adapters = eBasicAdapters(); + if (adapters != null) { - for (Adapter adapter : eBasicAdapters()) + for (Adapter adapter : adapters) { view.subscribe(this, adapter); } @@ -747,7 +751,6 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec // When setting the resource to null we assume that detach has already been called in the resource implementation // - if (!isSameView && resource != null) { oldResource.detached(this); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOWrapperImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectWrapper.java index 3c324a14e0..9138f9fdba 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOWrapperImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectWrapper.java @@ -33,10 +33,11 @@ import org.eclipse.emf.ecore.resource.Resource; /** * @author Eike Stepper + * @since 2.0 */ -public abstract class CDOWrapperImpl implements InternalCDOObject +public abstract class CDOObjectWrapper implements InternalCDOObject { - private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOWrapperImpl.class); + private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectWrapper.class); protected CDOID id; @@ -44,7 +45,7 @@ public abstract class CDOWrapperImpl implements InternalCDOObject protected InternalEObject instance; - public CDOWrapperImpl() + public CDOObjectWrapper() { super(); } @@ -95,6 +96,46 @@ public abstract class CDOWrapperImpl implements InternalCDOObject throw new UnsupportedOperationException("Not yet implemented"); } + /** + * @since 2.0 + */ + public void eFireRead(int featureID) + { + // Do nothing + } + + /** + * @since 2.0 + */ + public void eFireWrite(int featureID) + { + // Do nothing + } + + /** + * @since 2.0 + */ + /* + * IMPORTANT: Compile errors in this method might indicate an old version of EMF. Legacy support is only enabled for + * EMF with fixed bug #247130. These compile errors do not affect native models! + */ + public EList<InternalEObject.EReadListener> eReadListeners() + { + return instance.eReadListeners(); + } + + /** + * @since 2.0 + */ + /* + * IMPORTANT: Compile errors in this method might indicate an old version of EMF. Legacy support is only enabled for + * EMF with fixed bug #247130. These compile errors do not affect native models! + */ + public EList<InternalEObject.EWriteListener> eWriteListeners() + { + return instance.eWriteListeners(); + } + public EList<Adapter> eAdapters() { return instance.eAdapters(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionConfigurationImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionConfigurationImpl.java index 6b95265257..def45867fc 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionConfigurationImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionConfigurationImpl.java @@ -30,8 +30,6 @@ public class CDOSessionConfigurationImpl implements CDOSessionConfiguration private String repositoryName; - private boolean legacySupportEnabled; - private IFailOverStrategy failOverStrategy; private CDOPackageRegistry packageRegistry; @@ -66,17 +64,6 @@ public class CDOSessionConfigurationImpl implements CDOSessionConfiguration this.repositoryName = repositoryName; } - public boolean isLegacySupportEnabled() - { - return legacySupportEnabled; - } - - public void setLegacySupportEnabled(boolean enabled) - { - checkNotOpen(); - legacySupportEnabled = enabled; - } - public IFailOverStrategy getFailOverStrategy() { return failOverStrategy; @@ -105,14 +92,20 @@ public class CDOSessionConfigurationImpl implements CDOSessionConfiguration this.packageRegistry = packageRegistry; } - public void setSelfPopulatingPackageRegistry() + /** + * @since 2.0 + */ + public void setEagerPackageRegistry() { - setPackageRegistry(CDOUtil.createSelfPopulatingPackageRegistry()); + setPackageRegistry(CDOUtil.createEagerPackageRegistry()); } - public void setDemandPopulatingPackageRegistry() + /** + * @since 2.0 + */ + public void setLazyPackageRegistry() { - setPackageRegistry(CDOUtil.createDemandPopulatingPackageRegistry()); + setPackageRegistry(CDOUtil.createLazyPackageRegistry()); } /** @@ -150,7 +143,6 @@ public class CDOSessionConfigurationImpl implements CDOSessionConfiguration session = new CDOSessionImpl(); session.setConnector(connector); session.setRepositoryName(repositoryName); - session.setLegacySupportEnabled(legacySupportEnabled); session.setFailOverStrategy(failOverStrategy); session.setPackageRegistry(packageRegistry); session.getRevisionManager().setCache(revisionCache); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionFactory.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionFactory.java index ca4198821e..3d2cbcd35c 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionFactory.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionFactory.java @@ -75,9 +75,8 @@ public class CDOSessionFactory extends Factory } String repositoryName = result.get("repositoryName"); - boolean legacySupportEnabled = TRUE.equals(result.get("legacySupportEnabled")); boolean automaticPackageRegistry = TRUE.equals(result.get("automaticPackageRegistry")); - return createSession(repositoryName, legacySupportEnabled, automaticPackageRegistry, null); + return createSession(repositoryName, automaticPackageRegistry, null); } catch (URISyntaxException ex) { @@ -90,19 +89,21 @@ public class CDOSessionFactory extends Factory return (CDOSession)container.getElement(PRODUCT_GROUP, TYPE, description); } - public static CDOSessionImpl createSession(String repositoryName, boolean legacySupportEnabled, - boolean automaticPackageRegistry, IFailOverStrategy failOverStrategy) + /** + * @since 2.0 + */ + public static CDOSessionImpl createSession(String repositoryName, boolean automaticPackageRegistry, + IFailOverStrategy failOverStrategy) { CDOSessionImpl session = new CDOSessionImpl(); if (automaticPackageRegistry) { - CDOPackageRegistryImpl.SelfPopulating packageRegistry = new CDOPackageRegistryImpl.SelfPopulating(); + CDOPackageRegistryImpl.Eager packageRegistry = new CDOPackageRegistryImpl.Eager(); packageRegistry.setSession(session); session.setPackageRegistry(packageRegistry); } session.setRepositoryName(repositoryName); - session.setLegacySupportEnabled(legacySupportEnabled); session.setFailOverStrategy(failOverStrategy); return session; } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java index df5941873e..5c84c23c9b 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOSessionImpl.java @@ -28,28 +28,22 @@ import org.eclipse.emf.cdo.common.id.CDOIDObjectFactory; import org.eclipse.emf.cdo.common.id.CDOIDTemp; import org.eclipse.emf.cdo.common.id.CDOIDTempMeta; import org.eclipse.emf.cdo.common.id.CDOIDUtil; -import org.eclipse.emf.cdo.common.model.CDOClass; -import org.eclipse.emf.cdo.common.model.CDOClassRef; import org.eclipse.emf.cdo.common.model.CDOPackage; import org.eclipse.emf.cdo.common.model.CDOPackageURICompressor; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; -import org.eclipse.emf.cdo.common.util.TransportException; import org.eclipse.emf.cdo.spi.common.InternalCDORevision; import org.eclipse.emf.cdo.util.CDOPackageRegistry; import org.eclipse.emf.cdo.util.CDOUtil; -import org.eclipse.emf.cdo.util.LegacySystemNotAvailableException; import org.eclipse.emf.internal.cdo.bundle.OM; import org.eclipse.emf.internal.cdo.protocol.LoadLibrariesRequest; import org.eclipse.emf.internal.cdo.protocol.OpenSessionRequest; import org.eclipse.emf.internal.cdo.protocol.OpenSessionResult; import org.eclipse.emf.internal.cdo.protocol.PassiveUpdateRequest; -import org.eclipse.emf.internal.cdo.protocol.QueryObjectTypesRequest; import org.eclipse.emf.internal.cdo.protocol.SyncRevisionRequest; import org.eclipse.emf.internal.cdo.protocol.ViewsChangedRequest; import org.eclipse.emf.internal.cdo.util.CDOPackageRegistryImpl; -import org.eclipse.emf.internal.cdo.util.FSMUtil; import org.eclipse.emf.internal.cdo.util.ModelUtil; import org.eclipse.net4j.channel.IChannel; @@ -90,8 +84,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; /** * @author Eike Stepper @@ -103,8 +95,6 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD private int sessionID; - private boolean legacySupportEnabled; - private boolean passiveUpdateEnabled = true; private int referenceChunkSize; @@ -148,8 +138,6 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD private CDORevisionManagerImpl revisionManager; - private ConcurrentMap<CDOID, CDOClass> types = new ConcurrentHashMap<CDOID, CDOClass>(); - private Set<CDOViewImpl> views = new HashSet<CDOViewImpl>(); @ExcludeFromDump @@ -197,24 +185,6 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD return cdoidObjectFactory.createCDOIDObject(in); } - public boolean isLegacySupportEnabled() - { - return legacySupportEnabled; - } - - public void setLegacySupportEnabled(boolean legacySupportEnabled) - { - checkInactive(); - // TODO Adjust this when legacy system is working again: - // if (legacySupportEnabled && !FSMUtil.isLegacySystemAvailable()) - if (legacySupportEnabled) - { - throw new LegacySystemNotAvailableException(); - } - - this.legacySupportEnabled = legacySupportEnabled; - } - public int getReferenceChunkSize() { return referenceChunkSize; @@ -540,32 +510,6 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD metaInstanceToIDMap.put(metaInstance, newID); } - public CDOClass getObjectType(CDOID id) - { - return types.get(id); - } - - public CDOClass requestObjectType(CDOID id) - { - try - { - QueryObjectTypesRequest request = new QueryObjectTypesRequest(channel, Collections.singletonList(id)); - CDOClassRef[] typeRefs = getFailOverStrategy().send(request); - CDOClass type = typeRefs[0].resolve(packageManager); - registerObjectType(id, type); - return type; - } - catch (Exception ex) - { - throw new TransportException(ex); - } - } - - public void registerObjectType(CDOID id, CDOClass type) - { - types.put(id, type); - } - /** * @since 2.0 */ @@ -734,11 +678,6 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD protected void doBeforeActivate() throws Exception { super.doBeforeActivate(); - if (legacySupportEnabled && !FSMUtil.isLegacySystemAvailable()) - { - throw new LegacySystemNotAvailableException(); - } - if (channel == null && connector == null) { throw new IllegalStateException("channel == null && connector == null"); @@ -766,8 +705,7 @@ public class CDOSessionImpl extends Container<CDOView> implements CDOSession, CD channel = connector.openChannel(CDOProtocolConstants.PROTOCOL_NAME, this); } - OpenSessionRequest request = new OpenSessionRequest(channel, repositoryName, legacySupportEnabled, - passiveUpdateEnabled); + OpenSessionRequest request = new OpenSessionRequest(channel, repositoryName, passiveUpdateEnabled); OpenSessionResult result = getFailOverStrategy().send(request); sessionID = result.getSessionID(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java index c9f4d856aa..97abdaa6a1 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStateMachine.java @@ -446,11 +446,11 @@ public final class CDOStateMachine extends FiniteStateMachine<CDOState, CDOEvent object.cdoInternalPostAttach(); changeState(object, CDOState.NEW); - List<InternalCDOObject> contents = mapOfContents.get(object); - // Prepare content tree + List<InternalCDOObject> contents = mapOfContents.get(object); for (InternalCDOObject content : contents) { + // TODO Just call execute()?! INSTANCE.process(content, CDOEvent.ATTACH, mapOfContents); } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java index 224c9889e1..96fd137102 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOStore.java @@ -501,8 +501,8 @@ public final class CDOStore implements EStore lastLookupEFeature = eFeature; lastLookupCDOFeature = cdoFeature; } - return cdoFeature; + return cdoFeature; } private void loadAhead(InternalCDORevision revision, CDOFeature cdoFeature, CDOID id, int index) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java index 434592b23f..0b5723b533 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOTransactionImpl.java @@ -636,11 +636,11 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa if (object instanceof CDOResourceImpl) { - register(lastSavepoint.getNewResources(), object); + registerNew(lastSavepoint.getNewResources(), object); } else { - register(lastSavepoint.getNewObjects(), object); + registerNew(lastSavepoint.getNewObjects(), object); } } @@ -695,12 +695,19 @@ public class CDOTransactionImpl extends CDOViewImpl implements InternalCDOTransa TRACER.format("Registering dirty object {0}", object); } - registerFeatureDelta(object, featureDelta); - register(lastSavepoint.getDirtyObjects(), object); + if (featureDelta != null) + { + registerFeatureDelta(object, featureDelta); + } + + registerNew(lastSavepoint.getDirtyObjects(), object); } + /** + * TODO Simon: Should this method go to CDOSavePointImpl? + */ @SuppressWarnings("unchecked") - private void register(Map map, InternalCDOObject object) + private void registerNew(Map map, InternalCDOObject object) { Object old = map.put(object.cdoID(), object); if (old != null) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java index 1720de7c9b..2d7bcc81c2 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOViewImpl.java @@ -30,11 +30,9 @@ import org.eclipse.emf.cdo.common.CDOProtocolConstants; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDAndVersion; import org.eclipse.emf.cdo.common.id.CDOIDMeta; -import org.eclipse.emf.cdo.common.id.CDOIDObject; import org.eclipse.emf.cdo.common.id.CDOIDProvider; import org.eclipse.emf.cdo.common.id.CDOIDUtil; import org.eclipse.emf.cdo.common.model.CDOClass; -import org.eclipse.emf.cdo.common.model.CDOClassRef; import org.eclipse.emf.cdo.common.revision.CDORevisionResolver; import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta; import org.eclipse.emf.cdo.common.util.CDOException; @@ -389,7 +387,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement public InternalCDOObject getObject(CDOID id) { - return getObject(id, false); + return getObject(id, true); } /** @@ -425,7 +423,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement } else { - localLookupObject = createProxy(id); + return null; } } @@ -501,7 +499,7 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement throw new ImplementationError("No metaInstance for " + id); } - return new CDOMetaImpl(this, metaInstance, id); + return new CDOMetaWrapper(this, metaInstance, id); } /** @@ -524,18 +522,6 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement /** * @since 2.0 */ - public void registerProxyResource(CDOResourceImpl resource) - { - resource.cdoInternalSetResource(resource); - resource.cdoInternalSetView(this); - resource.cdoInternalSetID(getResourceID(resource.getPath())); - resource.cdoInternalSetState(CDOState.PROXY); - registerObject(resource); - } - - /** - * @since 2.0 - */ protected void cleanObject(InternalCDOObject object, InternalCDORevision revision) { if (object instanceof CDOResourceImpl) @@ -559,45 +545,6 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement object.cdoInternalPostLoad(); } - private InternalCDOObject createProxy(CDOID id) - { - if (TRACER.isEnabled()) - { - TRACER.format("Creating proxy for " + id); - } - - CDOClass cdoClass = getObjectType(id); - InternalCDOObject object = newInstance(cdoClass); - if (object instanceof CDOResourceImpl) - { - object.cdoInternalSetResource((CDOResourceImpl)object); - } - - object.cdoInternalSetView(this); - object.cdoInternalSetID(id); - object.cdoInternalSetState(CDOState.PROXY); - return object; - } - - private CDOClass getObjectType(CDOID id) - { - CDOClass type = session.getObjectType(id); - if (type != null) - { - return type; - } - - if (id.isLegacy()) - { - CDOClassRef typeRef = ((CDOIDObject)id).getClassRef(); - type = typeRef.resolve(session.getPackageManager()); - session.registerObjectType(id, type); - return type; - } - - return session.requestObjectType(id); - } - public CDOID provideCDOID(Object idOrObject) { Object shouldBeCDOID = convertObjectToID(idOrObject); @@ -646,18 +593,19 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement if (potentialObject instanceof InternalEObject && !(potentialObject instanceof InternalCDOObject)) { - InternalEObject eObject = (InternalEObject)potentialObject; - - // Only adapt object that are already adapted. - // We do not want to create a attach without goign through the normal process. - if (EcoreUtil.getAdapter(eObject.eAdapters(), CDOAdapterImpl.class) != null) + try { - InternalCDOObject adapter = FSMUtil.adapt(eObject, this); - if (adapter != null) + InternalEObject eObject = (InternalEObject)potentialObject; + Object legacyListener = FSMUtil.getLegacyWrapper(eObject); + if (legacyListener != null) { - potentialObject = adapter; + potentialObject = legacyListener; } } + catch (Throwable ex) + { + OM.LOG.warn(ex); + } } if (potentialObject instanceof InternalCDOObject) @@ -700,6 +648,18 @@ public class CDOViewImpl extends org.eclipse.net4j.util.event.Notifier implement return potentialID; } + /** + * @since 2.0 + */ + public void registerProxyResource(CDOResourceImpl resource) + { + resource.cdoInternalSetResource(resource); + resource.cdoInternalSetView(this); + resource.cdoInternalSetID(getResourceID(resource.getPath())); + resource.cdoInternalSetState(CDOState.PROXY); + registerObject(resource); + } + public void registerObject(InternalCDOObject object) { if (TRACER.isEnabled()) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/LegacySupportEnabler.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/LegacySupportEnabler.java deleted file mode 100644 index 1a6dd32c85..0000000000 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/LegacySupportEnabler.java +++ /dev/null @@ -1,44 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2004 - 2008 Eike Stepper, Germany. - * 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: - * Eike Stepper - initial API and implementation - **************************************************************************/ -package org.eclipse.emf.internal.cdo; - -import org.eclipse.net4j.util.container.IElementProcessor; -import org.eclipse.net4j.util.container.IManagedContainer; - -/** - * @author Eike Stepper - */ -public class LegacySupportEnabler implements IElementProcessor -{ - private boolean legacySupportEnabled; - - public LegacySupportEnabler(boolean legacySupportEnabled) - { - this.legacySupportEnabled = legacySupportEnabled; - } - - public LegacySupportEnabler() - { - this(true); - } - - public Object process(IManagedContainer container, String productGroup, String factoryType, String description, - Object element) - { - if (element instanceof CDOSessionImpl) - { - CDOSessionImpl session = (CDOSessionImpl)element; - session.setLegacySupportEnabled(legacySupportEnabled); - } - - return element; - } -} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/OpenSessionRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/OpenSessionRequest.java index aaead75b90..a9977bf1d6 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/OpenSessionRequest.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/OpenSessionRequest.java @@ -41,18 +41,14 @@ public class OpenSessionRequest extends CDOClientRequest<OpenSessionResult> private String repositoryName; - private boolean legacySupportEnabled; - private boolean passiveUpdateEnabled; private OpenSessionResult result; - public OpenSessionRequest(IChannel channel, String repositoryName, boolean legacySupportEnabled, - boolean passiveUpdateEnabled) + public OpenSessionRequest(IChannel channel, String repositoryName, boolean passiveUpdateEnabled) { super(channel); this.repositoryName = repositoryName; - this.legacySupportEnabled = legacySupportEnabled; this.passiveUpdateEnabled = passiveUpdateEnabled; } @@ -109,13 +105,6 @@ public class OpenSessionRequest extends CDOClientRequest<OpenSessionResult> if (PROTOCOL_TRACER.isEnabled()) { - PROTOCOL_TRACER.format("Writing legacySupportEnabled: {0}", legacySupportEnabled); - } - - out.writeBoolean(legacySupportEnabled); - - if (PROTOCOL_TRACER.isEnabled()) - { PROTOCOL_TRACER.format("Writing passiveUpdateEnabled: {0}", passiveUpdateEnabled); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/QueryObjectTypesRequest.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/QueryObjectTypesRequest.java deleted file mode 100644 index dd9080c98a..0000000000 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/protocol/QueryObjectTypesRequest.java +++ /dev/null @@ -1,84 +0,0 @@ -/*************************************************************************** - * Copyright (c) 2004 - 2008 Eike Stepper, Germany. - * 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: - * Eike Stepper - initial API and implementation - **************************************************************************/ -package org.eclipse.emf.internal.cdo.protocol; - -import org.eclipse.emf.cdo.common.CDODataInput; -import org.eclipse.emf.cdo.common.CDODataOutput; -import org.eclipse.emf.cdo.common.CDOProtocolConstants; -import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.common.model.CDOClassRef; - -import org.eclipse.emf.internal.cdo.bundle.OM; - -import org.eclipse.net4j.channel.IChannel; -import org.eclipse.net4j.util.om.trace.ContextTracer; - -import java.io.IOException; -import java.util.List; - -/** - * @author Eike Stepper - */ -public class QueryObjectTypesRequest extends CDOClientRequest<CDOClassRef[]> -{ - private static final ContextTracer PROTOCOL_TRACER = new ContextTracer(OM.DEBUG_PROTOCOL, - QueryObjectTypesRequest.class); - - private List<CDOID> ids; - - public QueryObjectTypesRequest(IChannel channel, List<CDOID> ids) - { - super(channel); - this.ids = ids; - } - - @Override - protected short getSignalID() - { - return CDOProtocolConstants.SIGNAL_QUERY_OBJECT_TYPES; - } - - @Override - protected void requesting(CDODataOutput out) throws IOException - { - if (PROTOCOL_TRACER.isEnabled()) - { - PROTOCOL_TRACER.format("Writing {0} IDs", ids.size()); - } - - out.writeInt(ids.size()); - for (CDOID id : ids) - { - if (PROTOCOL_TRACER.isEnabled()) - { - PROTOCOL_TRACER.format("Writing ID: {0}", id); - } - - out.writeCDOID(id); - } - } - - @Override - protected CDOClassRef[] confirming(CDODataInput in) throws IOException - { - CDOClassRef[] types = new CDOClassRef[ids.size()]; - for (int i = 0; i < types.length; i++) - { - types[i] = in.readCDOClassRef(); - if (PROTOCOL_TRACER.isEnabled()) - { - PROTOCOL_TRACER.format("Read type: {0}", types[i]); - } - } - - return types; - } -} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageRegistryImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageRegistryImpl.java index a22b994153..7e97014f07 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageRegistryImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageRegistryImpl.java @@ -240,6 +240,66 @@ public class CDOPackageRegistryImpl extends EPackageRegistryImpl implements CDOP /** * @author Eike Stepper */ + public static class Eager extends SessionBound + { + private static final long serialVersionUID = 1L; + + private IListener typeListener = new ContainerEventAdapter<Map.Entry<String, CDOPackageType>>() + { + @Override + protected void onAdded(IContainer<java.util.Map.Entry<String, CDOPackageType>> container, + java.util.Map.Entry<String, CDOPackageType> entry) + { + addEntry(entry); + } + }; + + public Eager() + { + } + + @Override + protected void sessionActivated() + { + for (Map.Entry<String, CDOPackageType> entry : CDOPackageTypeRegistry.INSTANCE.entrySet()) + { + addEntry(entry); + } + + CDOPackageTypeRegistry.INSTANCE.addListener(typeListener); + } + + @Override + protected void sessionAboutToDeactivate() + { + CDOPackageTypeRegistry.INSTANCE.removeListener(typeListener); + } + + protected void addEntry(Map.Entry<String, CDOPackageType> entry) + { + CDOPackageType packageType = entry.getValue(); + if (packageType != CDOPackageType.LEGACY) + { + String uri = entry.getKey(); + if (!containsKey(uri)) + { + try + { + EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(uri); + putEPackage(ePackage); + } + catch (RuntimeException ex) + { + OM.LOG.error(ex); + } + } + } + } + } + + /** + * @author Eike Stepper + */ public static class TransactionBound extends SessionBound implements CDOTransactionHandler { private static final long serialVersionUID = 1L; @@ -326,73 +386,13 @@ public class CDOPackageRegistryImpl extends EPackageRegistryImpl implements CDOP /** * @author Eike Stepper */ - public static class SelfPopulating extends SessionBound - { - private static final long serialVersionUID = 1L; - - private IListener typeListener = new ContainerEventAdapter<Map.Entry<String, CDOPackageType>>() - { - @Override - protected void onAdded(IContainer<java.util.Map.Entry<String, CDOPackageType>> container, - java.util.Map.Entry<String, CDOPackageType> entry) - { - addEntry(entry); - } - }; - - public SelfPopulating() - { - } - - @Override - protected void sessionActivated() - { - for (Map.Entry<String, CDOPackageType> entry : CDOPackageTypeRegistry.INSTANCE.entrySet()) - { - addEntry(entry); - } - - CDOPackageTypeRegistry.INSTANCE.addListener(typeListener); - } - - @Override - protected void sessionAboutToDeactivate() - { - CDOPackageTypeRegistry.INSTANCE.removeListener(typeListener); - } - - protected void addEntry(Map.Entry<String, CDOPackageType> entry) - { - CDOPackageType packageType = entry.getValue(); - if (packageType != CDOPackageType.LEGACY) - { - String uri = entry.getKey(); - if (!containsKey(uri)) - { - try - { - EPackage ePackage = EPackage.Registry.INSTANCE.getEPackage(uri); - putEPackage(ePackage); - } - catch (RuntimeException ex) - { - OM.LOG.error(ex); - } - } - } - } - } - - /** - * @author Eike Stepper - */ - public static class DemandPopulating extends TransactionBound + public static class Lazy extends TransactionBound { private static final long serialVersionUID = 1L; private Set<EClass> usedClasses = new HashSet<EClass>(); - public DemandPopulating() + public Lazy() { } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageTypeRegistryImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageTypeRegistryImpl.java index ebf97c3f1e..9a8bc2b5ff 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageTypeRegistryImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/CDOPackageTypeRegistryImpl.java @@ -12,9 +12,9 @@ package org.eclipse.emf.internal.cdo.util; import org.eclipse.emf.cdo.CDOObject; import org.eclipse.emf.cdo.eresource.EresourcePackage; +import org.eclipse.emf.cdo.util.CDOFactory; import org.eclipse.emf.cdo.util.CDOPackageType; import org.eclipse.emf.cdo.util.CDOPackageTypeRegistry; -import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.internal.cdo.bundle.OM; @@ -24,9 +24,12 @@ import org.eclipse.net4j.util.registry.HashMapRegistry; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; +import org.eclipse.emf.ecore.EFactory; +import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.impl.EPackageImpl; import org.eclipse.emf.ecore.plugin.EcorePlugin; +import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; @@ -38,7 +41,6 @@ import org.eclipse.core.runtime.dynamichelpers.IExtensionTracker; import org.eclipse.core.runtime.dynamichelpers.IFilter; import org.osgi.framework.Bundle; -import org.osgi.framework.Constants; import java.util.HashMap; import java.util.Map; @@ -63,43 +65,6 @@ public final class CDOPackageTypeRegistryImpl extends HashMapRegistry<String, CD } } - public CDOPackageType getPackageType(EPackage ePackage) - { - if (ePackage.getClass() == EPackageImpl.class) - { - // Dynamic packages can be considered native - return CDOPackageType.NATIVE; - } - - EPackage topLevelPackage = ModelUtil.getTopLevelPackage(ePackage); - EClass eClass = getAnyEClass(topLevelPackage); - if (eClass == null) - { - throw new IllegalArgumentException("ePackage does not contain classes"); - } - - try - { - if (isConverted(eClass)) - { - return CDOPackageType.CONVERTED; - } - } - catch (Throwable ignore) - { - // Legacy system might not be available - } - - // TODO This might not work if the model interface don't extend CDOObject - Class<?> instanceClass = eClass.getInstanceClass(); - if (CDOObject.class.isAssignableFrom(instanceClass)) - { - return CDOPackageType.NATIVE; - } - - return CDOPackageType.LEGACY; - } - public void register(EPackage ePackage) { put(ePackage.getNsURI(), getPackageType(ePackage)); @@ -115,11 +80,6 @@ public final class CDOPackageTypeRegistryImpl extends HashMapRegistry<String, CD put(uri, CDOPackageType.NATIVE); } - public void registerConverted(String uri) - { - put(uri, CDOPackageType.CONVERTED); - } - @Override protected void doActivate() throws Exception { @@ -191,46 +151,8 @@ public final class CDOPackageTypeRegistryImpl extends HashMapRegistry<String, CD { return CDOPackageType.NATIVE; } - else - { - String version = (String)bundle.getHeaders().get(Constants.BUNDLE_VERSION); - if (version.endsWith(CDOUtil.CDO_VERSION_SUFFIX)) - { - return CDOPackageType.CONVERTED; - } - else - { - return CDOPackageType.LEGACY; - } - } - } - private EClass getAnyEClass(EPackage ePackage) - { - for (EClassifier classifier : ePackage.getEClassifiers()) - { - if (classifier instanceof EClass) - { - return (EClass)classifier; - } - } - - for (EPackage subpackage : ePackage.getESubpackages()) - { - EClass eClass = getAnyEClass(subpackage); - if (eClass != null) - { - return eClass; - } - } - - return null; - } - - private boolean isConverted(EClass eClass) - { - Class<?> instanceClass = eClass.getInstanceClass(); - return org.eclipse.emf.ecore.impl.CDOAware.class.isAssignableFrom(instanceClass); + return CDOPackageType.LEGACY; } private void connectExtensionTracker() @@ -270,4 +192,55 @@ public final class CDOPackageTypeRegistryImpl extends HashMapRegistry<String, CD } }; } + + public static CDOPackageType getPackageType(EPackage ePackage) + { + if (ePackage.getClass() == EPackageImpl.class) + { + EFactory factory = ePackage.getEFactoryInstance(); + if (factory instanceof CDOFactory) + { + return CDOPackageType.NATIVE; + } + + return CDOPackageType.LEGACY; + } + + EPackage topLevelPackage = ModelUtil.getTopLevelPackage(ePackage); + EClass eClass = getAnyEClass(topLevelPackage); + if (eClass == null) + { + return CDOPackageType.LEGACY; + } + + EObject testObject = EcoreUtil.create(eClass); + if (testObject instanceof CDOObject) + { + return CDOPackageType.NATIVE; + } + + return CDOPackageType.LEGACY; + } + + private static EClass getAnyEClass(EPackage ePackage) + { + for (EClassifier classifier : ePackage.getEClassifiers()) + { + if (classifier instanceof EClass) + { + return (EClass)classifier; + } + } + + for (EPackage subpackage : ePackage.getESubpackages()) + { + EClass eClass = getAnyEClass(subpackage); + if (eClass != null) + { + return eClass; + } + } + + return null; + } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java index b55a0a6215..476eff0763 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/util/FSMUtil.java @@ -12,20 +12,15 @@ package org.eclipse.emf.internal.cdo.util; import org.eclipse.emf.cdo.CDOObject; -import org.eclipse.emf.cdo.CDOSession; import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.CDOView; import org.eclipse.emf.cdo.common.id.CDOID; -import org.eclipse.emf.cdo.util.LegacySystemNotAvailableException; -import org.eclipse.emf.internal.cdo.CDOAdapterImpl; -import org.eclipse.emf.internal.cdo.CDOLegacyImpl; -import org.eclipse.emf.internal.cdo.CDOMetaImpl; +import org.eclipse.emf.internal.cdo.CDOLegacyWrapper; +import org.eclipse.emf.internal.cdo.CDOMetaWrapper; import org.eclipse.emf.internal.cdo.CDOViewImpl; import org.eclipse.emf.internal.cdo.InternalCDOObject; -import org.eclipse.emf.internal.cdo.bundle.OM; -import org.eclipse.emf.common.notify.Adapter; import org.eclipse.emf.common.util.EList; import org.eclipse.emf.ecore.EGenericType; import org.eclipse.emf.ecore.EModelElement; @@ -34,7 +29,6 @@ import org.eclipse.emf.ecore.InternalEObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; -import java.lang.reflect.Method; import java.util.Collection; import java.util.Iterator; @@ -43,52 +37,10 @@ import java.util.Iterator; */ public final class FSMUtil { - private static Method adaptLegacyMethod = initAdaptLegacyMethod(); - private FSMUtil() { } - private static Method initAdaptLegacyMethod() - { - // TODO Fix when legacy mode is supported again... - // try - // { - // Class<?> c = Class.forName("org.eclipse.emf.internal.cdo.CDOCallbackImpl"); - // if (c != null) - // { - // final Class<?>[] params = { Object.class, CDOView.class }; - // Method method = c.getDeclaredMethod("adapt", params); - // if (method != null) - // { - // return method; - // } - // } - // } - // catch (Throwable ignore) - // { - // // Only for testing: - // // ignore.printStackTrace(); - // } - // - // OM.LOG.info(LegacySystemNotAvailableException.LEGACY_SYSTEM_NOT_AVAILABLE); - return null; - } - - public static boolean isLegacySystemAvailable() - { - return adaptLegacyMethod != null; - } - - public static void checkLegacySystemAvailability(CDOSession session, CDOObject object) - throws LegacySystemNotAvailableException - { - if (!session.isLegacySupportEnabled() && object instanceof CDOLegacyImpl) - { - throw new LegacySystemNotAvailableException(); - } - } - public static boolean isTransient(CDOObject object) { CDOState state = object.cdoState(); @@ -101,6 +53,12 @@ public final class FSMUtil return state == CDOState.NEW; } + public static boolean isMeta(Object object) + { + return object instanceof EModelElement || object instanceof EGenericType + || object instanceof org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl; + } + /** * @param view * Only needed if object is a meta instance. @@ -117,55 +75,81 @@ public final class FSMUtil throw new IllegalArgumentException("object == null"); } - if (object instanceof EModelElement || object instanceof EGenericType - || object instanceof org.eclipse.emf.ecore.impl.EStringToStringMapEntryImpl) + if (isMeta(object)) { - InternalEObject eObject = (InternalEObject)object; - if (view == null) - { - throw new IllegalArgumentException("view == null"); - } + return adaptMeta((InternalEObject)object, view); + } - if (eObject.eIsProxy()) - { - eObject = (InternalEObject)EcoreUtil.resolve(eObject, view.getResourceSet()); - } + if (object instanceof InternalEObject) + { + return adaptLegacy((InternalEObject)object); + } - CDOID id = ((CDOViewImpl)view).getSession().lookupMetaInstanceID(eObject); - if (id != null) - { - return new CDOMetaImpl((CDOViewImpl)view, eObject, id); - } + return null; + } + + public static InternalCDOObject adaptMeta(InternalEObject object, CDOView view) + { + if (view == null) + { + throw new IllegalArgumentException("view == null"); } - if (isLegacySystemAvailable()) + if (object.eIsProxy()) { - try - { - return (InternalCDOObject)adaptLegacyMethod.invoke(null, object, view); - } - catch (Throwable t) - { - OM.LOG.info(t); - } + object = (InternalEObject)EcoreUtil.resolve(object, view.getResourceSet()); } - if (object instanceof InternalEObject) + CDOID id = ((CDOViewImpl)view).getSession().lookupMetaInstanceID(object); + if (id != null) { - EList<Adapter> adapters = ((InternalEObject)object).eAdapters(); - CDOAdapterImpl adapter = (CDOAdapterImpl)EcoreUtil.getAdapter(adapters, CDOAdapterImpl.class); - if (adapter == null) + return new CDOMetaWrapper((CDOViewImpl)view, object, id); + } + + return null; + } + + /* + * IMPORTANT: Compile errors in this method might indicate an old version of EMF. Legacy support is only enabled for + * EMF with fixed bug #247130. These compile errors do not affect native models! + */ + public static InternalCDOObject adaptLegacy(InternalEObject object) + { + EList<InternalEObject.EReadListener> readListeners = object.eReadListeners(); + CDOLegacyWrapper wrapper = getLegacyWrapper(readListeners); + if (wrapper == null) + { + wrapper = new CDOLegacyWrapper(object); + // TODO Only Load/Attach transitions should actually *add* the wrappers! + readListeners.add(0, wrapper); + object.eWriteListeners().add(0, wrapper); + } + + return wrapper; + } + + public static CDOLegacyWrapper getLegacyWrapper(EList<?> listeners) + { + for (Object listener : listeners) + { + if (listener.getClass() == CDOLegacyWrapper.class) { - adapter = new CDOAdapterImpl(); - adapters.add(adapter); + return (CDOLegacyWrapper)listener; } - - return adapter; } return null; } + /* + * IMPORTANT: Compile errors in this method might indicate an old version of EMF. Legacy support is only enabled for + * EMF with fixed bug #247130. These compile errors do not affect native models! + */ + public static Object getLegacyWrapper(InternalEObject object) + { + return getLegacyWrapper(object.eReadListeners()); + } + /** * Similar to {@link EcoreUtil#getAllProperContents(Resource, boolean)} except gives only one depth */ |