Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlgoubet2011-04-07 06:47:42 +0000
committerlgoubet2011-04-07 06:47:42 +0000
commit1d77f163c42234f8287f3fd0fe313ead0ac7fabd (patch)
treeef141a72f0ebe68a63a67c90e938e3f21304110f
parent472c819c28d956b590b780fcae899d6dc2962ea6 (diff)
downloadorg.eclipse.emf.compare-1d77f163c42234f8287f3fd0fe313ead0ac7fabd.tar.gz
org.eclipse.emf.compare-1d77f163c42234f8287f3fd0fe313ead0ac7fabd.tar.xz
org.eclipse.emf.compare-1d77f163c42234f8287f3fd0fe313ead0ac7fabd.zip
Commiting current WIP on logical resources
-rw-r--r--plugins/org.eclipse.emf.compare.logical/META-INF/MANIFEST.MF10
-rw-r--r--plugins/org.eclipse.emf.compare.logical/plugin.xml14
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFAdapterFactory.java29
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFModelProvider.java41
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFResourceMapping.java54
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/adapter/EMFAdapterFactory.java49
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/ContentTypePropertyTester.java (renamed from plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/ContentTypePropertyTester.java)36
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/DelegatingURIConverter.java200
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFLogicalModelMessages.java82
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFResourceUtil.java56
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/emflogicalmodelmessages.properties12
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFModelProvider.java91
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFResourceMapping.java167
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFCompareAdapter.java86
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFModelDelta.java239
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFSaveableBuffer.java137
-rw-r--r--plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/view/EMFSynchronizationContentProvider.java171
17 files changed, 1346 insertions, 128 deletions
diff --git a/plugins/org.eclipse.emf.compare.logical/META-INF/MANIFEST.MF b/plugins/org.eclipse.emf.compare.logical/META-INF/MANIFEST.MF
index 2740060ca..eb8b72311 100644
--- a/plugins/org.eclipse.emf.compare.logical/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.emf.compare.logical/META-INF/MANIFEST.MF
@@ -7,6 +7,14 @@ Bundle-Activator: org.eclipse.emf.compare.logical.Activator
Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources;bundle-version="3.7.100",
org.eclipse.emf.ecore;bundle-version="2.7.0",
- org.eclipse.core.expressions;bundle-version="3.4.200"
+ org.eclipse.core.expressions;bundle-version="3.4.200",
+ org.eclipse.emf.compare;bundle-version="1.2.0",
+ org.eclipse.team.ui;bundle-version="3.5.200",
+ org.eclipse.ui.workbench;bundle-version="3.7.0",
+ org.eclipse.jface;bundle-version="3.7.0",
+ org.eclipse.compare;bundle-version="3.5.200",
+ org.eclipse.team.core;bundle-version="3.6.0",
+ org.eclipse.ui.navigator;bundle-version="3.5.0",
+ org.eclipse.emf.edit.ui;bundle-version="2.7.0"
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
diff --git a/plugins/org.eclipse.emf.compare.logical/plugin.xml b/plugins/org.eclipse.emf.compare.logical/plugin.xml
index 5cb321a8e..c2ae2b09c 100644
--- a/plugins/org.eclipse.emf.compare.logical/plugin.xml
+++ b/plugins/org.eclipse.emf.compare.logical/plugin.xml
@@ -6,7 +6,7 @@
name="EMF Compare Model Provider"
point="org.eclipse.core.resources.modelProviders">
<modelProvider
- class="org.eclipse.emf.compare.logical.EMFModelProvider">
+ class="org.eclipse.emf.compare.logical.model.EMFModelProvider">
</modelProvider>
<enablement>
<and>
@@ -33,11 +33,21 @@
<extension
point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
- class="org.eclipse.emf.compare.logical.ContentTypePropertyTester"
+ class="org.eclipse.emf.compare.logical.common.ContentTypePropertyTester"
id="org.eclipse.emf.compare.contentTypeTester"
namespace="org.eclipse.emf.compare.contentType"
properties="contentTypeId"
type="org.eclipse.core.resources.IResource">
</propertyTester>
</extension>
+ <extension
+ point="org.eclipse.core.runtime.adapters">
+ <factory
+ adaptableType="org.eclipse.emf.compare.logical.model.EMFModelProvider"
+ class="org.eclipse.emf.compare.logical.adapter.EMFAdapterFactory">
+ <adapter
+ type="org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter">
+ </adapter>
+ </factory>
+ </extension>
</plugin>
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFAdapterFactory.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFAdapterFactory.java
deleted file mode 100644
index d4dc96cfa..000000000
--- a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFAdapterFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package org.eclipse.emf.compare.logical;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.mapping.ResourceMapping;
-import org.eclipse.core.runtime.IAdapterFactory;
-
-public class EMFAdapterFactory implements IAdapterFactory {
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
- */
- public Object getAdapter(Object adaptableObject, Class adapterType) {
- if (adapterType == ResourceMapping.class && adaptableObject instanceof IResource) {
- new EMFResourceMapping((IResource)adaptableObject);
- }
-
- return null;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
- */
- public Class[] getAdapterList() {
- return new Class[] {ResourceMapping.class,};
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFModelProvider.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFModelProvider.java
deleted file mode 100644
index f1a0df711..000000000
--- a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFModelProvider.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.eclipse.emf.compare.logical;
-
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.mapping.ModelProvider;
-import org.eclipse.core.resources.mapping.ResourceMapping;
-import org.eclipse.core.resources.mapping.ResourceMappingContext;
-import org.eclipse.core.resources.mapping.ResourceTraversal;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-public class EMFModelProvider extends ModelProvider {
- public static final String PROVIDER_ID = "org.eclipse.emf.compare.model.provider"; //$NON-NLS-1$
-
- public EMFModelProvider() {
- System.out.println();
- }
-
- @Override
- public ResourceMapping[] getMappings(IResource resource, ResourceMappingContext context,
- IProgressMonitor monitor) throws CoreException {
- return super.getMappings(resource, context, monitor);
- }
-
- @Override
- public ResourceMapping[] getMappings(IResource[] resources, ResourceMappingContext context,
- IProgressMonitor monitor) throws CoreException {
- return super.getMappings(resources, context, monitor);
- }
-
- @Override
- public ResourceMapping[] getMappings(ResourceTraversal[] traversals, ResourceMappingContext context,
- IProgressMonitor monitor) throws CoreException {
- return super.getMappings(traversals, context, monitor);
- }
-
- @Override
- public ResourceTraversal[] getTraversals(ResourceMapping[] mappings, ResourceMappingContext context,
- IProgressMonitor monitor) throws CoreException {
- return super.getTraversals(mappings, context, monitor);
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFResourceMapping.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFResourceMapping.java
deleted file mode 100644
index 2beb01f64..000000000
--- a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/EMFResourceMapping.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package org.eclipse.emf.compare.logical;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.mapping.ResourceMapping;
-import org.eclipse.core.resources.mapping.ResourceMappingContext;
-import org.eclipse.core.resources.mapping.ResourceTraversal;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-
-public class EMFResourceMapping extends ResourceMapping {
- private final IResource resource;
-
- public EMFResourceMapping(IResource resource) {
- this.resource = resource;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.core.resources.mapping.ResourceMapping#getModelObject()
- */
- @Override
- public Object getModelObject() {
- return resource;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.core.resources.mapping.ResourceMapping#getModelProviderId()
- */
- @Override
- public String getModelProviderId() {
- return EMFModelProvider.PROVIDER_ID;
- }
-
- /**
- * {@inheritDoc}
- *
- * @see org.eclipse.core.resources.mapping.ResourceMapping#getProjects()
- */
- @Override
- public IProject[] getProjects() {
- return new IProject[] {resource.getProject(),};
- }
-
- @Override
- public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor)
- throws CoreException {
- return new ResourceTraversal[] {new ResourceTraversal(new IResource[] {resource,},
- IResource.DEPTH_INFINITE, IResource.NONE)};
- }
-}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/adapter/EMFAdapterFactory.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/adapter/EMFAdapterFactory.java
new file mode 100644
index 000000000..60c2db4de
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/adapter/EMFAdapterFactory.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.adapter;
+
+import org.eclipse.core.runtime.IAdapterFactory;
+import org.eclipse.emf.compare.logical.model.EMFModelProvider;
+import org.eclipse.emf.compare.logical.synchronization.EMFCompareAdapter;
+import org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter;
+
+/**
+ * This will be used to adapt EMF types to various parts of the logical model framework.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class EMFAdapterFactory implements IAdapterFactory {
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapter(java.lang.Object, java.lang.Class)
+ */
+ @SuppressWarnings("rawtypes")
+ public Object getAdapter(Object adaptableObject, Class adapterType) {
+ Object adapter = null;
+ if (adaptableObject instanceof EMFModelProvider) {
+ if (adapterType == ISynchronizationCompareAdapter.class) {
+ adapter = new EMFCompareAdapter(EMFModelProvider.PROVIDER_ID);
+ }
+ }
+ return adapter;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.runtime.IAdapterFactory#getAdapterList()
+ */
+ @SuppressWarnings("rawtypes")
+ public Class[] getAdapterList() {
+ return new Class[] {ISynchronizationCompareAdapter.class,};
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/ContentTypePropertyTester.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/ContentTypePropertyTester.java
index 3e92aa341..91e008eb9 100644
--- a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/ContentTypePropertyTester.java
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/ContentTypePropertyTester.java
@@ -1,4 +1,14 @@
-package org.eclipse.emf.compare.logical;
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.common;
import java.io.IOException;
import java.io.InputStream;
@@ -10,9 +20,22 @@ import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
+/**
+ * This will be used as a property tester for plugin.xml 'enablement' values. Specifically, we'll use this to
+ * check whether a given IFile has a given content type ID.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
public class ContentTypePropertyTester extends PropertyTester {
+ /** Name of the property we'll test with this tester. */
private static final String PROPERTY_CONTENT_TYPE_ID = "contentTypeId"; //$NON-NLS-1$
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.expressions.IPropertyTester#test(java.lang.Object, java.lang.String,
+ * java.lang.Object[], java.lang.Object)
+ */
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
if (receiver instanceof IFile && expectedValue instanceof String) {
if (PROPERTY_CONTENT_TYPE_ID.equals(property)) {
@@ -22,6 +45,17 @@ public class ContentTypePropertyTester extends PropertyTester {
return false;
}
+ /**
+ * This will return <code>true</code> if and only if the given IFile has the given <em>contentTypeId</em>
+ * configured (as returned by {@link IContentTypeManager#findContentTypesFor(InputStream, String)
+ * Platform.getContentTypeManager().findContentTypesFor(InputStream, String)}.
+ *
+ * @param resource
+ * The resource from which to test the content types.
+ * @param contentTypeId
+ * Fully qualified identifier of the content type this <em>resource</em> has to feature.
+ * @return <code>true</code> if the given {@link IFile} has the given content type.
+ */
private boolean hasContentType(IFile resource, String contentTypeId) {
IContentTypeManager ctManager = Platform.getContentTypeManager();
InputStream resourceContent = null;
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/DelegatingURIConverter.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/DelegatingURIConverter.java
new file mode 100644
index 000000000..f129e629a
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/DelegatingURIConverter.java
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.common;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ContentHandler;
+import org.eclipse.emf.ecore.resource.URIConverter;
+import org.eclipse.emf.ecore.resource.URIHandler;
+import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl;
+
+/**
+ * This implementation of an {@link URIConverter URI Converter} will delegate all calls to another.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class DelegatingURIConverter extends ExtensibleURIConverterImpl {
+ /** Our delegate {@link URIConverter}. */
+ private URIConverter delegate;
+
+ /**
+ * Instantiates our {@link URIConverter} given its delegate.
+ *
+ * @param delegate
+ * Our delegate {@link URIConverter}.
+ */
+ public DelegatingURIConverter(URIConverter delegate) {
+ this.delegate = delegate;
+
+ // Reset what has been done by the super constructor
+ uriHandlers.clear();
+ contentHandlers.clear();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#contentDescription(org.eclipse.emf.common.util.URI,
+ * java.util.Map)
+ */
+ @Override
+ public Map<String, ?> contentDescription(URI uri, Map<?, ?> options) throws IOException {
+ return delegate.contentDescription(uri, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#createInputStream(org.eclipse.emf.common.util.URI)
+ */
+ @Override
+ public InputStream createInputStream(URI uri) throws IOException {
+ return delegate.createInputStream(uri);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#createInputStream(org.eclipse.emf.common.util.URI,
+ * java.util.Map)
+ */
+ @Override
+ public InputStream createInputStream(URI uri, Map<?, ?> options) throws IOException {
+ return delegate.createInputStream(uri, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#createOutputStream(org.eclipse.emf.common.util.URI)
+ */
+ @Override
+ public OutputStream createOutputStream(URI uri) throws IOException {
+ return delegate.createOutputStream(uri);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#createOutputStream(org.eclipse.emf.common.util.URI,
+ * java.util.Map)
+ */
+ @Override
+ public OutputStream createOutputStream(URI uri, Map<?, ?> options) throws IOException {
+ return delegate.createOutputStream(uri, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#delete(org.eclipse.emf.common.util.URI, java.util.Map)
+ */
+ @Override
+ public void delete(URI uri, Map<?, ?> options) throws IOException {
+ delegate.delete(uri, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#exists(org.eclipse.emf.common.util.URI, java.util.Map)
+ */
+ @Override
+ public boolean exists(URI uri, Map<?, ?> options) {
+ return delegate.exists(uri, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#getAttributes(org.eclipse.emf.common.util.URI,
+ * java.util.Map)
+ */
+ @Override
+ public Map<String, ?> getAttributes(URI uri, Map<?, ?> options) {
+ return delegate.getAttributes(uri, options);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#getContentHandlers()
+ */
+ @Override
+ public EList<ContentHandler> getContentHandlers() {
+ // This will be called during init, before the delegate is set
+ if (delegate == null) {
+ return super.getContentHandlers();
+ }
+ return delegate.getContentHandlers();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#getURIHandler(org.eclipse.emf.common.util.URI)
+ */
+ @Override
+ public URIHandler getURIHandler(URI uri) {
+ return delegate.getURIHandler(uri);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#getURIHandlers()
+ */
+ @Override
+ public EList<URIHandler> getURIHandlers() {
+ // This will be called during init, before the delegate is set
+ if (delegate == null) {
+ return super.getURIHandlers();
+ }
+ return delegate.getURIHandlers();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#getURIMap()
+ */
+ @Override
+ public Map<URI, URI> getURIMap() {
+ return delegate.getURIMap();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#normalize(org.eclipse.emf.common.util.URI)
+ */
+ @Override
+ public URI normalize(URI uri) {
+ return delegate.normalize(uri);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.emf.ecore.resource.URIConverter#setAttributes(org.eclipse.emf.common.util.URI,
+ * java.util.Map, java.util.Map)
+ */
+ @Override
+ public void setAttributes(URI uri, Map<String, ?> attributes, Map<?, ?> options) throws IOException {
+ delegate.setAttributes(uri, attributes, options);
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFLogicalModelMessages.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFLogicalModelMessages.java
new file mode 100644
index 000000000..078381d0b
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFLogicalModelMessages.java
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.common;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+ * Utility class to access externalized Strings for EMF Compare's logical model integration.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">Laurent Goubet</a>
+ */
+public final class EMFLogicalModelMessages {
+ /** Full qualified path to the properties file in which to seek the keys. */
+ private static final String BUNDLE_NAME = "org.eclipse.emf.compare.emflogicalmodelmessages"; //$NON-NLS-1$
+
+ /** Contains the locale specific {@link String}s needed by this plug-in. */
+ private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle.getBundle(BUNDLE_NAME);
+
+ /**
+ * Utility classes don't need to (and shouldn't) be instantiated.
+ */
+ private EMFLogicalModelMessages() {
+ // prevents instantiation
+ }
+
+ /**
+ * This will return an unformatted String from the resource bundle.
+ *
+ * @param key
+ * Key of the String we seek.
+ * @return An unformatted String from the bundle.
+ */
+ private static String internalGetString(String key) {
+ try {
+ return RESOURCE_BUNDLE.getString(key);
+ } catch (MissingResourceException e) {
+ return '!' + key + '!';
+ }
+ }
+
+ /**
+ * Returns the specified {@link String} from the resource bundle.
+ *
+ * @param key
+ * Key of the String we seek.
+ * @return The String from the resource bundle associated with <code>key</code>.
+ * <code>'!' + key + '!'</code> will be returned in case we didn't find it in the bundle.
+ */
+ public static String getString(String key) {
+ // Pass through MessageFormat so that we're consistent in the handling of special chars such as the
+ // apostrophe
+ return MessageFormat.format(internalGetString(key), new Object[] {});
+ }
+
+ /**
+ * Returns a String from the resource bundle bound with the given arguments.
+ *
+ * @param key
+ * Key of the String we seek.
+ * @param arguments
+ * Arguments for the String formatting.
+ * @return formatted {@link String}.
+ * @see MessageFormat#format(String, Object[])
+ */
+ public static String getString(String key, Object... arguments) {
+ if (arguments == null) {
+ return getString(key);
+ }
+ return MessageFormat.format(internalGetString(key), arguments);
+ }
+
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFResourceUtil.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFResourceUtil.java
new file mode 100644
index 000000000..cf760be71
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/EMFResourceUtil.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.common;
+
+import java.io.IOException;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.util.ModelUtils;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+
+/**
+ * This will provide utility methods for going back and forth from {@link Resource}s to {@link IResource}s.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public final class EMFResourceUtil {
+ /** Utility classes don't need to (and shouldn't) be instantiated. */
+ private EMFResourceUtil() {
+ // Hides default constructor
+ }
+
+ /**
+ * Returns the EMF {@link Resource} saved within the given {@link IFile}.
+ *
+ * @param file
+ * The file from which to load an EMF {@link Resource}.
+ * @param resourceSet
+ * The resource set in which to load the model.
+ * @return The EMF {@link Resource} saved within the given {@link IFile}.
+ */
+ public static final Resource getResource(IFile file, ResourceSet resourceSet) {
+ for (Resource resource : resourceSet.getResources()) {
+ if (resource.getURI().toString().equals(file.getFullPath().toString())) {
+ return resource;
+ }
+ }
+ try {
+ return ModelUtils.load(URI.createPlatformResourceURI(file.getFullPath().toString(), true),
+ resourceSet).eResource();
+ } catch (IOException e) {
+ // FIXME handle this gracefully
+ throw new RuntimeException(e);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/emflogicalmodelmessages.properties b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/emflogicalmodelmessages.properties
new file mode 100644
index 000000000..c2e83c241
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/common/emflogicalmodelmessages.properties
@@ -0,0 +1,12 @@
+################################################################################
+# Copyright (c) 2006, 2011 Obeo.
+# 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:
+# Obeo - initial API and implementation
+################################################################################
+## note : apostrophes need to be doubled in these messages or they'll be ignored
+synchronize.job.label = Querying EMF synchronization state \ No newline at end of file
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFModelProvider.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFModelProvider.java
new file mode 100644
index 000000000..615009acc
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFModelProvider.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.mapping.ModelProvider;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.compare.logical.common.EMFResourceUtil;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+
+/**
+ * This implementation of a {@link ModelProvider} will be used to provide the logical model associated with
+ * EMF models.
+ * <p>
+ * Concretely, an EMF model can span multiple physical resources (fragmented models); this model provider can
+ * be used to find all of these associated physical resources.
+ * </p>
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class EMFModelProvider extends ModelProvider {
+ /** ID of this model provider. Must match the definition from the plugin.xml. */
+ public static final String PROVIDER_ID = "org.eclipse.emf.compare.model.provider"; //$NON-NLS-1$
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.resources.mapping.ModelProvider#getMappings(org.eclipse.core.resources.IResource,
+ * org.eclipse.core.resources.mapping.ResourceMappingContext,
+ * org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public ResourceMapping[] getMappings(IResource resource, ResourceMappingContext context,
+ IProgressMonitor monitor) throws CoreException {
+ /*
+ * TODO check that this also works when synchronizing a folder containing a fragmented model which
+ * fragment(s) are located in another folder.
+ */
+ // TODO what additional information can the context provide us?
+ if (resource instanceof IFile && resource.exists() && resource.isAccessible()) {
+ return getMappings((IFile)resource, monitor);
+ }
+ return super.getMappings(resource, context, monitor);
+ }
+
+ /**
+ * Return the {@link ResourceMapping}s that cover the given {@link IFile}.
+ *
+ * @param file
+ * The file for which to determine mappings.
+ * @param monitor
+ * A progress monitor, or <code>null</code> if progress reporting is not desired.
+ * @return The {@link ResourceMapping}s that cover the given {@link IFile}.
+ */
+ private ResourceMapping[] getMappings(IFile file, IProgressMonitor monitor) {
+ List<ResourceMapping> mappings = new ArrayList<ResourceMapping>();
+ // FIXME find a way to dispose of this resource set
+ Resource resource = EMFResourceUtil.getResource(file, createLogicalModelResourceSet());
+ if (resource != null) {
+ mappings.add(new EMFResourceMapping(file, resource, PROVIDER_ID));
+ }
+ return mappings.toArray(new ResourceMapping[mappings.size()]);
+ }
+
+ /**
+ * Creates the resource set that should be used to load this model's resources.
+ *
+ * @return The resource set that should be used to load this model's resources.
+ */
+ private ResourceSet createLogicalModelResourceSet() {
+ ResourceSet resourceSet = new ResourceSetImpl();
+ return resourceSet;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFResourceMapping.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFResourceMapping.java
new file mode 100644
index 000000000..eb23af8d3
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/model/EMFResourceMapping.java
@@ -0,0 +1,167 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.model;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.ResourcesPlugin;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceMappingContext;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.util.EcoreUtil;
+
+/**
+ * This will be used to map EMF {@link Resource}s to their physical {@link IResource}s.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class EMFResourceMapping extends ResourceMapping {
+ /** The physical resource of this mapping. */
+ private final IResource resource;
+
+ /** The EMF Resource of this mapping. */
+ private final Resource emfResource;
+
+ /** The Model provider for which this mapping has been created. */
+ private final String providerId;
+
+ /**
+ * Instantiates our mapping given both the physical {@link IResource} and the logical {@link Resource}.
+ *
+ * @param resource
+ * The physical resource of this mapping.
+ * @param emfResource
+ * The EMF Resource of this mapping.
+ * @param providerId
+ * The Model provider for which this mapping should be created.
+ */
+ public EMFResourceMapping(IResource resource, Resource emfResource, String providerId) {
+ this.resource = resource;
+ this.emfResource = emfResource;
+ this.providerId = providerId;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.resources.mapping.ResourceMapping#getModelObject()
+ */
+ @Override
+ public Object getModelObject() {
+ return emfResource;
+ }
+
+ /**
+ * Returns this mapping's physical resource.
+ *
+ * @return This mapping's physical resource.
+ */
+ public IResource getIResource() {
+ return resource;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.resources.mapping.ResourceMapping#getModelProviderId()
+ */
+ @Override
+ public String getModelProviderId() {
+ return providerId;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.resources.mapping.ResourceMapping#getProjects()
+ */
+ @Override
+ public IProject[] getProjects() {
+ Set<IResource> physicalResources = resolvePhysicalResources();
+
+ Set<IProject> projects = new LinkedHashSet<IProject>(physicalResources.size());
+ for (IResource iResource : physicalResources) {
+ projects.add(iResource.getProject());
+ }
+
+ return projects.toArray(new IProject[projects.size()]);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.core.resources.mapping.ResourceMapping#getTraversals(org.eclipse.core.resources.mapping.ResourceMappingContext,
+ * org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ public ResourceTraversal[] getTraversals(ResourceMappingContext context, IProgressMonitor monitor)
+ throws CoreException {
+ Set<IResource> physicalResources = resolvePhysicalResources();
+
+ ResourceTraversal traversal = new ResourceTraversal(
+ physicalResources.toArray(new IResource[physicalResources.size()]), IResource.DEPTH_ONE,
+ IResource.NONE);
+
+ return new ResourceTraversal[] {traversal,};
+ }
+
+ /**
+ * This will resolve all logical (EMF) {@link Resource}s that constitute this model, then resolve the
+ * corresponding physical {@link IResource}s and return them.
+ *
+ * @return The list of all physical resources that constitute this model.
+ */
+ private Set<IResource> resolvePhysicalResources() {
+ Set<Resource> logicalResources = resolveLogicalResources();
+
+ Set<IResource> physicalResources = new LinkedHashSet<IResource>(logicalResources.size());
+ for (Resource eResource : logicalResources) {
+ if (eResource == emfResource) {
+ physicalResources.add(resource);
+ } else {
+ URI uri = eResource.getURI();
+ if (uri != null) {
+ IPath path = new Path(uri.path());
+ IResource iResource = ResourcesPlugin.getWorkspace().getRoot()
+ .findMember(path.removeFirstSegments(1));
+ if (iResource != null && iResource.exists() && iResource.isAccessible()) {
+ physicalResources.add(iResource);
+ }
+ }
+ }
+ }
+
+ return physicalResources;
+ }
+
+ /**
+ * This will try and resolve all logical resources that constitute this model.
+ *
+ * @return The list of all logical resources that constitute this model.
+ */
+ private Set<Resource> resolveLogicalResources() {
+ EcoreUtil.resolveAll(emfResource.getResourceSet());
+
+ Set<Resource> result = new LinkedHashSet<Resource>();
+ result.addAll(emfResource.getResourceSet().getResources());
+
+ return result;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFCompareAdapter.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFCompareAdapter.java
new file mode 100644
index 000000000..11d1c0fee
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFCompareAdapter.java
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.synchronization;
+
+import org.eclipse.compare.structuremergeviewer.ICompareInput;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.team.core.mapping.ISynchronizationContext;
+import org.eclipse.team.ui.mapping.SynchronizationCompareAdapter;
+import org.eclipse.ui.IMemento;
+
+/**
+ * This implementation of a {@link SynchronizationCompareAdapter} will be used to determine the difference
+ * between two EMF logical models.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class EMFCompareAdapter extends SynchronizationCompareAdapter {
+ /** Cache key for our saveable comparison buffer. */
+ private static final String SAVEABLE_BUFFER = "org.eclipse.emf.compare.logical.saveable.buffer"; //$NON-NLS-1$
+
+ /** Identifier of the model this adapter will compare. */
+ private final String modelProviderId;
+
+ /**
+ * Instantiates our adapter given the identifier of the logical model to compare.
+ *
+ * @param modelProviderId
+ * Identifier of the model this adapter will compare.
+ */
+ public EMFCompareAdapter(String modelProviderId) {
+ this.modelProviderId = modelProviderId;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationCompareAdapter#asCompareInput(org.eclipse.team.core.mapping.ISynchronizationContext,
+ * java.lang.Object)
+ */
+ @Override
+ public ICompareInput asCompareInput(ISynchronizationContext context, Object o) {
+ // FIXME
+ return super.asCompareInput(context, o);
+ }
+
+ /**
+ * Initializes this compare adapter given the current synchronization context.
+ *
+ * @param context
+ * The context from which to retrieve comparison information.
+ * @param monitor
+ * Monitor on which to display progress information.
+ */
+ public void initialize(ISynchronizationContext context, IProgressMonitor monitor) {
+ EMFModelDelta delta = EMFModelDelta.createDelta(context, modelProviderId);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter#restore(org.eclipse.ui.IMemento)
+ */
+ public ResourceMapping[] restore(IMemento memento) {
+ // Don't restore
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter#save(org.eclipse.core.resources.mapping.ResourceMapping[],
+ * org.eclipse.ui.IMemento)
+ */
+ public void save(ResourceMapping[] mappings, IMemento memento) {
+ // Don't save
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFModelDelta.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFModelDelta.java
new file mode 100644
index 000000000..33b7743db
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFModelDelta.java
@@ -0,0 +1,239 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.synchronization;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.eclipse.core.internal.events.ResourceDelta;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.compare.logical.model.EMFResourceMapping;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.team.core.diff.IDiff;
+import org.eclipse.team.core.diff.IDiffTree;
+import org.eclipse.team.core.diff.IThreeWayDiff;
+import org.eclipse.team.core.history.IFileRevision;
+import org.eclipse.team.core.mapping.IResourceDiff;
+import org.eclipse.team.core.mapping.ISynchronizationContext;
+
+/**
+ * This class will serve as a super class of all elements describing deltas between EMF models.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class EMFModelDelta {
+ /** Children of this delta. */
+ private final List<EMFModelDelta> children = new ArrayList<EMFModelDelta>();
+
+ /** Parent of this delta. */
+ private EMFModelDelta parent;
+
+ /** Identifier of the model provider for which this delta has been created. */
+ private String modelProviderId;
+
+ /** Synchronization context of this delta. */
+ private ISynchronizationContext context;
+
+ /**
+ * Creates the root of our model delta.
+ *
+ * @param context
+ * Synchronization context of this delta.
+ * @param modelProviderId
+ * Identifier of the model provider for which this delta should be created.
+ */
+ private EMFModelDelta(ISynchronizationContext context, String modelProviderId) {
+ this.modelProviderId = modelProviderId;
+ this.context = context;
+ }
+
+ /**
+ * Creates a new child delta under the given parent.
+ *
+ * @param parent
+ * Parent of the new delta. Can be <code>null</code> for root deltas.
+ */
+ private EMFModelDelta(EMFModelDelta parent) {
+ this.parent = parent;
+ if (parent != null) {
+ parent.addChild(this);
+ }
+ }
+
+ /**
+ * Initializes a synchronization delta given the identifier of the model provider that required this delta
+ * and the current synchronization context.
+ *
+ * @param context
+ * Synchronization context of this delta.
+ * @param modelProviderId
+ * Identifier of the model provider for which this delta should be created.
+ * @return The created Synchronization delta.
+ */
+ public static EMFModelDelta createDelta(ISynchronizationContext context, String modelProviderId) {
+ EMFModelDelta delta = new EMFModelDelta(context, modelProviderId);
+
+ delta.initialize();
+
+ return delta;
+ }
+
+ /**
+ * This will be called internally to create or reset the comparison delta.
+ */
+ private void initialize() {
+ children.clear();
+
+ // Extract the emf and physcial resources from the scope
+ ResourceMapping[] mappings = context.getScope().getMappings();
+ Set<Resource> emfResourcesInScope = new LinkedHashSet<Resource>(mappings.length);
+ Set<IResource> iResourcesInScope = new LinkedHashSet<IResource>(mappings.length);
+ for (ResourceMapping mapping : mappings) {
+ if (modelProviderId.equals(mapping.getModelProviderId()) && mapping instanceof EMFResourceMapping) {
+ Object modelObject = ((EMFResourceMapping)mapping).getModelObject();
+ if (modelObject instanceof Resource) {
+ emfResourcesInScope.add((Resource)modelObject);
+ iResourcesInScope.add(((EMFResourceMapping)mapping).getIResource());
+ }
+
+ }
+ }
+ if (emfResourcesInScope.size() != iResourcesInScope.size()) {
+ // FIXME throw exception
+ }
+
+ // Compute the delta for each resource
+ IDiffTree diffTree = context.getDiffTree();
+ Iterator<Resource> emfResourcesIterator = emfResourcesInScope.iterator();
+ Iterator<IResource> iResourcesIterator = iResourcesInScope.iterator();
+ while (emfResourcesIterator.hasNext() && iResourcesIterator.hasNext()) {
+ Resource emfResource = emfResourcesIterator.next();
+ IResource iResource = iResourcesIterator.next();
+
+ IDiff delta = diffTree.getDiff(iResource.getFullPath());
+
+ if (delta != null && delta.getKind() != IDiff.NO_CHANGE) {
+ if (delta instanceof IThreeWayDiff) {
+ handleThreeWayDiff((IThreeWayDiff)delta, emfResource);
+ } else {
+ // FIXME handleTwoWayDiff()
+ }
+ }
+ }
+ }
+
+ /**
+ * Handles three-way deltas.
+ *
+ * @param delta
+ * The delta we are to build EMF deltas for.
+ */
+ private void handleThreeWayDiff(IThreeWayDiff delta, Resource localVariant) {
+ IResourceDiff remoteChange = (IResourceDiff)delta.getRemoteChange();
+ if (remoteChange != null) {
+ IFileRevision remoteVariant = remoteChange.getAfterState();
+ Resource remoteResource = loadRemoteResource(localResource, remoteVariant.getStorage(monitor));
+
+ IFileRevision baseVariant = remoteChange.getBeforeState();
+ Resource baseResource = createRemoteResource(localResource, baseVariant.getStorage(monitor));
+
+ ResourceDelta resourceDelta = new ResourceDelta(this, localResource, baseResource,
+ remoteResource, delta);
+ DELTA_TREE_BUILDER.buildDelta(resourceDelta, remoteResource, baseResource);
+ } else {
+ // FIXME No remote change. for now, assume that remote == base
+ IResourceDiff localChange = (IResourceDiff)(delta).getLocalChange();
+
+ IFileRevision baseVariant = localChange.getBeforeState();
+ Resource remoteResource = createRemoteResource(localResource, baseVariant.getStorage(monitor));
+ Resource baseResource = createRemoteResource(localResource, baseVariant.getStorage(monitor));
+
+ ResourceDelta resourceDelta = new ResourceDelta(this, localResource, baseResource,
+ remoteResource, delta);
+ DELTA_TREE_BUILDER.buildDelta(resourceDelta, remoteResource, baseResource);
+ }
+ }
+
+ /**
+ * This will try and load a resoruce corresponding to the given local variant from the given storage.
+ *
+ * @param localVariant
+ * Local variant of the resource we need read from <em>storage</em>.
+ * @param storage
+ * The storage from which to read a remote resource.
+ * @return The loaded resource.
+ * @throws CoreException
+ * Thrown if we did not manage to load the specified resource from the specified storage.
+ */
+ private Resource loadRemoteResource(Resource localVariant, IStorage storage) throws CoreException {
+ // "copy" the local resource set for the remote variant
+ ResourceSet localResourceSet = localVariant.getResourceSet();
+
+ ResourceSet resourceSet = new ResourceSetImpl();
+ resourceSet.setPackageRegistry(localResourceSet.getPackageRegistry());
+ resourceSet.setResourceFactoryRegistry(localResourceSet.getResourceFactoryRegistry());
+ resourceSet.setURIConverter(localResourceSet.getURIConverter());
+
+ URI localURI = localVariant.getURI();
+ Resource remoteResource = resourceSet.createResource(localURI);
+
+ InputStream remoteStream = null;
+ try {
+ remoteStream = storage.getContents();
+ remoteResource.load(remoteStream, Collections.emptyMap());
+ } catch (IOException e) {
+ // FIXME log
+ } finally {
+ if (remoteStream != null) {
+ try {
+ remoteStream.close();
+ } catch (IOException e) {
+ // FIXME log
+ }
+ }
+ }
+
+ return remoteResource;
+ }
+
+ /**
+ * Return all of the children of this delta.
+ *
+ * @return All of the children of this delta.
+ */
+ public List<EMFModelDelta> getChildren() {
+ return new ArrayList<EMFModelDelta>(children);
+ }
+
+ /**
+ * Adds a new child to this delta, making sure that the new child's parent reference point to
+ * <code>this</code> aftewards.
+ *
+ * @param child
+ * The child that is to be added to this delta.
+ */
+ public void addChild(EMFModelDelta child) {
+ children.add(child);
+ child.parent = this;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFSaveableBuffer.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFSaveableBuffer.java
new file mode 100644
index 000000000..12897e6d9
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/EMFSaveableBuffer.java
@@ -0,0 +1,137 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.synchronization;
+
+import java.io.IOException;
+import java.util.Collections;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.compare.logical.model.EMFModelProvider;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.team.ui.mapping.SaveableComparison;
+
+/**
+ * Instances of this class will be used to buffer the changes made to the EMF logical models during a
+ * comparison and determine when a save is needed.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class EMFSaveableBuffer extends SaveableComparison {
+ /** Cache key for the logical model buffer within the synchronization cache. */
+ public static final String SYNCHRONIZATION_CACHE_KEY = EMFModelProvider.PROVIDER_ID + ".sync.cache"; //$NON-NLS-1$
+
+ /** Human-readable name of this saveable. */
+ private final String name;
+
+ /** Resource set which contains the actual models. */
+ private final ResourceSet resourceSet;
+
+ /**
+ * Creates our buffer given its human-readable name and its underlying resource set.
+ *
+ * @param name
+ * Human-readable name of this saveable.
+ * @param resourceSet
+ * Resource set which contains the actual models.
+ */
+ public EMFSaveableBuffer(String name, ResourceSet resourceSet) {
+ this.name = name;
+ this.resourceSet = resourceSet;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SaveableComparison#performSave(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected void performSave(IProgressMonitor monitor) throws CoreException {
+ for (Resource resource : resourceSet.getResources()) {
+ try {
+ resource.save(Collections.emptyMap());
+ } catch (IOException e) {
+ // FIXME provide feedback
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SaveableComparison#performRevert(org.eclipse.core.runtime.IProgressMonitor)
+ */
+ @Override
+ protected void performRevert(IProgressMonitor monitor) {
+ // FIXME how can we revert changes made to this logical model?
+ // for (Resource resource : resourceSet.getResources()) {
+ // resource.unload();
+ // }
+ // EcoreUtil.resolveAll(resourceSet);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.Saveable#getName()
+ */
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.Saveable#getToolTipText()
+ */
+ @Override
+ public String getToolTipText() {
+ return getName();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.Saveable#getImageDescriptor()
+ */
+ @Override
+ public ImageDescriptor getImageDescriptor() {
+ // FIXME where is this displayed when non-null?
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.Saveable#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object object) {
+ return object instanceof EMFSaveableBuffer && name.equals(((EMFSaveableBuffer)object).name)
+ && resourceSet.equals(((EMFSaveableBuffer)object).resourceSet);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.ui.Saveable#hashCode()
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int hashCode = prime * name.hashCode();
+ hashCode += prime * resourceSet.hashCode();
+ return hashCode;
+ }
+}
diff --git a/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/view/EMFSynchronizationContentProvider.java b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/view/EMFSynchronizationContentProvider.java
new file mode 100644
index 000000000..ffc161c2d
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.logical/src/org/eclipse/emf/compare/logical/synchronization/view/EMFSynchronizationContentProvider.java
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2011 Obeo.
+ * 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:
+ * Obeo - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.logical.synchronization.view;
+
+import org.eclipse.core.resources.mapping.ModelProvider;
+import org.eclipse.core.resources.mapping.ResourceMapping;
+import org.eclipse.core.resources.mapping.ResourceTraversal;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.emf.compare.logical.common.EMFLogicalModelMessages;
+import org.eclipse.emf.compare.logical.model.EMFModelProvider;
+import org.eclipse.emf.compare.logical.model.EMFResourceMapping;
+import org.eclipse.emf.compare.logical.synchronization.EMFCompareAdapter;
+import org.eclipse.emf.compare.logical.synchronization.EMFSaveableBuffer;
+import org.eclipse.emf.compare.util.AdapterUtils;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.team.core.mapping.ISynchronizationContext;
+import org.eclipse.team.ui.mapping.ISynchronizationCompareAdapter;
+import org.eclipse.team.ui.mapping.SynchronizationContentProvider;
+
+/**
+ * This will be used to provide content information to the synchronize view's navigator when asked about EMF
+ * synchronization state.
+ *
+ * @author <a href="mailto:laurent.goubet@obeo.fr">laurent Goubet</a>
+ */
+public class EMFSynchronizationContentProvider extends SynchronizationContentProvider {
+ /** This will be used to determine icons and labels of the EObjects. */
+ private final AdapterFactoryContentProvider delegateContentProvider;
+
+ /**
+ * Instantiates our content provider.
+ */
+ public EMFSynchronizationContentProvider() {
+ this.delegateContentProvider = new AdapterFactoryContentProvider(AdapterUtils.getAdapterFactory());
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#dispose()
+ */
+ @Override
+ public void dispose() {
+ super.dispose();
+ delegateContentProvider.dispose();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getDelegateContentProvider()
+ */
+ @Override
+ protected ITreeContentProvider getDelegateContentProvider() {
+ return delegateContentProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#isInitialized(org.eclipse.team.core.mapping.ISynchronizationContext)
+ */
+ @Override
+ protected boolean isInitialized(ISynchronizationContext context) {
+ return context.getCache().get(EMFSaveableBuffer.SYNCHRONIZATION_CACHE_KEY) != null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#requestInitialization(org.eclipse.team.core.mapping.ISynchronizationContext)
+ */
+ @Override
+ protected void requestInitialization(final ISynchronizationContext context) {
+ Job emfSynchronizationJob = new Job(EMFLogicalModelMessages.getString("synchronize.job.label")) { //$NON-NLS-1$
+ @Override
+ protected IStatus run(IProgressMonitor monitor) {
+ EMFCompareAdapter emfCompareAdapter = null;
+ ModelProvider modelProvider = getModelProvider();
+ if (modelProvider instanceof EMFModelProvider) {
+ Object adapter = modelProvider.getAdapter(ISynchronizationCompareAdapter.class);
+ if (adapter instanceof EMFCompareAdapter) {
+ emfCompareAdapter = (EMFCompareAdapter)adapter;
+ }
+ }
+
+ if (emfCompareAdapter != null) {
+ emfCompareAdapter.initialize(context, monitor);
+ }
+
+ Display.getDefault().asyncExec(new Runnable() {
+ public void run() {
+ refresh();
+ }
+ });
+
+ return Status.OK_STATUS;
+ }
+ };
+ emfSynchronizationJob.schedule();
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getChildrenInContext(org.eclipse.team.core.mapping.ISynchronizationContext,
+ * java.lang.Object, java.lang.Object[])
+ */
+ @Override
+ protected Object[] getChildrenInContext(ISynchronizationContext context, Object parent, Object[] children) {
+ // FIXME Override this by browsing the EMF Delta
+ return super.getChildrenInContext(context, parent, children);
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getTraversals(org.eclipse.team.core.mapping.ISynchronizationContext,
+ * java.lang.Object)
+ */
+ @Override
+ protected ResourceTraversal[] getTraversals(ISynchronizationContext context, Object object) {
+ // We're taking care of the traversal in getChildrenInContext()
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getModelProviderId()
+ */
+ @Override
+ protected String getModelProviderId() {
+ return EMFModelProvider.PROVIDER_ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @see org.eclipse.team.ui.mapping.SynchronizationContentProvider#getModelRoot()
+ */
+ @Override
+ protected Object getModelRoot() {
+ // Try and find the current resource set
+ ResourceMapping[] mappings = getScope().getMappings();
+ for (ResourceMapping mapping : mappings) {
+ if (EMFModelProvider.PROVIDER_ID.equals(mapping.getModelProviderId())
+ && mapping instanceof EMFResourceMapping) {
+ Object modelObject = ((EMFResourceMapping)mapping).getModelObject();
+ if (modelObject instanceof Resource) {
+ return ((Resource)modelObject).getResourceSet();
+ }
+ }
+ }
+ return null;
+ }
+}

Back to the top