From 0e3ca786fa1d1e46fd49b3a11e48f7f869801890 Mon Sep 17 00:00:00 2001 From: Zackhardtoname Date: Mon, 29 Jul 2019 16:43:18 -0400 Subject: [PATCH] Implement reverse operator Functionality: reverse the edges from the input design space. Details: Upon selecting reverse operator a. Delete input option b. Display some guidance Close #14 --- .../data/neo4j/controller/KnoxController.java | 34 +++++++++++++++++-- .../knox/spring/data/neo4j/domain/Edge.java | 1 - .../neo4j/operations/ReverseOperator.java | 22 ++++++++++++ .../neo4j/services/DesignSpaceService.java | 34 +++++++++++++++---- src/main/resources/static/js/endpoints.js | 18 +++++++++- src/main/resources/static/js/knox.js | 14 ++++++++ 6 files changed, 113 insertions(+), 10 deletions(-) create mode 100644 src/main/java/knox/spring/data/neo4j/operations/ReverseOperator.java 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; } } });