diff --git a/src/main/java/fold/io/CustomFoldReader.java b/src/main/java/fold/io/CustomFoldReader.java index d7bc150..0255088 100644 --- a/src/main/java/fold/io/CustomFoldReader.java +++ b/src/main/java/fold/io/CustomFoldReader.java @@ -1,5 +1,6 @@ package fold.io; +import com.fasterxml.jackson.jr.ob.JSON; import fold.model.FoldFile; import java.io.IOException; @@ -35,9 +36,13 @@ public CustomFoldReader(Class tClass, InputStream inputStream) { */ public T read() throws FoldFileFormatException { try { - return json.beanFrom(tClass, inputStream); + return getJson().beanFrom(tClass, inputStream); } catch (IOException e) { throw new FoldFileFormatException(e); } } + + protected JSON getJson() { + return json; + } } diff --git a/src/main/java/fold/io/LenientFoldReader.java b/src/main/java/fold/io/LenientFoldReader.java new file mode 100644 index 0000000..afe330c --- /dev/null +++ b/src/main/java/fold/io/LenientFoldReader.java @@ -0,0 +1,27 @@ +package fold.io; + +import com.fasterxml.jackson.jr.ob.JSON; +import fold.model.FoldFile; + +import java.io.InputStream; + +import static fold.io.impl.Fold.lenient; + +/** + * Does not throw an exception when unexpected fields are encountered. + */ +public class LenientFoldReader extends CustomFoldReader { + /** + * Create a new FoldReader from an InputStream. + * + * @param inputStream The InputStream to read from when reading this FoldFile. + */ + public LenientFoldReader(InputStream inputStream) { + super(FoldFile.class, inputStream); + } + + @Override + protected JSON getJson() { + return lenient; + } +} diff --git a/src/main/java/fold/io/impl/Fold.java b/src/main/java/fold/io/impl/Fold.java index c2a8986..0876fac 100644 --- a/src/main/java/fold/io/impl/Fold.java +++ b/src/main/java/fold/io/impl/Fold.java @@ -6,6 +6,11 @@ public class Fold { public static JSON json = JSON.builder() .register(new JrSimpleTreeExtension()) - .register(new FoldJacksonJrExtension()) + .register(new FoldJacksonJrExtension(true)) + .build(); + + public static final JSON lenient = JSON.builder() + .register(new JrSimpleTreeExtension()) + .register(new FoldJacksonJrExtension(false)) .build(); } diff --git a/src/main/java/fold/io/impl/FoldFileValueReader.java b/src/main/java/fold/io/impl/FoldFileValueReader.java index d40a47b..2134bbe 100644 --- a/src/main/java/fold/io/impl/FoldFileValueReader.java +++ b/src/main/java/fold/io/impl/FoldFileValueReader.java @@ -11,10 +11,12 @@ class FoldFileValueReader extends ValueReader { private final Class type; + private final boolean strict; - public FoldFileValueReader(Class type) { + public FoldFileValueReader(Class type, boolean strict) { super(FoldFile.class); this.type = type; + this.strict = strict; } @Override @@ -27,7 +29,7 @@ public Object read(JSONReader reader, JsonParser p) throws IOException { throw new RuntimeException(e); } - FoldFrameValueReader.FoldFrameFactory foldFrameFactory = new FoldFrameValueReader.FoldFrameFactory(instance.getRootFrame()); + FoldFrameValueReader.FoldFrameFactory foldFrameFactory = new FoldFrameValueReader.FoldFrameFactory(instance.getRootFrame(), strict); String fieldName; while ((fieldName = p.nextFieldName()) != null) { diff --git a/src/main/java/fold/io/impl/FoldFrameValueReader.java b/src/main/java/fold/io/impl/FoldFrameValueReader.java index a639de8..5e8b727 100644 --- a/src/main/java/fold/io/impl/FoldFrameValueReader.java +++ b/src/main/java/fold/io/impl/FoldFrameValueReader.java @@ -14,8 +14,11 @@ import java.util.List; class FoldFrameValueReader extends ValueReader { - public FoldFrameValueReader() { + private final boolean strict; + + public FoldFrameValueReader(boolean strict) { super(FoldFrame.class); + this.strict = strict; } private static List> readListListOf(Class type, JSONReader reader, JsonParser p) throws IOException { @@ -128,7 +131,7 @@ public Object read(JSONReader reader, JsonParser p) throws IOException { String fieldName; - FoldFrameFactory foldFrameFactory = new FoldFrameFactory(frame); + FoldFrameFactory foldFrameFactory = new FoldFrameFactory(frame, strict); while ((fieldName = p.nextFieldName()) != null) { foldFrameFactory.readField(fieldName, reader, p); @@ -141,6 +144,7 @@ public Object read(JSONReader reader, JsonParser p) throws IOException { public static class FoldFrameFactory { private final FoldFrame instance; + private final boolean strict; List> vertices_coords = new ArrayList<>(); List> vertices_vertices = new ArrayList<>(); List> vertices_edges = new ArrayList<>(); @@ -159,8 +163,9 @@ public static class FoldFrameFactory { List> edgeOrders = new ArrayList<>(); List> faceOrders = new ArrayList<>(); - public FoldFrameFactory(FoldFrame instance) { + public FoldFrameFactory(FoldFrame instance, boolean strict) { this.instance = instance; + this.strict = strict; } public void readField(String fieldName, JSONReader reader, JsonParser p) throws IOException { @@ -231,7 +236,9 @@ public void readField(String fieldName, JSONReader reader, JsonParser p) throws faceOrders = readListListOf(Integer.class, reader, p); break; default: - throw new FoldFileFormatException("Field \"" + fieldName + "\" not valid"); + if (strict) { + throw new FoldFileFormatException("Field \"" + fieldName + "\" not valid"); + } } } diff --git a/src/main/java/fold/io/impl/FoldJacksonJrExtension.java b/src/main/java/fold/io/impl/FoldJacksonJrExtension.java index d20321b..eef216a 100644 --- a/src/main/java/fold/io/impl/FoldJacksonJrExtension.java +++ b/src/main/java/fold/io/impl/FoldJacksonJrExtension.java @@ -11,19 +11,25 @@ import fold.model.FoldFrame; class FoldJacksonJrExtension extends JacksonJrExtension { + private final boolean strict; + + public FoldJacksonJrExtension(boolean strict) { + this.strict = strict; + } + @Override protected void register(ExtensionContext ctx) { ctx.appendProvider(new FoldHandlerProvider()); } - private static class FoldHandlerProvider extends ReaderWriterProvider { + private class FoldHandlerProvider extends ReaderWriterProvider { @SuppressWarnings("unchecked") public ValueReader findValueReader(JSONReader readContext, Class type) { if (type == FoldFrame.class) { - return new FoldFrameValueReader(); + return new FoldFrameValueReader(strict); } if (FoldFile.class.isAssignableFrom(type)) { - return new FoldFileValueReader<>((Class) type); + return new FoldFileValueReader<>((Class) type, strict); } return null; } diff --git a/src/test/java/fold/StrictTest.java b/src/test/java/fold/StrictTest.java new file mode 100644 index 0000000..98081c2 --- /dev/null +++ b/src/test/java/fold/StrictTest.java @@ -0,0 +1,37 @@ +package fold; + +import fold.io.FoldFileFormatException; +import fold.io.FoldReader; +import fold.io.LenientFoldReader; +import fold.model.FoldFile; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.io.FileInputStream; +import java.util.Objects; + +public class StrictTest { + @Test + public void testReadNonStrict() throws Exception { + File saveFile = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("fold/extra_fields.fold")).getFile()); + + FoldFile foldFile; + try (FileInputStream inputStream = new FileInputStream(saveFile)) { + LenientFoldReader foldReader = new LenientFoldReader(inputStream); + foldFile = foldReader.read(); + } + + Assertions.assertEquals(1.2, foldFile.getSpec()); + } + + @Test + public void testReadStrict() throws Exception { + File saveFile = new File(Objects.requireNonNull(getClass().getClassLoader().getResource("fold/extra_fields.fold")).getFile()); + + try (FileInputStream inputStream = new FileInputStream(saveFile)) { + FoldReader foldReader = new FoldReader(inputStream); + Assertions.assertThrows(FoldFileFormatException.class, foldReader::read); + } + } +} diff --git a/src/test/resources/fold/extra_fields.fold b/src/test/resources/fold/extra_fields.fold new file mode 100644 index 0000000..27875a5 --- /dev/null +++ b/src/test/resources/fold/extra_fields.fold @@ -0,0 +1,10 @@ +{ + "file_spec": 1.2, + "version": 1.2, + "file_creator": "Crease Pattern Editor", + "file_classes": [ + "singleModel" + ], + "file_author": "test", + "file_description": "The description" +}