Skip to content

Commit b60772b

Browse files
committed
extend CJ api, better mutation for CjDoc stuff
1 parent f217f6c commit b60772b

31 files changed

+256
-104
lines changed

base/src/main/java/com/graphinout/base/cj/document/CjDirection.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
package com.graphinout.base.cj.document;
22

3+
import org.jspecify.annotations.NonNull;
34
import org.jspecify.annotations.Nullable;
45

56
/**
67
* Direction for edge endpoints according to Connected JSON specification.
78
*/
89
public enum CjDirection {
9-
IN("in"),
10-
OUT("out"),
11-
UNDIR("undir");
10+
IN("in"), OUT("out"), UNDIR("undir");
1211

1312
public static final CjDirection DEFAULT = CjDirection.UNDIR;
1413

@@ -18,13 +17,18 @@ public enum CjDirection {
1817
this.value = value;
1918
}
2019

21-
public static CjDirection of(@Nullable String value) {
20+
/**
21+
* @param value may be null for default (undirected)
22+
* @throws IllegalArgumentException if value is invalid (null is ok)
23+
*/
24+
public static @NonNull CjDirection of(@Nullable String value) throws IllegalArgumentException {
2225
for (CjDirection direction : values()) {
2326
if (direction.value.equals(value)) {
2427
return direction;
2528
}
2629
}
27-
return UNDIR; // default
30+
if (value == null) return UNDIR; // default
31+
throw new IllegalArgumentException("Unknown direction: " + value);
2832
}
2933

3034
public boolean isDirected() {

base/src/main/java/com/graphinout/base/cj/document/ICjCoreElement.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
/**
1313
* A common super-interface for {@link ICjGraph}, {@link ICjNode} and {@link ICjEdge}.
1414
*/
15-
public interface ICjCoreElement extends ICjHasId, ICjHasUri, ICjElement {
15+
public interface ICjCoreElement extends ICjHasId, ICjHasUri, ICjHasGraphs, ICjElement {
1616

1717
class ParentIterator implements Iterator<ICjElement> {
1818

@@ -96,8 +96,8 @@ static int findPositionOfChildInParent(ICjElement parent, ICjElement child) {
9696
default String abbreviatedUri() {
9797
String uri = uri();
9898
String effectiveBaseUri = effectiveBaseUri();
99-
if (uri.startsWith(effectiveBaseUri+"#")) {
100-
return uri.substring(effectiveBaseUri.length()+1);
99+
if (uri.startsWith(effectiveBaseUri + "#")) {
100+
return uri.substring(effectiveBaseUri.length() + 1);
101101
}
102102
if (uri.startsWith(effectiveBaseUri)) {
103103
return uri.substring(effectiveBaseUri.length());
@@ -170,8 +170,7 @@ default Iterator<ICjElement> parentIterator() {
170170
*/
171171
default @NonNull String unstableId() {
172172
String thisId = id();
173-
if (thisId != null)
174-
return thisId;
173+
if (thisId != null) return thisId;
175174

176175
Iterator<ICjElement> it = parentIterator();
177176
StringBuilder sb = new StringBuilder();

base/src/main/java/com/graphinout/base/cj/document/ICjDocument.java

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -25,43 +25,10 @@ default Stream<ICjElement> directChildren() {
2525
return Stream.concat(Stream.concat(Stream.of(data().ifNotEmpty()), Stream.of(connectedJson())).filter(Objects::nonNull), graphs());
2626
}
2727

28-
/**
29-
* @return All edges in the document, from all graphs and subgraphs.
30-
*/
31-
default Stream<ICjEdge> edgesAll() {
32-
return graphsAll().flatMap(ICjGraph::edges);
33-
}
34-
3528
default @NonNull String effectiveBaseUri() {
3629
return nonNullOrDefault(baseUri(), CjUris.BASE_URI_FALLBACK);
3730
}
3831

39-
default @Nullable ICjEdge findEdgeById(@NonNull String edgeId) throws IllegalStateException {
40-
return edgesAll().filter(e -> e.matchesId(this, edgeId)).findFirst().orElse(null);
41-
}
42-
43-
default @Nullable ICjGraph findGraph(String id) {
44-
return graphsAll().filter(g -> g.matchesId(this, id)).findFirst().orElse(null);
45-
}
46-
47-
default @Nullable ICjNode findNodeById(@NonNull String id) throws IllegalStateException {
48-
return nodesAll().filter(n -> n.matchesId(this, id)).findFirst().orElse(null);
49-
}
50-
51-
/**
52-
* @return All nodes in the document, from all graphs and subgraphs.
53-
*/
54-
default Stream<ICjNode> nodesAll() {
55-
return graphsAll().flatMap(ICjGraph::nodes);
56-
}
57-
58-
default Stream<ICjNode> nodesAllIncludingImplied() {
59-
return Stream.concat(//
60-
nodesAll(), //
61-
edgesAll().flatMap(ICjEdge::nodesResolved) //
62-
).distinct().sorted();
63-
}
64-
6532
/**
6633
* @return the single graph (or null if none).
6734
* @throws IllegalStateException if multiple graphs are present

base/src/main/java/com/graphinout/base/cj/document/ICjEdge.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ public interface ICjEdge extends ICjEdgeChunk, ICjHasGraphs, ICjCoreElement, Com
1616

1717
/**
1818
* Compare first by chunk properties, then by graph arrays
19-
*
20-
* @param other
21-
* @return
2219
*/
2320
@Override
2421
default int compareTo(@NonNull ICjEdge other) {
@@ -28,6 +25,12 @@ default int compareTo(@NonNull ICjEdge other) {
2825
.compare(this, other);
2926
}
3027

28+
default void copyTo(ICjEdgeMutable targetEdge) {
29+
ICjEdgeChunk.super.copyTo(targetEdge);
30+
graphs().forEach(sourceGraph -> targetEdge.addGraph(sourceGraph::copyTo));
31+
}
32+
33+
3134
@Override
3235
default Stream<ICjElement> directChildren() {
3336
return Stream.concat(Stream.concat(Stream.of(data()), endpoints()), graphs());

base/src/main/java/com/graphinout/base/cj/document/ICjEdgeChunk.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ default void fireStartChunk(ICjWriter cjWriter, boolean sort) {
5454
cjWriter.edgeStart();
5555
// streaming order: id, label, type, endpoints, data, graphs
5656
cjWriter.maybe(id(), cjWriter::id);
57-
fireLabelMaybe(cjWriter,sort);
57+
fireLabelMaybe(cjWriter, sort);
5858
ofNullable(edgeType()).ifPresent(cjWriter::edgeType);
5959
cjWriter.list(endpoints().toList(), CjType.ArrayOfEndpoints, sort, (iCjEndpoint, cjWriter1) -> iCjEndpoint.fire(cjWriter1, sort));
6060
fireDataMaybe(cjWriter);

base/src/main/java/com/graphinout/base/cj/document/ICjElement.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,42 @@ default Stream<ICjElement> allElements() {
2020
return Stream.concat(Stream.of(this), directChildren().flatMap(ICjElement::allElements));
2121
}
2222

23+
/** @throws ClassCastException if this is not a Document */
2324
default ICjDocumentMutable asDocument() {
2425
return (ICjDocumentMutable) this;
2526
}
2627

28+
/** @throws ClassCastException if this is not a Edge */
2729
default ICjEdgeMutable asEdge() {
2830
return (ICjEdgeMutable) this;
2931
}
3032

33+
/** @throws ClassCastException if this is not a Endpoint */
3134
default ICjEndpointMutable asEndpoint() {
3235
return (ICjEndpointMutable) this;
3336
}
3437

38+
/** @throws ClassCastException if this is not a Graph */
3539
default ICjGraphMutable asGraph() {
3640
return (ICjGraphMutable) this;
3741
}
3842

43+
/** @throws ClassCastException if this is not a HasGraphs */
44+
default ICjHasGraphsMutable asHasGraphsMutable() {
45+
return (ICjHasGraphsMutable) this;
46+
}
47+
48+
/** @throws ClassCastException if this is not a Node */
3949
default ICjNodeMutable asNode() {
4050
return (ICjNodeMutable) this;
4151
}
4252

53+
/** @throws ClassCastException if this is not a Port */
4354
default ICjPortMutable asPort() {
4455
return (ICjPortMutable) this;
4556
}
4657

58+
/** @throws ClassCastException if this is not a HasData */
4759
default ICjHasDataMutable asWithData() {
4860
return (ICjHasDataMutable) this;
4961
}
@@ -64,4 +76,5 @@ default IJsonObject toJsonValue() {
6476
return Objects.requireNonNull(json2JsonValueWriter.resultJsonRootObject()).asObject();
6577
}
6678

79+
6780
}

base/src/main/java/com/graphinout/base/cj/document/ICjGraph.java

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import com.graphinout.foundation.pure.collections.jajson.JaJson;
55
import com.graphinout.foundation.pure.util.Comparables;
66
import org.jspecify.annotations.NonNull;
7-
import org.jspecify.annotations.Nullable;
87

98
import java.util.Map;
109
import java.util.stream.Stream;
@@ -24,6 +23,13 @@ default int compareTo(@NonNull ICjGraph other) {
2423
.compare(this, other);
2524
}
2625

26+
default void copyTo(ICjGraphMutable targetGraph) {
27+
ICjGraphChunk.super.copyTo(targetGraph);
28+
nodes().forEach(sourceNode -> targetGraph.addNode(sourceNode::copyTo));
29+
edges().forEach(sourceEdge -> targetGraph.addEdge(sourceEdge::copyTo));
30+
graphs().forEach(sourceSubGraph -> targetGraph.addGraph(sourceSubGraph::copyTo));
31+
}
32+
2733
/** Edge count in this graph, excluding subgraphs */
2834
default long countEdgesDirect() {
2935
return edges().count();
@@ -69,16 +75,14 @@ default Stream<ICjGraph> graphsNestedNonRecursive() {
6975

7076
Stream<ICjNode> nodes();
7177

72-
default @Nullable ICjNode findNodeById(String nodeId) {
73-
// must use the effectiveUri of this graph
74-
String nodeUri = CjUris.uri(effectiveBaseUri(), nodeId);
75-
return document().findNodeById(nodeUri);
76-
}
77-
7878
default Map<String, Object> toJaJsonMap() {
7979
return JaJson.createMap() //
80-
.putMaybe(CjConstants.ID, id()).putMaybe(CjConstants.LABEL, label(), ICjLabel::toJaJsonMap).putMaybe(CjConstants.GRAPH__NODES, nodes(), ICjNode::toJaJsonMap).putMaybe(CjConstants.GRAPH__EDGES, edges(), ICjEdge::toJaJsonMap).putMaybe(CjConstants.DATA, data().ifNotEmpty(), ICjData::toJaJsonValue).putMaybe(CjConstants.GRAPHS, graphs(), ICjGraph::toJaJsonMap).build();
80+
.putMaybe(CjConstants.ID, id()) //
81+
.putMaybe(CjConstants.LABEL, label(), ICjLabel::toJaJsonMap) //
82+
.putMaybe(CjConstants.GRAPH__NODES, nodes(), ICjNode::toJaJsonMap) //
83+
.putMaybe(CjConstants.GRAPH__EDGES, edges(), ICjEdge::toJaJsonMap) //
84+
.putMaybe(CjConstants.DATA, data().ifNotEmpty(), ICjData::toJaJsonValue) //
85+
.putMaybe(CjConstants.GRAPHS, graphs(), ICjGraph::toJaJsonMap).build();
8186
}
8287

83-
8488
}

base/src/main/java/com/graphinout/base/cj/document/ICjGraphChunk.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import com.graphinout.foundation.pure.util.Comparables;
55
import org.jspecify.annotations.Nullable;
66

7+
import static com.graphinout.foundation.pure.functional.Nullables.ifPresentAccept;
8+
79
/**
810
* The part of a graph which can be sent in one go. Memory requirements for all data in this chunk are expected to be
911
* below 50 MB.
@@ -24,6 +26,13 @@ static int compare(ICjGraphChunk a, ICjGraphChunk b) {
2426
*/
2527
@Nullable String baseUri();
2628

29+
default void copyTo(ICjGraphChunkMutable target) {
30+
ifPresentAccept(id(), target::id);
31+
ifPresentAccept(baseUri(), target::baseUri);
32+
ifPresentAccept(label(), sourceLabel -> target.labelMutable(sourceLabel::copyTo));
33+
data(data -> target.dataJsonValue(data.jsonValue()));
34+
}
35+
2736
default void fireStartChunk(ICjWriter cjWriter, boolean sort) {
2837
cjWriter.graphStart();
2938
cjWriter.maybe(id(), cjWriter::id);

base/src/main/java/com/graphinout/base/cj/document/ICjGraphMutable.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,8 @@ default ICjNodeMutable addNode() {
3131
return addNode(node -> {});
3232
}
3333

34+
void removeNode(ICjNode node);
35+
36+
void removeEdge(ICjEdge edge);
37+
3438
}

base/src/main/java/com/graphinout/base/cj/document/ICjHasDataMutable.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
import com.graphinout.base.cj.data.CjDataProperty;
44
import com.graphinout.foundation.pure.json.document.IJsonFactory;
5+
import com.graphinout.foundation.pure.json.document.IJsonValue;
56
import com.graphinout.foundation.pure.json.document.IJsonXmlString;
67
import org.jspecify.annotations.NonNull;
8+
import org.jspecify.annotations.Nullable;
79

810
import java.util.function.Consumer;
911

@@ -22,6 +24,14 @@ default void addProperty(String key, String value) {
2224
@Override
2325
@NonNull ICjDataMutable data();
2426

27+
default void dataJsonValue(@Nullable IJsonValue jsonValue) {
28+
if (jsonValue == null) {
29+
dataMutable(ICjDataMutable::removeJsonValue);
30+
} else {
31+
dataMutable(data -> data.setJsonValue(jsonValue));
32+
}
33+
}
34+
2535
/**
2636
* If an {@link ICjDataMutable} was created (none existed) it is auto-aded to the CJ entity, if it is not empty.
2737
*

0 commit comments

Comments
 (0)