Skip to content

Commit

Permalink
Dot importer edge attributes (jgrapht#998)
Browse files Browse the repository at this point in the history
* Enhanced DOTImporter to allow creating edges and vertices with all
attributes

* Fixed missing update

* Fixed typo
  • Loading branch information
d-michail authored Nov 4, 2020
1 parent 85f1250 commit 101d7df
Show file tree
Hide file tree
Showing 5 changed files with 339 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ public abstract class BaseEventDrivenImporter<V, E>
private List<Consumer<Integer>> vertexCountConsumers;
private List<Consumer<Integer>> edgeCountConsumers;
private List<Consumer<V>> vertexConsumers;
private List<BiConsumer<V, Map<String, Attribute>>> vertexWithAttributesConsumers;
private List<Consumer<E>> edgeConsumers;
private List<BiConsumer<E, Map<String, Attribute>>> edgeWithAttributesConsumers;
private List<BiConsumer<String, Attribute>> graphAttributeConsumers;
private List<BiConsumer<Pair<V, String>, Attribute>> vertexAttributeConsumers;
private List<BiConsumer<Pair<E, String>, Attribute>> edgeAttributeConsumers;
Expand All @@ -51,7 +53,9 @@ public BaseEventDrivenImporter()
this.vertexCountConsumers = new ArrayList<>();
this.edgeCountConsumers = new ArrayList<>();
this.vertexConsumers = new ArrayList<>();
this.vertexWithAttributesConsumers = new ArrayList<>();
this.edgeConsumers = new ArrayList<>();
this.edgeWithAttributesConsumers = new ArrayList<>();
this.graphAttributeConsumers = new ArrayList<>();
this.vertexAttributeConsumers = new ArrayList<>();
this.edgeAttributeConsumers = new ArrayList<>();
Expand Down Expand Up @@ -198,6 +202,24 @@ public void removeVertexAttributeConsumer(BiConsumer<Pair<V, String>, Attribute>
vertexAttributeConsumers.remove(consumer);
}

/**
* Add a vertex with attributes consumer.
*
* @param consumer the consumer
*/
public void addVertexWithAttributesConsumer(BiConsumer<V, Map<String, Attribute>> consumer) {
vertexWithAttributesConsumers.add(consumer);
}

/**
* Remove a vertex with attributes consumer
*
* @param consumer the consumer
*/
public void removeVertexWithAttributesConsumer(BiConsumer<V, Map<String, Attribute>> consumer) {
vertexWithAttributesConsumers.remove(consumer);
}

/**
* Add an edge attribute consumer.
*
Expand All @@ -218,6 +240,24 @@ public void removeEdgeAttributeConsumer(BiConsumer<Pair<E, String>, Attribute> c
edgeAttributeConsumers.remove(consumer);
}

/**
* Add an edge with attributes consumer.
*
* @param consumer the consumer
*/
public void addEdgeWithAttributesConsumer(BiConsumer<E, Map<String, Attribute>> consumer) {
edgeWithAttributesConsumers.add(consumer);
}

/**
* Remove an edge with attributes consumer
*
* @param consumer the consumer
*/
public void removeEdgeWithAttributesConsumer(BiConsumer<E, Map<String, Attribute>> consumer) {
edgeWithAttributesConsumers.remove(consumer);
}

/**
* Notify for the vertex count.
*
Expand Down Expand Up @@ -247,6 +287,17 @@ protected void notifyVertex(V v)
{
vertexConsumers.forEach(c -> c.accept(v));
}

/**
* Notify for a vertex with attributes.
*
* @param v the vertex
* @param attrs the attributes
*/
protected void notifyVertexWithAttributes(V v, Map<String, Attribute> attrs)
{
vertexWithAttributesConsumers.forEach(c -> c.accept(v, attrs));
}

/**
* Notify for an edge.
Expand All @@ -258,6 +309,17 @@ protected void notifyEdge(E e)
edgeConsumers.forEach(c -> c.accept(e));
}

/**
* Notify for an edge with attributes.
*
* @param e the edge
* @param attrs the attributes
*/
protected void notifyEdgeWithAttributes(E e, Map<String, Attribute> attrs)
{
edgeWithAttributesConsumers.forEach(c -> c.accept(e, attrs));
}

/**
* Notify for a graph attribute
*
Expand Down
29 changes: 29 additions & 0 deletions jgrapht-io/src/main/java/org/jgrapht/nio/EventDrivenImporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.io.*;
import java.nio.charset.*;
import java.util.Map;
import java.util.function.*;

/**
Expand Down Expand Up @@ -87,6 +88,20 @@ public interface EventDrivenImporter<V, E>
*/
void removeVertexConsumer(Consumer<V> consumer);

/**
* Add a vertex with attributes consumer.
*
* @param consumer the consumer
*/
void addVertexWithAttributesConsumer(BiConsumer<V, Map<String, Attribute>> consumer);

/**
* Remove a vertex with attributes consumer
*
* @param consumer the consumer
*/
void removeVertexWithAttributesConsumer(BiConsumer<V, Map<String, Attribute>> consumer);

/**
* Add an edge consumer.
*
Expand All @@ -101,6 +116,20 @@ public interface EventDrivenImporter<V, E>
*/
void removeEdgeConsumer(Consumer<E> consumer);

/**
* Add an edge with attributes consumer.
*
* @param consumer the consumer
*/
void addEdgeWithAttributesConsumer(BiConsumer<E, Map<String, Attribute>> consumer);

/**
* Remove an edge with attributes consumer
*
* @param consumer the consumer
*/
void removeEdgeWithAttributesConsumer(BiConsumer<E, Map<String, Attribute>> consumer);

/**
* Add a graph attribute consumer.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

/**
* Import a graph from a DOT file.
Expand Down Expand Up @@ -54,11 +55,26 @@ public class DOTEventDrivenImporter

// identifier unescape rule
private final CharSequenceTranslator UNESCAPE_ID;


private boolean notifyVertexAttributesOutOfOrder;
private boolean notifyEdgeAttributesOutOfOrder;

/**
* Constructs a new importer.
*/
public DOTEventDrivenImporter() {
this(true, true);
}

/**
* Constructs a new importer.
*
* @param notifyVertexAttributesOutOfOrder whether to notify for vertex attributes out-of-order even if
* they appear together in the input
* @param notifyEdgeAttributesOutOfOrder whether to notify for edge attributes out-of-order even if
* they appear together in the input
*/
public DOTEventDrivenImporter()
public DOTEventDrivenImporter(boolean notifyVertexAttributesOutOfOrder, boolean notifyEdgeAttributesOutOfOrder)
{
super();
Map<CharSequence, CharSequence> lookupMap = new HashMap<>();
Expand All @@ -67,6 +83,9 @@ public DOTEventDrivenImporter()
lookupMap.put("\\'", "'");
lookupMap.put("\\", "");
UNESCAPE_ID = new AggregateTranslator(new LookupTranslator(lookupMap));

this.notifyVertexAttributesOutOfOrder = notifyVertexAttributesOutOfOrder;
this.notifyEdgeAttributesOutOfOrder = notifyEdgeAttributesOutOfOrder;
}

@Override
Expand Down Expand Up @@ -342,9 +361,16 @@ public void exitEdgeStatement(DOTParser.EdgeStatementContext ctx)
}

