package dgm.graphs; import com.fasterxml.jackson.databind.JsonNode; import dgm.*; import dgm.exceptions.UnreachableCodeReachedException; import org.neo4j.helpers.collection.Iterables; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.*; class EmptySubgraph implements Subgraph { @Override public Iterable<Edge> edges() { return Iterables.empty(); } @Override public Map<String, JsonNode> properties() { return Collections.emptyMap(); } } class MergedSubgraph implements Subgraph { final ArrayList<Subgraph.Edge> edges = new ArrayList<Subgraph.Edge>(); final Map<String,JsonNode> properties = new HashMap<String, JsonNode>(); final Logger log = LoggerFactory.getLogger(MergedSubgraph.class); public MergedSubgraph(Iterable<Subgraph> subgraphs) { for(Subgraph s : subgraphs) { // add all edges for(Subgraph.Edge se : s.edges()) { // check and warn for duplicate edges hasEdgeCheck(se); edges.add(se); } // add all properties for(String key : s.properties().keySet()) if(properties.containsKey(key)) log.warn("Duplicate property with key {} found while merging", key); properties.putAll(s.properties()); } } private boolean hasEdgeCheck(Subgraph.Edge edge) { for(Subgraph.Edge e : edges) { final boolean a = e.other().equals(edge.other()); final boolean b = e.label().equals(edge.label()); final boolean c = e.direction().equals(edge.direction()); if(a && b && c) { log.warn("Adding an edge ({},{},{}) that already exists in the subgraph", new Object[]{edge.label(), edge.other(), edge.direction()}); return true; } } return false; } @Override public Iterable<Edge> edges() { return edges; } @Override public Map<String, JsonNode> properties() { return properties; } } /** * Helper methods for {@link Subgraph}s */ public class Subgraphs { final public static Subgraph EMPTY_SUBGRAPH = new EmptySubgraph(); /** * If the Subgraph if commited with ID {@code center}, compute the {@link EdgeID} for this {@code edge}. */ public static final EdgeID edgeID(final ID center, final Subgraph.Edge edge) { switch (edge.direction()) { case INWARDS: // center <---- edge.other() return new EdgeID(edge.other(), edge.label(), center); case OUTWARDS: // center ----> edge.other() return new EdgeID(center, edge.label(), edge.other()); default: throw new UnreachableCodeReachedException(); } } public static Subgraph merge(Iterable<Subgraph> subgraphs) { return new MergedSubgraph(subgraphs); } public static Subgraph merge(Subgraph... subgraphs) { return merge(Arrays.asList(subgraphs)); } }