Skip to content

Commit

Permalink
WIP simple JSON load/write, but write is broken
Browse files Browse the repository at this point in the history
  • Loading branch information
garfieldnate committed Jan 8, 2025
1 parent 17127d5 commit 7b08ccf
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 5 deletions.
90 changes: 90 additions & 0 deletions src/main/java/edu/umich/soar/visualsoar/files/SoarDatamapJson.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package edu.umich.soar.visualsoar.files;

import static edu.umich.soar.visualsoar.files.Util.JSON_OBJECT_MAPPER;
import static edu.umich.soar.visualsoar.files.Util.saveToFile;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonPOJOBuilder;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;

@JsonDeserialize(builder = SoarDatamapJson.Builder.class)
public class SoarDatamapJson {

private enum VertexType {
SOAR_ID,
ENUMERATION,
INTEGER_RANGE,
INTEGER,
FLOAT_RANGE,
FLOAT,
STRING,
FOREIGN,
}

private final String id;
private final VertexType vertexType;

SoarDatamapJson(String id, VertexType vertexType) {
this.id = id;
this.vertexType = vertexType;
}

@JsonPOJOBuilder(buildMethodName = "build", withPrefix = "with")
static class Builder {
private String id;
private SoarDatamapJson.VertexType vertexType;

public Builder withId(String id) {
this.id = id;
return this;
}

public Builder withVertexType(SoarDatamapJson.VertexType vertexType) {
this.vertexType = vertexType;
return this;
}

public SoarDatamapJson build() {
return new SoarDatamapJson(id, vertexType);
}
}

public static SoarDatamapJson loadFromJson(String json) throws JsonProcessingException {
return JSON_OBJECT_MAPPER.readValue(json, SoarDatamapJson.class);
}

private static class JsonWriter implements Util.Writer {
private final SoarDatamapJson json;

private JsonWriter(SoarDatamapJson json) {
this.json = json;
}

@Override
public void write(OutputStream out) throws IOException {
JSON_OBJECT_MAPPER.writerFor(SoarDatamapJson.class).writeValue(out, json);
}
}

public static void writeJsonToFile(Path destination, SoarDatamapJson json) throws IOException {
saveToFile(destination, new JsonWriter(json));
}

public static void main(String[] args) throws IOException {
SoarDatamapJson json =
SoarDatamapJson.loadFromJson("{\"id\":\"XYZ\", \"vertexType\":\"FLOAT\"}");
System.out.println(json.id);
System.out.println(json.vertexType);
assert json.id.equals("XYZ");
assert json.vertexType.equals(VertexType.FLOAT);
Path destination = Paths.get("sample-output.json");
writeJsonToFile(destination, json);
// TODO: NEXT: output file contains empty object!
System.err.println("Please inspect " + destination + " for JSON output");
}
}
53 changes: 48 additions & 5 deletions src/main/java/edu/umich/soar/visualsoar/files/Util.java
Original file line number Diff line number Diff line change
@@ -1,28 +1,58 @@
package edu.umich.soar.visualsoar.files;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.logging.Logger;

import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_JAVA_COMMENTS;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_LEADING_PLUS_SIGN_FOR_NUMBERS;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_LEADING_ZEROS_FOR_NUMBERS;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_SINGLE_QUOTES;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_TRAILING_COMMA;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_TRAILING_DECIMAL_POINT_FOR_NUMBERS;
import static com.fasterxml.jackson.core.json.JsonReadFeature.ALLOW_UNQUOTED_FIELD_NAMES;
import static java.nio.file.StandardCopyOption.ATOMIC_MOVE;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;

public class Util {
private static final Logger LOGGER = Logger.getLogger(Util.class.getName());
public static final JsonFactory JSON_FACTORY =
JsonFactory.builder()
// configure, if necessary:
.enable(ALLOW_JAVA_COMMENTS)
.enable(ALLOW_UNQUOTED_FIELD_NAMES)
.enable(ALLOW_TRAILING_COMMA)
.enable(ALLOW_SINGLE_QUOTES)
// TODO: are we sure that NaN's could be used for anything?
.enable(ALLOW_NON_NUMERIC_NUMBERS)
.enable(ALLOW_LEADING_ZEROS_FOR_NUMBERS)
.enable(ALLOW_LEADING_PLUS_SIGN_FOR_NUMBERS)
.enable(ALLOW_LEADING_DECIMAL_POINT_FOR_NUMBERS)
.enable(ALLOW_TRAILING_DECIMAL_POINT_FOR_NUMBERS)
.build();

public static final ObjectMapper JSON_OBJECT_MAPPER = new ObjectMapper(JSON_FACTORY);

@FunctionalInterface
public interface Writer {
void write(OutputStream out);
void write(OutputStream out) throws IOException;
}

/**
* Write to the destination file from {@code writer} as atomically as possible.
*/
public void Save(Path destination, Writer writer) throws java.io.IOException {
/** Write to the destination file from {@code writer} as atomically as possible. */
public static void saveToFile(Path destination, Writer writer) throws java.io.IOException {
// Write to a temp file first, then make the final changes via a rename,
// which can often be done atomically. This prevents issues such as overwriting a file with a
// incomplete data, as could be the case if we hit an IO exception in the middle of writing the
Expand All @@ -46,4 +76,17 @@ public void Save(Path destination, Writer writer) throws java.io.IOException {
Files.move(tempPath, destination, REPLACE_EXISTING);
}
}

/**
* Load JSON file with very lenient parser settings in the direction of natural JavaScript syntax
* (so JSON5)
*/
public void loadJson() {
try (JsonParser parser = JSON_FACTORY.createParser(new File("TODO"))) {
} catch(JsonParseException e) {

} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

0 comments on commit 7b08ccf

Please sign in to comment.