| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| == Node Neighbors | ||
|
|
||
| You can find the distinct connected nodes "n" levels or away quickly with these following procedures. | ||
|
|
||
| You can use '>' or '<' for all outgoing or incoming relationships, or specify the types you are interested in. | ||
|
|
||
| [cols="1m,5"] | ||
| |=== | ||
| | apoc.neighbors.tohop(node, rel-direction-pattern, distance) | returns distinct nodes of the given relationships in the pattern up to a certain distance | ||
| | apoc.neighbors.tohop.count(node, rel-direction-pattern, distance) | returns the count of distinct nodes of the given relationships in the pattern up to a certain distance | ||
| | apoc.neighbors.byhop(node, rel-direction-pattern, distance) | returns distinct nodes of the given relationships in the pattern grouped by distance | ||
| | apoc.neighbors.byhop.count(node, rel-direction-pattern, distance) | returns the count distinct nodes of the given relationships in the pattern grouped by distance | ||
| | apoc.neighbors.athop(node, rel-direction-pattern, distance) | returns distinct nodes of the given relationships in the pattern at a certain distance | ||
| | apoc.neighbors.athop.count(node, rel-direction-pattern, distance) | returns the count of distinct nodes of the given relationships in the pattern at a certain distance | ||
| |=== | ||
|
|
||
|
|
||
|
|
||
|
|
||
| === Example | ||
|
|
||
| .Graph Setup | ||
| [source,cypher] | ||
| ---- | ||
| CREATE (a:First), (b:Neighbor), (c:Neighbor), (d:Neighbor), | ||
| (a)-[:KNOWS]->(b), (b)-[:KNOWS]->(a), | ||
| (b)-[:KNOWS]->(c), (c)-[:KNOWS]->(d) | ||
| ---- | ||
|
|
||
| [source,cypher] | ||
| ---- | ||
| MATCH (n:First) WITH n | ||
| CALL apoc.neighbors.tohop(n,'KNOWS>', 3) YIELD node AS neighbor | ||
| RETURN neighbor | ||
| ---- | ||
|
|
||
| [source,cypher] | ||
| ---- | ||
| MATCH (n:First) WITH n | ||
| CALL apoc.neighbors.tohop.count(n,'KNOWS>', 3) YIELD value AS number | ||
| RETURN number | ||
| ---- | ||
|
|
||
| [source,cypher] | ||
| ---- | ||
| MATCH (n:First) WITH n | ||
| CALL apoc.neighbors.byhop(n,'KNOWS>', 3) YIELD nodes AS neighbors | ||
| RETURN neighbors | ||
| ---- | ||
|
|
||
| [source,cypher] | ||
| ---- | ||
| MATCH (n:First) WITH n | ||
| CALL apoc.neighbors.byhop.count(n,'KNOWS>', 3) YIELD value AS numbers | ||
| RETURN numbers | ||
| ---- | ||
|
|
||
| [source,cypher] | ||
| ---- | ||
| MATCH (n:First) WITH n | ||
| CALL apoc.neighbors.athop(n,'KNOWS>', 3) YIELD nodes AS neighbors | ||
| RETURN neighbors | ||
| ---- | ||
|
|
||
| [source,cypher] | ||
| ---- | ||
| MATCH (n:First) WITH n | ||
| CALL apoc.neighbors.athop.count(n,'KNOWS>', 3) YIELD value AS numbers | ||
| RETURN numbers | ||
| ---- |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package apoc.cypher; | ||
|
|
||
| import apoc.ApocConfiguration; | ||
| import org.neo4j.helpers.collection.MapUtil; | ||
| import org.neo4j.kernel.AvailabilityGuard; | ||
| import org.neo4j.kernel.internal.GraphDatabaseAPI; | ||
| import org.neo4j.logging.Log; | ||
|
|
||
| import java.util.Map; | ||
| import java.util.SortedMap; | ||
| import java.util.TreeMap; | ||
|
|
||
| public class CypherInitializer implements AvailabilityGuard.AvailabilityListener { | ||
| private final GraphDatabaseAPI db; | ||
| private final Log userLog; | ||
|
|
||
| public CypherInitializer(GraphDatabaseAPI db, Log userLog) { | ||
| this.db = db; | ||
| this.userLog = userLog; | ||
| } | ||
|
|
||
| @Override | ||
| public void available() { | ||
| SortedMap<String, Object> initializers = new TreeMap<>(ApocConfiguration.get("initializer.cypher")); | ||
| for (Object initializer: initializers.values()) { | ||
| String query = initializer.toString(); | ||
| try { | ||
| db.execute(query); | ||
| userLog.info("successfully initialized: " + query); | ||
| } catch (Exception e) { | ||
| userLog.warn("error upon initialization, running: "+query, e); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void unavailable() { | ||
| // intentionally empty | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| package apoc.export.json; | ||
|
|
||
| import apoc.Description; | ||
| import apoc.export.util.ExportConfig; | ||
| import apoc.export.util.NodesAndRelsSubGraph; | ||
| import apoc.export.util.ProgressReporter; | ||
| import apoc.result.ProgressInfo; | ||
| import apoc.util.Util; | ||
| import org.neo4j.cypher.export.DatabaseSubGraph; | ||
| import org.neo4j.cypher.export.SubGraph; | ||
| import org.neo4j.graphdb.GraphDatabaseService; | ||
| import org.neo4j.graphdb.Node; | ||
| import org.neo4j.graphdb.Relationship; | ||
| import org.neo4j.graphdb.Result; | ||
| import org.neo4j.procedure.Context; | ||
| import org.neo4j.procedure.Name; | ||
| import org.neo4j.procedure.Procedure; | ||
|
|
||
| import java.io.PrintWriter; | ||
| import java.util.Collection; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.stream.Stream; | ||
|
|
||
| import static apoc.util.FileUtils.checkWriteAllowed; | ||
| import static apoc.util.FileUtils.getPrintWriter; | ||
|
|
||
| public class ExportJson { | ||
| @Context | ||
| public GraphDatabaseService db; | ||
|
|
||
| public ExportJson(GraphDatabaseService db) { | ||
| this.db = db; | ||
| } | ||
|
|
||
| public ExportJson() { | ||
| } | ||
|
|
||
| @Procedure | ||
| @Description("apoc.exportJson.json.all(file,config) - exports whole database as json to the provided file") | ||
| public Stream<ProgressInfo> all(@Name("file") String fileName, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) throws Exception { | ||
|
|
||
| String source = String.format("database: nodes(%d), rels(%d)", Util.nodeCount(db), Util.relCount(db)); | ||
| return exportJson(fileName, source, new DatabaseSubGraph(db), config); | ||
| } | ||
|
|
||
| @Procedure | ||
| @Description("apoc.exportJson.json.data(nodes,rels,file,config) - exports given nodes and relationships as json to the provided file") | ||
| public Stream<ProgressInfo> data(@Name("nodes") List<Node> nodes, @Name("rels") List<Relationship> rels, @Name("file") String fileName, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) throws Exception { | ||
|
|
||
| String source = String.format("data: nodes(%d), rels(%d)", nodes.size(), rels.size()); | ||
| return exportJson(fileName, source, new NodesAndRelsSubGraph(db, nodes, rels), config); | ||
| } | ||
| @Procedure | ||
| @Description("apoc.exportJson.json.graph(graph,file,config) - exports given graph object as json to the provided file") | ||
| public Stream<ProgressInfo> graph(@Name("graph") Map<String,Object> graph, @Name("file") String fileName, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) throws Exception { | ||
|
|
||
| Collection<Node> nodes = (Collection<Node>) graph.get("nodes"); | ||
| Collection<Relationship> rels = (Collection<Relationship>) graph.get("relationships"); | ||
| String source = String.format("graph: nodes(%d), rels(%d)", nodes.size(), rels.size()); | ||
| return exportJson(fileName, source, new NodesAndRelsSubGraph(db, nodes, rels), config); | ||
| } | ||
|
|
||
| @Procedure | ||
| @Description("apoc.exportJson.json.query(query,file,{config,...,params:{params}}) - exports results from the cypher kernelTransaction as json to the provided file") | ||
| public Stream<ProgressInfo> query(@Name("query") String query, @Name("file") String fileName, @Name(value = "config", defaultValue = "{}") Map<String, Object> config) throws Exception { | ||
| Map<String,Object> params = config == null ? Collections.emptyMap() : (Map<String,Object>)config.getOrDefault("params", Collections.emptyMap()); | ||
| Result result = db.execute(query,params); | ||
| String source = String.format("kernelTransaction: cols(%d)", result.columns().size()); | ||
| return exportJson(fileName, source,result,config); | ||
| } | ||
|
|
||
| private Stream<ProgressInfo> exportJson(@Name("file") String fileName, String source, Object data, Map<String,Object> config) throws Exception { | ||
| checkWriteAllowed(); | ||
| ExportConfig c = new ExportConfig(config); | ||
| ProgressReporter reporter = new ProgressReporter(null, null, new ProgressInfo(fileName, source, "json")); | ||
| JsonFormat exporter = new JsonFormat(db); | ||
| try (PrintWriter printWriter = getPrintWriter(fileName, null);) { | ||
| if (data instanceof SubGraph) | ||
| exporter.dump(((SubGraph)data),printWriter,reporter,c); | ||
| if (data instanceof Result) | ||
| exporter.dump(((Result)data),printWriter,reporter,c); | ||
| } | ||
| return reporter.stream(); | ||
| } | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,196 @@ | ||
| package apoc.export.json; | ||
|
|
||
| import apoc.export.util.ExportConfig; | ||
| import apoc.export.util.Format; | ||
| import apoc.export.util.Reporter; | ||
| import apoc.meta.Meta; | ||
| import apoc.result.ProgressInfo; | ||
| import com.fasterxml.jackson.core.JsonFactory; | ||
| import com.fasterxml.jackson.core.JsonGenerator; | ||
| import com.fasterxml.jackson.core.Version; | ||
| import com.fasterxml.jackson.core.util.MinimalPrettyPrinter; | ||
| import com.fasterxml.jackson.databind.ObjectMapper; | ||
| import com.fasterxml.jackson.databind.SerializationFeature; | ||
| import com.fasterxml.jackson.databind.module.SimpleModule; | ||
| import org.neo4j.cypher.export.SubGraph; | ||
| import org.neo4j.graphdb.*; | ||
| import org.neo4j.graphdb.spatial.Point; | ||
|
|
||
| import java.io.IOException; | ||
| import java.io.Reader; | ||
| import java.io.Writer; | ||
| import java.time.temporal.TemporalAccessor; | ||
| import java.util.HashMap; | ||
| import java.util.List; | ||
| import java.util.Map; | ||
| import java.util.function.Consumer; | ||
|
|
||
| public class JsonFormat implements Format { | ||
| private final GraphDatabaseService db; | ||
|
|
||
| private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper().configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); | ||
|
|
||
| static { | ||
| SimpleModule module = new SimpleModule("Neo4jApocSerializer", new Version(1, 0, 0, "")); | ||
| module.addSerializer(Point.class, new PointSerializer()); | ||
| module.addSerializer(TemporalAccessor.class, new TemporalSerializer()); | ||
| OBJECT_MAPPER.registerModule(module); | ||
| } | ||
|
|
||
| public JsonFormat(GraphDatabaseService db) { | ||
| this.db = db; | ||
| } | ||
|
|
||
| @Override | ||
| public ProgressInfo load(Reader reader, Reporter reporter, ExportConfig config) throws Exception { | ||
| return null; | ||
| } | ||
|
|
||
| private ProgressInfo dump(Writer writer, Reporter reporter, Consumer<JsonGenerator> consumer) throws Exception { | ||
| try (Transaction tx = db.beginTx(); JsonGenerator jsonGenerator = getJsonGenerator(writer);) { | ||
|
|
||
| consumer.accept(jsonGenerator); | ||
|
|
||
| tx.success(); | ||
| return reporter.getTotal(); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public ProgressInfo dump(SubGraph graph, Writer writer, Reporter reporter, ExportConfig config) throws Exception { | ||
| Consumer<JsonGenerator> consumer = (jsonGenerator) -> { | ||
| try { | ||
| writeNodes(graph.getNodes(), reporter, jsonGenerator, config); | ||
| writeRels(graph.getRelationships(), reporter, jsonGenerator, config); | ||
| } catch (IOException e) { | ||
| throw new RuntimeException(e); | ||
| } | ||
| }; | ||
| return dump(writer, reporter, consumer); | ||
| } | ||
|
|
||
| public ProgressInfo dump(Result result, Writer writer, Reporter reporter, ExportConfig config) throws Exception { | ||
| Consumer<JsonGenerator> consumer = (jsonGenerator) -> { | ||
| try { | ||
| String[] header = result.columns().toArray(new String[result.columns().size()]); | ||
| result.accept((row) -> { | ||
| writeJsonResult(reporter, header, jsonGenerator, row, config); | ||
| reporter.nextRow(); | ||
| return true; | ||
| }); | ||
| } catch (IOException e) { | ||
| throw new RuntimeException(e); | ||
| } | ||
| }; | ||
| return dump(writer, reporter, consumer); | ||
| } | ||
|
|
||
| private JsonGenerator getJsonGenerator(Writer writer) throws IOException { | ||
| JsonFactory jsonF = new JsonFactory(); | ||
| JsonGenerator jsonGenerator = jsonF.createGenerator(writer); | ||
| jsonGenerator.setCodec(OBJECT_MAPPER); | ||
| jsonGenerator.setPrettyPrinter(new MinimalPrettyPrinter("\n")); | ||
| return jsonGenerator; | ||
| } | ||
|
|
||
| private void writeNodes(Iterable<Node> nodes, Reporter reporter, JsonGenerator jsonGenerator,ExportConfig config) throws IOException { | ||
| for (Node node : nodes) { | ||
| writeNode(reporter, jsonGenerator, node, config); | ||
| } | ||
| } | ||
|
|
||
| private void writeNode(Reporter reporter, JsonGenerator jsonGenerator, Node node, ExportConfig config) throws IOException { | ||
| Map<String, Object> allProperties = node.getAllProperties(); | ||
| JsonFormatSerializer.DEFAULT.writeNode(jsonGenerator, node, config); | ||
| reporter.update(1, 0, allProperties.size()); | ||
| } | ||
|
|
||
| private void writeRels(Iterable<Relationship> rels, Reporter reporter, JsonGenerator jsonGenerator, ExportConfig config) throws IOException { | ||
| for (Relationship rel : rels) { | ||
| writeRel(reporter, jsonGenerator, rel, config); | ||
| } | ||
| } | ||
|
|
||
| private void writeRel(Reporter reporter, JsonGenerator jsonGenerator, Relationship rel, ExportConfig config) throws IOException { | ||
| Map<String, Object> allProperties = rel.getAllProperties(); | ||
| JsonFormatSerializer.DEFAULT.writeRelationship(jsonGenerator, rel, config); | ||
| reporter.update(0, 1, allProperties.size()); | ||
| } | ||
|
|
||
| private void writeJsonResult(Reporter reporter, String[] header, JsonGenerator jsonGenerator, Result.ResultRow row, ExportConfig config) throws IOException { | ||
| jsonGenerator.writeStartObject(); | ||
| for (int col = 0; col < header.length; col++) { | ||
| String keyName = header[col]; | ||
| Object value = row.get(keyName); | ||
| write(reporter, jsonGenerator, config, keyName, value, true); | ||
| } | ||
| jsonGenerator.writeEndObject(); | ||
| } | ||
|
|
||
| private void write(Reporter reporter, JsonGenerator jsonGenerator, ExportConfig config, String keyName, Object value, boolean writeKey) throws IOException { | ||
| Meta.Types type = Meta.Types.of(value); | ||
| switch (type) { | ||
| case NODE: | ||
| writeFieldName(jsonGenerator, keyName, writeKey); | ||
| writeNode(reporter, jsonGenerator, (Node) value, config); | ||
| break; | ||
| case RELATIONSHIP: | ||
| writeFieldName(jsonGenerator, keyName, writeKey); | ||
| writeRel(reporter, jsonGenerator, (Relationship) value, config); | ||
| break; | ||
| case PATH: | ||
| writeFieldName(jsonGenerator, keyName, writeKey); | ||
| writePath(reporter, jsonGenerator, config, (Path) value); | ||
| break; | ||
| case MAP: | ||
| if (writeKey) { | ||
| jsonGenerator.writeObjectFieldStart(keyName); | ||
| } else { | ||
| jsonGenerator.writeStartObject(); | ||
| writeKey = true; | ||
| } | ||
| Map<String, Object> map = (HashMap<String, Object>) value; | ||
| for (Map.Entry<String, Object> entry : map.entrySet()) { | ||
| write(reporter, jsonGenerator, config, entry.getKey(), entry.getValue(), writeKey); | ||
| } | ||
| jsonGenerator.writeEndObject(); | ||
| break; | ||
| case LIST: | ||
| if (writeKey) { | ||
| jsonGenerator.writeArrayFieldStart(keyName); | ||
| } else { | ||
| jsonGenerator.writeStartArray(); | ||
| } | ||
| List<Object> list = (List<Object>) value; | ||
| for (Object elem : list) { | ||
| write(reporter, jsonGenerator, config, keyName, elem, false); | ||
| } | ||
| jsonGenerator.writeEndArray(); | ||
| break; | ||
| default: | ||
| JsonFormatSerializer.DEFAULT.serializeProperty(jsonGenerator, keyName, value, writeKey); | ||
| reporter.update(0, 0, 1); | ||
| break; | ||
|
|
||
| } | ||
| } | ||
|
|
||
| private void writeFieldName(JsonGenerator jsonGenerator, String keyName, boolean writeKey) throws IOException { | ||
| if (writeKey) { | ||
| jsonGenerator.writeFieldName(keyName); | ||
| } | ||
| } | ||
|
|
||
| private void writePath(Reporter reporter, JsonGenerator jsonGenerator, ExportConfig config, Path path) throws IOException { | ||
| jsonGenerator.writeStartObject(); | ||
| jsonGenerator.writeObjectField("length", path.length()); | ||
| jsonGenerator.writeArrayFieldStart("rels"); | ||
| writeRels(path.relationships(), reporter, jsonGenerator, config); | ||
| jsonGenerator.writeEndArray(); | ||
| jsonGenerator.writeArrayFieldStart("nodes"); | ||
| writeNodes(path.nodes(), reporter, jsonGenerator, config); | ||
| jsonGenerator.writeEndArray(); | ||
| jsonGenerator.writeEndObject(); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| package apoc.export.json; | ||
|
|
||
| import apoc.export.util.ExportConfig; | ||
| import com.fasterxml.jackson.core.JsonGenerator; | ||
| import org.neo4j.graphdb.Label; | ||
| import org.neo4j.graphdb.Node; | ||
| import org.neo4j.graphdb.Relationship; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.Map; | ||
|
|
||
| public enum JsonFormatSerializer { | ||
|
|
||
| DEFAULT() { | ||
|
|
||
| @Override | ||
| public void writeNode(JsonGenerator jsonGenerator, Node node, ExportConfig config) throws IOException { | ||
| jsonGenerator.writeStartObject(); | ||
| jsonGenerator.writeStringField("type", "node"); | ||
| writeNodeDetails(jsonGenerator, node, true); | ||
| jsonGenerator.writeEndObject(); | ||
| } | ||
|
|
||
| @Override | ||
| public void writeRelationship(JsonGenerator jsonGenerator, Relationship rel, ExportConfig config) throws IOException { | ||
| Node startNode = rel.getStartNode(); | ||
| Node endNode = rel.getEndNode(); | ||
| jsonGenerator.writeStartObject(); | ||
| jsonGenerator.writeStringField("id", String.valueOf(rel.getId())); | ||
| jsonGenerator.writeStringField("type", "relationship"); | ||
| jsonGenerator.writeStringField("label", rel.getType().toString()); | ||
| serializeProperties(jsonGenerator, rel.getAllProperties()); | ||
| writeRelationshipNode(jsonGenerator, "start", startNode, config); | ||
| writeRelationshipNode(jsonGenerator, "end", endNode, config); | ||
| jsonGenerator.writeEndObject(); | ||
| } | ||
|
|
||
| @Override | ||
| public void serializeProperties(JsonGenerator jsonGenerator, Map<String, Object> properties) throws IOException { | ||
| if(properties != null && !properties.isEmpty()) { | ||
| jsonGenerator.writeObjectFieldStart("properties"); | ||
| for (Map.Entry<String, Object> entry : properties.entrySet()) { | ||
| String key = entry.getKey(); | ||
| Object value = entry.getValue(); | ||
| serializeProperty(jsonGenerator, key, value, true); | ||
| } | ||
| jsonGenerator.writeEndObject(); | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public void serializeProperty(JsonGenerator jsonGenerator, String key, Object value, boolean writeKey) throws IOException { | ||
| if (value == null) { | ||
| if (writeKey) { | ||
| jsonGenerator.writeNullField(key); | ||
| } else { | ||
| jsonGenerator.writeNull(); | ||
| } | ||
| } else { | ||
| if (writeKey) { | ||
| jsonGenerator.writeObjectField(key, value); | ||
| } else { | ||
| jsonGenerator.writeObject(value); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| private void writeNodeDetails(JsonGenerator jsonGenerator, Node node, boolean withNodeProperties) throws IOException { | ||
| jsonGenerator.writeStringField("id", String.valueOf(node.getId())); | ||
| Iterable<Label> labels = node.getLabels(); | ||
| if (labels.iterator().hasNext()) { | ||
| jsonGenerator.writeArrayFieldStart("labels"); | ||
| for (Label label : labels) { | ||
| jsonGenerator.writeString(label.toString()); | ||
| } | ||
| jsonGenerator.writeEndArray(); | ||
| } | ||
| if (withNodeProperties) { | ||
| serializeProperties(jsonGenerator, node.getAllProperties()); | ||
| } | ||
| } | ||
|
|
||
| private void writeRelationshipNode(JsonGenerator jsonGenerator, String type, Node node, ExportConfig config) throws IOException { | ||
| jsonGenerator.writeObjectFieldStart(type); | ||
|
|
||
| writeNodeDetails(jsonGenerator, node, config.writeNodeProperties()); | ||
| jsonGenerator.writeEndObject(); | ||
| } | ||
| }; | ||
|
|
||
| public abstract void writeNode(JsonGenerator jsonGenerator, Node node, ExportConfig config) throws IOException; | ||
|
|
||
| public abstract void writeRelationship(JsonGenerator jsonGenerator, Relationship relationship, ExportConfig config) throws IOException; | ||
|
|
||
| public abstract void serializeProperties(JsonGenerator jsonGenerator, Map<String,Object> properties) throws IOException; | ||
|
|
||
| public abstract void serializeProperty(JsonGenerator jsonGenerator, String key, Object value, boolean writeKey) throws IOException; | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| package apoc.export.json; | ||
|
|
||
| import com.fasterxml.jackson.core.JsonGenerator; | ||
| import com.fasterxml.jackson.databind.JsonSerializer; | ||
| import com.fasterxml.jackson.databind.SerializerProvider; | ||
| import org.neo4j.graphdb.spatial.Point; | ||
| import org.neo4j.values.storable.CoordinateReferenceSystem; | ||
|
|
||
| import java.io.IOException; | ||
| import java.util.List; | ||
|
|
||
| public class PointSerializer extends JsonSerializer<Point> { | ||
| @Override | ||
| public void serialize(Point value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { | ||
|
|
||
| String crsType = value.getCRS().getType(); | ||
| List<Double> coordinate = value.getCoordinate().getCoordinate(); | ||
|
|
||
| if (crsType.startsWith(CoordinateReferenceSystem.Cartesian.toString())) { | ||
| if (coordinate.size() == 3) { | ||
| jsonGenerator.writeObject(new PointCartesian(crsType, coordinate.get(0), coordinate.get(1), coordinate.get(2))); | ||
| } else { | ||
| jsonGenerator.writeObject(new PointCartesian(crsType, coordinate.get(0), coordinate.get(1))); | ||
| } | ||
| } else { | ||
| if (coordinate.size() == 3) { | ||
| jsonGenerator.writeObject(new PointWgs(crsType, coordinate.get(0), coordinate.get(1), coordinate.get(2))); | ||
| } else { | ||
| jsonGenerator.writeObject(new PointWgs(crsType, coordinate.get(0), coordinate.get(1))); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
||
| class PointCartesian { | ||
| private String crs; | ||
| private Double x; | ||
| private Double y; | ||
| private Double z; | ||
|
|
||
| public PointCartesian(String crs, Double x, Double y, Double z) { | ||
| this.crs = crs; | ||
| this.x = x; | ||
| this.y = y; | ||
| this.z = z; | ||
| } | ||
|
|
||
| public PointCartesian(String crs, Double x, Double y) { | ||
| this.crs = crs; | ||
| this.x = x; | ||
| this.y = y; | ||
| } | ||
|
|
||
| public String getCrs() { | ||
| return crs; | ||
| } | ||
|
|
||
| public void setCrs(String crs) { | ||
| this.crs = crs; | ||
| } | ||
|
|
||
| public Double getX() { | ||
| return x; | ||
| } | ||
|
|
||
| public void setX(Double x) { | ||
| this.x = x; | ||
| } | ||
|
|
||
| public Double getY() { | ||
| return y; | ||
| } | ||
|
|
||
| public void setY(Double y) { | ||
| this.y = y; | ||
| } | ||
|
|
||
| public Double getZ() { | ||
| return z; | ||
| } | ||
|
|
||
| public void setZ(Double z) { | ||
| this.z = z; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| class PointWgs { | ||
| private String crs; | ||
| private Double latitude; | ||
| private Double longitude; | ||
| private Double height; | ||
|
|
||
| public PointWgs(String crs, Double latitude, Double longitude, Double height) { | ||
| this.crs = crs; | ||
| this.latitude = latitude; | ||
| this.longitude = longitude; | ||
| this.height = height; | ||
| } | ||
|
|
||
| public PointWgs(String crs, Double latitude, Double longitude) { | ||
| this.crs = crs; | ||
| this.latitude = latitude; | ||
| this.longitude = longitude; | ||
| } | ||
|
|
||
| public String getCrs() { | ||
| return crs; | ||
| } | ||
|
|
||
| public void setCrs(String crs) { | ||
| this.crs = crs; | ||
| } | ||
|
|
||
| public Double getLatitude() { | ||
| return latitude; | ||
| } | ||
|
|
||
| public void setLatitude(Double latitude) { | ||
| this.latitude = latitude; | ||
| } | ||
|
|
||
| public Double getLongitude() { | ||
| return longitude; | ||
| } | ||
|
|
||
| public void setLongitude(Double longitude) { | ||
| this.longitude = longitude; | ||
| } | ||
|
|
||
| public Double getHeight() { | ||
| return height; | ||
| } | ||
|
|
||
| public void setHeight(Double height) { | ||
| this.height = height; | ||
| } | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package apoc.export.json; | ||
|
|
||
| import com.fasterxml.jackson.core.JsonGenerator; | ||
| import com.fasterxml.jackson.databind.JsonSerializer; | ||
| import com.fasterxml.jackson.databind.SerializerProvider; | ||
|
|
||
| import java.io.IOException; | ||
| import java.time.temporal.TemporalAccessor; | ||
|
|
||
| public class TemporalSerializer extends JsonSerializer<TemporalAccessor> { | ||
|
|
||
| @Override | ||
| public void serialize(TemporalAccessor value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException { | ||
| if (value == null) { | ||
| jsonGenerator.writeNull(); | ||
| } | ||
| jsonGenerator.writeString(value.toString()); | ||
| } | ||
| } |