diff options
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOResourceNodeStore.java')
-rw-r--r-- | plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOResourceNodeStore.java | 179 |
1 files changed, 154 insertions, 25 deletions
diff --git a/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOResourceNodeStore.java b/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOResourceNodeStore.java index 61dd38469f..51a65056f8 100644 --- a/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOResourceNodeStore.java +++ b/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOResourceNodeStore.java @@ -10,15 +10,30 @@ */ package org.eclipse.emf.cdo.workspace.internal.efs; +import org.eclipse.emf.cdo.common.id.CDOID; +import org.eclipse.emf.cdo.common.id.CDOIDUtil; +import org.eclipse.emf.cdo.common.model.CDOClassInfo; import org.eclipse.emf.cdo.eresource.CDOResource; import org.eclipse.emf.cdo.eresource.CDOResourceFolder; import org.eclipse.emf.cdo.eresource.CDOResourceNode; import org.eclipse.emf.cdo.transaction.CDOTransaction; +import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.view.CDOView; +import org.eclipse.emf.cdo.workspace.internal.efs.CDOWorkspaceStore.SaveContext; import org.eclipse.emf.cdo.workspace.internal.efs.bundle.OM; import org.eclipse.net4j.util.WrappedException; +import org.eclipse.emf.common.util.EList; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.EReference; +import org.eclipse.emf.ecore.EStructuralFeature; +import org.eclipse.emf.ecore.InternalEObject; +import org.eclipse.emf.ecore.util.EcoreUtil; +import org.eclipse.emf.ecore.xmi.XMIResource; +import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl; +import org.eclipse.emf.spi.cdo.InternalCDOObject; + import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -27,6 +42,7 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.OutputStream; import java.util.List; /** @@ -95,31 +111,144 @@ public final class CDOResourceNodeStore extends AbstractResourceNodeStore }.run(); } - // @Override - // public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException - // { - // return new ResourceNodeRunnable<OutputStream>() - // { - // @Override - // protected OutputStream run(CDOResourceNode node) - // { - // ByteArrayOutputStream baos = new ByteArrayOutputStream(); - // CDOResource resource = (CDOResource)node; - // - // try - // { - // resource.save(baos, null); - // } - // catch (Exception ex) - // { - // OM.LOG.error(ex); - // throw WrappedException.wrap(ex); - // } - // - // return new ByteArrayInputStream(baos.toByteArray()); - // } - // }.run(); - // } + @Override + public OutputStream openOutputStream(int options, IProgressMonitor monitor) throws CoreException + { + return new ByteArrayOutputStream() + { + @Override + public void close() throws IOException + { + byte[] bytes = toByteArray(); + InputStream in = new ByteArrayInputStream(bytes); + + XMIResource xmiResource = new XMIResourceImpl(); + xmiResource.load(in, null); + + EList<EObject> contents = xmiResource.getContents(); + SaveContext saveContext = getWorkspaceStore().getSaveContext(); + handleSavedObjects(contents, xmiResource, saveContext); + + saveContext.save(); + } + }; + } + + protected void handleSavedObjects(EList<EObject> contents, XMIResource xmiResource, SaveContext saveContext) + { + for (EObject eObject : contents) + { + handleSavedObject((InternalEObject)eObject, xmiResource, saveContext); + handleSavedObjects(eObject.eContents(), xmiResource, saveContext); + } + } + + protected void handleSavedObject(InternalEObject eObject, XMIResource xmiResource, SaveContext saveContext) + { + InternalCDOObject cdoObject = getCDOObject(eObject, xmiResource, saveContext, true); + + CDOClassInfo classInfo = cdoObject.cdoRevision().getClassInfo(); + for (EStructuralFeature feature : classInfo.getAllPersistentFeatures()) + { + boolean reference = feature instanceof EReference; + Object value = eObject.eGet(feature); + if (feature.isMany()) + { + @SuppressWarnings("unchecked") + List<Object> source = (List<Object>)value; + + @SuppressWarnings("unchecked") + List<Object> target = (List<Object>)cdoObject.eGet(feature); + target.clear(); + + for (Object element : source) + { + if (reference) + { + element = getCDOObject((InternalEObject)element, xmiResource, saveContext, false); + } + + target.add(element); + } + } + else + { + if (reference) + { + value = getCDOObject((InternalEObject)value, xmiResource, saveContext, false); + } + + cdoObject.eSet(feature, value); + } + } + } + + private InternalCDOObject getCDOObject(InternalEObject eObject, XMIResource xmiResource, SaveContext saveContext, + boolean createOnDemand) + { + if (eObject == null) + { + return null; + } + + String fragment = xmiResource.getID(eObject); + InternalCDOObject cdoObject = null; + + try + { + CDOID id = CDOIDUtil.read(fragment); + cdoObject = (InternalCDOObject)saveContext.getTransaction().getObject(id); + } + catch (Exception ex) + { + //$FALL-THROUGH$ + } + + if (cdoObject == null) + { + cdoObject = saveContext.getNewObject(fragment); + } + + if (cdoObject == null) + { + if (createOnDemand) + { + EObject eContainer = eObject.eContainer(); + if (eContainer == null) + { + // TODO: implement CDOResourceNodeStore.getCDOObject(eObject, xmiResource, saveContext, createOnDemand) + throw new UnsupportedOperationException(); + } + + InternalCDOObject cdoContainer = getCDOObject((InternalEObject)eContainer, xmiResource, saveContext, false); + EObject newInstance = EcoreUtil.create(eObject.eClass()); + + EReference containmentFeature = eObject.eContainmentFeature(); + if (containmentFeature.isMany()) + { + @SuppressWarnings("unchecked") + List<Object> list = (List<Object>)cdoContainer.eGet(containmentFeature); + list.add(newInstance); + } + else + { + cdoContainer.eSet(containmentFeature, newInstance); + } + + cdoObject = (InternalCDOObject)CDOUtil.getCDOObject(newInstance); + saveContext.registerNewObject(fragment, cdoObject); + } + else + { + // saveContext.registerForwardReference(fragment, cdoObject); + + // TODO: implement CDOResourceNodeStore.getCDOObject(eObject, xmiResource, saveContext, createOnDemand) + throw new UnsupportedOperationException(); + } + } + + return cdoObject; + } @Override public void delete(int options, IProgressMonitor monitor) throws CoreException |