diff options
author | Eike Stepper | 2012-10-02 06:22:55 +0000 |
---|---|---|
committer | Eike Stepper | 2012-10-02 06:22:55 +0000 |
commit | b4ca9cb665d6254836021a5998d426b9292a7d90 (patch) | |
tree | 6c0dcc3d1161386735a0ed94f0454ce6e8369272 /plugins/org.eclipse.emf.cdo.compare | |
parent | 973c58e4c37dd772a32c2107e89c9c184a1ce81d (diff) | |
download | cdo-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
Diffstat (limited to 'plugins/org.eclipse.emf.cdo.compare')
-rw-r--r-- | plugins/org.eclipse.emf.cdo.compare/src/org/eclipse/emf/cdo/compare/CDOCompareUtil.java | 152 |
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> |