Pair<String, String> pe = Pair.of(sourceVertex, targetVertex);
notifyEdge(pe);
for (String key : edgeAttrs.keySet()) {
notifyEdgeAttribute(pe, key, edgeAttrs.get(key));

if (notifyEdgeAttributesOutOfOrder) {
// notify individually
notifyEdge(pe);
for(Entry<String, Attribute> entry: edgeAttrs.entrySet()) {
notifyEdgeAttribute(pe, entry.getKey(), entry.getValue());
}
} else {
// notify with all attributes
notifyEdgeWithAttributes(pe, edgeAttrs);
}
}
}
Expand Down Expand Up @@ -425,11 +451,15 @@ public void exitNodeStatement(DOTParser.NodeStatementContext ctx)
// append extra attributes
defaultAttrs.putAll(attrs);

notifyVertex(nodeId);
for (String key : defaultAttrs.keySet()) {
notifyVertexAttribute(nodeId, key, defaultAttrs.get(key));
if (notifyVertexAttributesOutOfOrder) {
notifyVertex(nodeId);
for(Entry<String, Attribute> entry: defaultAttrs.entrySet()) {
notifyVertexAttribute(nodeId, entry.getKey(), entry.getValue());
}
} else {
notifyVertexWithAttributes(nodeId, defaultAttrs);
}

vertices.add(nodeId);
scope.addVertex(nodeId);
} else {
Expand Down Expand Up @@ -474,10 +504,16 @@ public void exitNodeStatementNoAttributes(DOTParser.NodeStatementNoAttributesCon
SubgraphScope scope = subgraphScopes.element();
// find default attributes
Map<String, Attribute> defaultAttrs = new HashMap<>(scope.nodeAttrs);
notifyVertex(nodeId);
for (String key : defaultAttrs.keySet()) {
notifyVertexAttribute(nodeId, key, defaultAttrs.get(key));

if (notifyVertexAttributesOutOfOrder) {
notifyVertex(nodeId);
for(Entry<String, Attribute> entry: defaultAttrs.entrySet()) {
notifyVertexAttribute(nodeId, entry.getKey(), entry.getValue());
}
} else {
notifyVertexWithAttributes(nodeId, defaultAttrs);
}

vertices.add(nodeId);
scope.addVertex(nodeId);
}
Expand Down
Loading

0 comments on commit 101d7df

Please sign in to comment.