diff --git a/pom.xml b/pom.xml
index 82a3d0d..e80320d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -82,6 +82,13 @@
2.4.0
+
+
+
+ org.springframework.boot
+ spring-boot-devtools
+ true
+
@@ -91,11 +98,8 @@
spring-boot-maven-plugin
-
-
-
spring-snapshots
@@ -118,6 +122,4 @@
-
-
\ No newline at end of file
diff --git a/src/main/examples/transcriptional_unit.txt b/src/main/examples/transcriptional_unit.txt
index 0106477..370a778 100644
--- a/src/main/examples/transcriptional_unit.txt
+++ b/src/main/examples/transcriptional_unit.txt
@@ -16,12 +16,12 @@ CREATE (d1)-[:CONTAINS]->(n8)
CREATE (d1)-[:CONTAINS]->(n10)
CREATE (d1)-[:CONTAINS]->(n13)
-CREATE (n1)-[:PRECEDES {componentIDs: ["p1"], componentRoles: ["promoter"], orientation: "inline"}]->(n2)
-CREATE (n2)-[:PRECEDES {componentIDs: ["p2"], componentRoles: ["promoter"], orientation: "inline"}]->(n4)
-CREATE (n4)-[:PRECEDES {componentIDs: ["rz1"], componentRoles: ["ribozyme"], orientation: "inline"}]->(n6)
-CREATE (n6)-[:PRECEDES {componentIDs: ["rb1"], componentRoles: ["ribosome_entry_site"], orientation: "inline"}]->(n8)
-CREATE (n8)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "inline"}]->(n10)
-CREATE (n10)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "inline"}]->(n13)
+CREATE (n1)-[:PRECEDES {componentIDs: ["p1"], componentRoles: ["promoter"], orientation: "INLINE"}]->(n2)
+CREATE (n2)-[:PRECEDES {componentIDs: ["p2"], componentRoles: ["promoter"], orientation: "INLINE"}]->(n4)
+CREATE (n4)-[:PRECEDES {componentIDs: ["rz1"], componentRoles: ["ribozyme"], orientation: "INLINE"}]->(n6)
+CREATE (n6)-[:PRECEDES {componentIDs: ["rb1"], componentRoles: ["ribosome_entry_site"], orientation: "INLINE"}]->(n8)
+CREATE (n8)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "INLINE"}]->(n10)
+CREATE (n10)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "INLINE"}]->(n13)
CREATE (d1)-[:ARCHIVES]->(b0:Branch {branchID: "test1"})-[:CONTAINS]->(c0:Commit {commitID: "c0"})-[:CONTAINS]->(s1:Snapshot {nodeIndex: 7})
CREATE (d1)-[:SELECTS]->(b0)-[:LATEST]->(c0)
@@ -42,12 +42,12 @@ CREATE (s1)-[:CONTAINS]->(n31)
CREATE (s1)-[:CONTAINS]->(n33)
CREATE (s1)-[:CONTAINS]->(n36)
-CREATE (n23)-[:PRECEDES {componentIDs: ["p1"], componentRoles: ["promoter"], orientation: "inline"}]->(n25)
-CREATE (n25)-[:PRECEDES {componentIDs: ["p2"], componentRoles: ["promoter"], orientation: "inline"}]->(n27)
-CREATE (n27)-[:PRECEDES {componentIDs: ["rz1"], componentRoles: ["ribozyme"], orientation: "inline"}]->(n29)
-CREATE (n29)-[:PRECEDES {componentIDs: ["rb1"], componentRoles: ["ribosome_entry_site"], orientation: "inline"}]->(n31)
-CREATE (n31)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "inline"}]->(n33)
-CREATE (n33)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "inline"}]->(n36)
+CREATE (n23)-[:PRECEDES {componentIDs: ["p1"], componentRoles: ["promoter"], orientation: "INLINE"}]->(n25)
+CREATE (n25)-[:PRECEDES {componentIDs: ["p2"], componentRoles: ["promoter"], orientation: "INLINE"}]->(n27)
+CREATE (n27)-[:PRECEDES {componentIDs: ["rz1"], componentRoles: ["ribozyme"], orientation: "INLINE"}]->(n29)
+CREATE (n29)-[:PRECEDES {componentIDs: ["rb1"], componentRoles: ["ribosome_entry_site"], orientation: "INLINE"}]->(n31)
+CREATE (n31)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "INLINE"}]->(n33)
+CREATE (n33)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "INLINE"}]->(n36)
CREATE (d2:DesignSpace {spaceID: "test2", nodeIndex: 5, commitIndex: 1})
@@ -63,10 +63,10 @@ CREATE (d2)-[:CONTAINS]->(n17)
CREATE (d2)-[:CONTAINS]->(n19)
CREATE (d2)-[:CONTAINS]->(n22)
-CREATE (n13b)-[:PRECEDES {componentIDs: ["p1","p2"], componentRoles: ["promoter"], orientation: "inline"}]->(n15)
-CREATE (n15)-[:PRECEDES {componentIDs: ["rb1","rb2"], componentRoles: ["ribosome_entry_site"], orientation: "inline"}]->(n17)
-CREATE (n17)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "inline"}]->(n19)
-CREATE (n19)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "inline"}]->(n22)
+CREATE (n13b)-[:PRECEDES {componentIDs: ["p1","p2"], componentRoles: ["promoter"], orientation: "INLINE"}]->(n15)
+CREATE (n15)-[:PRECEDES {componentIDs: ["rb1","rb2"], componentRoles: ["ribosome_entry_site"], orientation: "INLINE"}]->(n17)
+CREATE (n17)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "INLINE"}]->(n19)
+CREATE (n19)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "INLINE"}]->(n22)
CREATE (d2)-[:ARCHIVES]->(b1:Branch {branchID: "test2"})-[:CONTAINS]->(c1:Commit {commitID: "c0"})-[:CONTAINS]->(s2:Snapshot {nodeIndex: 5})
CREATE (d2)-[:SELECTS]->(b1)-[:LATEST]->(c1)
@@ -83,9 +83,9 @@ CREATE (s2)-[:CONTAINS]->(n41)
CREATE (s2)-[:CONTAINS]->(n43)
CREATE (s2)-[:CONTAINS]->(n46)
-CREATE (n37)-[:PRECEDES {componentIDs: ["p1","p2"], componentRoles: ["promoter"], orientation: "inline"}]->(n39)
-CREATE (n39)-[:PRECEDES {componentIDs: ["rb1","rb2"], componentRoles: ["ribosome_entry_site"], orientation: "inline"}]->(n41)
-CREATE (n41)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "inline"}]->(n43)
-CREATE (n43)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "inline"}]->(n46)
+CREATE (n37)-[:PRECEDES {componentIDs: ["p1","p2"], componentRoles: ["promoter"], orientation: "INLINE"}]->(n39)
+CREATE (n39)-[:PRECEDES {componentIDs: ["rb1","rb2"], componentRoles: ["ribosome_entry_site"], orientation: "INLINE"}]->(n41)
+CREATE (n41)-[:PRECEDES {componentIDs: ["c1"], componentRoles: ["CDS"], orientation: "INLINE"}]->(n43)
+CREATE (n43)-[:PRECEDES {componentIDs: ["t1"], componentRoles: ["terminator"], orientation: "INLINE"}]->(n46)
;
\ No newline at end of file
diff --git a/src/main/java/knox/spring/data/neo4j/controller/KnoxController.java b/src/main/java/knox/spring/data/neo4j/controller/KnoxController.java
index 99a1aaf..9fd3148 100644
--- a/src/main/java/knox/spring/data/neo4j/controller/KnoxController.java
+++ b/src/main/java/knox/spring/data/neo4j/controller/KnoxController.java
@@ -4,10 +4,8 @@
import java.io.InputStream;
import java.util.*;
-import knox.spring.data.neo4j.domain.DesignSpace;
import knox.spring.data.neo4j.exception.*;
import knox.spring.data.neo4j.sample.DesignSampler.EnumerateType;
-import knox.spring.data.neo4j.sbol.SBOLConversion;
import knox.spring.data.neo4j.services.DesignSpaceService;
import org.sbolstandard.core2.SBOLConversionException;
@@ -522,6 +520,38 @@ public ResponseEntity mergeDesignSpaces(@RequestParam(value = "inputSpac
}
}
+ /**
+ * @api {post} /designSpace/reverse Reverse
+ * @apiName reverseDesignSpace
+ * @apiGroup DesignSpace
+ *
+ * @apiParam {String} inputSpaceID ID for the input design space to be reversed.
+ * @apiParam {String} outputSpaceID ID for the output design space resulting from reverse. If omitted, then the result is
+ * stored in the input design space.
+ *
+ * @apiDescription Reverse the edges from the input design space.
+ */
+ @RequestMapping(value = "/designSpace/reverse", method = RequestMethod.POST)
+ public ResponseEntity reverseDesignSpace(@RequestParam(value = "inputSpaceID", required = true) String inputSpaceID,
+ @RequestParam(value = "outputSpaceID", required = false) String outputSpaceID) {
+ try {
+ long startTime = System.nanoTime();
+
+ if (outputSpaceID == null) {
+ designSpaceService.reverseDesignSpace(inputSpaceID);
+ } else {
+ designSpaceService.reverseDesignSpace(inputSpaceID, outputSpaceID);
+ }
+
+ return new ResponseEntity("{\"message\": \"Design space was successfully reversed after " +
+ (System.nanoTime() - startTime) + " ns.\"}", HttpStatus.NO_CONTENT);
+ } catch (ParameterEmptyException | DesignSpaceNotFoundException |
+ DesignSpaceConflictException | DesignSpaceBranchesConflictException ex) {
+ return new ResponseEntity("{\"message\": \"" + ex.getMessage() + "\"}",
+ HttpStatus.BAD_REQUEST);
+ }
+ }
+
/**
* @api {post} /designSpace/or OR
* @apiName orDesignSpaces
diff --git a/src/main/java/knox/spring/data/neo4j/domain/Edge.java b/src/main/java/knox/spring/data/neo4j/domain/Edge.java
index ec5547e..1248fc9 100644
--- a/src/main/java/knox/spring/data/neo4j/domain/Edge.java
+++ b/src/main/java/knox/spring/data/neo4j/domain/Edge.java
@@ -555,7 +555,6 @@ public boolean hasOrientation() {
return isInline() || isReverseComplement();
}
-
public boolean hasOrientation(Orientation orientation) {
return hasOrientation() && this.orientation.equals(orientation);
}
diff --git a/src/main/java/knox/spring/data/neo4j/operations/ReverseOperator.java b/src/main/java/knox/spring/data/neo4j/operations/ReverseOperator.java
new file mode 100644
index 0000000..875380e
--- /dev/null
+++ b/src/main/java/knox/spring/data/neo4j/operations/ReverseOperator.java
@@ -0,0 +1,22 @@
+package knox.spring.data.neo4j.operations;
+
+import knox.spring.data.neo4j.domain.Edge;
+import knox.spring.data.neo4j.domain.NodeSpace;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+public class ReverseOperator {
+ public static void apply(NodeSpace inputSpace, NodeSpace outputSpace) {
+ //copy input space to a new output space
+ outputSpace.copyNodeSpace(inputSpace);
+
+ Set allEdges = outputSpace.getEdges();
+
+ //traverse all edges of input space and flip the orientation attribute
+ for(Edge edge: allEdges){
+ edge.reverseOrientation();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/knox/spring/data/neo4j/services/DesignSpaceService.java b/src/main/java/knox/spring/data/neo4j/services/DesignSpaceService.java
index a106b58..70baa56 100644
--- a/src/main/java/knox/spring/data/neo4j/services/DesignSpaceService.java
+++ b/src/main/java/knox/spring/data/neo4j/services/DesignSpaceService.java
@@ -9,14 +9,11 @@
import knox.spring.data.neo4j.domain.Snapshot;
import knox.spring.data.neo4j.exception.*;
import knox.spring.data.neo4j.operations.ANDOperator;
-import knox.spring.data.neo4j.operations.Concatenation;
import knox.spring.data.neo4j.operations.JoinOperator;
import knox.spring.data.neo4j.operations.MergeOperator;
import knox.spring.data.neo4j.operations.OROperator;
-import knox.spring.data.neo4j.operations.Product;
+import knox.spring.data.neo4j.operations.ReverseOperator;
import knox.spring.data.neo4j.operations.RepeatOperator;
-import knox.spring.data.neo4j.operations.Star;
-import knox.spring.data.neo4j.operations.Union;
import knox.spring.data.neo4j.repositories.BranchRepository;
import knox.spring.data.neo4j.repositories.CommitRepository;
import knox.spring.data.neo4j.repositories.DesignSpaceRepository;
@@ -325,7 +322,31 @@ public void mergeBranches(String targetSpaceID, List inputBranchIDs,
saveDesignSpace(targetSpace);
}
-
+
+ public void reverseDesignSpace(String inputSpaceID) {
+ reverseDesignSpace(inputSpaceID, inputSpaceID);
+ }
+
+ public void reverseDesignSpace(String inputSpaceID, String outputSpaceID) {
+ List inputSpaceIDs = new ArrayList<>();
+ inputSpaceIDs.add(inputSpaceID);
+ List inputSpaces = new ArrayList(inputSpaceIDs.size());
+
+ DesignSpace outputSpace = loadIOSpaces(inputSpaceIDs, outputSpaceID, inputSpaces);
+
+ ReverseOperator.apply(inputSpaces.get(0), outputSpace);
+
+
+ List inputSnaps = new ArrayList(inputSpaces.size());
+
+ NodeSpace outputSnap = mergeVersionHistories(castNodeSpacesToDesignSpaces(inputSpaces),
+ outputSpace, inputSnaps);
+
+ ReverseOperator.apply(inputSnaps.get(0), outputSnap);
+
+ saveDesignSpace(outputSpace);
+ }
+
private DesignSpace loadIOSpaces(List inputSpaceIDs, String outputSpaceID,
List inputSpaces) {
for (String inputSpaceID : inputSpaceIDs) {
@@ -863,7 +884,8 @@ private DesignSpace findDesignSpace(String targetSpaceID) {
}
private DesignSpace loadDesignSpace(String targetSpaceID) {
- DesignSpace targetSpace = designSpaceRepository.findOne(getDesignSpaceGraphID(targetSpaceID), 3);
+ Long keyID = getDesignSpaceGraphID(targetSpaceID);
+ DesignSpace targetSpace = designSpaceRepository.findOne(keyID, 3);
for (Commit commit : targetSpace.getCommits()) {
commit.setSnapshot(reloadSnapshot(commit.getSnapshot()));
diff --git a/src/main/resources/static/js/endpoints.js b/src/main/resources/static/js/endpoints.js
index 912b74f..346377b 100644
--- a/src/main/resources/static/js/endpoints.js
+++ b/src/main/resources/static/js/endpoints.js
@@ -30,7 +30,8 @@ export const operators = {
OR: 'or',
AND: 'and',
MERGE: 'merge',
- REPEAT: 'repeat'
+ REPEAT: 'repeat',
+ REVERSE: 'reverse'
};
@@ -288,4 +289,19 @@ export function designSpaceMerge(inputSpaces, outputSpace, tolerance){
} else {
swalError(request.response);
}
+}
+
+export function designSpaceReverse(inputSpace, outputSpace){
+ let query = "?";
+ query += encodeQueryParameter("inputSpaceID", inputSpace, query);
+ query += encodeQueryParameter("outputSpaceID", outputSpace, query);
+
+ let request = new XMLHttpRequest();
+ request.open("POST", endpoints.DESIGN + "/" + operators.REVERSE + query, false);
+ request.send(null);
+ if (request.status >= 200 && request.status < 300) {
+ swalSuccess();
+ } else {
+ swalError(request.response);
+ }
}
\ No newline at end of file
diff --git a/src/main/resources/static/js/knox.js b/src/main/resources/static/js/knox.js
index fea12f9..849376c 100644
--- a/src/main/resources/static/js/knox.js
+++ b/src/main/resources/static/js/knox.js
@@ -517,6 +517,15 @@ $('#apply-operators-tooltip').click(() => {
}
div.appendChild(tolDiv);
}
+ if(this.value === endpoint.operators.REVERSE){
+ if(div.contains(inputDiv)){
+ div.removeChild(inputDiv);
+ }
+ const guidance = document.createElement("P");
+ const text = document.createTextNode("The current designSpace will be reversed.");
+ guidance.appendChild(text);
+ div.appendChild(guidance);
+ }
});
swal({
@@ -557,6 +566,11 @@ $('#apply-operators-tooltip').click(() => {
case endpoint.operators.MERGE:
endpoint.designSpaceMerge(inputSpaces, outputSpace, tolerance);
break;
+
+ case endpoint.operators.REVERSE:
+ // the reverse operator would only reverse one inputSpace
+ endpoint.designSpaceReverse(inputSpaces[0], outputSpace);
+ break;
}
}
});