Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2010-10-24 14:40:18 -0400
committerEike Stepper2010-10-24 14:40:18 -0400
commit9168ead7296d27eb457097bfae1db721e2796f35 (patch)
tree0f19ec758ac44f53adf81be9d80783a39c140bea /plugins/org.eclipse.emf.cdo.workspace.efs
parentde88dc652b6dece80b49455ff645139e073a4b42 (diff)
downloadcdo-9168ead7296d27eb457097bfae1db721e2796f35.tar.gz
cdo-9168ead7296d27eb457097bfae1db721e2796f35.tar.xz
cdo-9168ead7296d27eb457097bfae1db721e2796f35.zip
[327405] Provide an offline CDOWorkspace with Checkout/Update/Commit workflows
https://bugs.eclipse.org/bugs/show_bug.cgi?id=327405
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.workspace.efs')
-rw-r--r--plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOResourceNodeStore.java179
-rw-r--r--plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOWorkspaceStore.java65
2 files changed, 219 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
diff --git a/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOWorkspaceStore.java b/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOWorkspaceStore.java
index caa00da76c..7eb67b98b6 100644
--- a/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOWorkspaceStore.java
+++ b/plugins/org.eclipse.emf.cdo.workspace.efs/src/org/eclipse/emf/cdo/workspace/internal/efs/CDOWorkspaceStore.java
@@ -12,6 +12,8 @@ package org.eclipse.emf.cdo.workspace.internal.efs;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.eresource.CDOResourceNode;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
+import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.view.CDOView;
import org.eclipse.emf.cdo.workspace.CDOWorkspace;
import org.eclipse.emf.cdo.workspace.efs.CDOWorkspaceFSUtil;
@@ -20,6 +22,7 @@ import org.eclipse.net4j.util.WrappedException;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.spi.cdo.InternalCDOObject;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.CoreException;
@@ -29,7 +32,9 @@ import java.io.File;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* @author Eike Stepper
@@ -46,6 +51,8 @@ public final class CDOWorkspaceStore extends AbstractResourceNodeStore
private CDOView view;
+ private SaveContext saveContext;
+
public CDOWorkspaceStore(String name, File location)
{
this.name = name;
@@ -147,6 +154,16 @@ public final class CDOWorkspaceStore extends AbstractResourceNodeStore
return this;
}
+ public SaveContext getSaveContext()
+ {
+ if (saveContext == null)
+ {
+ saveContext = new SaveContext();
+ }
+
+ return saveContext;
+ }
+
@Override
protected synchronized CDOView getView()
{
@@ -185,4 +202,52 @@ public final class CDOWorkspaceStore extends AbstractResourceNodeStore
}
}
}
+
+ /**
+ * @author Eike Stepper
+ */
+ public final class SaveContext
+ {
+ private CDOTransaction transaction;
+
+ private Map<String, InternalCDOObject> newObjects = new HashMap<String, InternalCDOObject>();
+
+ public SaveContext()
+ {
+ transaction = workspace.openTransaction();
+ }
+
+ public CDOTransaction getTransaction()
+ {
+ return transaction;
+ }
+
+ public void save()
+ {
+ try
+ {
+ transaction.commit();
+ }
+ catch (CommitException ex)
+ {
+ throw WrappedException.wrap(ex);
+ }
+ finally
+ {
+ saveContext = null;
+ newObjects = null;
+ IOUtil.closeSilent(transaction);
+ }
+ }
+
+ public void registerNewObject(String fragment, InternalCDOObject object)
+ {
+ newObjects.put(fragment, object);
+ }
+
+ public InternalCDOObject getNewObject(String fragment)
+ {
+ return newObjects.get(fragment);
+ }
+ }
}

Back to the top