diff options
author | Eike Stepper | 2012-10-07 10:59:06 +0000 |
---|---|---|
committer | Eike Stepper | 2012-10-07 10:59:06 +0000 |
commit | e403c787d6ea93d6e557b8296bb56f84fad633e3 (patch) | |
tree | 88897cfcd95e846a209352bcf2f2a58d3f163b46 | |
parent | f79754573c9fa8fdcb95915b4da730d0f1a0c34f (diff) | |
download | cdo-e403c787d6ea93d6e557b8296bb56f84fad633e3.tar.gz cdo-e403c787d6ea93d6e557b8296bb56f84fad633e3.tar.xz cdo-e403c787d6ea93d6e557b8296bb56f84fad633e3.zip |
[391312] Provide per-CDOObject histories
https://bugs.eclipse.org/bugs/show_bug.cgi?id=391312
17 files changed, 595 insertions, 245 deletions
diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitHistory.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitHistory.java index 81fe852f1a..274c10a60e 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitHistory.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitHistory.java @@ -11,11 +11,8 @@ package org.eclipse.emf.cdo.common.commit; import org.eclipse.emf.cdo.common.branch.CDOBranch; -import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; -import org.eclipse.net4j.util.container.Container; - -import java.util.LinkedList; +import org.eclipse.net4j.util.container.IContainer; /** * A cache for the {@link CDOCommitInfo commit infos} of a branch or of an entire repository. @@ -23,164 +20,29 @@ import java.util.LinkedList; * @author Eike Stepper * @since 4.2 */ -public class CDOCommitHistory extends Container<CDOCommitInfo> implements CDOCommitInfoHandler +public interface CDOCommitHistory extends IContainer<CDOCommitInfo>, CDOCommitInfoHandler { public static final int DEFAULT_LOAD_COUNT = 25; - private final CDOCommitInfoManager manager; - - private final CDOBranch branch; - - private int loadCount = DEFAULT_LOAD_COUNT; - - private LinkedList<CDOCommitInfo> commitInfos = new LinkedList<CDOCommitInfo>(); - - private CDOCommitInfo[] elements; - - private Thread loaderThread; - - private Object loaderThreadLock = new Object(); - - public CDOCommitHistory(CDOCommitInfoManager manager, CDOBranch branch) - { - super(true); - this.manager = manager; - this.branch = branch; - } - - public final CDOCommitInfoManager getManager() - { - return manager; - } - - public final CDOBranch getBranch() - { - return branch; - } - - public final int getLoadCount() - { - return loadCount; - } - - public void setLoadCount(int loadCount) - { - this.loadCount = loadCount; - } - - @Override - public boolean isEmpty() - { - checkActive(); - synchronized (commitInfos) - { - return commitInfos.isEmpty(); - } - } - - public CDOCommitInfo[] getElements() - { - checkActive(); - synchronized (commitInfos) - { - if (elements == null) - { - elements = commitInfos.toArray(new CDOCommitInfo[commitInfos.size()]); - } - - return elements; - } - } + public CDOCommitInfoManager getManager(); - public boolean loadCommitInfos() - { - synchronized (loaderThreadLock) - { - if (loaderThread != null) - { - return false; - } - - loaderThread = new Thread("CDOCommitHistoryLoader") - { - @Override - public void run() - { - doLoadCommitInfos(); - - synchronized (loaderThreadLock) - { - loaderThread = null; - } - } - }; - } + public CDOBranch getBranch(); - loaderThread.start(); - return true; - } + public int getLoadCount(); - public void handleCommitInfo(CDOCommitInfo commitInfo) - { - synchronized (commitInfos) - { - commitInfos.addFirst(commitInfo); - elements = null; - } + public void setLoadCount(int loadCount); - fireElementAddedEvent(commitInfo); - } + public boolean load(); - @Override - protected void doActivate() throws Exception + /** + * Provides consumers with {@link CDOCommitHistory histories}. + * + * @author Eike Stepper + */ + public interface Provider<KEY, HISTORY extends CDOCommitHistory> { - super.doActivate(); - manager.addCommitInfoHandler(this); - loadCommitInfos(); - } - - @Override - protected void doDeactivate() throws Exception - { - manager.removeCommitInfoHandler(this); - - synchronized (commitInfos) - { - commitInfos.clear(); - elements = null; - } - - super.doDeactivate(); - } - - protected void doLoadCommitInfos() - { - final long startTime; - synchronized (commitInfos) - { - startTime = commitInfos.isEmpty() ? CDOBranchPoint.UNSPECIFIED_DATE : commitInfos.getLast().getTimeStamp(); - } - - manager.getCommitInfos(branch, startTime, null, null, -loadCount, new CDOCommitInfoHandler() - { - private boolean ignore = startTime != CDOBranchPoint.UNSPECIFIED_DATE; - - public void handleCommitInfo(CDOCommitInfo commitInfo) - { - if (ignore) - { - ignore = false; - return; - } - - synchronized (commitInfos) - { - commitInfos.addLast(commitInfo); - elements = null; - } + public CDOCommitHistory getHistory(); - fireElementAddedEvent(commitInfo); - } - }); + public HISTORY getHistory(KEY key); } } diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitInfoManager.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitInfoManager.java index b0fda11af9..5f3f35101d 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitInfoManager.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/common/commit/CDOCommitInfoManager.java @@ -22,19 +22,10 @@ import org.eclipse.emf.cdo.common.branch.CDOBranch; * @apiviz.landmark * @apiviz.uses {@link CDOCommitInfo} - - manages */ -public interface CDOCommitInfoManager extends CDOCommitInfoProvider +public interface CDOCommitInfoManager extends CDOCommitInfoProvider, + CDOCommitHistory.Provider<CDOBranch, CDOCommitHistory> { /** - * @since 4.2 - */ - public CDOCommitHistory getHistory(); - - /** - * @since 4.2 - */ - public CDOCommitHistory getHistory(CDOBranch branch); - - /** * @since 4.0 */ public CDOCommitInfo getCommitInfo(long timeStamp); diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitHistoryImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitHistoryImpl.java new file mode 100644 index 0000000000..6e8746b048 --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitHistoryImpl.java @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others. + * 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.internal.common.commit; + +import org.eclipse.emf.cdo.common.branch.CDOBranch; +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; +import org.eclipse.emf.cdo.common.commit.CDOCommitHistory; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfoHandler; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager; +import org.eclipse.emf.cdo.internal.common.bundle.OM; + +import org.eclipse.net4j.util.container.Container; + +import java.util.LinkedList; +import java.util.ListIterator; + +/** + * @author Eike Stepper + * @since 4.2 + */ +public class CDOCommitHistoryImpl extends Container<CDOCommitInfo> implements CDOCommitHistory +{ + public static final int DEFAULT_LOAD_COUNT = 25; + + private final CDOCommitInfoManager manager; + + private final CDOBranch branch; + + private int loadCount = DEFAULT_LOAD_COUNT; + + private LinkedList<CDOCommitInfo> commitInfos = new LinkedList<CDOCommitInfo>(); + + private CDOCommitInfo[] elements; + + private Thread loaderThread; + + private Object loaderThreadLock = new Object(); + + public CDOCommitHistoryImpl(CDOCommitInfoManager manager, CDOBranch branch) + { + super(true); + this.manager = manager; + this.branch = branch; + } + + public final CDOCommitInfoManager getManager() + { + return manager; + } + + public final CDOBranch getBranch() + { + return branch; + } + + public final int getLoadCount() + { + return loadCount; + } + + public void setLoadCount(int loadCount) + { + this.loadCount = loadCount; + } + + @Override + public boolean isEmpty() + { + checkActive(); + synchronized (commitInfos) + { + return commitInfos.isEmpty(); + } + } + + public CDOCommitInfo[] getElements() + { + checkActive(); + synchronized (commitInfos) + { + if (elements == null) + { + elements = commitInfos.toArray(new CDOCommitInfo[commitInfos.size()]); + } + + return elements; + } + } + + public boolean load() + { + synchronized (loaderThreadLock) + { + if (loaderThread != null) + { + return false; + } + + loaderThread = new Thread("CDOCommitHistoryLoader") + { + @Override + public void run() + { + try + { + doLoadCommitInfos(); + } + catch (Throwable ex) + { + OM.LOG.error(ex); + } + finally + { + synchronized (loaderThreadLock) + { + loaderThread = null; + } + } + } + }; + } + + loaderThread.start(); + return true; + } + + public void handleCommitInfo(CDOCommitInfo commitInfo) + { + long timeStamp = commitInfo.getTimeStamp(); + synchronized (commitInfos) + { + if (commitInfos.isEmpty() || timeStamp > commitInfos.getFirst().getTimeStamp()) + { + commitInfos.addFirst(commitInfo); + } + else + { + if (timeStamp < commitInfos.getLast().getTimeStamp()) + { + commitInfos.addLast(commitInfo); + } + else + { + for (ListIterator<CDOCommitInfo> it = commitInfos.listIterator(); it.hasNext();) + { + CDOCommitInfo current = it.next(); + long currentTimeStamp = current.getTimeStamp(); + if (timeStamp == currentTimeStamp) + { + // Ignore duplicate commit infos + return; + } + + if (timeStamp < currentTimeStamp) + { + it.add(commitInfo); + break; + } + } + } + } + + elements = null; + } + + fireElementAddedEvent(commitInfo); + } + + @Override + protected void doActivate() throws Exception + { + super.doActivate(); + manager.addCommitInfoHandler(this); + load(); + } + + @Override + protected void doDeactivate() throws Exception + { + manager.removeCommitInfoHandler(this); + super.doDeactivate(); + } + + protected void doLoadCommitInfos() + { + final long startTime; + synchronized (commitInfos) + { + startTime = commitInfos.isEmpty() ? CDOBranchPoint.UNSPECIFIED_DATE : commitInfos.getLast().getTimeStamp(); + } + + manager.getCommitInfos(branch, startTime, null, null, -loadCount, new CDOCommitInfoHandler() + { + private boolean ignore = startTime != CDOBranchPoint.UNSPECIFIED_DATE; + + public void handleCommitInfo(CDOCommitInfo commitInfo) + { + if (ignore) + { + ignore = false; + return; + } + + CDOCommitHistoryImpl.this.handleCommitInfo(commitInfo); + } + }); + } +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitHistoryProviderImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitHistoryProviderImpl.java new file mode 100644 index 0000000000..aa637bb89a --- /dev/null +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitHistoryProviderImpl.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others. + * 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo.internal.common.commit; + +import org.eclipse.emf.cdo.common.commit.CDOCommitHistory; + +import org.eclipse.net4j.util.event.IListener; +import org.eclipse.net4j.util.lifecycle.ILifecycle; +import org.eclipse.net4j.util.lifecycle.Lifecycle; +import org.eclipse.net4j.util.lifecycle.LifecycleEventAdapter; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.WeakHashMap; + +/** + * @author Eike Stepper + * @since 4.2 + */ +public abstract class CDOCommitHistoryProviderImpl<KEY, HISTORY extends CDOCommitHistory> extends Lifecycle implements + CDOCommitHistory.Provider<KEY, HISTORY> +{ + private Map<CDOCommitHistory, KEY> histories = new WeakHashMap<CDOCommitHistory, KEY>(); + + private IListener historyListener = new LifecycleEventAdapter() + { + @Override + protected void onDeactivated(ILifecycle lifecycle) + { + CDOCommitHistory history = (CDOCommitHistory)lifecycle; + history.removeListener(this); + + synchronized (histories) + { + histories.remove(lifecycle); + } + } + }; + + public CDOCommitHistoryProviderImpl() + { + } + + public CDOCommitHistory getHistory() + { + return getHistory(null); + } + + public HISTORY getHistory(KEY key) + { + synchronized (histories) + { + for (Entry<CDOCommitHistory, KEY> entry : histories.entrySet()) + { + KEY currentKey = entry.getValue(); + if (currentKey == key) + { + CDOCommitHistory history = entry.getKey(); + return activateHistory(history); + } + } + + CDOCommitHistory history = createHistory(key); + history.addListener(historyListener); + histories.put(history, key); + return activateHistory(history); + } + } + + protected abstract CDOCommitHistory createHistory(KEY key); + + @SuppressWarnings("unchecked") + private HISTORY activateHistory(CDOCommitHistory history) + { + LifecycleUtil.activate(history); + return (HISTORY)history; + } +} diff --git a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitInfoManagerImpl.java b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitInfoManagerImpl.java index 0983bc32ed..4002bd7bb0 100644 --- a/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitInfoManagerImpl.java +++ b/plugins/org.eclipse.emf.cdo.common/src/org/eclipse/emf/cdo/internal/common/commit/CDOCommitInfoManagerImpl.java @@ -20,24 +20,19 @@ import org.eclipse.emf.cdo.internal.common.bundle.OM; import org.eclipse.emf.cdo.spi.common.commit.CDOCommitInfoUtil; import org.eclipse.emf.cdo.spi.common.commit.InternalCDOCommitInfoManager; -import org.eclipse.net4j.util.lifecycle.Lifecycle; - import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.WeakHashMap; /** * @author Andre Dietisheim */ -public class CDOCommitInfoManagerImpl extends Lifecycle implements InternalCDOCommitInfoManager +public class CDOCommitInfoManagerImpl extends CDOCommitHistoryProviderImpl<CDOBranch, CDOCommitHistory> implements + InternalCDOCommitInfoManager { private CommitInfoLoader commitInfoLoader; private List<CDOCommitInfoHandler> commitInfoHandlers = new ArrayList<CDOCommitInfoHandler>(); - private Map<CDOCommitHistory, Boolean> histories = new WeakHashMap<CDOCommitHistory, Boolean>(); - public CDOCommitInfoManagerImpl() { } @@ -105,31 +100,6 @@ public class CDOCommitInfoManagerImpl extends Lifecycle implements InternalCDOCo return new CDOCommitInfoImpl(this, branch, timeStamp, previousTimeStamp, userID, comment, commitData); } - public CDOCommitHistory getHistory() - { - return getHistory(null); - } - - public CDOCommitHistory getHistory(CDOBranch branch) - { - synchronized (histories) - { - for (CDOCommitHistory history : histories.keySet()) - { - if (history.getBranch() == branch) - { - history.activate(); - return history; - } - } - - CDOCommitHistory history = new CDOCommitHistory(this, branch); - histories.put(history, Boolean.TRUE); - history.activate(); - return history; - } - } - public CDOCommitInfo getCommitInfo(long timeStamp) { checkActive(); @@ -171,4 +141,10 @@ public class CDOCommitInfoManagerImpl extends Lifecycle implements InternalCDOCo super.doBeforeActivate(); checkState(commitInfoLoader, "commitInfoLoader"); //$NON-NLS-1$ } + + @Override + protected CDOCommitHistory createHistory(CDOBranch key) + { + return new CDOCommitHistoryImpl(this, key); + } } diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/SelectBranchPointDialog.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/SelectBranchPointDialog.java index 18983fb8c1..6fdc70048a 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/SelectBranchPointDialog.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/internal/ui/dialogs/SelectBranchPointDialog.java @@ -196,7 +196,7 @@ public class SelectBranchPointDialog extends TitleAreaDialog implements Validati }; control.setLayoutData(UIUtil.createGridData()); - control.setInput(new CommitHistoryComposite.Input(session, null)); + control.setInput(new CommitHistoryComposite.Input(session, null, null)); } protected void createTagsTab(Composite parent) diff --git a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/CommitHistoryComposite.java b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/CommitHistoryComposite.java index 2733d22918..9977da988b 100644 --- a/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/CommitHistoryComposite.java +++ b/plugins/org.eclipse.emf.cdo.ui/src/org/eclipse/emf/cdo/ui/widgets/CommitHistoryComposite.java @@ -11,6 +11,7 @@ package org.eclipse.emf.cdo.ui.widgets; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.common.branch.CDOBranch; import org.eclipse.emf.cdo.common.commit.CDOCommitHistory; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; @@ -21,6 +22,7 @@ import org.eclipse.emf.cdo.ui.shared.SharedIcons; import org.eclipse.emf.cdo.util.CDOUtil; import org.eclipse.emf.cdo.view.CDOView; +import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.ui.StructuredContentProvider; import org.eclipse.net4j.util.ui.TableLabelProvider; @@ -44,8 +46,6 @@ public class CommitHistoryComposite extends Composite { private CDOCommitHistory history; - private CDOCommitHistory lastHistory; - private TableViewer tableViewer; private LabelProvider labelProvider; @@ -96,27 +96,34 @@ public class CommitHistoryComposite extends Composite { this.input = input; - CDOBranch inputBranch = input.getBranch(); CDOSession session = input.getSession(); - String userID = session.getUserID(); + CDOBranch branch = input.getBranch(); - labelProvider.setLocalUserID(userID); - labelProvider.setInputBranch(inputBranch); + labelProvider.setLocalUserID(session.getUserID()); + labelProvider.setInputBranch(branch); - setHistory(session, inputBranch); + setHistory(session, branch, input.getObject()); tableViewer.setInput(history); } - protected void setHistory(CDOSession session, CDOBranch branch) + protected void setHistory(CDOSession session, CDOBranch branch, CDOObject object) { - CDOCommitInfoManager commitInfoManager = session.getCommitInfoManager(); - history = commitInfoManager.getHistory(branch); - if (lastHistory != null && lastHistory != history) + CDOCommitHistory oldHistory = history; + + if (object == null) + { + CDOCommitInfoManager commitInfoManager = session.getCommitInfoManager(); + history = commitInfoManager.getHistory(branch); + } + else { - lastHistory.deactivate(); + history = object.cdoHistory(); } - lastHistory = history; + if (oldHistory != null && oldHistory != history) + { + LifecycleUtil.deactivate(oldHistory); + } } @Override @@ -150,46 +157,52 @@ public class CommitHistoryComposite extends Composite private final CDOBranch branch; - public Input(Object object) + private final CDOObject object; + + public Input(Object delegate) { - if (object instanceof CDOSession) + if (delegate instanceof CDOSession) { - session = (CDOSession)object; + session = (CDOSession)delegate; branch = null; + object = null; return; } - if (object instanceof CDOView) + if (delegate instanceof CDOView) { - CDOView view = (CDOView)object; + CDOView view = (CDOView)delegate; session = view.getSession(); branch = view.getBranch(); + object = null; return; } - if (object instanceof EObject) + if (delegate instanceof EObject) { - EObject eObject = (EObject)object; + EObject eObject = (EObject)delegate; CDOObject cdoObject = CDOUtil.getCDOObject(eObject); if (cdoObject != null) { CDOView view = cdoObject.cdoView(); - if (view != null) + if (view != null && cdoObject.cdoState() != CDOState.NEW) { session = view.getSession(); branch = view.getBranch(); + object = cdoObject; return; } } } - throw new IllegalStateException("Illegal input: " + object); + throw new IllegalStateException("Illegal input: " + delegate); } - public Input(CDOSession session, CDOBranch branch) + public Input(CDOSession session, CDOBranch branch, CDOObject object) { this.session = session; this.branch = branch; + this.object = object; } public final CDOSession getSession() @@ -202,13 +215,19 @@ public class CommitHistoryComposite extends Composite return branch; } + public final CDOObject getObject() + { + return object; + } + @Override public int hashCode() { final int prime = 31; int result = 1; - result = prime * result + (branch == null ? 0 : branch.hashCode()); result = prime * result + (session == null ? 0 : session.hashCode()); + result = prime * result + (branch == null ? 0 : branch.hashCode()); + result = prime * result + (object == null ? 0 : object.hashCode()); return result; } @@ -231,40 +250,45 @@ public class CommitHistoryComposite extends Composite } Input other = (Input)obj; - if (branch == null) + if (session == null) { - if (other.branch != null) + if (other.session != null) { return false; } } - else if (!branch.equals(other.branch)) + else if (!session.equals(other.session)) { return false; } - if (session == null) + if (branch == null) { - if (other.session != null) + if (other.branch != null) { return false; } } - else if (!session.equals(other.session)) + else if (!branch.equals(other.branch)) { return false; } - return true; + return object == other.object; } @Override public String toString() { - String str = session.getRepositoryInfo().getName(); + String str = "Repostory: " + session.getRepositoryInfo().getName(); if (branch != null) { - str += " [" + branch.getPathName() + "]"; + str += ", Branch: " + branch.getPathName(); + } + + if (object != null) + { + str += ", Object: " + object; } return str; diff --git a/plugins/org.eclipse.emf.cdo/.settings/.api_filters b/plugins/org.eclipse.emf.cdo/.settings/.api_filters index 0d93a2fbab..0df439f080 100644 --- a/plugins/org.eclipse.emf.cdo/.settings/.api_filters +++ b/plugins/org.eclipse.emf.cdo/.settings/.api_filters @@ -4,6 +4,12 @@ <filter id="403804204"> <message_arguments> <message_argument value="org.eclipse.emf.cdo.CDOObject"/> + <message_argument value="cdoHistory()"/> + </message_arguments> + </filter> + <filter id="403804204"> + <message_arguments> + <message_argument value="org.eclipse.emf.cdo.CDOObject"/> <message_argument value="cdoLockState()"/> </message_arguments> </filter> @@ -133,6 +139,12 @@ <message_argument value="CDOView"/> </message_arguments> </filter> + <filter id="574619656"> + <message_arguments> + <message_argument value="CDOCommonView"/> + <message_argument value="CDOView"/> + </message_arguments> + </filter> </resource> <resource path="src/org/eclipse/emf/cdo/view/CDOView.java" type="org.eclipse.emf.cdo.view.CDOView$Options"> <filter id="571473929"> diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOObject.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOObject.java index f6436a0f0f..d83e6e239c 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOObject.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOObject.java @@ -28,7 +28,7 @@ import org.eclipse.emf.spi.cdo.InternalCDOObject; * properties and features of those objects. * <p> * Note that, by contract, every instance of CDOObject can also be cast to {@link InternalCDOObject}. - * + * * @author Eike Stepper * @apiviz.landmark * @apiviz.has {@link CDOState} @@ -47,7 +47,7 @@ public interface CDOObject extends EObject, CDOWithID * If the state of this object is {@link CDOState#NEW NEW} the returned CDOID instance can be cast to * {@link CDOIDTemp} and is unique in the scope of the associated {@link #cdoView() transaction}. In all other states * a non-<code>null</code> return value uniquely identifies a persistent object in the scope of the whole repository. - * + * * @see #cdoState() */ public CDOID cdoID(); @@ -63,7 +63,7 @@ public interface CDOObject extends EObject, CDOWithID * <p> * This method is a convenience method to determine whether the {@link #cdoState() state} of this object is either * {@link CDOState#CONFLICT CONFLICT} or {@link CDOState#INVALID_CONFLICT INVALID_CONFLICT}. - * + * * @since 2.0 */ public boolean cdoConflict(); @@ -74,7 +74,7 @@ public interface CDOObject extends EObject, CDOWithID * <p> * This method is a convenience method to determine whether the {@link #cdoState() state} of this object is either * {@link CDOState#INVALID INVALID} or {@link CDOState#INVALID_CONFLICT INVALID_CONFLICT}. - * + * * @since 2.0 */ public boolean cdoInvalid(); @@ -82,7 +82,7 @@ public interface CDOObject extends EObject, CDOWithID /** * Returns the {@link CDOView view} this object is associated with, or <code>null</code> if this object is not * associated with a view. This view manages all aspects of this object and cahces it as long as required. - * + * * @since 2.0 */ public CDOView cdoView(); @@ -101,7 +101,7 @@ public interface CDOObject extends EObject, CDOWithID * This method may not return <code>null</code> return for objects that have no {@link #cdoDirectResource() direct * resource}. Please note that, depending on the containment depth of this object, the evaluation of the resource can * be a costly operation. - * + * * @see #cdoDirectResource() */ public CDOResource cdoResource(); @@ -112,14 +112,14 @@ public interface CDOObject extends EObject, CDOWithID * <p> * Please note that, independend of the containment depth of this object, the evaluation of the direct resource is an * operation with a constant cost. - * + * * @since 2.0 */ public CDOResource cdoDirectResource(); /** * Returns the read lock associated with this object. - * + * * @return Never <code>null</code>. * @since 2.0 */ @@ -127,7 +127,7 @@ public interface CDOObject extends EObject, CDOWithID /** * Returns the write lock associated with this object. - * + * * @return Never <code>null</code>. * @since 2.0 */ @@ -143,14 +143,14 @@ public interface CDOObject extends EObject, CDOWithID * <p> * It thus allows a view to ensure that it is the only that who will be able to obtain a write lock in the future, * without preventing read locks to be obtained by others at this moment. - * + * * @since 4.1 */ public CDOLock cdoWriteOption(); /** * Returns the {@link CDOLockState} of this object. - * + * * @since 4.1 */ public CDOLockState cdoLockState(); @@ -159,7 +159,7 @@ public interface CDOObject extends EObject, CDOWithID * Ensures that the revisions of the contained objects up to the given depth are in the local * {@link CDORevisionManager revision cache}. Subsequent access to the respective contained objects will not lead to * server round-trips after calling this method. - * + * * @param depth * {@link CDORevision#DEPTH_NONE}, {@link CDORevision#DEPTH_INFINITE} or any other positive integer number. * @since 3.0 @@ -170,4 +170,9 @@ public interface CDOObject extends EObject, CDOWithID * TODO: JavaDoc */ public void cdoReload(); + + /** + * @since 4.2 + */ + public CDOObjectHistory cdoHistory(); } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOObjectHistory.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOObjectHistory.java new file mode 100644 index 0000000000..5ba06fc4dc --- /dev/null +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/CDOObjectHistory.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others. + * 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.cdo; + +import org.eclipse.emf.cdo.common.commit.CDOCommitHistory; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; + +/** + * A cache for the {@link CDOCommitInfo commit infos} of an {@link CDOObject object}. + * + * @author Eike Stepper + * @since 4.2 + */ +public interface CDOObjectHistory extends CDOCommitHistory +{ + public CDOObject getCDOObject(); +} diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java index 3e49faed29..cb1a099095 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/transaction/CDOPushTransaction.java @@ -11,11 +11,13 @@ package org.eclipse.emf.cdo.transaction; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOObjectHistory; import org.eclipse.emf.cdo.CDOObjectReference; import org.eclipse.emf.cdo.common.CDOCommonRepository; 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.CDOCommitHistory; import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.revision.CDORevision; @@ -727,6 +729,22 @@ public class CDOPushTransaction extends Notifier implements CDOTransaction return delegate.compareRevisions(source); } + /** + * @since 4.2 + */ + public CDOCommitHistory getHistory() + { + return delegate.getHistory(); + } + + /** + * @since 4.2 + */ + public CDOObjectHistory getHistory(CDOObject object) + { + return delegate.getHistory(object); + } + public CDOSavepoint setSavepoint() { return delegate.setSavepoint(); diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java index 50f003e91c..7c0510dafa 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/cdo/view/CDOView.java @@ -16,11 +16,13 @@ import org.eclipse.emf.cdo.CDOAdapter; import org.eclipse.emf.cdo.CDOInvalidationNotification; import org.eclipse.emf.cdo.CDONotification; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOObjectHistory; import org.eclipse.emf.cdo.CDOObjectReference; import org.eclipse.emf.cdo.common.CDOCommonView; 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.CDOCommitHistory; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.revision.CDORevision; import org.eclipse.emf.cdo.common.util.CDOException; @@ -87,7 +89,8 @@ import java.util.Set; * @apiviz.uses {@link CDOViewLocksChangedEvent} - - fires * @apiviz.uses {@link CDOViewTargetChangedEvent} - - fires */ -public interface CDOView extends CDOCommonView, CDOUpdatable, INotifier +public interface CDOView extends CDOCommonView, CDOUpdatable, CDOCommitHistory.Provider<CDOObject, CDOObjectHistory>, + INotifier { /** * Returns the {@link CDOSession session} this view was opened by. diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java index 41c3237c20..d3d127c75f 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/CDOObjectImpl.java @@ -13,6 +13,7 @@ package org.eclipse.emf.internal.cdo; import org.eclipse.emf.cdo.CDOLock; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOObjectHistory; import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.lock.CDOLockState; @@ -165,6 +166,14 @@ public class CDOObjectImpl extends EStoreEObjectImpl implements InternalCDOObjec } /** + * @since 4.2 + */ + public CDOObjectHistory cdoHistory() + { + return view.getHistory(this); + } + + /** * @since 2.0 */ public boolean cdoConflict() diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOExternalObject.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOExternalObject.java index 7d806b4c2f..1c83dc47cf 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOExternalObject.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOExternalObject.java @@ -11,6 +11,7 @@ package org.eclipse.emf.internal.cdo.object; import org.eclipse.emf.cdo.CDOLock; +import org.eclipse.emf.cdo.CDOObjectHistory; import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.common.lock.CDOLockState; import org.eclipse.emf.cdo.common.revision.CDORevision; @@ -64,4 +65,9 @@ public class CDOExternalObject extends CDOObjectWrapperBase { // Do nothing } + + public CDOObjectHistory cdoHistory() + { + return null; + } } diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java index 3568f1e090..556cfa85f8 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/object/CDOLegacyWrapper.java @@ -12,6 +12,7 @@ package org.eclipse.emf.internal.cdo.object; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOObjectHistory; import org.eclipse.emf.cdo.CDOState; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.model.CDOModelUtil; @@ -133,6 +134,11 @@ public abstract class CDOLegacyWrapper extends CDOObjectWrapper CDOStateMachine.INSTANCE.reload(this); } + public CDOObjectHistory cdoHistory() + { + return view.getHistory(this); + } + public CDOState cdoInternalSetState(CDOState state) { if (this.state != state) diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java index 2d94d780a2..14bf61f6a9 100644 --- a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/AbstractCDOView.java @@ -13,11 +13,14 @@ package org.eclipse.emf.internal.cdo.view; import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOObjectHistory; import org.eclipse.emf.cdo.CDOObjectReference; import org.eclipse.emf.cdo.CDOState; 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.CDOCommitHistory; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfoManager; import org.eclipse.emf.cdo.common.id.CDOID; import org.eclipse.emf.cdo.common.id.CDOIDExternal; import org.eclipse.emf.cdo.common.id.CDOIDUtil; @@ -39,6 +42,7 @@ import org.eclipse.emf.cdo.eresource.CDOResourceNode; import org.eclipse.emf.cdo.eresource.CDOTextResource; import org.eclipse.emf.cdo.eresource.EresourcePackage; import org.eclipse.emf.cdo.eresource.impl.CDOResourceImpl; +import org.eclipse.emf.cdo.internal.common.commit.CDOCommitHistoryProviderImpl; import org.eclipse.emf.cdo.internal.common.revision.delta.CDORevisionDeltaImpl; import org.eclipse.emf.cdo.session.CDOSession; import org.eclipse.emf.cdo.spi.common.branch.CDOBranchUtil; @@ -70,7 +74,6 @@ import org.eclipse.net4j.util.collection.CloseableIterator; import org.eclipse.net4j.util.collection.ConcurrentArray; import org.eclipse.net4j.util.collection.Pair; import org.eclipse.net4j.util.event.IListener; -import org.eclipse.net4j.util.lifecycle.Lifecycle; import org.eclipse.net4j.util.lifecycle.LifecycleUtil; import org.eclipse.net4j.util.om.log.OMLogger; import org.eclipse.net4j.util.om.trace.ContextTracer; @@ -105,7 +108,8 @@ import java.util.Set; /** * @author Eike Stepper */ -public abstract class AbstractCDOView extends Lifecycle implements InternalCDOView +public abstract class AbstractCDOView extends CDOCommitHistoryProviderImpl<CDOObject, CDOObjectHistory> implements + InternalCDOView { private static final ContextTracer TRACER = new ContextTracer(OM.DEBUG_VIEW, AbstractCDOView.class); @@ -1553,6 +1557,20 @@ public abstract class AbstractCDOView extends Lifecycle implements InternalCDOVi } @Override + public CDOCommitHistory getHistory() + { + CDOBranch branch = getBranch(); + CDOCommitInfoManager commitInfoManager = getSession().getCommitInfoManager(); + return commitInfoManager.getHistory(branch); + } + + @Override + protected CDOCommitHistory createHistory(CDOObject key) + { + return new CDOObjectHistoryImpl(key); + } + + @Override protected void doDeactivate() throws Exception { viewSet = null; diff --git a/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOObjectHistoryImpl.java b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOObjectHistoryImpl.java new file mode 100644 index 0000000000..dc3baf14eb --- /dev/null +++ b/plugins/org.eclipse.emf.cdo/src/org/eclipse/emf/internal/cdo/view/CDOObjectHistoryImpl.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2004 - 2012 Eike Stepper (Berlin, Germany) and others. + * 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: + * Eike Stepper - initial API and implementation + */ +package org.eclipse.emf.internal.cdo.view; + +import org.eclipse.emf.cdo.CDOObject; +import org.eclipse.emf.cdo.CDOObjectHistory; +import org.eclipse.emf.cdo.common.branch.CDOBranchPoint; +import org.eclipse.emf.cdo.common.branch.CDOBranchVersion; +import org.eclipse.emf.cdo.common.commit.CDOCommitInfo; +import org.eclipse.emf.cdo.common.revision.CDORevision; +import org.eclipse.emf.cdo.common.revision.CDORevisionManager; +import org.eclipse.emf.cdo.internal.common.commit.CDOCommitHistoryImpl; + +/** + * A cache for the {@link CDOCommitInfo commit infos} of a branch or of an entire repository. + * + * @author Eike Stepper + * @since 4.2 + */ +public class CDOObjectHistoryImpl extends CDOCommitHistoryImpl implements CDOObjectHistory +{ + private final CDORevisionManager revisionManager; + + private final CDOObject object; + + private CDORevision loadedRevision; + + public CDOObjectHistoryImpl(CDOObject object) + { + super(object.cdoView().getSession().getCommitInfoManager(), object.cdoRevision().getBranch()); + revisionManager = object.cdoView().getSession().getRevisionManager(); + this.object = object; + } + + public CDOObject getCDOObject() + { + return object; + } + + @Override + protected void doLoadCommitInfos() + { + int count = getLoadCount(); + for (int i = 0; i < count; i++) + { + if (loadedRevision == null) + { + loadedRevision = object.cdoRevision(); + } + else + { + int version = loadedRevision.getVersion(); + if (version > CDOBranchVersion.FIRST_VERSION) + { + CDOBranchVersion previous = loadedRevision.getBranch().getVersion(version - 1); + loadedRevision = revisionManager.getRevisionByVersion(object.cdoID(), previous, CDORevision.UNCHUNKED, true); + } + else + { + CDOBranchPoint base = loadedRevision.getBranch().getBase(); + if (base.getBranch() == null) + { + // Reached repository creation + break; + } + + CDORevision revision = revisionManager.getRevision(object.cdoID(), base, CDORevision.UNCHUNKED, + CDORevision.DEPTH_NONE, true); + if (revision == null) + { + // Reached branch where the object does not exist + break; + } + + loadedRevision = revision; + } + } + + CDOCommitInfo commitInfo = getManager().getCommitInfo(loadedRevision.getTimeStamp()); + handleCommitInfo(commitInfo); + } + } +} |