diff --git a/src/main/java/knox/spring/data/neo4j/domain/NodeSpace.java b/src/main/java/knox/spring/data/neo4j/domain/NodeSpace.java index 5143a9b..cc4c0a6 100644 --- a/src/main/java/knox/spring/data/neo4j/domain/NodeSpace.java +++ b/src/main/java/knox/spring/data/neo4j/domain/NodeSpace.java @@ -830,15 +830,16 @@ public void deleteBlankEdges(Set blankEdges) { } public boolean deleteBlankEdge(Edge edge, HashMap> nodeIDToIncomingEdges) { - if ((nodeIDToIncomingEdges.get(edge.getHeadID()).size() == 1 || edge.getTail().getNumEdges() == 1) + if (((nodeIDToIncomingEdges.containsKey(edge.getHeadID()) && nodeIDToIncomingEdges.get(edge.getHeadID()).size() == 1) + || edge.getTail().getNumEdges() == 1) && !edge.getTail().hasDiffNodeType(edge.getHead()) && (!edge.getTail().isAcceptNode() || edge.getHead().isAcceptNode() || nodeIDToIncomingEdges.get(edge.getHeadID()).size() == 1) && (!edge.getHead().isStartNode() || edge.getTail().isStartNode() || edge.getTail().getNumEdges() == 1) && (!edge.getTail().isStartNode() - || nodeIDToIncomingEdges.get(edge.getHeadID()).size() == 1 - || !nodeIDToIncomingEdges.get(edge.getTailID()).isEmpty())) { + || (nodeIDToIncomingEdges.containsKey(edge.getHeadID()) && nodeIDToIncomingEdges.get(edge.getHeadID()).size() == 1) + || (nodeIDToIncomingEdges.containsKey(edge.getTailID()) && !nodeIDToIncomingEdges.get(edge.getTailID()).isEmpty()))) { edge.delete(); Set headEdges = edge.getHead().removeEdges(); @@ -851,11 +852,13 @@ public boolean deleteBlankEdge(Edge edge, HashMap> nodeIDToInc Set incomingHeadEdges = new HashSet(); - for (Edge incomingHeadEdge : nodeIDToIncomingEdges.get(edge.getHeadID())) { - if (incomingHeadEdge != edge) { - incomingHeadEdge.setHead(edge.getTail()); - - incomingHeadEdges.add(incomingHeadEdge); + if (nodeIDToIncomingEdges.containsKey(edge.getHeadID())) { + for (Edge incomingHeadEdge : nodeIDToIncomingEdges.get(edge.getHeadID())) { + if (incomingHeadEdge != edge) { + incomingHeadEdge.setHead(edge.getTail()); + + incomingHeadEdges.add(incomingHeadEdge); + } } } diff --git a/src/main/java/knox/spring/data/neo4j/sbol/SBOLConversion.java b/src/main/java/knox/spring/data/neo4j/sbol/SBOLConversion.java index 1fe436f..bf0558c 100644 --- a/src/main/java/knox/spring/data/neo4j/sbol/SBOLConversion.java +++ b/src/main/java/knox/spring/data/neo4j/sbol/SBOLConversion.java @@ -85,40 +85,41 @@ private List recurseVariableComponents(CombinatorialDerivation combin // order components by sequence constraints VariableComponent[] sortedVCs = sortVariableComponents(combinatorialDerivation); for (VariableComponent variableComponent : sortedVCs) { + if (variableComponent != null) { + // recurse through variant derivations + Set variantDerivs = variableComponent.getVariantDerivations(); - // recurse through variant derivations - Set variantDerivs = variableComponent.getVariantDerivations(); + Boolean hasVariants = !variableComponent.getVariants().isEmpty() || !variableComponent.getVariantCollections().isEmpty(); - Boolean hasVariants = !variableComponent.getVariants().isEmpty() || !variableComponent.getVariantCollections().isEmpty(); - - //handle structure for just repeats - if (variantDerivs.size() == 1 && !hasVariants){ - for (CombinatorialDerivation cv : variantDerivs) { - inputSpace.add(applyOperator(variableComponent.getOperator(), recurseVariableComponents(cv))); + //handle structure for just repeats + if (variantDerivs.size() == 1 && !hasVariants){ + for (CombinatorialDerivation cv : variantDerivs) { + inputSpace.add(applyOperator(variableComponent.getOperator(), recurseVariableComponents(cv))); + } } - } - //else handle collapsed complex ORs - else if (variantDerivs.size() > 0){ - List orSpace = new LinkedList<>(); - NodeSpace outputSpace = new NodeSpace(); + //else handle collapsed complex ORs + else if (variantDerivs.size() > 0){ + List orSpace = new LinkedList<>(); + NodeSpace outputSpace = new NodeSpace(); - if (hasVariants){ - orSpace.add(createNodeSpaceFromVariableComponent(variableComponent, template)); //add variants - } + if (hasVariants){ + orSpace.add(createNodeSpaceFromVariableComponent(variableComponent, template)); //add variants + } - for (CombinatorialDerivation cv : variantDerivs) { - orSpace.add(applyOperator(OperatorType.ONE, recurseVariableComponents(cv))); - } + for (CombinatorialDerivation cv : variantDerivs) { + orSpace.add(applyOperator(OperatorType.ONE, recurseVariableComponents(cv))); + } - OROperator.apply(orSpace, outputSpace); //"or" all the elements in the list - List tempSpace = new LinkedList<>(); - tempSpace.add(outputSpace); - inputSpace.add(applyOperator(variableComponent.getOperator(), tempSpace)); - } + OROperator.apply(orSpace, outputSpace); //"or" all the elements in the list + List tempSpace = new LinkedList<>(); + tempSpace.add(outputSpace); + inputSpace.add(applyOperator(variableComponent.getOperator(), tempSpace)); + } - else if (hasVariants){ - inputSpace.add(createNodeSpaceFromVariableComponent(variableComponent, template)); + else if (hasVariants){ + inputSpace.add(createNodeSpaceFromVariableComponent(variableComponent, template)); + } } } @@ -128,20 +129,69 @@ else if (hasVariants){ private VariableComponent[] sortVariableComponents(CombinatorialDerivation combinatorialDerivation){ //make ordered components from sequence constraints List orderedComponents = new ArrayList<>(); - Set seqConstraints = combinatorialDerivation.getTemplate().getSequenceConstraints(); + + ComponentDefinition template = combinatorialDerivation.getTemplate(); + Set seqConstraints = template.getSequenceConstraints(); + + //check if total ordering + Set subjectURIs = new HashSet(); + Set objectURIs = new HashSet(); + + Set firstURI = new HashSet(); + Set lastURI = new HashSet(); + + HashMap precedesMap = new HashMap(); + for (SequenceConstraint constraint : seqConstraints) { - //subject precedes object - Component subject = constraint.getSubject(); - Component object = constraint.getObject(); - int subIndex = orderedComponents.indexOf(subject); - int objIndex = orderedComponents.indexOf(object); - if (subIndex == -1 && objIndex == -1){ - orderedComponents.add(subject); - orderedComponents.add(object); - }else if(subIndex > -1){ - orderedComponents.add(subIndex+1, object); - }else if(objIndex > -1){ - orderedComponents.add(objIndex, subject); + if (constraint.getRestriction().equals(RestrictionType.PRECEDES)) { + subjectURIs.add(constraint.getSubjectURI()); + objectURIs.add(constraint.getObjectURI()); + + firstURI.add(constraint.getSubjectURI()); + lastURI.add(constraint.getObjectURI()); + + precedesMap.put(constraint.getSubjectURI(), constraint.getObjectURI()); + } + } + + firstURI.removeAll(objectURIs); + lastURI.removeAll(subjectURIs); + + boolean totalOrdering; + + if (firstURI.size() == 1 && lastURI.size() == 1) { + URI currentURI = firstURI.iterator().next(); + + orderedComponents.add(template.getComponent(currentURI)); + + while (precedesMap.containsKey(currentURI)) { + currentURI = precedesMap.get(currentURI); + + orderedComponents.add(template.getComponent(currentURI)); + } + + totalOrdering = currentURI.equals(lastURI.iterator().next()); + } else { + totalOrdering = false; + } + + if (!totalOrdering) { + orderedComponents.clear(); + + for (SequenceConstraint constraint : seqConstraints) { + //subject precedes object + Component subject = constraint.getSubject(); + Component object = constraint.getObject(); + int subIndex = orderedComponents.indexOf(subject); + int objIndex = orderedComponents.indexOf(object); + if (subIndex == -1 && objIndex == -1){ + orderedComponents.add(subject); + orderedComponents.add(object); + }else if(subIndex > -1){ + orderedComponents.add(subIndex+1, object); + }else if(objIndex > -1){ + orderedComponents.add(objIndex, subject); + } } }