Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEike Stepper2012-10-02 02:22:55 -0400
committerEike Stepper2012-10-02 02:22:55 -0400
commitb4ca9cb665d6254836021a5998d426b9292a7d90 (patch)
tree6c0dcc3d1161386735a0ed94f0454ce6e8369272
parent973c58e4c37dd772a32c2107e89c9c184a1ce81d (diff)
downloadcdo-b4ca9cb665d6254836021a5998d426b9292a7d90.tar.gz
cdo-b4ca9cb665d6254836021a5998d426b9292a7d90.tar.xz
cdo-b4ca9cb665d6254836021a5998d426b9292a7d90.zip
[390808] Integrate CDO with EMF Compare
https://bugs.eclipse.org/bugs/show_bug.cgi?id=390808
-rw-r--r--plugins/org.eclipse.emf.cdo.compare/src/org/eclipse/emf/cdo/compare/CDOCompareUtil.java152
1 files changed, 117 insertions, 35 deletions
diff --git a/plugins/org.eclipse.emf.cdo.compare/src/org/eclipse/emf/cdo/compare/CDOCompareUtil.java b/plugins/org.eclipse.emf.cdo.compare/src/org/eclipse/emf/cdo/compare/CDOCompareUtil.java
index 361a401886..f26649572f 100644
--- a/plugins/org.eclipse.emf.cdo.compare/src/org/eclipse/emf/cdo/compare/CDOCompareUtil.java
+++ b/plugins/org.eclipse.emf.cdo.compare/src/org/eclipse/emf/cdo/compare/CDOCompareUtil.java
@@ -13,14 +13,21 @@ package org.eclipse.emf.cdo.compare;
import static com.google.common.base.Preconditions.checkNotNull;
import org.eclipse.emf.cdo.CDOObject;
+import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.commit.CDOChangeSetData;
+import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.revision.CDORevision;
+import org.eclipse.emf.cdo.compare.CDOCompareUtil.CDOComparisonScope.AllContents;
+import org.eclipse.emf.cdo.compare.CDOCompareUtil.CDOComparisonScope.Minimal;
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.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil;
+import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOView;
@@ -74,7 +81,39 @@ import java.util.Iterator;
import java.util.Set;
/**
- * Various static methods that may help EMF Compare in a CDO scope.
+ * Provides static factory methods that return CDO-scoped {@link Comparison comparisons}.
+ * <p>
+ * Two different {@link IComparisonScope scopes} are supported:
+ * <ul>
+ * <li>{@link AllContents CDOComparisonScope.AllContents} takes an arbitrary {@link CDOObject object} (including {@link CDOResourceNode resource nodes})
+ * and returns {@link Match matches} for <b>all</b> elements of its {@link EObject#eAllContents() content tree}. This scope has the advantage that the comparison can
+ * be rooted at specific objects that are different from (below of) the root resource. The disadvantage is that all the transitive children of this specific object are
+ * matched, whether they differ or not. Major parts of huge repositories can be loaded to the client side easily, if no attention is paid.
+ * The following methods return comparisons that are based on this scope algorithm:
+ * <ul>
+ * <li>{@link #compare(EObject, CDOBranchPoint)}
+ * <li>{@link #compare(EObject, CDOBranchPoint, boolean)}
+ * </ul>
+ * <li>{@link Minimal CDOComparisonScope.Minimal} takes a {@link CDOView view}/{@link CDOTransaction transaction}
+ * and returns {@link Match matches} only for the <b>changed</b> elements of the entire content tree of its {@link CDOView#getRootResource() root resource}.
+ * The advantage of this scope is that CDO-specific mechanisms are used to efficiently (remotely) determine the set of changed objects. Only those and their container
+ * objects are considered as matches, making this scope scale seamlessly with the overall size of a repository.
+ * The following methods return comparisons that are based on this scope algorithm:
+ * <ul>
+ * <li>{@link #compare(CDOView, CDOBranchPoint)}
+ * <li>{@link #compare(CDOView, CDOBranchPoint, boolean)}
+ * </ul>
+ * </ul>
+ * The {@link IComparisonScope#getRight() right side} of a comparison is specified as a {@link CDOBranchPoint} which, among others, can be another {@link CDOView}
+ * (which then is not closed when the comparison is closed) or a {@link CDOCommitInfo}. The {@link IComparisonScope#getOrigin() origin side} of a comparison is
+ * automatically {@link CDOBranchUtil#getAncestor(CDOBranchPoint, CDOBranchPoint) determined} by inspecting the {@link CDOBranch branch tree} and used if its different from the left or right side.
+ * <p>
+ * The comparions returned from these factory methods are all of the type {@link CloseableComparison} and the caller is responsible to call {@link CloseableComparison#close()}
+ * on them when they're not needed anymore. The reason is that the scopes may or may not open a number of addional {@link CDOView views} on the local {@link CDOSession session}
+ * that need to be closed at some point.
+ * <p>
+ * The {@link IEObjectMatcher matcher} used by the comparisons is based on an {@link CDOIDFunction ID function} that considers the {@link CDOID}s of the {@link CDOObject objects}.
+ * {@link CDOResource Resources} and {@link CDOResourceFolder folders} are treated as normal {@link EObject}s.
*
* @author Eike Stepper
*/
@@ -84,14 +123,26 @@ public final class CDOCompareUtil
{
}
- public static CloseableComparison compare(CDOView leftView, CDOBranchPoint right)
+ /**
+ * Same as {@link #compare(CDOView, CDOBranchPoint, boolean) compare(leftRoot, right, true)}.
+ */
+ public static CloseableComparison compare(EObject leftRoot, CDOBranchPoint right)
{
- return compare(leftView, right, true);
+ return compare(leftRoot, right, true);
}
- public static CloseableComparison compare(CDOView leftView, CDOBranchPoint right, boolean threeWay)
+ /**
+ * Takes an arbitrary {@link CDOObject object} (including {@link CDOResourceNode resource nodes}) and returns {@link Match matches} for <b>all</b> elements of its {@link EObject#eAllContents() content tree}. This scope has the advantage that the comparison can
+ * be rooted at specific objects that are different from (below of) the root resource. The disadvantage is that all the transitive children of this specific object are
+ * matched, whether they differ or not. Major parts of huge repositories can be loaded to the client side easily, if no attention is paid.
+ */
+ public static CloseableComparison compare(EObject leftRoot, CDOBranchPoint right, boolean tryThreeWay)
{
Set<Object> objectsToDeactivateOnClose = new HashSet<Object>();
+
+ CDOObject leftObject = CDOUtil.getCDOObject(leftRoot);
+ CDOView leftView = leftObject.cdoView();
+ CDOBranchPoint left = CDOBranchUtil.copyBranchPoint(leftView);
CDOSession session = leftView.getSession();
CDOView rightView;
@@ -109,45 +160,42 @@ public final class CDOCompareUtil
objectsToDeactivateOnClose.add(rightView);
}
+ Notifier rightObject = rightView.getObject(leftObject);
+
CDOView originView = null;
- if (threeWay)
+ Notifier originObject = null;
+ if (tryThreeWay)
{
- CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(leftView, rightView);
- if (!ancestor.equals(leftView) && !ancestor.equals(rightView))
+ CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(left, right);
+ if (!ancestor.equals(left) && !ancestor.equals(right))
{
originView = session.openView(ancestor);
+ originObject = originView.getObject(leftObject);
objectsToDeactivateOnClose.add(originView);
}
}
- Set<CDOID> ids;
- if (originView != null)
- {
- MergeData mergeData = ((InternalCDOSession)session).getMergeData(leftView, rightView, null);
- ids = mergeData.getIDs();
- }
- else
- {
- CDOChangeSetData changeSetData = leftView.compareRevisions(right);
- ids = new HashSet<CDOID>(changeSetData.getChangeKinds().keySet());
- }
-
- IComparisonScope scope = new CDOComparisonScope.Minimal(leftView, rightView, originView, ids);
+ IComparisonScope scope = new CDOComparisonScope.AllContents(leftObject, rightObject, originObject);
return createComparison(scope, objectsToDeactivateOnClose);
}
- public static CloseableComparison compare(EObject leftRoot, CDOBranchPoint right)
+ /**
+ * Same as {@link #compare(EObject, CDOBranchPoint, boolean) compare(leftView, right, true)}.
+ */
+ public static CloseableComparison compare(CDOView leftView, CDOBranchPoint right)
{
- return compare(leftRoot, right, true);
+ return compare(leftView, right, true);
}
- public static CloseableComparison compare(EObject leftRoot, CDOBranchPoint right, boolean threeWay)
+ /**
+ * Takes a {@link CDOView view}/{@link CDOTransaction transaction}
+ * and returns {@link Match matches} only for the <b>changed</b> elements of the entire content tree of its {@link CDOView#getRootResource() root resource}.
+ * The advantage of this scope is that CDO-specific mechanisms are used to efficiently (remotely) determine the set of changed objects. Only those and their container
+ * objects are considered as matches, making this scope scale seamlessly with the overall size of a repository.
+ */
+ public static CloseableComparison compare(CDOView leftView, CDOBranchPoint right, boolean tryThreeWay)
{
Set<Object> objectsToDeactivateOnClose = new HashSet<Object>();
-
- CDOObject leftObject = CDOUtil.getCDOObject(leftRoot);
- CDOView leftView = leftObject.cdoView();
- CDOBranchPoint left = CDOBranchUtil.copyBranchPoint(leftView);
CDOSession session = leftView.getSession();
CDOView rightView;
@@ -165,22 +213,30 @@ public final class CDOCompareUtil
objectsToDeactivateOnClose.add(rightView);
}
- Notifier rightObject = rightView.getObject(leftObject);
-
CDOView originView = null;
- Notifier originObject = null;
- if (threeWay)
+ if (tryThreeWay)
{
- CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(left, right);
- if (!ancestor.equals(left) && !ancestor.equals(right))
+ CDOBranchPoint ancestor = CDOBranchUtil.getAncestor(leftView, rightView);
+ if (!ancestor.equals(leftView) && !ancestor.equals(rightView))
{
originView = session.openView(ancestor);
- originObject = originView.getObject(leftObject);
objectsToDeactivateOnClose.add(originView);
}
}
- IComparisonScope scope = new CDOComparisonScope.AllContents(leftObject, rightObject, originObject);
+ Set<CDOID> ids;
+ if (originView != null)
+ {
+ MergeData mergeData = ((InternalCDOSession)session).getMergeData(leftView, rightView, null);
+ ids = mergeData.getIDs();
+ }
+ else
+ {
+ CDOChangeSetData changeSetData = leftView.compareRevisions(right);
+ ids = new HashSet<CDOID>(changeSetData.getChangeKinds().keySet());
+ }
+
+ IComparisonScope scope = new CDOComparisonScope.Minimal(leftView, rightView, originView, ids);
return createComparison(scope, objectsToDeactivateOnClose);
}
@@ -202,6 +258,8 @@ public final class CDOCompareUtil
}
/**
+ * A {@link Comparison comparison} that can be closed to dispose of used resources.
+ *
* @author Eike Stepper
*/
public static class CDOComparison extends DelegatingComparison implements CloseableComparison
@@ -238,6 +296,8 @@ public final class CDOCompareUtil
}
/**
+ * A CDO-specific base implementation of a {@link IComparisonScope comparison scope}.
+ *
* @author Eike Stepper
*/
public static abstract class CDOComparisonScope extends AbstractComparisonScope
@@ -258,6 +318,16 @@ public final class CDOCompareUtil
}
/**
+ * Takes an arbitrary {@link CDOObject object} (including {@link CDOResourceNode resource nodes})
+ * and returns {@link Match matches} for <b>all</b> elements of its {@link EObject#eAllContents() content tree}. This scope has the advantage that the comparison can
+ * be rooted at specific objects that are different from (below of) the root resource. The disadvantage is that all the transitive children of this specific object are
+ * matched, whether they differ or not. Major parts of huge repositories can be loaded to the client side easily, if no attention is paid.
+ * The following methods return comparisons that are based on this scope algorithm:
+ * <ul>
+ * <li>{@link CDOCompareUtil#compare(EObject, CDOBranchPoint)}
+ * <li>{@link CDOCompareUtil#compare(EObject, CDOBranchPoint, boolean)}
+ * </ul>
+ *
* @author Eike Stepper
*/
public static class AllContents extends CDOComparisonScope
@@ -274,6 +344,16 @@ public final class CDOCompareUtil
}
/**
+ * Takes a {@link CDOView view}/{@link CDOTransaction transaction}
+ * and returns {@link Match matches} only for the <b>changed</b> elements of the entire content tree of its {@link CDOView#getRootResource() root resource}.
+ * The advantage of this scope is that CDO-specific mechanisms are used to efficiently (remotely) determine the set of changed objects. Only those and their container
+ * objects are considered as matches, making this scope scale seamlessly with the overall size of a repository.
+ * The following methods return comparisons that are based on this scope algorithm:
+ * <ul>
+ * <li>{@link CDOCompareUtil#compare(CDOView, CDOBranchPoint)}
+ * <li>{@link CDOCompareUtil#compare(CDOView, CDOBranchPoint, boolean)}
+ * </ul>
+ *
* @author Eike Stepper
*/
public static class Minimal extends CDOComparisonScope implements Predicate<EObject>
@@ -364,6 +444,8 @@ public final class CDOCompareUtil
}
/**
+ * An {@link CDOIDFunction ID function} that considers the {@link CDOID}s of {@link CDOObject objects}.
+ *
* @author Eike Stepper
*/
public static class CDOIDFunction implements Function<EObject, String>

Back to the top