Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 151009 Details for
Bug 247226
Transparently support legacy models (CDOLegacyAdapter)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read
this important communication.
[patch]
LegacyAdapter Patch
LegacyAdapterPatch.txt (text/plain), 65.88 KB, created by
Martin Fluegge
on 2009-10-31 15:30:32 EDT
(
hide
)
Description:
LegacyAdapter Patch
Filename:
MIME Type:
Creator:
Martin Fluegge
Created:
2009-10-31 15:30:32 EDT
Size:
65.88 KB
patch
obsolete
>### Eclipse Workspace Patch 1.0 >#P org.eclipse.emf.cdo >Index: src/org/eclipse/emf/internal/cdo/CDOLegacyAdapter.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyAdapter.java,v >retrieving revision 1.4 >diff -u -r1.4 CDOLegacyAdapter.java >--- src/org/eclipse/emf/internal/cdo/CDOLegacyAdapter.java 7 May 2009 08:40:40 -0000 1.4 >+++ src/org/eclipse/emf/internal/cdo/CDOLegacyAdapter.java 31 Oct 2009 18:59:33 -0000 >@@ -10,6 +10,10 @@ > */ > package org.eclipse.emf.internal.cdo; > >+import org.eclipse.emf.internal.cdo.bundle.OM; >+ >+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.Notifier; >@@ -24,92 +28,113 @@ > */ > public class CDOLegacyAdapter extends CDOLegacyWrapper implements Adapter.Internal > { >- public CDOLegacyAdapter() >- { >- super(null); >- } >- >- public void setTarget(Notifier newTarget) >- { >- instance = (InternalEObject)newTarget; >- } >- >- public void unsetTarget(Notifier oldTarget) >- { >- if (instance == oldTarget) >- { >- instance = null; >- } >- } >- >- public Notifier getTarget() >- { >- return instance; >- } >- >- public boolean isAdapterForType(Object type) >- { >- return type == CDOLegacyAdapter.class; >- } >- >- public void notifyChanged(Notification msg) >- { >- CDOStore store = view.getStore(); >- EStructuralFeature feature = (EStructuralFeature)msg.getFeature(); >- switch (msg.getEventType()) >- { >- case Notification.SET: >- store.set(instance, feature, msg.getPosition(), msg.getNewValue()); >- break; >- >- case Notification.UNSET: >- store.unset(instance, feature); >- break; >- >- case Notification.MOVE: >- // TODO Is that correct? >- store.move(instance, feature, msg.getPosition(), (Integer)msg.getOldValue()); >- break; >- >- case Notification.ADD: >- store.add(instance, feature, msg.getPosition(), msg.getNewValue()); >- break; >- >- case Notification.ADD_MANY: >- { >- int pos = msg.getPosition(); >- @SuppressWarnings("unchecked") >- List<Object> list = (List<Object>)msg.getNewValue(); >- for (Object object : list) >- { >- // TODO Is that correct? >- store.add(instance, feature, pos++, object); >- } >- } >- >- break; >- >- case Notification.REMOVE: >- store.remove(instance, feature, msg.getPosition()); >- break; >- >- case Notification.REMOVE_MANY: >- { >- int pos = msg.getPosition(); >- @SuppressWarnings("unchecked") >- List<Object> list = (List<Object>)msg.getOldValue(); >- for (int i = 0; i < list.size(); i++) >- { >- store.remove(instance, feature, pos); >- } >- } >- >- break; >- } >- } >- >- @Override >- public void cdoInternalPostInvalidate() >- { >- } >+ >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOLegacyAdapter.class); >+ >+ public CDOLegacyAdapter() >+ { >+ super(null); >+ >+ } >+ >+ public void setTarget(Notifier newTarget) >+ { >+ >+ instance = (InternalEObject) newTarget; >+ >+ } >+ >+ public void unsetTarget(Notifier oldTarget) >+ { >+ if (instance == oldTarget) >+ { >+ instance = null; >+ } >+ } >+ >+ public Notifier getTarget() >+ { >+ return instance; >+ } >+ >+ public boolean isAdapterForType(Object type) >+ { >+ return type == CDOLegacyAdapter.class; >+ } >+ >+ public void notifyChanged(Notification msg) >+ { >+ >+ CDOStore store = view.getStore(); >+ EStructuralFeature feature = (EStructuralFeature) msg.getFeature(); >+ >+ //TODO Martin: Seems that it is quite uncool to set a transient feature to the view. Leads to an error because the the wrong featureID will be found in the revision. Discuss this with Eike. >+ if (feature.isTransient()) >+ { >+ return; >+ } >+ >+ switch (msg.getEventType()) >+ { >+ case Notification.SET: >+ store.set(instance, feature, msg.getPosition(), msg.getNewValue()); >+ break; >+ >+ case Notification.UNSET: >+ store.unset(instance, feature); >+ break; >+ >+ case Notification.MOVE: >+ // TODO Is that correct? >+ store.move(instance, feature, msg.getPosition(), (Integer) msg.getOldValue()); >+ break; >+ >+ case Notification.ADD: >+ store.add(instance, feature, msg.getPosition(), msg.getNewValue()); >+ break; >+ >+ case Notification.ADD_MANY: >+ { >+ >+ int pos = msg.getPosition(); >+ @SuppressWarnings("unchecked") >+ List<Object> list = (List<Object>) msg.getNewValue(); >+ for (Object object : list) >+ { >+ // TODO Is that correct? >+ store.add(instance, feature, pos++, object); >+ >+ } >+ } >+ >+ break; >+ >+ case Notification.REMOVE: >+ store.remove(instance, feature, msg.getPosition()); >+ break; >+ >+ case Notification.REMOVE_MANY: >+ { >+ int pos = msg.getPosition(); >+ @SuppressWarnings("unchecked") >+ List<Object> list = (List<Object>) msg.getOldValue(); >+ for (int i = 0; i < list.size(); i++) >+ { >+ store.remove(instance, feature, pos); >+ } >+ } >+ >+ break; >+ } >+ } >+ >+ // @Override >+ // public void cdoInternalPostInvalidate() >+ // { >+ // System.out.println("********************* Calling cdoInternalPostInvalidate() "); >+ // InternalCDORevision revision = cdoView().getRevision(cdoID(), true); >+ // cdoInternalSetRevision(revision); >+ // revisionToInstance(); >+ // cdoInternalSetState(CDOState.CLEAN); >+ // } > } >Index: src/org/eclipse/emf/internal/cdo/CDOLegacyWrapper.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOLegacyWrapper.java,v >retrieving revision 1.30 >diff -u -r1.30 CDOLegacyWrapper.java >--- src/org/eclipse/emf/internal/cdo/CDOLegacyWrapper.java 20 Oct 2009 06:51:12 -0000 1.30 >+++ src/org/eclipse/emf/internal/cdo/CDOLegacyWrapper.java 31 Oct 2009 18:59:33 -0000 >@@ -15,6 +15,7 @@ > import org.eclipse.emf.cdo.common.id.CDOID; > import org.eclipse.emf.cdo.common.model.CDOModelUtil; > import org.eclipse.emf.cdo.common.model.CDOPackageRegistry; >+import org.eclipse.emf.cdo.common.model.CDOType; > import org.eclipse.emf.cdo.common.protocol.CDOProtocolConstants; > import org.eclipse.emf.cdo.common.revision.CDORevision; > import org.eclipse.emf.cdo.eresource.CDOResource; >@@ -28,9 +29,9 @@ > 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.impl.NotifyingListImpl; > import org.eclipse.emf.common.util.URI; >+import org.eclipse.emf.ecore.EAttribute; > import org.eclipse.emf.ecore.EClass; > import org.eclipse.emf.ecore.EClassifier; > import org.eclipse.emf.ecore.EObject; >@@ -46,6 +47,8 @@ > import java.lang.reflect.InvocationHandler; > import java.lang.reflect.Method; > import java.lang.reflect.Proxy; >+import java.util.HashMap; >+import java.util.Map; > > /** > * @author Eike Stepper >@@ -53,536 +56,958 @@ > */ > public abstract class CDOLegacyWrapper extends CDOObjectWrapper > { >- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOLegacyWrapper.class); >+ //private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOLegacyWrapper.class); > >- protected CDOState state; >+ //TODO Martin: with OM.DEBUG_VIEW I managed activating traces. Should ask Eike how the tracing works in general. >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_VIEW, CDOLegacyWrapper.class); > >- protected InternalCDORevision revision; >+ protected CDOState state; > >- public CDOLegacyWrapper(InternalEObject instance) >- { >- this.instance = instance; >- state = CDOState.TRANSIENT; >- } >- >- public CDOState cdoState() >- { >- return state; >- } >- >- public InternalCDORevision cdoRevision() >- { >- return revision; >- } >- >- 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); //$NON-NLS-1$ >- } >- >- CDOState oldState = this.state; >- this.state = state; >- adjustEProxy(); >- if (view != null) >- { >- view.handleObjectStateChanged(this, oldState, state); >- } >- >- return oldState; >- } >- >- return null; >- } >- >- public void cdoInternalSetRevision(CDORevision revision) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Setting revision: {0}", revision); //$NON-NLS-1$ >- } >- >- this.revision = (InternalCDORevision)revision; >- } >- >- public void cdoInternalPostAttach() >- { >- instanceToRevision(); >- >- // 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(boolean remote) >- { >- // Do nothing >- } >- >- public void cdoInternalPreCommit() >- { >- // instanceToRevision(); >- // if (cdoState() == CDOState.DIRTY) // NEW is handled in PrepareTransition >- // { >- // CDORevisionManagerImpl revisionManager = (CDORevisionManagerImpl)cdoView().getSession().getRevisionManager(); >- // 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 cdoInternalPreLoad() >- { >- } >- >- public void cdoInternalPostLoad() >- { >- // TODO Consider not remembering the revisin after copying it to the instance (spare 1/2 of the space) >- revisionToInstance(); >- } >- >- public void cdoInternalPostInvalidate() >- { >- } >- >- public void cdoInternalCleanup() >- { >- } >- >- @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 + "]"; //$NON-NLS-1$ //$NON-NLS-2$ >- } >- >- protected void instanceToRevision() >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Transfering instance to revision: {0} --> {1}", instance, revision); //$NON-NLS-1$ >- } >- >- // Handle containment >- instanceToRevisionContainment(); >- >- // Handle values >- CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); >- EClass eClass = revision.getEClass(); >- for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass)) >- { >- instanceToRevisionFeature(feature, packageRegistry); >- } >- } >- >- protected 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)); >- } >- } >- >- protected void instanceToRevisionFeature(EStructuralFeature feature, CDOPackageRegistry packageRegistry) >- { >- Object instanceValue = getInstanceValue(instance, feature, packageRegistry); >- CDOObjectImpl.instanceToRevisionFeature(view, this, feature, instanceValue); >- } >- >- /** >- * TODO Simon: Fix this whole mess ;-) >- */ >- protected void revisionToInstance() >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Transfering revision to instance: {0} --> {1}", revision, instance); //$NON-NLS-1$ >- } >- >- boolean deliver = instance.eDeliver(); >- if (deliver) >- { >- instance.eSetDeliver(false); >- } >- >- try >- { >- // Handle containment >- revisionToInstanceContainment(); >- >- // Handle values >- CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); >- EClass eClass = revision.getEClass(); >- for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass)) >- { >- revisionToInstanceFeature(feature, packageRegistry); >- } >- } >- finally >- { >- if (deliver) >- { >- instance.eSetDeliver(true); >- } >- } >- } >- >- protected 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()); >- } >- >- protected void revisionToInstanceFeature(EStructuralFeature feature, CDOPackageRegistry packageRegistry) >- { >- // Attempt 4 >- Object value = revision.getValue(feature); >- view.getStore().set(instance, feature, Notification.NO_INDEX, value); >- } >- >- protected Resource.Internal getInstanceResource(InternalEObject instance) >- { >- return instance.eDirectResource(); >- } >- >- protected InternalEObject getInstanceContainer(InternalEObject instance) >- { >- return instance.eInternalContainer(); >- } >- >- protected int getInstanceContainerFeatureID(InternalEObject instance) >- { >- return instance.eContainerFeatureID(); >- } >- >- protected Object getInstanceValue(InternalEObject instance, EStructuralFeature feature, >- CDOPackageRegistry packageRegistry) >- { >- return instance.eGet(feature); >- } >- >- protected void setInstanceResource(Resource.Internal resource) >- { >- Method method = ReflectUtil.getMethod(instance.getClass(), "eSetDirectResource", Resource.Internal.class); //$NON-NLS-1$ >- ReflectUtil.invokeMethod(method, instance, resource); >- } >- >- protected void setInstanceContainer(InternalEObject container, int containerFeatureID) >- { >- Method method = ReflectUtil.getMethod(instance.getClass(), "eBasicSetContainer", InternalEObject.class, int.class); //$NON-NLS-1$ >- ReflectUtil.invokeMethod(method, instance, container, containerFeatureID); >- } >- >- protected void setInstanceValue(InternalEObject instance, EStructuralFeature feature, Object value) >- { >- instance.eSet(feature, 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! >- */ >- protected InternalEObject getEObjectFromPotentialID(InternalCDOView view, EStructuralFeature 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) >- */ >- protected InternalEObject createProxy(InternalCDOView view, EStructuralFeature feature, CDOID id) >- { >- EClassifier eType = feature.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 Ed: Fix whole mess ;-) >- */ >- protected void clearEList(InternalEList<Object> list) >- { >- while (!list.isEmpty()) >- { >- Object toBeRemoved = list.basicGet(0); >- list.basicRemove(toBeRemoved, null); >- } >- } >- >- /** >- * TODO Consider using only EMF concepts for resolving proxies! >- */ >- protected void resolveAllProxies() >- { >- // if (!allProxiesResolved) >- { >- CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); >- EClass eClass = revision.getEClass(); >- for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass)) >- { >- if (feature instanceof EReference) >- { >- 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") >- protected void resolveProxies(EStructuralFeature 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 = (InternalCDOObject)view.getObject(id); >- InternalEObject instance = resolved.cdoInternalInstance(); >- >- // TODO LEGACY >- // // 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 = (InternalCDOObject)view.getObject(id); >- InternalEObject instance = resolved.cdoInternalInstance(); >- setInstanceValue(instance, feature, instance); >- } >- } >- } >- } >- >- 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); //$NON-NLS-1$ >- if (TRACER.isEnabled()) >- { >- TRACER.format("Setting proxyURI {0} for {1}", uri, instance); //$NON-NLS-1$ >- } >- >- instance.eSetProxyURI(uri); >- } >- } >- else >- { >- if (instance.eIsProxy()) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Unsetting proxyURI for {0}", instance); //$NON-NLS-1$ >- } >- >- instance.eSetProxyURI(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); >- } >- } >- >- 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"); //$NON-NLS-1$ >- >- private static final Method eIsProxyMethod = ReflectUtil.getMethod(EObject.class, "eIsProxy"); //$NON-NLS-1$ >- >- private static final Method eProxyURIMethod = ReflectUtil.getMethod(InternalEObject.class, "eProxyURI"); //$NON-NLS-1$ >- >- 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()); >- } >- } >+ protected InternalCDORevision revision; >+ >+ /** >+ * @since 3.0 >+ * @description It could happen the while <i>revisionToInstance()</i> is >+ * executed externally the <i>internalPostLoad()</i> method will >+ * be called. This happens for example if >+ * <i>internalPostInvalidate()</i> is called. The leads to >+ * another <i>revisionToInstance()</i> call while the first call >+ * has not finished. This is certainly not so cool. That's why >+ * <b>underConstruction</b> will flag that >+ * <i>revisionToInstance()</i> is still running and avoid the >+ * second call. >+ */ >+ private boolean underConstruction = false; >+ >+ /** >+ * This local ThreadMap stores all pre-registered objects. This avoids a >+ * neverending loop when setting the container for the object >+ */ >+ private static ThreadLocal<Map<CDOID, EObject>> localThread = new InheritableThreadLocal<Map<CDOID, EObject>>() >+ { >+ @Override >+ protected synchronized Map<CDOID, EObject> initialValue() >+ { >+ return new HashMap<CDOID, EObject>(); >+ } >+ }; >+ >+ //TODO Martin: threadCount could be removed if clearing the ThreadMap is not necessary >+ private static Integer threadCount = 0; >+ >+ public CDOLegacyWrapper(InternalEObject instance) >+ { >+ this.instance = instance; >+ state = CDOState.TRANSIENT; >+ >+ } >+ >+ public CDOState cdoState() >+ { >+ return state; >+ } >+ >+ public InternalCDORevision cdoRevision() >+ { >+ return revision; >+ } >+ >+ 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); //$NON-NLS-1$ >+ } >+ >+ CDOState oldState = this.state; >+ this.state = state; >+ adjustEProxy(); >+ if (view != null) >+ { >+ view.handleObjectStateChanged(this, oldState, state); >+ } >+ >+ return oldState; >+ } >+ >+ return null; >+ } >+ >+ public void cdoInternalSetRevision(CDORevision revision) >+ { >+ >+ trace("Setting revision: " + revision + ""); >+ this.revision = (InternalCDORevision) revision; >+ } >+ >+ public void cdoInternalPostAttach() >+ { >+ instanceToRevision(); >+ >+ // 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(boolean remote) >+ { >+ >+ } >+ >+ public void cdoInternalPreCommit() >+ { >+ // instanceToRevision(); >+ // if (cdoState() == CDOState.DIRTY) // NEW is handled in PrepareTransition >+ // { >+ // CDORevisionManagerImpl revisionManager = (CDORevisionManagerImpl)cdoView().getSession().getRevisionManager(); >+ // 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 cdoInternalPreLoad() >+ { >+ >+ } >+ >+ public void cdoInternalPostLoad() >+ { >+ >+ // TODO Consider not remembering the revisin after copying it to the instance (spare 1/2 of the space) >+ revisionToInstance(); >+ >+ } >+ >+ public void cdoInternalPostInvalidate() >+ { >+ >+ InternalCDORevision revision = cdoView().getRevision(cdoID(), true); >+ cdoInternalSetRevision(revision); >+ revisionToInstance(); >+ cdoInternalSetState(CDOState.CLEAN); >+ >+ } >+ >+ public void cdoInternalCleanup() >+ { >+ >+ } >+ >+ @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 + "]"; >+ } >+ >+ protected 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(); >+ EClass eClass = revision.getEClass(); >+ for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass)) >+ { >+ instanceToRevisionFeature(feature, packageRegistry); >+ } >+ } >+ >+ protected 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)); >+ } >+ } >+ >+ protected void instanceToRevisionFeature(EStructuralFeature feature, CDOPackageRegistry packageRegistry) >+ { >+ >+ Object instanceValue = getInstanceValue(instance, feature, packageRegistry); >+ CDOObjectImpl.instanceToRevisionFeature(view, this, feature, instanceValue); >+ } >+ >+ /** >+ * TODO Simon: Fix this whole mess ;-) >+ */ >+ protected void revisionToInstance() >+ { >+ >+ if (isUnderConstruction()) //return if revisionToInstance was called befor to avoid doubled calls >+ { >+ return; >+ } >+ setUnderConstruction(true); >+ >+ 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 >+ >+ preRegisterObject(this); >+ incrementThreadCount(); >+ >+ trace("Thread " + localThread + " MAP: (" + instance + ") {" + getPreRegisteredObjects() + "}"); >+ revisionToInstanceContainment(); >+ >+ // Handle values >+ //CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); >+ EClass eClass = revision.getEClass(); >+ for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass)) >+ { >+ revisionToInstanceFeature(feature); >+ } >+ } >+ catch (Exception e) >+ { >+ e.printStackTrace(); >+ } >+ finally >+ { >+ if (deliver) >+ { >+ instance.eSetDeliver(true); >+ } >+ decrementThreadCount(); >+ if (getPreRegisteredObjects() != null) >+ { >+ if (getThreadCount() == 0) >+ { >+ >+ //localThread.remove(); // TODO Martin: check why new objects will be created if this list is cleared >+ >+ } >+ } >+ setUnderConstruction(false); >+ } >+ >+ } >+ >+ private void decrementThreadCount() >+ { >+ threadCount--; >+ } >+ >+ private void incrementThreadCount() >+ { >+ threadCount++; >+ } >+ >+ private Integer getThreadCount() >+ { >+ return threadCount; >+ } >+ >+ /** >+ * adds an object to the pre-registered objects list which hold all created >+ * objects even if they are not registered in the view >+ */ >+ private void preRegisterObject(CDOLegacyWrapper wrapper) >+ { >+ getPreRegisteredObjects().put(wrapper.cdoID(), wrapper); >+ } >+ >+ /** >+ * >+ * >+ */ >+ protected void revisionToInstanceContainment() >+ { >+ >+ CDOID resourceID = revision.getResourceID(); >+ InternalEObject resource = getEObjectFromPotentialID(view, null, resourceID); >+ setInstanceResource((Resource.Internal) resource); >+ >+ Object containerID = revision.getContainerID(); >+ InternalEObject container; >+ >+ container = getEObjectFromPotentialID(view, null, containerID); >+ >+ setInstanceContainer(container, revision.getContainingFeatureID()); >+ >+ } >+ >+ private Map<CDOID, EObject> getPreRegisteredObjects() >+ { >+ return localThread.get(); >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ protected void revisionToInstanceFeature(EStructuralFeature feature) >+ { >+ >+ if (feature.isMany()) >+ { >+ int size = view.getStore().size(instance, feature); >+ >+ if (!state.equals(CDOState.CONFLICT)) //do not do anything with the list if state is conflict >+ { >+ InternalEList list = (InternalEList) instance.eGet(feature); >+ EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal) feature; >+ //EReference oppositeReference = cdoID().isTemporary() ? null : internalFeature.getEOpposite(); >+ >+ clearList(feature, list); >+ >+ for (int index = 0; index < size; index++) >+ { >+ >+ Object object = getValueFromFeature(feature, index); >+ try >+ { >+ trace("Adding " + object + " to feature " + feature + "in instance " + instance); >+ instance.eInverseAdd((InternalEObject) object, feature.getFeatureID(), object.getClass(), null); >+ >+ } >+ //catch (ArrayIndexOutOfBoundsException e) //TODO: Martin fallback if eInverseAdd is not implemented (felegated to eDynmic... and resulted in an execption). maybe basicadd is enough >+ catch (Exception e) >+ { >+ trace("Error: " + e.getMessage()); >+ >+ list.basicAdd(object, null);//this seems to be wrong >+ >+ } >+ } >+ } >+ >+ } >+ else >+ { >+ Object object = getValueFromFeature(feature, 0); >+ if (feature instanceof EAttribute) >+ { >+ >+ trace("Setting attribute value " + object + " to feature " + feature + " in instance " + instance); >+ eSet(feature, object); >+ } >+ else >+ { >+ >+ if (instance != null) >+ { >+ if (object != null) >+ { >+ try >+ { >+ trace("Adding object " + object + " to feature " + feature + " in instance " + instance); >+ instance.eInverseAdd((InternalEObject) object, feature.getFeatureID(), ((EObject) object).getClass(), null); >+ trace("Added object " + object + " to feature " + feature + " in instance " + instance); >+ } >+ catch (Exception e) >+ { >+ //e.printStackTrace(); >+ //TODO Martin: Should handle this exception more carefully >+ trace("Error: " + e.getMessage() + " trying to use eSet"); >+ >+ instance.eSet(feature.getFeatureID(), object); >+ >+ } >+ >+ //TODO Martin: check if adjusting the opposite is needed here >+ // EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal) feature; >+ // EReference oppositeReference = cdoID().isTemporary() ? null : internalFeature.getEOpposite(); >+ // if (oppositeReference != null && object != null) >+ // { >+ // adjustOppositeReference(instance, (InternalEObject) object, oppositeReference); >+ // } >+ } >+ else >+ { >+ try >+ { >+ trace("Setting feature " + feature + " to null in instance " + instance); >+ instance.eInverseAdd((InternalEObject) object, feature.getFeatureID(), null, null); >+ } >+ catch (Exception e) >+ { >+ //e.printStackTrace(); >+ //TODO Martin: Should handle this exception more carefully >+ instance.eSet(feature.getFeatureID(), null); >+ trace(e.getMessage()); >+ } >+ } >+ } >+ } >+ } >+ } >+ >+ private void clearList(EStructuralFeature feature, InternalEList list) >+ { >+ >+ //attempt 2 >+ int size = list.size(); >+ for (int i = 0; i < size; i++) >+ { >+ InternalEObject obj = (InternalEObject) list.get(0); >+ instance.eInverseRemove(obj, feature.getFeatureID(), obj.getClass(), null); >+ >+ } >+ } >+ >+ /** >+ * This method retrieves the value from the feature at the given index. It >+ * retrieves the value either from the views's store or the internal >+ * pre-registration Map. >+ * >+ * @param feature the feature to retireive the value from >+ * @param index the given index of the object in the feature >+ * @return the value from the feature at the given index >+ */ >+ private Object getValueFromFeature(EStructuralFeature feature, int index) >+ { >+ >+ Object object = null; >+ >+ object = revision.get(feature, index); >+ >+ if (object == null) >+ { >+ return null; //TODO Martin: chekc if this is correct >+ } >+ >+ CDOType type = CDOModelUtil.getType(feature.getEType()); >+ if (type != null) >+ { >+ object = type.convertToEMF(feature.getEType(), object); >+ if (object instanceof CDOID) >+ { >+ if (getPreRegisteredObjects().get(object) != null) >+ { >+ object = ((CDOLegacyWrapper) getPreRegisteredObjects().get(object)).instance;//getEObjectFromPotentialID(view, feature, object); >+ } >+ else >+ //if Object not preregistered get the object from the view which creates it or returns a still registered object >+ { >+ >+ object = view.getStore().get(instance, feature, index); >+ if (object != null) >+ { >+ CDOLegacyWrapper wrapper = FSMUtil.getLegacyAdapter(((EObject) object).eAdapters()); >+ if (wrapper == null) >+ { >+ wrapper = (CDOLegacyWrapper) FSMUtil.adaptLegacy((InternalEObject) object); >+ } >+ preRegisterObject(wrapper); >+ // getPreRegisteredObjects().put(wrapper.cdoID(), wrapper); >+ } >+ >+ } >+ } >+ } >+ >+ return object; >+ } >+ >+ private void adjustOppositeReference(InternalEObject instance, InternalEObject object, EReference oppositeReference) >+ { >+ >+ trace("Setting opposite: " + object + " in Feature " + oppositeReference + " in instance " + instance + ""); >+ boolean deliver = object.eDeliver(); //disable notifications >+ if (deliver) >+ { >+ object.eSetDeliver(false); >+ } >+ try >+ { >+ if (oppositeReference.isMany()) >+ { >+ >+ //TODO Martin: ist this correct? Should I adjust opposite here? >+ //((InternalEList<Object>) object.eGet(oppositeReference)).basicAdd(instance, null); >+ } >+ else >+ { >+ >+ //TODO Martin: this only increases performance if getter is cheaper than setter. Should discuss this. >+ if (object.eGet(oppositeReference) != instance) >+ { >+ >+ object.eInverseAdd(instance, oppositeReference.getFeatureID(), ((EObject) instance).getClass(), null); >+ } >+ } >+ } >+ finally >+ { >+ if (deliver) >+ { >+ object.eSetDeliver(true); >+ } >+ } >+ >+ } >+ >+ //TODO Martin: remove this uncommented block if sure that it is not needed anymore >+ // private void convertAndSetList(EStructuralFeature feature, int size) >+ // { >+ // >+ // EStructuralFeature.Internal internalFeature = (EStructuralFeature.Internal) feature; >+ // EReference oppositeReference = cdoID().isTemporary() ? null : internalFeature.getEOpposite(); >+ // >+ // >+ // List<Object> tmp = new ArrayList<Object>(); >+ // for (int index = 0; index < size; index++) >+ // { >+ // //Object object = view.getStore().get(instance, feature, index); >+ // Object object = getValueFromFeature(feature, index); >+ // tmp.add(object); >+ // >+ // >+ // // if (oppositeReference != null) >+ // // { >+ // // adjustOppositeReference(instance, (InternalEObject) object, oppositeReference); >+ // // } >+ // } >+ // InternalEList list = (InternalEList) instance.eGet(feature); >+ // internalSynchronizeLists(tmp, list, feature.getFeatureID(), oppositeReference); >+ // >+ // } >+ // >+ // private void internalSynchronizeLists(List<Object> tmp, InternalEList list, int featureId, EReference oppositeReference) >+ // { >+ // //remove >+ // for (Object obj : list) >+ // { >+ // >+ // if (!tmp.contains(obj))//remove if removed from list >+ // { >+ // >+ // list.basicRemove(obj, null); >+ // adjustOppositeReference(instance, (InternalEObject) obj, oppositeReference); >+ // >+ // //((BasicEObjectImpl) instance).eInverseRemove((InternalEObject) obj, featureId, null); >+ // //((InternalEObject) obj).eBasicRemoveFromContainer(null); >+ // // NotificationChain eInverseRemove = ((InternalEObject) obj).eInverseRemove(instance, featureId, instance.getClass(), null); >+ // // NotificationChain basicRemove = list.basicRemove(obj, eInverseRemove); >+ // // basicRemove.dispatch(); >+ // //((InternalEObject) obj).eInternalContainer() >+ // >+ // //((InternalEObject) obj).eContainer().notify(); >+ // // Method method = ReflectUtil.getMethod(obj.getClass(), "eBasicRemoveFromContainer", InternalEObject.class, int.class); //$NON-NLS-1$ >+ // // ReflectUtil.invokeMethod(method, obj); >+ // >+ // >+ // } >+ // } >+ // >+ // for (Object obj : tmp) >+ // { >+ // if (!list.basicContains(obj))//remove if removed from list >+ // { >+ // >+ // list.basicAdd(obj, null); >+ // if (oppositeReference != null) >+ // { >+ // adjustOppositeReference(instance, (InternalEObject) obj, oppositeReference); >+ // } >+ // >+ // //instance.eInverseAdd((InternalEObject) obj, featureId, ((EObject) obj).getClass(), null); >+ // //((EObjectImpl) instance).eInverseAdd((InternalEObject) obj, featureId, null); >+ // //((InternalEObject) obj).eBasicSetContainer(instance, ((InternalEObject) obj).eContainerFeatureID(), null); >+ // >+ // //list.add(obj); >+ // } >+ // } >+ // } >+ >+ protected Resource.Internal getInstanceResource(InternalEObject instance) >+ { >+ return instance.eDirectResource(); >+ } >+ >+ protected InternalEObject getInstanceContainer(InternalEObject instance) >+ { >+ return instance.eInternalContainer(); >+ } >+ >+ protected int getInstanceContainerFeatureID(InternalEObject instance) >+ { >+ return instance.eContainerFeatureID(); >+ } >+ >+ protected Object getInstanceValue(InternalEObject instance, EStructuralFeature feature, CDOPackageRegistry packageRegistry) >+ { >+ return instance.eGet(feature); >+ } >+ >+ protected void setInstanceResource(Resource.Internal resource) >+ { >+ Method method = ReflectUtil.getMethod(instance.getClass(), "eSetDirectResource", Resource.Internal.class); //$NON-NLS-1$ >+ ReflectUtil.invokeMethod(method, instance, resource); >+ } >+ >+ protected void setInstanceContainer(InternalEObject container, int containerFeatureID) >+ { >+ Method method = ReflectUtil.getMethod(instance.getClass(), "eBasicSetContainer", InternalEObject.class, int.class); //$NON-NLS-1$ >+ ReflectUtil.invokeMethod(method, instance, container, containerFeatureID); >+ } >+ >+ protected void setInstanceValue(InternalEObject instance, EStructuralFeature feature, Object value) >+ { >+ instance.eSet(feature, 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! >+ */ >+ protected InternalEObject getEObjectFromPotentialID(InternalCDOView view, EStructuralFeature feature, Object potentialID) >+ { >+ >+ if (getPreRegisteredObjects().get(potentialID) != null) >+ { >+ >+ potentialID = ((CDOLegacyWrapper) getPreRegisteredObjects().get(potentialID)).instance; >+ >+ trace("getting Object (" + potentialID + ") from localThread instead of the view"); >+ >+ } >+ else >+ { >+ >+ 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) >+ */ >+ protected InternalEObject createProxy(InternalCDOView view, EStructuralFeature feature, CDOID id) >+ { >+ EClassifier eType = feature.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 Ed: Fix whole mess ;-) >+ */ >+ protected void clearEList(InternalEList<Object> list) >+ { >+ while (!list.isEmpty()) >+ { >+ Object toBeRemoved = list.basicGet(0); >+ list.basicRemove(toBeRemoved, null); >+ } >+ } >+ >+ /** >+ * TODO Consider using only EMF concepts for resolving proxies! >+ */ >+ protected void resolveAllProxies() >+ { >+ // if (!allProxiesResolved) >+ { >+ CDOPackageRegistry packageRegistry = cdoView().getSession().getPackageRegistry(); >+ EClass eClass = revision.getEClass(); >+ for (EStructuralFeature feature : CDOModelUtil.getAllPersistentFeatures(eClass)) >+ { >+ if (feature instanceof EReference) >+ { >+ 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") >+ protected void resolveProxies(EStructuralFeature 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 = (InternalCDOObject) view.getObject(id); >+ InternalEObject instance = resolved.cdoInternalInstance(); >+ >+ // TODO LEGACY >+ // // 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 = (InternalCDOObject) view.getObject(id); >+ InternalEObject instance = resolved.cdoInternalInstance(); >+ setInstanceValue(instance, feature, instance); >+ } >+ } >+ } >+ } >+ >+ 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); //$NON-NLS-1$ >+ 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 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()); >+ } >+ } >+ >+ private void trace(String trace) >+ { >+ >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format(trace); >+ } >+ //System.out.println(trace); >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public synchronized void setUnderConstruction(boolean underConstruction) >+ { >+ this.underConstruction = underConstruction; >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public boolean isUnderConstruction() >+ { >+ return underConstruction; >+ } > } >Index: src/org/eclipse/emf/internal/cdo/CDOObjectWrapper.java >=================================================================== >RCS file: /cvsroot/modeling/org.eclipse.emf/org.eclipse.emf.cdo/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectWrapper.java,v >retrieving revision 1.17 >diff -u -r1.17 CDOObjectWrapper.java >--- src/org/eclipse/emf/internal/cdo/CDOObjectWrapper.java 23 Sep 2009 17:19:29 -0000 1.17 >+++ src/org/eclipse/emf/internal/cdo/CDOObjectWrapper.java 31 Oct 2009 18:59:33 -0000 >@@ -42,349 +42,346 @@ > */ > public abstract class CDOObjectWrapper implements InternalCDOObject > { >- private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectWrapper.class); >+ private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_OBJECT, CDOObjectWrapper.class); > >- protected CDOID id; >+ protected CDOID id; > >- protected InternalCDOView view; >+ protected InternalCDOView view; > >- protected InternalEObject instance; >+ protected InternalEObject instance; > >- public CDOObjectWrapper() >- { >- } >- >- public CDOID cdoID() >- { >- return id; >- } >- >- public InternalCDOView cdoView() >- { >- return view; >- } >- >- public CDOResourceImpl cdoResource() >- { >- Resource resource = eResource(); >- if (resource instanceof CDOResourceImpl) >- { >- return (CDOResourceImpl)resource; >- } >- >- return null; >- } >- >- /** >- * @since 2.0 >- */ >- public CDOResourceImpl cdoDirectResource() >- { >- Resource.Internal resource = eDirectResource(); >- if (resource instanceof CDOResourceImpl) >- { >- return (CDOResourceImpl)resource; >- } >- >- return null; >- } >- >- public void cdoInternalSetID(CDOID id) >- { >- if (id == null) >- { >- throw new IllegalArgumentException("id == null"); //$NON-NLS-1$ >- } >- >- if (TRACER.isEnabled()) >- { >- TRACER.format("Setting ID: {0} for {1}", id, instance); //$NON-NLS-1$ >- } >- >- this.id = id; >- } >- >- public void cdoInternalSetView(CDOView view) >- { >- if (TRACER.isEnabled()) >- { >- TRACER.format("Setting view: {0} for {1}", view, instance); //$NON-NLS-1$ >- } >- >- this.view = (InternalCDOView)view; >- } >- >- public InternalEObject cdoInternalInstance() >- { >- return instance; >- } >- >- /** >- * @since 2.0 >- */ >- public boolean cdoConflict() >- { >- return FSMUtil.isConflict(this); >- } >- >- /** >- * @since 2.0 >- */ >- public boolean cdoInvalid() >- { >- return FSMUtil.isInvalid(this); >- } >- >- /** >- * @since 3.0 >- */ >- public void cdoPrefetch(int depth) >- { >- view.prefetchRevisions(id, depth); >- } >- >- public EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID) >- { >- // TODO Implement method CDOWrapperImpl.cdoInternalDynamicFeature() >- throw new UnsupportedOperationException("Not yet implemented"); //$NON-NLS-1$ >- } >- >- /** >- * @since 2.0 >- */ >- public CDOLock cdoReadLock() >- { >- throw new UnsupportedOperationException(); >- } >- >- /** >- * @since 2.0 >- */ >- public CDOLock cdoWriteLock() >- { >- throw new UnsupportedOperationException(); >- } >- >- public EList<Adapter> eAdapters() >- { >- return instance.eAdapters(); >- } >- >- public TreeIterator<EObject> eAllContents() >- { >- return instance.eAllContents(); >- } >- >- public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) >- { >- return instance.eBaseStructuralFeatureID(derivedFeatureID, baseClass); >- } >- >- public NotificationChain eBasicRemoveFromContainer(NotificationChain notifications) >- { >- return instance.eBasicRemoveFromContainer(notifications); >- } >- >- public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID, >- NotificationChain notifications) >- { >- return instance.eBasicSetContainer(newContainer, newContainerFeatureID, notifications); >- } >- >- public EClass eClass() >- { >- return instance.eClass(); >- } >- >- public EObject eContainer() >- { >- return instance.eContainer(); >- } >- >- public int eContainerFeatureID() >- { >- return instance.eContainerFeatureID(); >- } >- >- public EStructuralFeature eContainingFeature() >- { >- return instance.eContainingFeature(); >- } >- >- public EReference eContainmentFeature() >- { >- return instance.eContainmentFeature(); >- } >- >- public EList<EObject> eContents() >- { >- return instance.eContents(); >- } >- >- public EList<EObject> eCrossReferences() >- { >- return instance.eCrossReferences(); >- } >- >- public boolean eDeliver() >- { >- return instance.eDeliver(); >- } >- >- public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) >- { >- return instance.eDerivedStructuralFeatureID(baseFeatureID, baseClass); >- } >- >- public Resource.Internal eDirectResource() >- { >- return instance.eDirectResource(); >- } >- >- public Object eGet(EStructuralFeature feature, boolean resolve, boolean coreType) >- { >- return instance.eGet(feature, resolve, coreType); >- } >- >- public Object eGet(EStructuralFeature feature, boolean resolve) >- { >- return instance.eGet(feature, resolve); >- } >- >- public Object eGet(EStructuralFeature feature) >- { >- return instance.eGet(feature); >- } >- >- public Object eGet(int featureID, boolean resolve, boolean coreType) >- { >- return instance.eGet(featureID, resolve, coreType); >- } >- >- public InternalEObject eInternalContainer() >- { >- return instance.eInternalContainer(); >- } >- >- public Resource.Internal eInternalResource() >- { >- return instance.eInternalResource(); >- } >- >- public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class<?> baseClass, >- NotificationChain notifications) >- { >- return instance.eInverseAdd(otherEnd, featureID, baseClass, notifications); >- } >- >- public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class<?> baseClass, >- NotificationChain notifications) >- { >- return instance.eInverseRemove(otherEnd, featureID, baseClass, notifications); >- } >- >- public boolean eIsProxy() >- { >- return instance.eIsProxy(); >- } >- >- public boolean eIsSet(EStructuralFeature feature) >- { >- return instance.eIsSet(feature); >- } >- >- public boolean eIsSet(int featureID) >- { >- return instance.eIsSet(featureID); >- } >- >- public boolean eNotificationRequired() >- { >- return instance.eNotificationRequired(); >- } >- >- public void eNotify(Notification notification) >- { >- instance.eNotify(notification); >- } >- >- public EObject eObjectForURIFragmentSegment(String uriFragmentSegment) >- { >- return instance.eObjectForURIFragmentSegment(uriFragmentSegment); >- } >- >- public URI eProxyURI() >- { >- return instance.eProxyURI(); >- } >- >- public EObject eResolveProxy(InternalEObject proxy) >- { >- return instance.eResolveProxy(proxy); >- } >- >- public Resource eResource() >- { >- return instance.eResource(); >- } >- >- public void eSet(EStructuralFeature feature, Object newValue) >- { >- instance.eSet(feature, newValue); >- } >- >- public void eSet(int featureID, Object newValue) >- { >- instance.eSet(featureID, newValue); >- } >- >- public void eSetClass(EClass class1) >- { >- instance.eSetClass(class1); >- } >- >- public void eSetDeliver(boolean deliver) >- { >- instance.eSetDeliver(deliver); >- } >- >- public void eSetProxyURI(URI uri) >- { >- instance.eSetProxyURI(uri); >- } >- >- public NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications) >- { >- return instance.eSetResource(resource, notifications); >- } >- >- public void eSetStore(EStore store) >- { >- instance.eSetStore(store); >- } >- >- public Setting eSetting(EStructuralFeature feature) >- { >- return instance.eSetting(feature); >- } >- >- public EStore eStore() >- { >- return instance.eStore(); >- } >- >- public void eUnset(EStructuralFeature feature) >- { >- instance.eUnset(feature); >- } >- >- public void eUnset(int featureID) >- { >- instance.eUnset(featureID); >- } >- >- public String eURIFragmentSegment(EStructuralFeature feature, EObject object) >- { >- return instance.eURIFragmentSegment(feature, object); >- } >+ public CDOObjectWrapper() >+ { >+ } >+ >+ public CDOID cdoID() >+ { >+ return id; >+ } >+ >+ public InternalCDOView cdoView() >+ { >+ return view; >+ } >+ >+ public CDOResourceImpl cdoResource() >+ { >+ Resource resource = eResource(); >+ if (resource instanceof CDOResourceImpl) >+ { >+ return (CDOResourceImpl) resource; >+ } >+ >+ return null; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOResourceImpl cdoDirectResource() >+ { >+ Resource.Internal resource = eDirectResource(); >+ if (resource instanceof CDOResourceImpl) >+ { >+ return (CDOResourceImpl) resource; >+ } >+ >+ return null; >+ } >+ >+ public void cdoInternalSetID(CDOID id) >+ { >+ if (id == null) >+ { >+ //throw new IllegalArgumentException("id == null"); //$NON-NLS-1$ >+ } >+ >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Setting ID: {0} for {1}", id, instance); //$NON-NLS-1$ >+ } >+ >+ this.id = id; >+ } >+ >+ public void cdoInternalSetView(CDOView view) >+ { >+ if (TRACER.isEnabled()) >+ { >+ TRACER.format("Setting view: {0} for {1}", view, instance); //$NON-NLS-1$ >+ } >+ >+ this.view = (InternalCDOView) view; >+ } >+ >+ public InternalEObject cdoInternalInstance() >+ { >+ return instance; >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public boolean cdoConflict() >+ { >+ return FSMUtil.isConflict(this); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public boolean cdoInvalid() >+ { >+ return FSMUtil.isInvalid(this); >+ } >+ >+ /** >+ * @since 3.0 >+ */ >+ public void cdoPrefetch(int depth) >+ { >+ view.prefetchRevisions(id, depth); >+ } >+ >+ public EStructuralFeature cdoInternalDynamicFeature(int dynamicFeatureID) >+ { >+ // TODO Implement method CDOWrapperImpl.cdoInternalDynamicFeature() >+ throw new UnsupportedOperationException("Not yet implemented"); //$NON-NLS-1$ >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOLock cdoReadLock() >+ { >+ throw new UnsupportedOperationException(); >+ } >+ >+ /** >+ * @since 2.0 >+ */ >+ public CDOLock cdoWriteLock() >+ { >+ throw new UnsupportedOperationException(); >+ } >+ >+ public EList<Adapter> eAdapters() >+ { >+ return instance.eAdapters(); >+ } >+ >+ public TreeIterator<EObject> eAllContents() >+ { >+ return instance.eAllContents(); >+ } >+ >+ public int eBaseStructuralFeatureID(int derivedFeatureID, Class<?> baseClass) >+ { >+ return instance.eBaseStructuralFeatureID(derivedFeatureID, baseClass); >+ } >+ >+ public NotificationChain eBasicRemoveFromContainer(NotificationChain notifications) >+ { >+ return instance.eBasicRemoveFromContainer(notifications); >+ } >+ >+ public NotificationChain eBasicSetContainer(InternalEObject newContainer, int newContainerFeatureID, NotificationChain notifications) >+ { >+ return instance.eBasicSetContainer(newContainer, newContainerFeatureID, notifications); >+ } >+ >+ public EClass eClass() >+ { >+ return instance.eClass(); >+ } >+ >+ public EObject eContainer() >+ { >+ return instance.eContainer(); >+ } >+ >+ public int eContainerFeatureID() >+ { >+ return instance.eContainerFeatureID(); >+ } >+ >+ public EStructuralFeature eContainingFeature() >+ { >+ return instance.eContainingFeature(); >+ } >+ >+ public EReference eContainmentFeature() >+ { >+ return instance.eContainmentFeature(); >+ } >+ >+ public EList<EObject> eContents() >+ { >+ return instance.eContents(); >+ } >+ >+ public EList<EObject> eCrossReferences() >+ { >+ return instance.eCrossReferences(); >+ } >+ >+ public boolean eDeliver() >+ { >+ return instance.eDeliver(); >+ } >+ >+ public int eDerivedStructuralFeatureID(int baseFeatureID, Class<?> baseClass) >+ { >+ return instance.eDerivedStructuralFeatureID(baseFeatureID, baseClass); >+ } >+ >+ public Resource.Internal eDirectResource() >+ { >+ return instance.eDirectResource(); >+ } >+ >+ public Object eGet(EStructuralFeature feature, boolean resolve, boolean coreType) >+ { >+ return instance.eGet(feature, resolve, coreType); >+ } >+ >+ public Object eGet(EStructuralFeature feature, boolean resolve) >+ { >+ return instance.eGet(feature, resolve); >+ } >+ >+ public Object eGet(EStructuralFeature feature) >+ { >+ return instance.eGet(feature); >+ } >+ >+ public Object eGet(int featureID, boolean resolve, boolean coreType) >+ { >+ return instance.eGet(featureID, resolve, coreType); >+ } >+ >+ public InternalEObject eInternalContainer() >+ { >+ return instance.eInternalContainer(); >+ } >+ >+ public Resource.Internal eInternalResource() >+ { >+ return instance.eInternalResource(); >+ } >+ >+ public NotificationChain eInverseAdd(InternalEObject otherEnd, int featureID, Class<?> baseClass, NotificationChain notifications) >+ { >+ return instance.eInverseAdd(otherEnd, featureID, baseClass, notifications); >+ } >+ >+ public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, Class<?> baseClass, NotificationChain notifications) >+ { >+ return instance.eInverseRemove(otherEnd, featureID, baseClass, notifications); >+ } >+ >+ public boolean eIsProxy() >+ { >+ return instance.eIsProxy(); >+ } >+ >+ public boolean eIsSet(EStructuralFeature feature) >+ { >+ return instance.eIsSet(feature); >+ } >+ >+ public boolean eIsSet(int featureID) >+ { >+ return instance.eIsSet(featureID); >+ } >+ >+ public boolean eNotificationRequired() >+ { >+ return instance.eNotificationRequired(); >+ } >+ >+ public void eNotify(Notification notification) >+ { >+ instance.eNotify(notification); >+ } >+ >+ public EObject eObjectForURIFragmentSegment(String uriFragmentSegment) >+ { >+ return instance.eObjectForURIFragmentSegment(uriFragmentSegment); >+ } >+ >+ public URI eProxyURI() >+ { >+ return instance.eProxyURI(); >+ } >+ >+ public EObject eResolveProxy(InternalEObject proxy) >+ { >+ return instance.eResolveProxy(proxy); >+ } >+ >+ public Resource eResource() >+ { >+ return instance.eResource(); >+ } >+ >+ public void eSet(EStructuralFeature feature, Object newValue) >+ { >+ instance.eSet(feature, newValue); >+ } >+ >+ public void eSet(int featureID, Object newValue) >+ { >+ instance.eSet(featureID, newValue); >+ } >+ >+ public void eSetClass(EClass class1) >+ { >+ instance.eSetClass(class1); >+ } >+ >+ public void eSetDeliver(boolean deliver) >+ { >+ instance.eSetDeliver(deliver); >+ } >+ >+ public void eSetProxyURI(URI uri) >+ { >+ instance.eSetProxyURI(uri); >+ } >+ >+ public NotificationChain eSetResource(Resource.Internal resource, NotificationChain notifications) >+ { >+ return instance.eSetResource(resource, notifications); >+ } >+ >+ public void eSetStore(EStore store) >+ { >+ instance.eSetStore(store); >+ } >+ >+ public Setting eSetting(EStructuralFeature feature) >+ { >+ return instance.eSetting(feature); >+ } >+ >+ public EStore eStore() >+ { >+ return instance.eStore(); >+ } >+ >+ public void eUnset(EStructuralFeature feature) >+ { >+ instance.eUnset(feature); >+ } >+ >+ public void eUnset(int featureID) >+ { >+ instance.eUnset(featureID); >+ } >+ >+ public String eURIFragmentSegment(EStructuralFeature feature, EObject object) >+ { >+ return instance.eURIFragmentSegment(feature, object); >+ } > }
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 247226
:
112514
|
112894
|
134866
|
151009
|
151634
|
151651
|
152232
|
153867
|
153868
|
155030
|
155031
|
155181
|
155182
|
155400
|
163497
|
163499