timeaware: add Model.getRepository(node) (fixes #552362)
diff --git a/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/TimeAwareIndexer.java b/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/TimeAwareIndexer.java
index 65165e3..5b573a8 100644
--- a/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/TimeAwareIndexer.java
+++ b/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/TimeAwareIndexer.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2018 Aston University.
+ * Copyright (c) 2018-2019 Aston University.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
@@ -59,6 +59,7 @@
String lastRev;
try {
+ taGraph.setTime(0);
lastRev = getLastIndexedRevision(vcsManager);
} catch (Exception e) {
LOGGER.error("Could not fetch the last indexed revision", e);
@@ -89,17 +90,9 @@
console.println(String.format("Index revision %s (timepoint %d) of %s",
commit.getRevision(), epochMillis, commit.getDelta().getManager().getLocation()));
- taGraph.setTime(0);
- setLastIndexedRevision(vcsManager, commit.getRevision());
+ setIndexedRevision(vcsManager, commit);
}
}
-
- // The indexed repo might have commits in other paths - mark the last revision as done as well so
- // we do not keep trying to index again and again.
- synchronized (taGraph) {
- taGraph.setTime(0);
- setLastIndexedRevision(vcsManager, currentRevision);
- }
}
} catch (Exception e) {
LOGGER.error("Failed to synchronise repository " + vcsManager.getLocation(), e);
@@ -116,19 +109,20 @@
protected String getLastIndexedRevision(IVcsManager vcsManager) throws Exception {
String lastRev;
try (IGraphTransaction tx = graph.beginTransaction()) {
- VCSManagerIndex vcsIndex = new VCSManagerIndex(graph);
+ VCSManagerIndex vcsIndex = new VCSManagerIndex((ITimeAwareGraphDatabase) graph);
RepositoryNode repoNode = vcsIndex.getOrCreateRepositoryNode(vcsManager.getLocation());
- lastRev = repoNode.getLastRevision();
+ lastRev = repoNode.getLatest().getRevision();
tx.success();
}
return lastRev;
}
- protected void setLastIndexedRevision(IVcsManager vcsManager, String lastRev) throws Exception {
+ protected void setIndexedRevision(IVcsManager vcsManager, VcsCommit commit) throws Exception {
try (IGraphTransaction tx = graph.beginTransaction()) {
- VCSManagerIndex vcsIndex = new VCSManagerIndex(graph);
+ VCSManagerIndex vcsIndex = new VCSManagerIndex((ITimeAwareGraphDatabase) graph);
RepositoryNode repoNode = vcsIndex.getOrCreateRepositoryNode(vcsManager.getLocation());
- repoNode.setLastRevision(lastRev);
+ repoNode.setRevision(commit.getRevision());
+ repoNode.setMessage(commit.getMessage());
tx.success();
}
}
diff --git a/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/VCSManagerIndex.java b/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/VCSManagerIndex.java
index 024a887..013acb6 100644
--- a/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/VCSManagerIndex.java
+++ b/plugins/org.hawk.timeaware/src/org/hawk/timeaware/graph/VCSManagerIndex.java
@@ -17,13 +17,12 @@
package org.hawk.timeaware.graph;
import java.util.Collections;
-import java.util.List;
-import org.hawk.core.graph.IGraphDatabase;
import org.hawk.core.graph.IGraphIterable;
import org.hawk.core.graph.IGraphNode;
-import org.hawk.core.graph.IGraphNodeIndex;
+import org.hawk.core.graph.timeaware.ITimeAwareGraphDatabase;
import org.hawk.core.graph.timeaware.ITimeAwareGraphNode;
+import org.hawk.core.graph.timeaware.ITimeAwareGraphNodeIndex;
/**
* Keeps track of information in the graph about the various VCS. This class
@@ -32,17 +31,19 @@
public class VCSManagerIndex {
private static final String URI_PROPERTY = "uri";
- private final IGraphNodeIndex idx;
- private final IGraphDatabase db;
+ private final ITimeAwareGraphNodeIndex idx;
+ private final ITimeAwareGraphDatabase db;
/**
* Type-safe wrapper for the node we keep in the graph about a repository.
*/
public class RepositoryNode {
private static final String LASTREV_PROPERTY = "lastRevision";
- private final IGraphNode node;
+ private static final String MESSAGE_PROPERTY = "message";
- public RepositoryNode(IGraphNode n) {
+ private final ITimeAwareGraphNode node;
+
+ public RepositoryNode(ITimeAwareGraphNode n) {
this.node = n;
}
@@ -51,10 +52,10 @@
}
/**
- * Returns the last revision indexed for this VCS, or <code>null</code> if it
- * has not been indexed yet.
+ * Returns the revision indexed for this VCS at its current timepoint, or
+ * <code>null</code> if it has not been indexed yet.
*/
- public String getLastRevision() {
+ public String getRevision() {
final Object lastRev = node.getProperty(LASTREV_PROPERTY);
if (lastRev == null) {
return null;
@@ -66,20 +67,55 @@
/**
* Changes the last revision indexed for this VCS.
*/
- public void setLastRevision(String lastRev) {
+ public void setRevision(String lastRev) {
node.setProperty(LASTREV_PROPERTY, lastRev);
}
- public IGraphNode getNode() {
- return node;
+ /**
+ * Returns the latest version of this repository node.
+ *
+ * @throws Exception Error while fetching the latest version.
+ */
+ public RepositoryNode getLatest() throws Exception {
+ return new RepositoryNode(node.getLatest());
}
+
+ /**
+ * Returns the node at a different point in time.
+ */
+ public RepositoryNode travelInTime(long instant) throws Exception {
+ return new RepositoryNode(node.travelInTime(instant));
+ }
+
+ /**
+ * Returns the commit message associated with this revision.
+ */
+ public String getMessage() {
+ final Object message = node.getProperty(MESSAGE_PROPERTY);
+ return message == null ? null : message.toString();
+ }
+
+ /**
+ * Stores the commit message associated with this revision.
+ */
+ public void setMessage(String message) {
+ node.setProperty(MESSAGE_PROPERTY, message);
+ }
+
+ /**
+ * Returns the underlying node ID.
+ */
+ public Object getId() {
+ return node.getId();
+ }
+
}
/**
* Creates a new instance. Retrieves the existing node index in the graph,
* or creates a new one if it does not exist.
*/
- public VCSManagerIndex(IGraphDatabase db) {
+ public VCSManagerIndex(ITimeAwareGraphDatabase db) {
this.db = db;
this.idx = db.getOrCreateNodeIndex("_hawkVCSIndex");
}
@@ -91,9 +127,9 @@
public RepositoryNode getOrCreateRepositoryNode(String repoURI) {
IGraphIterable<? extends IGraphNode> iNode = idx.get(URI_PROPERTY, repoURI);
if (iNode.size() > 0) {
- return new RepositoryNode(iNode.getSingle());
+ return new RepositoryNode((ITimeAwareGraphNode) iNode.getSingle());
} else {
- final IGraphNode node = db.createNode(
+ final ITimeAwareGraphNode node = db.createNode(
Collections.singletonMap(URI_PROPERTY, repoURI), "_hawkRepo");
idx.add(node, URI_PROPERTY, repoURI);
return new RepositoryNode(node);
diff --git a/plugins/org.hawk.timeaware/src/org/hawk/timeaware/queries/TimeAwareEOLQueryEngine.java b/plugins/org.hawk.timeaware/src/org/hawk/timeaware/queries/TimeAwareEOLQueryEngine.java
index 2b580e9..f4ff8d9 100644
--- a/plugins/org.hawk.timeaware/src/org/hawk/timeaware/queries/TimeAwareEOLQueryEngine.java
+++ b/plugins/org.hawk.timeaware/src/org/hawk/timeaware/queries/TimeAwareEOLQueryEngine.java
@@ -47,6 +47,8 @@
import org.hawk.graph.FileNode;
import org.hawk.graph.GraphWrapper;
import org.hawk.graph.ModelElementNode;
+import org.hawk.timeaware.graph.VCSManagerIndex;
+import org.hawk.timeaware.graph.VCSManagerIndex.RepositoryNode;
import org.hawk.timeaware.queries.operations.reflective.TimeAwareNodeHistoryOperationContributor;
import org.hawk.timeaware.queries.operations.reflective.TypeHistoryOperationContributor;
import org.slf4j.Logger;
@@ -263,6 +265,29 @@
return allFNW;
}
+ /**
+ * Returns the {@link RepositoryNode} associated with this instance node.
+ *
+ * @throws Exception Error while travelling in time to the matching instant on
+ * the repository node.
+ */
+ public RepositoryNode getRepository(Object oInstanceNode) throws Exception {
+ if (oInstanceNode instanceof GraphNodeWrapper) {
+ GraphNodeWrapper gnw = (GraphNodeWrapper) oInstanceNode;
+ if (gnw.getNode() instanceof ITimeAwareGraphNode) {
+ ITimeAwareGraphNode taNode = (ITimeAwareGraphNode) gnw.getNode();
+ ModelElementNode me = new ModelElementNode(taNode);
+ String repoURL = me.getFileNode().getRepositoryURL();
+
+ final ITimeAwareGraphDatabase taGraph = (ITimeAwareGraphDatabase) graph;
+ final RepositoryNode repoNode = new VCSManagerIndex(taGraph).getOrCreateRepositoryNode(repoURL);
+
+ return repoNode.travelInTime(taNode.getTime());
+ }
+ }
+ return null;
+ }
+
private void setAllFiles(Function<IGraphNode, Iterable<? extends IGraphNode>> allFiles) {
this.allFiles = allFiles;
}
diff --git a/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/NodeHistoryTest.java b/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/NodeHistoryTest.java
index a9cb661..6fdda35 100644
--- a/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/NodeHistoryTest.java
+++ b/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/NodeHistoryTest.java
@@ -24,7 +24,6 @@
import java.io.File;
import java.util.Arrays;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
@@ -33,7 +32,6 @@
import org.hawk.backend.tests.BackendTestSuite;
import org.hawk.backend.tests.factories.IGraphDatabaseFactory;
import org.hawk.core.graph.timeaware.ITimeAwareGraphNode;
-import org.hawk.epsilon.emc.EOLQueryEngine;
import org.hawk.epsilon.emc.wrappers.GraphNodeWrapper;
import org.hawk.integration.tests.emf.EMFModelSupportFactory;
import org.hawk.svn.tests.rules.TemporarySVNRepository;
@@ -225,6 +223,23 @@
}
@Test
+ public void commitMessages() throws Throwable {
+ keepAddingChildren();
+ waitForSync(() -> {
+ assertEquals("Create root",
+ timeAwareEOL("return Model.getRepository(Tree.latest.all.selectOne(t|t.label='Root').earliest).message;"));
+ assertEquals("Add T1",
+ timeAwareEOL("return Model.getRepository(Tree.latest.all.selectOne(t|t.label='T1').earliest).message;"));
+ assertEquals("Add T2",
+ timeAwareEOL("return Model.getRepository(Tree.latest.all.selectOne(t|t.label='T2').earliest).message;"));
+ assertEquals("Add T3",
+ timeAwareEOL("return Model.getRepository(Tree.latest.all.selectOne(t|t.label='T3').earliest).message;"));
+
+ return null;
+ });
+ }
+
+ @Test
public void rangesAreBothInclusive() throws Throwable {
keepAddingChildren();
waitForSync(() -> {
diff --git a/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/VCSManagerIndexTest.java b/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/VCSManagerIndexTest.java
index 8d1a0cb..648d720 100644
--- a/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/VCSManagerIndexTest.java
+++ b/tests/org.hawk.timeaware.tests/src/org/hawk/timeaware/tests/VCSManagerIndexTest.java
@@ -26,6 +26,7 @@
import org.hawk.backend.tests.factories.IGraphDatabaseFactory;
import org.hawk.core.graph.IGraphDatabase;
import org.hawk.core.graph.IGraphTransaction;
+import org.hawk.core.graph.timeaware.ITimeAwareGraphDatabase;
import org.hawk.core.util.DefaultConsole;
import org.hawk.timeaware.graph.VCSManagerIndex;
import org.hawk.timeaware.graph.VCSManagerIndex.RepositoryNode;
@@ -70,7 +71,7 @@
db.run(dbFolder, new DefaultConsole());
try (IGraphTransaction tx = db.beginTransaction()) {
- this.idx = new VCSManagerIndex(db);
+ this.idx = new VCSManagerIndex((ITimeAwareGraphDatabase) db);
tx.success();
}
}
@@ -86,8 +87,8 @@
}
try (IGraphTransaction tx = db.beginTransaction()) {
assertEquals(repoURI, node.getURI());
- assertNull(node.getLastRevision());
- assertEquals(node.getNode().getId(), idx.getOrCreateRepositoryNode(repoURI).getNode().getId());
+ assertNull(node.getRevision());
+ assertEquals(node.getId(), idx.getOrCreateRepositoryNode(repoURI).getId());
tx.success();
}
}
@@ -99,12 +100,12 @@
try (IGraphTransaction tx = db.beginTransaction()) {
RepositoryNode node = idx.getOrCreateRepositoryNode(repoURI);
- node.setLastRevision(lastRev);
+ node.setRevision(lastRev);
tx.success();
}
try (IGraphTransaction tx = db.beginTransaction()) {
RepositoryNode node = idx.getOrCreateRepositoryNode(repoURI);
- assertEquals(lastRev, node.getLastRevision());
+ assertEquals(lastRev, node.getRevision());
tx.success();
}
}
@@ -116,18 +117,18 @@
Object firstId;
try (IGraphTransaction tx = db.beginTransaction()) {
RepositoryNode node = idx.getOrCreateRepositoryNode(repoURI);
- firstId = node.getNode().getId();
+ firstId = node.getId();
tx.success();
}
try (IGraphTransaction tx = db.beginTransaction()) {
RepositoryNode node = idx.getOrCreateRepositoryNode(repoURI);
- assertEquals(firstId, node.getNode().getId());
+ assertEquals(firstId, node.getId());
idx.removeRepositoryNode(repoURI);
tx.success();
}
try (IGraphTransaction tx = db.beginTransaction()) {
RepositoryNode node = idx.getOrCreateRepositoryNode(repoURI);
- assertNotEquals(firstId, node.getNode().getId());
+ assertNotEquals(firstId, node.getId());
tx.success();
}
}