diff --git a/content-api/src/main/java/module-info.java b/content-api/src/main/java/module-info.java new file mode 100644 index 0000000..865cb61 --- /dev/null +++ b/content-api/src/main/java/module-info.java @@ -0,0 +1,3 @@ +module org.xbib.content { + exports org.xbib.content; +} \ No newline at end of file diff --git a/content-core/src/main/java/org/xbib/content/settings/SettingsLoader.java b/content-api/src/main/java/org/xbib/content/SettingsLoader.java similarity index 80% rename from content-core/src/main/java/org/xbib/content/settings/SettingsLoader.java rename to content-api/src/main/java/org/xbib/content/SettingsLoader.java index 2b12a79..9687d6c 100644 --- a/content-core/src/main/java/org/xbib/content/settings/SettingsLoader.java +++ b/content-api/src/main/java/org/xbib/content/SettingsLoader.java @@ -1,6 +1,5 @@ -package org.xbib.content.settings; +package org.xbib.content; -import org.xbib.content.io.BytesReference; import java.io.IOException; import java.util.Map; import java.util.Set; @@ -25,8 +24,6 @@ public interface SettingsLoader { */ Map load(String source) throws IOException; - Map load(BytesReference bytesReference) throws IOException; - Map load(Map source) throws IOException; boolean canLoad(String source); diff --git a/content-core/src/main/java/org/xbib/content/ToXContent.java b/content-api/src/main/java/org/xbib/content/ToXContent.java similarity index 96% rename from content-core/src/main/java/org/xbib/content/ToXContent.java rename to content-api/src/main/java/org/xbib/content/ToXContent.java index 0f88e09..eab1650 100644 --- a/content-core/src/main/java/org/xbib/content/ToXContent.java +++ b/content-api/src/main/java/org/xbib/content/ToXContent.java @@ -25,9 +25,6 @@ public interface ToXContent { }; - /** - * - */ interface Params { String param(String key); diff --git a/content-core/src/main/java/org/xbib/content/XContent.java b/content-api/src/main/java/org/xbib/content/XContent.java similarity index 81% rename from content-core/src/main/java/org/xbib/content/XContent.java rename to content-api/src/main/java/org/xbib/content/XContent.java index 604677d..6582663 100644 --- a/content-core/src/main/java/org/xbib/content/XContent.java +++ b/content-api/src/main/java/org/xbib/content/XContent.java @@ -1,7 +1,5 @@ package org.xbib.content; -import org.xbib.content.io.BytesReference; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -15,6 +13,8 @@ public interface XContent { String name(); + boolean isXContent(byte[] data, int offset, int length); + /** * Creates a new generator using the provided output stream. * @@ -80,19 +80,4 @@ public interface XContent { */ XContentParser createParser(byte[] bytes, int offset, int length) throws IOException; - /** - * Creates a parser over the provided bytes. - * - * @param bytes bytes - * @return content parser - * @throws IOException if creation fails - */ - XContentParser createParser(BytesReference bytes) throws IOException; - - /** - * Returns true if content can be parsed/generated. - * @param bytes bytes - * @return true if content can be parsed/generated. - */ - boolean isXContent(BytesReference bytes); } diff --git a/content-api/src/main/java/org/xbib/content/XContentBuilder.java b/content-api/src/main/java/org/xbib/content/XContentBuilder.java new file mode 100644 index 0000000..abea1b1 --- /dev/null +++ b/content-api/src/main/java/org/xbib/content/XContentBuilder.java @@ -0,0 +1,152 @@ +package org.xbib.content; + +import java.io.Closeable; +import java.io.Flushable; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.Instant; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +public interface XContentBuilder extends ToXContent, Flushable, Closeable { + + XContentBuilder prettyPrint(); + + XContentBuilder rawField(String fieldName, byte[] content, int offset, int length) throws IOException; + + XContentBuilder copy(XContentBuilder builder) throws IOException; + + XContentBuilder copy(List builder) throws IOException; + + void copyCurrentStructure(XContentParser parser) throws IOException; + + XContentBuilder field(String name) throws IOException; + + XContentBuilder field(String name, ToXContent xContent) throws IOException; + + XContentBuilder field(String name, ToXContent xContent, ToXContent.Params params) throws IOException; + + XContentBuilder field(String name, boolean value) throws IOException; + + XContentBuilder field(String name, Boolean value) throws IOException; + + XContentBuilder field(String name, int value) throws IOException; + + XContentBuilder field(String name, Integer value) throws IOException; + + XContentBuilder field(String name, long value) throws IOException; + + XContentBuilder field(String name, Long value) throws IOException; + + XContentBuilder field(String name, float value) throws IOException; + + XContentBuilder field(String name, Float value) throws IOException; + + XContentBuilder field(String name, double value) throws IOException; + + XContentBuilder field(String name, Double value) throws IOException; + + XContentBuilder field(String name, BigInteger value) throws IOException; + + XContentBuilder field(String name, BigDecimal value) throws IOException; + + XContentBuilder field(String name, String value) throws IOException; + + XContentBuilder field(String name, Object value) throws IOException; + + XContentBuilder field(String name, int... value) throws IOException; + + XContentBuilder field(String name, long... value) throws IOException; + + XContentBuilder field(String name, double... value) throws IOException; + + XContentBuilder field(String name, float... value) throws IOException; + + XContentBuilder field(String name, byte[] value, int offset, int length) throws IOException; + + XContentBuilder field(String name, char[] value, int offset, int length) throws IOException; + + XContentBuilder nullField(String name) throws IOException; + + XContentBuilder fieldIfNotNull(String name, Boolean value) throws IOException; + + XContentBuilder fieldIfNotNull(String name, Integer value) throws IOException; + + XContentBuilder fieldIfNotNull(String name, Long value) throws IOException; + + XContentBuilder fieldIfNotNull(String name, Float value) throws IOException; + + XContentBuilder fieldIfNotNull(String name, Double value) throws IOException; + + XContentBuilder fieldIfNotNull(String name, String value) throws IOException; + + XContentBuilder fieldIfNotNull(String name, Object value) throws IOException; + + XContentBuilder value(boolean value) throws IOException; + + XContentBuilder value(Boolean value) throws IOException; + + XContentBuilder value(int value) throws IOException; + + XContentBuilder value(Integer value) throws IOException; + + XContentBuilder value(long value) throws IOException; + + XContentBuilder value(Long value) throws IOException; + + XContentBuilder value(float value) throws IOException; + + XContentBuilder value(Float value) throws IOException; + + XContentBuilder value(double value) throws IOException; + + XContentBuilder value(Double value) throws IOException; + + XContentBuilder value(BigInteger value) throws IOException; + + XContentBuilder value(BigDecimal value) throws IOException; + + XContentBuilder value(String value) throws IOException; + + XContentBuilder value(XContentBuilder builder) throws IOException; + + XContentBuilder value(Object value) throws IOException; + + XContentBuilder value(byte[] value) throws IOException; + + XContentBuilder value(byte[] value, int offset, int length) throws IOException; + + XContentBuilder value(Iterable value) throws IOException; + + XContentBuilder value(Map map) throws IOException; + + XContentBuilder nullValue() throws IOException; + + XContentBuilder array(String name, Collection values) throws IOException; + + XContentBuilder array(String name, String... values) throws IOException; + + XContentBuilder array(String name, Object... values) throws IOException; + + XContentBuilder startArray() throws IOException; + + XContentBuilder startArray(String name) throws IOException; + + XContentBuilder endArray() throws IOException; + + XContentBuilder startObject() throws IOException; + + XContentBuilder startObject(String name) throws IOException; + + XContentBuilder endObject() throws IOException; + + XContentBuilder map(Map map) throws IOException; + + XContentBuilder flatMap(Map map) throws IOException; + + XContentBuilder timeseriesMap(Map map) throws IOException; + + String string() throws IOException; +} diff --git a/content-core/src/main/java/org/xbib/content/XContentGenerator.java b/content-api/src/main/java/org/xbib/content/XContentGenerator.java similarity index 69% rename from content-core/src/main/java/org/xbib/content/XContentGenerator.java rename to content-api/src/main/java/org/xbib/content/XContentGenerator.java index 02d20c3..6a98664 100644 --- a/content-core/src/main/java/org/xbib/content/XContentGenerator.java +++ b/content-api/src/main/java/org/xbib/content/XContentGenerator.java @@ -1,7 +1,5 @@ package org.xbib.content; -import org.xbib.content.io.BytesReference; - import java.io.Closeable; import java.io.Flushable; import java.io.IOException; @@ -9,9 +7,6 @@ import java.io.OutputStream; import java.math.BigDecimal; import java.math.BigInteger; -/** - * - */ public interface XContentGenerator extends Flushable, Closeable { XContent content(); @@ -28,8 +23,6 @@ public interface XContentGenerator extends Flushable, Closeable { void writeFieldName(String name) throws IOException; - void writeFieldName(XContentString name) throws IOException; - void writeString(String text) throws IOException; void writeString(char[] text, int offset, int len) throws IOException; @@ -58,59 +51,34 @@ public interface XContentGenerator extends Flushable, Closeable { void writeStringField(String fieldName, String value) throws IOException; - void writeStringField(XContentString fieldName, String value) throws IOException; - void writeBooleanField(String fieldName, boolean value) throws IOException; - void writeBooleanField(XContentString fieldName, boolean value) throws IOException; - void writeNullField(String fieldName) throws IOException; void writeNumberField(String fieldName, int value) throws IOException; - void writeNumberField(XContentString fieldName, int value) throws IOException; - void writeNumberField(String fieldName, long value) throws IOException; - void writeNumberField(XContentString fieldName, long value) throws IOException; - void writeNumberField(String fieldName, double value) throws IOException; - void writeNumberField(XContentString fieldName, double value) throws IOException; - void writeNumberField(String fieldName, float value) throws IOException; - void writeNumberField(XContentString fieldName, float value) throws IOException; - void writeNumberField(String fieldName, BigInteger value) throws IOException; - void writeNumberField(XContentString fieldName, BigInteger value) throws IOException; - void writeNumberField(String fieldName, BigDecimal value) throws IOException; - void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException; - void writeBinaryField(String fieldName, byte[] data) throws IOException; - void writeBinaryField(XContentString fieldName, byte[] data) throws IOException; - void writeArrayFieldStart(String fieldName) throws IOException; - void writeArrayFieldStart(XContentString fieldName) throws IOException; - void writeObjectFieldStart(String fieldName) throws IOException; - void writeObjectFieldStart(XContentString fieldName) throws IOException; - void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException; void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) throws IOException; - void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) - throws IOException; - void writeValue(XContentBuilder builder) throws IOException; void copy(XContentBuilder builder, OutputStream outputStream) throws IOException; diff --git a/content-core/src/main/java/org/xbib/content/XContentParser.java b/content-api/src/main/java/org/xbib/content/XContentParser.java similarity index 94% rename from content-core/src/main/java/org/xbib/content/XContentParser.java rename to content-api/src/main/java/org/xbib/content/XContentParser.java index a53fe04..74f8502 100644 --- a/content-core/src/main/java/org/xbib/content/XContentParser.java +++ b/content-api/src/main/java/org/xbib/content/XContentParser.java @@ -6,9 +6,6 @@ import java.math.BigDecimal; import java.math.BigInteger; import java.util.Map; -/** - * - */ public interface XContentParser extends Closeable { XContent content(); @@ -45,11 +42,6 @@ public interface XContentParser extends Closeable { NumberType numberType() throws IOException; - /** - * Is the number type estimated or not (i.e. an int might actually be a long, its just low enough - * to be an int). - * @return true if number is estimated - */ boolean estimatedNumberType(); short shortValue() throws IOException; diff --git a/content-config/build.gradle b/content-config/build.gradle index 1ce8b51..4129eac 100644 --- a/content-config/build.gradle +++ b/content-config/build.gradle @@ -1,3 +1,5 @@ dependencies { + api project(':content-json') api project(':content-yaml') + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}" } diff --git a/content-config/src/main/java/module-info.java b/content-config/src/main/java/module-info.java index 33caa64..fc855aa 100644 --- a/content-config/src/main/java/module-info.java +++ b/content-config/src/main/java/module-info.java @@ -1,4 +1,5 @@ module org.xbib.content.config { exports org.xbib.content.config; + requires transitive org.xbib.content.json; requires transitive org.xbib.content.yaml; -} \ No newline at end of file +} diff --git a/content-config/src/main/java/org/xbib/content/config/ConfigLoader.java b/content-config/src/main/java/org/xbib/content/config/ConfigLoader.java index 3264116..b783d4f 100644 --- a/content-config/src/main/java/org/xbib/content/config/ConfigLoader.java +++ b/content-config/src/main/java/org/xbib/content/config/ConfigLoader.java @@ -2,7 +2,7 @@ package org.xbib.content.config; import org.xbib.content.json.JsonSettingsLoader; import org.xbib.content.settings.Settings; -import org.xbib.content.settings.SettingsLoader; +import org.xbib.content.SettingsLoader; import org.xbib.content.yaml.YamlSettingsLoader; import java.io.BufferedReader; import java.io.IOException; diff --git a/content-core/build.gradle b/content-core/build.gradle index 810e4a0..7eeafc5 100644 --- a/content-core/build.gradle +++ b/content-core/build.gradle @@ -1,4 +1,5 @@ dependencies { - api "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}" + api project(':content-api') api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures-tiny.version')}" + implementation "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}" } diff --git a/content-core/src/main/java/module-info.java b/content-core/src/main/java/module-info.java index d04552f..481fc2d 100644 --- a/content-core/src/main/java/module-info.java +++ b/content-core/src/main/java/module-info.java @@ -1,15 +1,16 @@ +import org.xbib.content.SettingsLoader; +import org.xbib.content.properties.PropertiesSettingsLoader; + module org.xbib.content.core { - exports org.xbib.content; + uses org.xbib.content.XContent; + uses SettingsLoader; exports org.xbib.content.io; - exports org.xbib.content.json; - exports org.xbib.content.settings; + exports org.xbib.content.properties; exports org.xbib.content.util.geo; exports org.xbib.content.util.unit; - requires org.xbib.datastructures.tiny; + exports org.xbib.content.core; + requires transitive org.xbib.content; + requires transitive org.xbib.datastructures.tiny; requires transitive com.fasterxml.jackson.core; - provides org.xbib.content.XContent with - org.xbib.content.json.JsonXContent; - provides org.xbib.content.settings.SettingsLoader with - org.xbib.content.settings.PropertiesSettingsLoader, - org.xbib.content.json.JsonSettingsLoader; + provides SettingsLoader with PropertiesSettingsLoader; } diff --git a/content-core/src/main/java/org/xbib/content/XContentBuilderString.java b/content-core/src/main/java/org/xbib/content/XContentBuilderString.java deleted file mode 100644 index ecf0974..0000000 --- a/content-core/src/main/java/org/xbib/content/XContentBuilderString.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.xbib.content; - -/** - * - */ -public class XContentBuilderString { - - private final XContentString string; - - public XContentBuilderString(String value) { - string = new XContentString(value); - } - - public XContentString string() { - return string; - } - -} diff --git a/content-core/src/main/java/org/xbib/content/XContentString.java b/content-core/src/main/java/org/xbib/content/XContentString.java deleted file mode 100644 index 7da1f63..0000000 --- a/content-core/src/main/java/org/xbib/content/XContentString.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.xbib.content; - -import com.fasterxml.jackson.core.io.SerializedString; - -/** - * - */ -public class XContentString extends SerializedString { - - private static final long serialVersionUID = -127711532459894341L; - - public XContentString(String v) { - super(v); - } -} diff --git a/content-core/src/main/java/org/xbib/content/AbstractXContentGenerator.java b/content-core/src/main/java/org/xbib/content/core/AbstractXContentGenerator.java similarity index 64% rename from content-core/src/main/java/org/xbib/content/AbstractXContentGenerator.java rename to content-core/src/main/java/org/xbib/content/core/AbstractXContentGenerator.java index a052210..22ec355 100644 --- a/content-core/src/main/java/org/xbib/content/AbstractXContentGenerator.java +++ b/content-core/src/main/java/org/xbib/content/core/AbstractXContentGenerator.java @@ -1,7 +1,7 @@ -package org.xbib.content; +package org.xbib.content.core; +import org.xbib.content.XContentGenerator; import java.io.IOException; -import java.io.OutputStream; import java.math.BigDecimal; import java.math.BigInteger; @@ -42,11 +42,6 @@ public abstract class AbstractXContentGenerator implements XContentGenerator { generator.writeFieldName(name); } - @Override - public void writeFieldName(XContentString name) throws IOException { - generator.writeFieldName(name); - } - @Override public void writeString(String text) throws IOException { generator.writeString(text); @@ -117,22 +112,11 @@ public abstract class AbstractXContentGenerator implements XContentGenerator { generator.writeStringField(fieldName, value); } - @Override - public void writeStringField(XContentString fieldName, String value) throws IOException { - generator.writeFieldName(fieldName); - } - @Override public void writeBooleanField(String fieldName, boolean value) throws IOException { generator.writeBooleanField(fieldName, value); } - @Override - public void writeBooleanField(XContentString fieldName, boolean value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeBoolean(value); - } - @Override public void writeNullField(String fieldName) throws IOException { generator.writeNullField(fieldName); @@ -143,104 +127,44 @@ public abstract class AbstractXContentGenerator implements XContentGenerator { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, int value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, long value) throws IOException { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, long value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, double value) throws IOException { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, double value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, float value) throws IOException { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, float value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, BigInteger value) throws IOException { generator.writeFieldName(fieldName); generator.writeNumber(value); } - @Override - public void writeNumberField(XContentString fieldName, BigInteger value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, BigDecimal value) throws IOException { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeBinaryField(String fieldName, byte[] data) throws IOException { generator.writeBinaryField(fieldName, data); } - @Override - public void writeBinaryField(XContentString fieldName, byte[] data) throws IOException { - generator.writeFieldName(fieldName); - generator.writeBinary(data); - } - @Override public void writeArrayFieldStart(String fieldName) throws IOException { generator.writeArrayFieldStart(fieldName); } - @Override - public void writeArrayFieldStart(XContentString fieldName) throws IOException { - generator.writeFieldName(fieldName); - generator.writeStartArray(); - } - @Override public void writeObjectFieldStart(String fieldName) throws IOException { generator.writeObjectFieldStart(fieldName); } - - @Override - public void writeObjectFieldStart(XContentString fieldName) throws IOException { - generator.writeFieldName(fieldName); - generator.writeStartObject(); - } - - @Override - public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { - flush(); - builder.bytes().streamOutput(outputStream); - } } diff --git a/content-core/src/main/java/org/xbib/content/AbstractXContentParser.java b/content-core/src/main/java/org/xbib/content/core/AbstractXContentParser.java similarity index 99% rename from content-core/src/main/java/org/xbib/content/AbstractXContentParser.java rename to content-core/src/main/java/org/xbib/content/core/AbstractXContentParser.java index bef5e71..69bbab7 100644 --- a/content-core/src/main/java/org/xbib/content/AbstractXContentParser.java +++ b/content-core/src/main/java/org/xbib/content/core/AbstractXContentParser.java @@ -1,5 +1,6 @@ -package org.xbib.content; +package org.xbib.content.core; +import org.xbib.content.XContentParser; import org.xbib.datastructures.tiny.TinyMap; import java.io.IOException; import java.util.ArrayList; diff --git a/content-core/src/main/java/org/xbib/content/XContentBuilder.java b/content-core/src/main/java/org/xbib/content/core/DefaultXContentBuilder.java similarity index 76% rename from content-core/src/main/java/org/xbib/content/XContentBuilder.java rename to content-core/src/main/java/org/xbib/content/core/DefaultXContentBuilder.java index 883bcf7..d6e2522 100644 --- a/content-core/src/main/java/org/xbib/content/XContentBuilder.java +++ b/content-core/src/main/java/org/xbib/content/core/DefaultXContentBuilder.java @@ -1,11 +1,14 @@ -package org.xbib.content; +package org.xbib.content.core; +import org.xbib.content.ToXContent; +import org.xbib.content.XContent; +import org.xbib.content.XContentBuilder; +import org.xbib.content.XContentGenerator; +import org.xbib.content.XContentParser; import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesStreamOutput; import org.xbib.content.util.geo.GeoPoint; -import java.io.Closeable; -import java.io.Flushable; import java.io.IOException; import java.io.OutputStream; import java.math.BigDecimal; @@ -21,10 +24,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; -/** - * - */ -public final class XContentBuilder implements ToXContent, Flushable, Closeable { +public final class DefaultXContentBuilder implements XContentBuilder { private final OutputStream outputStream; private final XContentGenerator generator; @@ -36,7 +36,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { * @param outputStream output stream * @throws IOException if construction fails */ - public XContentBuilder(XContent xContent, OutputStream outputStream) throws IOException { + public DefaultXContentBuilder(XContent xContent, OutputStream outputStream) throws IOException { this.outputStream = outputStream; this.generator = xContent.createGenerator(outputStream); } @@ -48,7 +48,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { * @throws IOException exception */ public static XContentBuilder builder(XContent xContent) throws IOException { - return new XContentBuilder(xContent, new BytesStreamOutput()); + return new DefaultXContentBuilder(xContent, new BytesStreamOutput()); } /** @@ -59,7 +59,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { * @throws IOException if build fails */ public static XContentBuilder builder(XContent xContent, OutputStream out) throws IOException { - return new XContentBuilder(xContent, out); + return new DefaultXContentBuilder(xContent, out); } @Override @@ -67,148 +67,72 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return builder.copy(this); } - public XContent content() { - return generator.content(); - } - - public XContentGenerator generator() { - return generator; - } - + @Override public XContentBuilder prettyPrint() { generator.usePrettyPrint(); return this; } + @Override + public XContentBuilder rawField(String fieldName, byte[] content, int offset, int length) throws IOException { + generator.writeRawField(fieldName, content, offset, length, outputStream); + return this; + } + + @Override + public XContentBuilder copy(XContentBuilder builder) throws IOException { + generator.copy(builder, outputStream); + return this; + } + + @Override + public XContentBuilder copy(List builder) throws IOException { + for (int i = 0; i < builder.size(); i++) { + if (i > 0) { + outputStream.write(','); + } + generator.copy(builder.get(i), outputStream); + } + return this; + } + + @Override + public void copyCurrentStructure(XContentParser parser) throws IOException { + generator.copyCurrentStructure(parser); + } + + @Override public XContentBuilder field(String name, ToXContent xContent) throws IOException { field(name); xContent.toXContent(this, ToXContent.EMPTY_PARAMS); return this; } + @Override public XContentBuilder field(String name, ToXContent xContent, ToXContent.Params params) throws IOException { field(name); xContent.toXContent(this, params); return this; } - public XContentBuilder startObject(String name) throws IOException { - field(name); - startObject(); - return this; - } - - public XContentBuilder startObject(XContentBuilderString name) throws IOException { - field(name); - startObject(); - return this; - } - - public XContentBuilder startObject() throws IOException { - generator.writeStartObject(); - return this; - } - - public XContentBuilder endObject() throws IOException { - generator.writeEndObject(); - return this; - } - - public XContentBuilder array(String name, Collection values) throws IOException { - startArray(name); - for (Object value : values) { - value(value); - } - endArray(); - return this; - } - - public XContentBuilder array(String name, String... values) throws IOException { - startArray(name); - for (String value : values) { - value(value); - } - endArray(); - return this; - } - - public XContentBuilder array(String name, Object... values) throws IOException { - startArray(name); - for (Object value : values) { - value(value); - } - endArray(); - return this; - } - - public XContentBuilder startArray(String name) throws IOException { - field(name); - startArray(); - return this; - } - - public XContentBuilder startArray(XContentBuilderString name) throws IOException { - field(name); - startArray(); - return this; - } - - public XContentBuilder startArray() throws IOException { - generator.writeStartArray(); - return this; - } - - public XContentBuilder endArray() throws IOException { - generator.writeEndArray(); - return this; - } - - public XContentBuilder field(XContentBuilderString name) throws IOException { - generator.writeFieldName(name.string()); - return this; - } - + @Override public XContentBuilder field(String name) throws IOException { Objects.requireNonNull(name); generator.writeFieldName(name); return this; } - public XContentBuilder field(String name, char[] value, int offset, int length) throws IOException { + @Override + public XContentBuilder field(String name, boolean value) throws IOException { field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeString(value, offset, length); - } + generator.writeBoolean(value); return this; } - public XContentBuilder field(String name, String value) throws IOException { + @Override + public XContentBuilder field(String name, Boolean value) throws IOException { field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeString(value); - } - return this; - } - - public XContentBuilder field(XContentBuilderString name, String value) throws IOException { - field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeString(value); - } - return this; - } - - public XContentBuilder fieldIfNotNull(String name, String value) throws IOException { - if (value != null) { - field(name); - generator.writeString(value); - } + generator.writeBoolean(value); return this; } @@ -222,36 +146,13 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder fieldIfNotNull(String name, Integer value) throws IOException { - if (value != null) { - field(name); - generator.writeNumber(value); - } - return this; - } - - public XContentBuilder field(XContentBuilderString name, Integer value) throws IOException { - field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeNumber(value); - } - return this; - } - public XContentBuilder field(String name, int value) throws IOException { field(name); generator.writeNumber(value); return this; } - public XContentBuilder field(XContentBuilderString name, int value) throws IOException { - field(name); - generator.writeNumber(value); - return this; - } - + @Override public XContentBuilder field(String name, Long value) throws IOException { field(name); if (value == null) { @@ -262,36 +163,14 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, Long value) throws IOException { - field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeNumber(value); - } - return this; - } - - public XContentBuilder fieldIfNotNull(String name, Long value) throws IOException { - if (value != null) { - field(name); - generator.writeNumber(value); - } - return this; - } - + @Override public XContentBuilder field(String name, long value) throws IOException { field(name); generator.writeNumber(value); return this; } - public XContentBuilder field(XContentBuilderString name, long value) throws IOException { - field(name); - generator.writeNumber(value); - return this; - } - + @Override public XContentBuilder field(String name, Float value) throws IOException { field(name); if (value == null) { @@ -302,36 +181,14 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, Float value) throws IOException { - field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeNumber(value); - } - return this; - } - - public XContentBuilder fieldIfNotNull(String name, Float value) throws IOException { - if (value != null) { - field(name); - generator.writeNumber(value); - } - return this; - } - + @Override public XContentBuilder field(String name, float value) throws IOException { field(name); generator.writeNumber(value); return this; } - public XContentBuilder field(XContentBuilderString name, float value) throws IOException { - field(name); - generator.writeNumber(value); - return this; - } - + @Override public XContentBuilder field(String name, Double value) throws IOException { field(name); if (value == null) { @@ -342,92 +199,69 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder fieldIfNotNull(String name, Double value) throws IOException { - if (value != null) { - field(name); - generator.writeNumber(value); - } - return this; - } - - public XContentBuilder field(XContentBuilderString name, Double value) throws IOException { - field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeNumber(value); - } - return this; - } - + @Override public XContentBuilder field(String name, double value) throws IOException { field(name); generator.writeNumber(value); return this; } - public XContentBuilder field(XContentBuilderString name, double value) throws IOException { - field(name); - generator.writeNumber(value); - return this; - } - + @Override public XContentBuilder field(String name, BigInteger value) throws IOException { field(name); generator.writeNumber(value); return this; } - public XContentBuilder field(XContentBuilderString name, BigInteger value) throws IOException { - field(name); - generator.writeNumber(value); - return this; - } - + @Override public XContentBuilder field(String name, BigDecimal value) throws IOException { field(name); generator.writeNumber(value); return this; } - public XContentBuilder field(XContentBuilderString name, BigDecimal value) throws IOException { + @Override + public XContentBuilder field(String name, String value) throws IOException { field(name); - generator.writeNumber(value); + if (value == null) { + generator.writeNull(); + } else { + generator.writeString(value); + } return this; } - public XContentBuilder field(String name, BytesReference value) throws IOException { + @Override + public XContentBuilder field(String name, Object value) throws IOException { field(name); - byte[] b = value.toBytes(); - generator.writeBinary(b, 0, b.length); - return this; - } - - public XContentBuilder field(XContentBuilderString name, BytesReference value) throws IOException { - field(name); - byte[] b = value.toBytes(); - generator.writeBinary(b, 0, b.length); + writeValue(value); return this; } + @Override public XContentBuilder field(String name, byte[] value, int offset, int length) throws IOException { field(name); generator.writeBinary(value, offset, length); return this; } + @Override + public XContentBuilder field(String name, char[] value, int offset, int length) throws IOException { + field(name); + if (value == null) { + generator.writeNull(); + } else { + generator.writeString(value, offset, length); + } + return this; + } + public XContentBuilder field(String name, Map value) throws IOException { field(name); value(value); return this; } - public XContentBuilder field(XContentBuilderString name, Map value) throws IOException { - field(name); - value(value); - return this; - } - public XContentBuilder field(String name, Iterable value) throws IOException { startArray(name); for (Object o : value) { @@ -437,15 +271,6 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, Iterable value) throws IOException { - startArray(name); - for (Object o : value) { - value(o); - } - endArray(); - return this; - } - public XContentBuilder field(String name, String... value) throws IOException { startArray(name); for (String o : value) { @@ -455,15 +280,6 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, String... value) throws IOException { - startArray(name); - for (String o : value) { - value(o); - } - endArray(); - return this; - } - public XContentBuilder field(String name, Object... value) throws IOException { startArray(name); for (Object o : value) { @@ -473,15 +289,6 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, Object... value) throws IOException { - startArray(name); - for (Object o : value) { - value(o); - } - endArray(); - return this; - } - public XContentBuilder field(String name, int... value) throws IOException { startArray(name); for (Object o : value) { @@ -491,24 +298,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, int offset, int length, int... value) throws IOException { - startArray(name); - for (int i = offset; i < length; i++) { - value(value[i]); - } - endArray(); - return this; - } - - public XContentBuilder field(XContentBuilderString name, int... value) throws IOException { - startArray(name); - for (Object o : value) { - value(o); - } - endArray(); - return this; - } - + @Override public XContentBuilder field(String name, long... value) throws IOException { startArray(name); for (Object o : value) { @@ -518,15 +308,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, long... value) throws IOException { - startArray(name); - for (Object o : value) { - value(o); - } - endArray(); - return this; - } - + @Override public XContentBuilder field(String name, float... value) throws IOException { startArray(name); for (Object o : value) { @@ -536,15 +318,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, float... value) throws IOException { - startArray(name); - for (Object o : value) { - value(o); - } - endArray(); - return this; - } - + @Override public XContentBuilder field(String name, double... value) throws IOException { startArray(name); for (Object o : value) { @@ -554,27 +328,34 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder field(XContentBuilderString name, double... value) throws IOException { - startArray(name); - for (Object o : value) { - value(o); + @Override + public XContentBuilder fieldIfNotNull(String name, Boolean value) throws IOException { + if (value != null) { + field(name); + generator.writeBoolean(value); } - endArray(); return this; } - public XContentBuilder field(String name, Object value) throws IOException { - field(name); - writeValue(value); + @Override + public XContentBuilder fieldIfNotNull(String name, String value) throws IOException { + if (value != null) { + field(name); + generator.writeString(value); + } return this; } - public XContentBuilder field(XContentBuilderString name, Object value) throws IOException { - field(name); - writeValue(value); + @Override + public XContentBuilder fieldIfNotNull(String name, Integer value) throws IOException { + if (value != null) { + field(name); + generator.writeNumber(value); + } return this; } + @Override public XContentBuilder fieldIfNotNull(String name, Object value) throws IOException { if (value != null) { return field(name, value); @@ -582,67 +363,52 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder value(Object value) throws IOException { - writeValue(value); - return this; - } - - public XContentBuilder field(String name, boolean value) throws IOException { - field(name); - generator.writeBoolean(value); - return this; - } - - public XContentBuilder field(String name, byte[] value) throws IOException { - field(name); - if (value == null) { - generator.writeNull(); - } else { - generator.writeBinary(value); + @Override + public XContentBuilder fieldIfNotNull(String name, Long value) throws IOException { + if (value != null) { + field(name); + generator.writeNumber(value); } return this; } + @Override + public XContentBuilder fieldIfNotNull(String name, Float value) throws IOException { + if (value != null) { + field(name); + generator.writeNumber(value); + } + return this; + } + + @Override + public XContentBuilder fieldIfNotNull(String name, Double value) throws IOException { + if (value != null) { + field(name); + generator.writeNumber(value); + } + return this; + } + + @Override public XContentBuilder nullField(String name) throws IOException { generator.writeNullField(name); return this; } + @Override public XContentBuilder nullValue() throws IOException { generator.writeNull(); return this; } - public XContentBuilder rawField(String fieldName, byte[] content) throws IOException { - generator.writeRawField(fieldName, content, outputStream); - return this; - } - - public XContentBuilder rawField(String fieldName, byte[] content, int offset, int length) throws IOException { - generator.writeRawField(fieldName, content, offset, length, outputStream); - return this; - } - - public XContentBuilder value(XContentBuilder builder) throws IOException { - generator.writeValue(builder); - return this; - } - - public XContentBuilder copy(XContentBuilder builder) throws IOException { - generator.copy(builder, outputStream); - return this; - } - - public XContentBuilder copy(List builder) throws IOException { - for (int i = 0; i < builder.size(); i++) { - if (i > 0) { - outputStream.write(','); - } - generator.copy(builder.get(i), outputStream); - } + @Override + public XContentBuilder value(boolean value) throws IOException { + generator.writeBoolean(value); return this; } + @Override public XContentBuilder value(Boolean value) throws IOException { if (value == null) { return nullValue(); @@ -650,11 +416,13 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return value(value.booleanValue()); } - public XContentBuilder value(boolean value) throws IOException { - generator.writeBoolean(value); + @Override + public XContentBuilder value(int value) throws IOException { + generator.writeNumber(value); return this; } + @Override public XContentBuilder value(Integer value) throws IOException { if (value == null) { return nullValue(); @@ -662,11 +430,13 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return value(value.intValue()); } - public XContentBuilder value(int value) throws IOException { + @Override + public XContentBuilder value(long value) throws IOException { generator.writeNumber(value); return this; } + @Override public XContentBuilder value(Long value) throws IOException { if (value == null) { return nullValue(); @@ -674,11 +444,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return value(value.longValue()); } - public XContentBuilder value(long value) throws IOException { - generator.writeNumber(value); - return this; - } - + @Override public XContentBuilder value(Float value) throws IOException { if (value == null) { return nullValue(); @@ -686,11 +452,19 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return value(value.floatValue()); } + @Override public XContentBuilder value(float value) throws IOException { generator.writeNumber(value); return this; } + @Override + public XContentBuilder value(double value) throws IOException { + generator.writeNumber(value); + return this; + } + + @Override public XContentBuilder value(Double value) throws IOException { if (value == null) { return nullValue(); @@ -698,21 +472,19 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return value(value.doubleValue()); } - public XContentBuilder value(double value) throws IOException { - generator.writeNumber(value); - return this; - } - + @Override public XContentBuilder value(BigInteger bi) throws IOException { generator.writeNumber(bi); return this; } + @Override public XContentBuilder value(BigDecimal bd) throws IOException { generator.writeNumber(bd); return this; } + @Override public XContentBuilder value(String value) throws IOException { if (value == null) { return nullValue(); @@ -721,6 +493,18 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } + @Override + public XContentBuilder value(XContentBuilder builder) throws IOException { + generator.writeValue(builder); + return this; + } + + @Override + public XContentBuilder value(Object value) throws IOException { + writeValue(value); + return this; + } + public XContentBuilder value(byte[] value) throws IOException { if (value == null) { return nullValue(); @@ -729,6 +513,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } + @Override public XContentBuilder value(byte[] value, int offset, int length) throws IOException { if (value == null) { return nullValue(); @@ -737,23 +522,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder value(BytesReference value) throws IOException { - if (value == null) { - return nullValue(); - } - byte[] b = value.toBytes(); - generator.writeBinary(b, 0, b.length); - return this; - } - - public XContentBuilder map(Map map) throws IOException { - if (map == null) { - return nullValue(); - } - writeMap(map); - return this; - } - + @Override public XContentBuilder value(Map map) throws IOException { if (map == null) { return nullValue(); @@ -762,22 +531,7 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder timeseriesMap(Map map) throws IOException { - if (map == null) { - return nullValue(); - } - writeInstantMap(map); - return this; - } - - public XContentBuilder flatMap(Map map) throws IOException { - if (map == null) { - return nullValue(); - } - writeFlatMap(map); - return this; - } - + @Override public XContentBuilder value(Iterable value) throws IOException { if (value == null) { return nullValue(); @@ -790,11 +544,119 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { return this; } - public XContentBuilder copyCurrentStructure(XContentParser parser) throws IOException { - generator.copyCurrentStructure(parser); + @Override + public XContentBuilder startObject(String name) throws IOException { + field(name); + startObject(); return this; } + @Override + public XContentBuilder startObject() throws IOException { + generator.writeStartObject(); + return this; + } + + @Override + public XContentBuilder endObject() throws IOException { + generator.writeEndObject(); + return this; + } + + @Override + public XContentBuilder array(String name, Collection values) throws IOException { + startArray(name); + for (Object value : values) { + value(value); + } + endArray(); + return this; + } + + @Override + public XContentBuilder array(String name, String... values) throws IOException { + startArray(name); + for (String value : values) { + value(value); + } + endArray(); + return this; + } + + @Override + public XContentBuilder array(String name, Object... values) throws IOException { + startArray(name); + for (Object value : values) { + value(value); + } + endArray(); + return this; + } + + @Override + public XContentBuilder startArray(String name) throws IOException { + field(name); + startArray(); + return this; + } + + @Override + public XContentBuilder startArray() throws IOException { + generator.writeStartArray(); + return this; + } + + @Override + public XContentBuilder endArray() throws IOException { + generator.writeEndArray(); + return this; + } + + @Override + public XContentBuilder map(Map map) throws IOException { + if (map == null) { + return nullValue(); + } + writeMap(map); + return this; + } + + @Override + public XContentBuilder timeseriesMap(Map map) throws IOException { + if (map == null) { + return nullValue(); + } + writeInstantMap(map); + return this; + } + + @Override + public XContentBuilder flatMap(Map map) throws IOException { + if (map == null) { + return nullValue(); + } + writeFlatMap(map); + return this; + } + + public XContentBuilder field(String name, BytesReference value) throws IOException { + return field(name, value.toBytes(), 0, value.length()); + } + + public XContentBuilder value(BytesReference value) throws IOException { + if (value == null) { + return nullValue(); + } + byte[] b = value.toBytes(); + generator.writeBinary(b, 0, b.length); + return this; + } + + @Override + public String string() throws IOException { + return bytes().toUtf8(); + } + @Override public void flush() throws IOException { generator.flush(); @@ -805,21 +667,19 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { generator.close(); } + public XContent content() { + return generator.content(); + } + + public XContentGenerator generator() { + return generator; + } + public BytesReference bytes() throws IOException { generator.close(); return ((BytesStreamOutput) outputStream).bytes(); } - /** - * Returns a string representation of the builder (only applicable for text based xcontent). - * Only applicable when the builder is constructed with {@link BytesStreamOutput}. - * @return string - * @throws IOException if string can not be converted to UTF-8 - */ - public String string() throws IOException { - return bytes().toUtf8(); - } - private void writeMap(Map map) throws IOException { generator.writeStartObject(); for (Map.Entry entry : map.entrySet()) { @@ -891,10 +751,10 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { generator.writeNumberField("lon", ((GeoPoint) value).lon()); generator.writeEndObject(); } else if (value instanceof Map) { - writeMap((Map) value); + writeMap((Map) value); } else if (value instanceof Iterable) { generator.writeStartArray(); - for (Object v : (Iterable) value) { + for (Object v : (Iterable) value) { if (v != value) { writeValue(v); } @@ -928,8 +788,8 @@ public final class XContentBuilder implements ToXContent, Flushable, Closeable { BytesReference bytes = (BytesReference) value; byte[] b = bytes.toBytes(); generator.writeBinary(b, 0, b.length); - } else if (value instanceof XContentBuilder) { - value((XContentBuilder) value); + } else if (value instanceof DefaultXContentBuilder) { + value((DefaultXContentBuilder) value); } else if (value instanceof ToXContent) { ((ToXContent) value).toXContent(this, ToXContent.EMPTY_PARAMS); } else if (value instanceof double[]) { diff --git a/content-core/src/main/java/org/xbib/content/XContentHelper.java b/content-core/src/main/java/org/xbib/content/core/XContentHelper.java similarity index 79% rename from content-core/src/main/java/org/xbib/content/XContentHelper.java rename to content-core/src/main/java/org/xbib/content/core/XContentHelper.java index bb60d48..c9dde04 100644 --- a/content-core/src/main/java/org/xbib/content/XContentHelper.java +++ b/content-core/src/main/java/org/xbib/content/core/XContentHelper.java @@ -1,16 +1,15 @@ -package org.xbib.content; +package org.xbib.content.core; +import org.xbib.content.XContent; +import org.xbib.content.XContentBuilder; +import org.xbib.content.XContentGenerator; +import org.xbib.content.XContentParser; import org.xbib.content.io.BytesReference; -import org.xbib.content.json.JsonXContent; import java.io.IOException; import java.io.Reader; -import java.nio.charset.StandardCharsets; import java.util.Map; -/** - * - */ public class XContentHelper { private static final String UNKNOWN_FORMAT = "unknown format"; @@ -19,7 +18,7 @@ public class XContentHelper { } public static XContentParser createParser(BytesReference bytes) throws IOException { - XContent content = XContentService.xContent(bytes); + XContent content = XContentService.xContent(bytes.toBytes(), 0, bytes.length()); if (content == null) { throw new IOException(UNKNOWN_FORMAT); } @@ -30,25 +29,24 @@ public class XContentHelper { return XContentService.xContent(data, offset, length).createParser(data, offset, length); } - public static Map convertFromJsonToMap(Reader reader) { + public static Map convertFromContentToMap(XContent content, Reader reader) { try { - return JsonXContent.jsonContent().createParser(reader).mapOrderedAndClose(); + return content.createParser(reader).mapOrderedAndClose(); } catch (IOException e) { throw new IllegalArgumentException("Failed to parse content to map", e); } } - public static Map convertToMap(String data) { + public static Map convertToMap(String data) { try { - XContent content = XContentService.xContent(data); - return content.createParser(data).mapOrderedAndClose(); + return XContentService.xContent(data).createParser(data).mapOrderedAndClose(); } catch (IOException e) { throw new IllegalArgumentException("failed to parse content to map", e); } } - public static Map convertToMap(BytesReference bytes, boolean ordered) { - XContent content = XContentService.xContent(bytes); + public static Map convertToMap(BytesReference bytes, boolean ordered) { + XContent content = XContentService.xContent(bytes.toBytes(), 0, bytes.length()); if (content == null) { throw new IllegalArgumentException(UNKNOWN_FORMAT); } @@ -64,12 +62,15 @@ public class XContentHelper { } } - public static Map convertToMap(byte[] data, boolean ordered) throws IOException { + public static Map convertToMap(byte[] data, boolean ordered) throws IOException { return convertToMap(data, 0, data.length, ordered); } - public static Map convertToMap(byte[] data, int offset, int length, boolean ordered) throws IOException { + public static Map convertToMap(byte[] data, int offset, int length, boolean ordered) throws IOException { XContent content = XContentService.xContent(data, offset, length); + if (content == null) { + throw new IOException("no xcontent found"); + } XContentParser parser = content.createParser(data, offset, length); if (ordered) { return parser.mapOrderedAndClose(); @@ -78,16 +79,14 @@ public class XContentHelper { } } - public static String convertToJson(BytesReference bytes, boolean reformatJson, boolean prettyPrint) throws IOException { - XContent xContent = XContentService.xContent(bytes); + public static String parseToString(BytesReference bytes, + boolean prettyPrint) throws IOException { + XContent xContent = XContentService.xContent(bytes.toBytes(), 0, bytes.length()); if (xContent == null) { throw new IOException(UNKNOWN_FORMAT); } - if (xContent == JsonXContent.jsonContent() && !reformatJson) { - return bytes.toUtf8(); - } try (XContentParser parser = xContent.createParser(bytes.streamInput()); - XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonContent())) { + XContentBuilder builder = DefaultXContentBuilder.builder(xContent)) { parser.nextToken(); if (prettyPrint) { builder.prettyPrint(); @@ -97,14 +96,14 @@ public class XContentHelper { } } - public static String convertToJson(byte[] data, int offset, int length, boolean reformatJson, boolean prettyPrint) + public static String parseToString(byte[] data, + int offset, + int length, + boolean prettyPrint) throws IOException { XContent xContent = XContentService.xContent(data, offset, length); - if (xContent == JsonXContent.jsonContent() && !reformatJson) { - return new String(data, offset, length, StandardCharsets.UTF_8); - } try (XContentParser parser = xContent.createParser(data, offset, length); - XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonContent())) { + XContentBuilder builder = DefaultXContentBuilder.builder(xContent)) { parser.nextToken(); if (prettyPrint) { builder.prettyPrint(); @@ -114,7 +113,8 @@ public class XContentHelper { } } - public static void copyCurrentStructure(XContentGenerator generator, XContentParser parser) throws IOException { + public static void copyCurrentStructure(XContentGenerator generator, + XContentParser parser) throws IOException { XContentParser.Token t = parser.currentToken(); if (t == XContentParser.Token.FIELD_NAME) { generator.writeFieldName(parser.currentName()); @@ -140,7 +140,8 @@ public class XContentHelper { } } - private static void copyCurrentEvent(XContentGenerator generator, XContentParser parser) throws IOException { + private static void copyCurrentEvent(XContentGenerator generator, + XContentParser parser) throws IOException { switch (parser.currentToken()) { case START_OBJECT: generator.writeStartObject(); @@ -243,5 +244,4 @@ public class XContentHelper { } return -1; } - } diff --git a/content-core/src/main/java/org/xbib/content/XContentService.java b/content-core/src/main/java/org/xbib/content/core/XContentService.java similarity index 68% rename from content-core/src/main/java/org/xbib/content/XContentService.java rename to content-core/src/main/java/org/xbib/content/core/XContentService.java index 699143c..609fc08 100644 --- a/content-core/src/main/java/org/xbib/content/XContentService.java +++ b/content-core/src/main/java/org/xbib/content/core/XContentService.java @@ -1,7 +1,8 @@ -package org.xbib.content; +package org.xbib.content.core; +import org.xbib.content.XContent; +import org.xbib.content.XContentBuilder; import org.xbib.content.io.BytesArray; -import org.xbib.content.io.BytesReference; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -9,9 +10,6 @@ import java.util.HashMap; import java.util.Map; import java.util.ServiceLoader; -/** - * - */ public class XContentService { private static final Map xcontents = new HashMap<>(); @@ -26,20 +24,17 @@ public class XContentService { } public static XContentBuilder builder(String name) throws IOException { - return xcontents.containsKey(name) ? XContentBuilder.builder(xcontents.get(name)) : null; - } - - public static XContent xContent(byte[] data, int offset, int length) { - return xContent(new BytesArray(data, offset, length)); + return xcontents.containsKey(name) ? DefaultXContentBuilder.builder(xcontents.get(name)) : null; } public static XContent xContent(String charSequence) { - return xContent(new BytesArray(charSequence.getBytes(StandardCharsets.UTF_8))); + BytesArray bytesArray = new BytesArray(charSequence.getBytes(StandardCharsets.UTF_8)); + return xContent(bytesArray.toBytes(), 0, bytesArray.length()); } - public static XContent xContent(BytesReference bytes) { + public static XContent xContent(byte[] data, int offset, int length) { for (XContent xcontent : xcontents.values()) { - if (xcontent.isXContent(bytes)) { + if (xcontent.isXContent(data, offset, length)) { return xcontent; } } diff --git a/content-core/src/main/java/org/xbib/content/package-info.java b/content-core/src/main/java/org/xbib/content/core/package-info.java similarity index 63% rename from content-core/src/main/java/org/xbib/content/package-info.java rename to content-core/src/main/java/org/xbib/content/core/package-info.java index 1de2977..4ef06c7 100644 --- a/content-core/src/main/java/org/xbib/content/package-info.java +++ b/content-core/src/main/java/org/xbib/content/core/package-info.java @@ -1,4 +1,4 @@ /** * Classes for content parsing and generating. */ -package org.xbib.content; +package org.xbib.content.core; diff --git a/content-core/src/main/java/org/xbib/content/json/package-info.java b/content-core/src/main/java/org/xbib/content/json/package-info.java deleted file mode 100644 index 83ebe9f..0000000 --- a/content-core/src/main/java/org/xbib/content/json/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes for JSON content. - */ -package org.xbib.content.json; diff --git a/content-core/src/main/java/org/xbib/content/settings/PropertiesSettingsLoader.java b/content-core/src/main/java/org/xbib/content/properties/PropertiesSettingsLoader.java similarity index 96% rename from content-core/src/main/java/org/xbib/content/settings/PropertiesSettingsLoader.java rename to content-core/src/main/java/org/xbib/content/properties/PropertiesSettingsLoader.java index c93aa27..a67e69a 100644 --- a/content-core/src/main/java/org/xbib/content/settings/PropertiesSettingsLoader.java +++ b/content-core/src/main/java/org/xbib/content/properties/PropertiesSettingsLoader.java @@ -1,6 +1,7 @@ -package org.xbib.content.settings; +package org.xbib.content.properties; import org.xbib.content.io.BytesReference; +import org.xbib.content.SettingsLoader; import java.io.IOException; import java.io.InputStreamReader; import java.io.Reader; @@ -38,7 +39,6 @@ public class PropertiesSettingsLoader implements SettingsLoader { } } - @Override public Map load(BytesReference ref) throws IOException { Properties props = new Properties(); try (Reader reader = new InputStreamReader(ref.streamInput(), StandardCharsets.UTF_8)) { diff --git a/content-core/src/main/java/org/xbib/content/properties/package-info.java b/content-core/src/main/java/org/xbib/content/properties/package-info.java new file mode 100644 index 0000000..3858ae9 --- /dev/null +++ b/content-core/src/main/java/org/xbib/content/properties/package-info.java @@ -0,0 +1,4 @@ +/** + * Classes for properties-based content. + */ +package org.xbib.content.properties; diff --git a/content-core/src/main/java/org/xbib/content/util/package-info.java b/content-core/src/main/java/org/xbib/content/util/package-info.java index fb4d082..854f01f 100644 --- a/content-core/src/main/java/org/xbib/content/util/package-info.java +++ b/content-core/src/main/java/org/xbib/content/util/package-info.java @@ -1,4 +1,4 @@ /** - * Utility classes for cotent. + * Utility classes for content. */ package org.xbib.content.util; diff --git a/content-core/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader b/content-core/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader new file mode 100644 index 0000000..561e5b9 --- /dev/null +++ b/content-core/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader @@ -0,0 +1 @@ +org.xbib.content.properties.PropertiesSettingsLoader diff --git a/content-core/src/main/resources/META-INF/services/org.xbib.content.settings.SettingsLoader b/content-core/src/main/resources/META-INF/services/org.xbib.content.settings.SettingsLoader deleted file mode 100644 index bda82af..0000000 --- a/content-core/src/main/resources/META-INF/services/org.xbib.content.settings.SettingsLoader +++ /dev/null @@ -1,2 +0,0 @@ -org.xbib.content.json.JsonSettingsLoader -org.xbib.content.settings.PropertiesSettingsLoader \ No newline at end of file diff --git a/content-core/src/test/java/org/xbib/content/settings/package-info.java b/content-core/src/test/java/org/xbib/content/settings/package-info.java deleted file mode 100644 index 8df16ca..0000000 --- a/content-core/src/test/java/org/xbib/content/settings/package-info.java +++ /dev/null @@ -1,4 +0,0 @@ -/** - * Classes for testing settings parsing and generating. - */ -package org.xbib.content.settings; diff --git a/content-core/src/test/java/org/xbib/content/package-info.java b/content-core/src/test/java/org/xbib/content/test/package-info.java similarity index 67% rename from content-core/src/test/java/org/xbib/content/package-info.java rename to content-core/src/test/java/org/xbib/content/test/package-info.java index 2df4888..f82ee97 100644 --- a/content-core/src/test/java/org/xbib/content/package-info.java +++ b/content-core/src/test/java/org/xbib/content/test/package-info.java @@ -1,4 +1,4 @@ /** * Classes for testing content parsing and generating. */ -package org.xbib.content; +package org.xbib.content.test; diff --git a/content-json/build.gradle b/content-json/build.gradle index 2708c43..1521370 100644 --- a/content-json/build.gradle +++ b/content-json/build.gradle @@ -1,5 +1,7 @@ dependencies { - api "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}" + api project(':content-core') + api project(':content-settings') + implementation "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}" testImplementation("org.mockito:mockito-core:${project.property('mockito.version')}") { exclude group: 'org.hamcrest' } diff --git a/content-json/src/main/java/module-info.java b/content-json/src/main/java/module-info.java index 0452788..1bc890d 100644 --- a/content-json/src/main/java/module-info.java +++ b/content-json/src/main/java/module-info.java @@ -1,9 +1,18 @@ +import org.xbib.content.SettingsLoader; + module org.xbib.content.json { + exports org.xbib.content.json; exports org.xbib.content.json.diff; exports org.xbib.content.json.jackson; exports org.xbib.content.json.mergepatch; exports org.xbib.content.json.patch; exports org.xbib.content.json.pointer; + requires transitive org.xbib.content.core; + requires transitive org.xbib.content.settings; requires transitive com.fasterxml.jackson.core; requires transitive com.fasterxml.jackson.databind; + provides org.xbib.content.XContent with + org.xbib.content.json.JsonXContent; + provides SettingsLoader with + org.xbib.content.json.JsonSettingsLoader; } diff --git a/content-core/src/main/java/org/xbib/content/json/JsonSettingsLoader.java b/content-json/src/main/java/org/xbib/content/json/JsonSettingsLoader.java similarity index 100% rename from content-core/src/main/java/org/xbib/content/json/JsonSettingsLoader.java rename to content-json/src/main/java/org/xbib/content/json/JsonSettingsLoader.java diff --git a/content-core/src/main/java/org/xbib/content/json/JsonXContent.java b/content-json/src/main/java/org/xbib/content/json/JsonXContent.java similarity index 84% rename from content-core/src/main/java/org/xbib/content/json/JsonXContent.java rename to content-json/src/main/java/org/xbib/content/json/JsonXContent.java index 7a0d5e9..ebbb797 100644 --- a/content-core/src/main/java/org/xbib/content/json/JsonXContent.java +++ b/content-json/src/main/java/org/xbib/content/json/JsonXContent.java @@ -5,9 +5,9 @@ import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonParser; import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; +import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.XContentGenerator; import org.xbib.content.XContentParser; -import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesStreamInput; import java.io.IOException; @@ -40,11 +40,11 @@ public class JsonXContent implements XContent { } public static XContentBuilder contentBuilder() throws IOException { - return XContentBuilder.builder(jsonXContent); + return DefaultXContentBuilder.builder(jsonXContent); } public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { - return XContentBuilder.builder(jsonXContent, outputStream); + return DefaultXContentBuilder.builder(jsonXContent, outputStream); } @Override @@ -83,28 +83,23 @@ public class JsonXContent implements XContent { return new JsonXContentParser(jsonFactory.createParser(data, offset, length)); } - @Override - public XContentParser createParser(BytesReference bytes) throws IOException { - return createParser(bytes.streamInput()); - } - @Override public XContentParser createParser(Reader reader) throws IOException { return new JsonXContentParser(jsonFactory.createParser(reader)); } @Override - public boolean isXContent(BytesReference bytes) { - int length = Math.min(bytes.length(), 20); + public boolean isXContent(byte[] bytes, int offset, int len) { + int length = Math.min(len, 20); if (length == 0) { return false; } - byte first = bytes.get(0); + byte first = bytes[offset]; if (first == '{') { return true; } - for (int i = 0; i < length; i++) { - if (bytes.get(i) == '{') { + for (int i = offset; i < offset + length; i++) { + if (bytes[i] == '{') { return true; } } diff --git a/content-core/src/main/java/org/xbib/content/json/JsonXContentGenerator.java b/content-json/src/main/java/org/xbib/content/json/JsonXContentGenerator.java similarity index 75% rename from content-core/src/main/java/org/xbib/content/json/JsonXContentGenerator.java rename to content-json/src/main/java/org/xbib/content/json/JsonXContentGenerator.java index 1ac922a..d013cb7 100644 --- a/content-core/src/main/java/org/xbib/content/json/JsonXContentGenerator.java +++ b/content-json/src/main/java/org/xbib/content/json/JsonXContentGenerator.java @@ -1,13 +1,13 @@ package org.xbib.content.json; import com.fasterxml.jackson.core.JsonGenerator; -import org.xbib.content.AbstractXContentGenerator; -import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; +import org.xbib.content.core.AbstractXContentGenerator; +import org.xbib.content.XContent; +import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.XContentGenerator; -import org.xbib.content.XContentHelper; +import org.xbib.content.core.XContentHelper; import org.xbib.content.XContentParser; -import org.xbib.content.XContentString; import org.xbib.content.io.BytesReference; import java.io.IOException; @@ -15,9 +15,6 @@ import java.io.OutputStream; import java.math.BigDecimal; import java.math.BigInteger; -/** - * - */ public class JsonXContentGenerator extends AbstractXContentGenerator { private final JsonGeneratorDelegate delegate; @@ -48,11 +45,6 @@ public class JsonXContentGenerator extends AbstractXContentGenerator { delegate.writeRawField(fieldName, content, offset, length, outputStream); } - @Override - public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { - delegate.writeRawField(fieldName, content, outputStream); - } - @Override public void writeValue(XContentBuilder builder) throws IOException { delegate.writeValue(builder); @@ -63,6 +55,15 @@ public class JsonXContentGenerator extends AbstractXContentGenerator { delegate.copyCurrentStructure(parser); } + @Override + public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { + flush(); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(outputStream); + } + } + @Override public void flush() throws IOException { delegate.flush(); @@ -117,11 +118,6 @@ public class JsonXContentGenerator extends AbstractXContentGenerator { jsonGenerator.writeFieldName(name); } - @Override - public void writeFieldName(XContentString name) throws IOException { - jsonGenerator.writeFieldName(name); - } - @Override public void writeString(String text) throws IOException { jsonGenerator.writeString(text); @@ -192,22 +188,11 @@ public class JsonXContentGenerator extends AbstractXContentGenerator { jsonGenerator.writeStringField(fieldName, value); } - @Override - public void writeStringField(XContentString fieldName, String value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - } - @Override public void writeBooleanField(String fieldName, boolean value) throws IOException { jsonGenerator.writeBooleanField(fieldName, value); } - @Override - public void writeBooleanField(XContentString fieldName, boolean value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeBoolean(value); - } - @Override public void writeNullField(String fieldName) throws IOException { jsonGenerator.writeNullField(fieldName); @@ -218,101 +203,47 @@ public class JsonXContentGenerator extends AbstractXContentGenerator { jsonGenerator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, int value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, long value) throws IOException { jsonGenerator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, long value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, double value) throws IOException { jsonGenerator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, double value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, float value) throws IOException { jsonGenerator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, float value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, BigInteger value) throws IOException { jsonGenerator.writeFieldName(fieldName); jsonGenerator.writeNumber(value); } - @Override - public void writeNumberField(XContentString fieldName, BigInteger value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, BigDecimal value) throws IOException { jsonGenerator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeNumber(value); - } - @Override public void writeBinaryField(String fieldName, byte[] data) throws IOException { jsonGenerator.writeBinaryField(fieldName, data); } - @Override - public void writeBinaryField(XContentString fieldName, byte[] data) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeBinary(data); - } - @Override public void writeArrayFieldStart(String fieldName) throws IOException { jsonGenerator.writeArrayFieldStart(fieldName); } - @Override - public void writeArrayFieldStart(XContentString fieldName) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeStartArray(); - } - @Override public void writeObjectFieldStart(String fieldName) throws IOException { jsonGenerator.writeObjectFieldStart(fieldName); } - @Override - public void writeObjectFieldStart(XContentString fieldName) throws IOException { - jsonGenerator.writeFieldName(fieldName); - jsonGenerator.writeStartObject(); - } - @Override public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException { jsonGenerator.writeRaw(",\""); @@ -332,7 +263,6 @@ public class JsonXContentGenerator extends AbstractXContentGenerator { outputStream.write(content, offset, length); } - @Override public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { jsonGenerator.writeRaw(",\""); jsonGenerator.writeRaw(fieldName); @@ -349,7 +279,10 @@ public class JsonXContentGenerator extends AbstractXContentGenerator { @Override public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { flush(); - builder.bytes().streamOutput(outputStream); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(outputStream); + } } @Override diff --git a/content-core/src/main/java/org/xbib/content/json/JsonXContentParser.java b/content-json/src/main/java/org/xbib/content/json/JsonXContentParser.java similarity index 98% rename from content-core/src/main/java/org/xbib/content/json/JsonXContentParser.java rename to content-json/src/main/java/org/xbib/content/json/JsonXContentParser.java index 1881b74..bbe1592 100644 --- a/content-core/src/main/java/org/xbib/content/json/JsonXContentParser.java +++ b/content-json/src/main/java/org/xbib/content/json/JsonXContentParser.java @@ -2,7 +2,7 @@ package org.xbib.content.json; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import org.xbib.content.AbstractXContentParser; +import org.xbib.content.core.AbstractXContentParser; import org.xbib.content.XContent; import org.xbib.content.XContentParser; @@ -10,9 +10,6 @@ import java.io.IOException; import java.math.BigDecimal; import java.math.BigInteger; -/** - * - */ public class JsonXContentParser extends AbstractXContentParser { protected final JsonParser parser; diff --git a/content-json/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader b/content-json/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader new file mode 100644 index 0000000..9fdac42 --- /dev/null +++ b/content-json/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader @@ -0,0 +1 @@ +org.xbib.content.json.JsonSettingsLoader diff --git a/content-core/src/main/resources/META-INF/services/org.xbib.content.XContent b/content-json/src/main/resources/META-INF/services/org.xbib.content.XContent similarity index 100% rename from content-core/src/main/resources/META-INF/services/org.xbib.content.XContent rename to content-json/src/main/resources/META-INF/services/org.xbib.content.XContent diff --git a/content-core/src/test/java/org/xbib/content/XContentBuilderTest.java b/content-json/src/test/java/org/xbib/content/json/XContentBuilderTest.java similarity index 97% rename from content-core/src/test/java/org/xbib/content/XContentBuilderTest.java rename to content-json/src/test/java/org/xbib/content/json/XContentBuilderTest.java index f2b7904..fecb89e 100644 --- a/content-core/src/test/java/org/xbib/content/XContentBuilderTest.java +++ b/content-json/src/test/java/org/xbib/content/json/XContentBuilderTest.java @@ -1,10 +1,13 @@ -package org.xbib.content; +package org.xbib.content.json; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.xbib.content.json.JsonXContent.contentBuilder; import org.junit.jupiter.api.Test; +import org.xbib.content.XContent; +import org.xbib.content.XContentBuilder; +import org.xbib.content.core.XContentService; import org.xbib.content.json.JsonXContent; import java.io.IOException; diff --git a/content-core/src/test/java/org/xbib/content/XContentParserTest.java b/content-json/src/test/java/org/xbib/content/json/XContentParserTest.java similarity index 92% rename from content-core/src/test/java/org/xbib/content/XContentParserTest.java rename to content-json/src/test/java/org/xbib/content/json/XContentParserTest.java index db051fd..aac3f21 100644 --- a/content-core/src/test/java/org/xbib/content/XContentParserTest.java +++ b/content-json/src/test/java/org/xbib/content/json/XContentParserTest.java @@ -1,8 +1,8 @@ -package org.xbib.content; +package org.xbib.content.json; import static org.junit.jupiter.api.Assertions.assertEquals; import org.junit.jupiter.api.Test; -import org.xbib.content.json.JsonXContent; +import org.xbib.content.XContentParser; import java.io.IOException; import java.util.Map; import java.util.logging.Level; diff --git a/content-rdf/build.gradle b/content-rdf/build.gradle index 1649a2b..7b14bac 100644 --- a/content-rdf/build.gradle +++ b/content-rdf/build.gradle @@ -2,4 +2,6 @@ dependencies { implementation project(':content-core') implementation project(':content-resource') implementation project(':content-xml') + implementation project(':content-json') + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${project.property('jackson.version')}" } diff --git a/content-rdf/src/main/java/module-info.java b/content-rdf/src/main/java/module-info.java index ab7e01d..577b61e 100644 --- a/content-rdf/src/main/java/module-info.java +++ b/content-rdf/src/main/java/module-info.java @@ -13,4 +13,5 @@ module org.xbib.content.rdf { requires transitive org.xbib.content.core; requires transitive org.xbib.content.resource; requires transitive org.xbib.content.xml; + requires transitive org.xbib.content.json; } diff --git a/content-rdf/src/main/java/org/xbib/content/rdf/RdfXContentGenerator.java b/content-rdf/src/main/java/org/xbib/content/rdf/RdfXContentGenerator.java index 43d2cbe..3d752d2 100644 --- a/content-rdf/src/main/java/org/xbib/content/rdf/RdfXContentGenerator.java +++ b/content-rdf/src/main/java/org/xbib/content/rdf/RdfXContentGenerator.java @@ -1,6 +1,7 @@ package org.xbib.content.rdf; import org.xbib.content.XContentBuilder; +import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.json.JsonXContent; import org.xbib.content.rdf.internal.DefaultAnonymousResource; import org.xbib.content.rdf.internal.DefaultResource; @@ -101,7 +102,8 @@ public class RdfXContentGenerator

implements RdfCon return; } flushed = true; - builder = XContentBuilder.builder(JsonXContent.jsonContent(), out); + // JSON output + builder = DefaultXContentBuilder.builder(JsonXContent.jsonContent(), out); builder.startObject(); build(this.resource); builder.endObject(); diff --git a/content-settings/build.gradle b/content-settings/build.gradle new file mode 100644 index 0000000..72f8c40 --- /dev/null +++ b/content-settings/build.gradle @@ -0,0 +1,5 @@ +dependencies { + api project(':content-core') + implementation "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}" + testImplementation project(":content-json") +} diff --git a/content-settings/src/main/java/module-info.java b/content-settings/src/main/java/module-info.java new file mode 100644 index 0000000..0ca9204 --- /dev/null +++ b/content-settings/src/main/java/module-info.java @@ -0,0 +1,5 @@ +module org.xbib.content.settings { + exports org.xbib.content.settings; + requires org.xbib.content.core; + +} diff --git a/content-core/src/main/java/org/xbib/content/settings/AbstractSettingsLoader.java b/content-settings/src/main/java/org/xbib/content/settings/AbstractSettingsLoader.java similarity index 94% rename from content-core/src/main/java/org/xbib/content/settings/AbstractSettingsLoader.java rename to content-settings/src/main/java/org/xbib/content/settings/AbstractSettingsLoader.java index 5eeb570..d8e05a0 100644 --- a/content-core/src/main/java/org/xbib/content/settings/AbstractSettingsLoader.java +++ b/content-settings/src/main/java/org/xbib/content/settings/AbstractSettingsLoader.java @@ -1,7 +1,9 @@ package org.xbib.content.settings; +import org.xbib.content.SettingsLoader; import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; +import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.XContentGenerator; import org.xbib.content.XContentParser; import org.xbib.content.io.BytesReference; @@ -27,15 +29,9 @@ public abstract class AbstractSettingsLoader implements SettingsLoader { } } - public Map load(BytesReference bytesReference) throws IOException { - try (XContentParser parser = content().createParser(bytesReference)) { - return load(parser); - } - } - @Override public Map load(Map map) throws IOException { - XContentBuilder builder = XContentBuilder.builder(content()); + XContentBuilder builder = DefaultXContentBuilder.builder(content()); builder.map(map); return load(builder.string()); } @@ -53,7 +49,7 @@ public abstract class AbstractSettingsLoader implements SettingsLoader { } public String flatMapAsString(BytesReference bytesReference) throws IOException { - try (XContentParser parser = content().createParser(bytesReference); + try (XContentParser parser = content().createParser(bytesReference.toBytes()); BytesStreamOutput bytesStreamOutput = new BytesStreamOutput(); XContentGenerator generator = content().createGenerator(bytesStreamOutput)) { return flatMapAsString(parser, bytesStreamOutput, generator); diff --git a/content-core/src/main/java/org/xbib/content/settings/PlaceholderResolver.java b/content-settings/src/main/java/org/xbib/content/settings/PlaceholderResolver.java similarity index 100% rename from content-core/src/main/java/org/xbib/content/settings/PlaceholderResolver.java rename to content-settings/src/main/java/org/xbib/content/settings/PlaceholderResolver.java diff --git a/content-core/src/main/java/org/xbib/content/settings/PropertyPlaceholder.java b/content-settings/src/main/java/org/xbib/content/settings/PropertyPlaceholder.java similarity index 100% rename from content-core/src/main/java/org/xbib/content/settings/PropertyPlaceholder.java rename to content-settings/src/main/java/org/xbib/content/settings/PropertyPlaceholder.java diff --git a/content-core/src/main/java/org/xbib/content/settings/Settings.java b/content-settings/src/main/java/org/xbib/content/settings/Settings.java similarity index 97% rename from content-core/src/main/java/org/xbib/content/settings/Settings.java rename to content-settings/src/main/java/org/xbib/content/settings/Settings.java index a715826..172295b 100644 --- a/content-core/src/main/java/org/xbib/content/settings/Settings.java +++ b/content-settings/src/main/java/org/xbib/content/settings/Settings.java @@ -1,8 +1,6 @@ package org.xbib.content.settings; -import static org.xbib.content.util.unit.ByteSizeValue.parseBytesSizeValue; -import static org.xbib.content.util.unit.TimeValue.parseTimeValue; -import org.xbib.content.json.JsonSettingsLoader; +import org.xbib.content.SettingsLoader; import org.xbib.datastructures.tiny.TinyMap; import org.xbib.content.util.unit.ByteSizeValue; import org.xbib.content.util.unit.TimeValue; @@ -252,11 +250,11 @@ public class Settings implements AutoCloseable { } public TimeValue getAsTime(String setting, TimeValue defaultValue) { - return parseTimeValue(get(setting), defaultValue); + return TimeValue.parseTimeValue(get(setting), defaultValue); } public ByteSizeValue getAsBytesSize(String setting, ByteSizeValue defaultValue) { - return parseBytesSizeValue(get(setting), defaultValue); + return ByteSizeValue.parseBytesSizeValue(get(setting), defaultValue); } public String[] getAsArray(String settingPrefix) { @@ -627,21 +625,6 @@ public class Settings implements AutoCloseable { return this; } - /** - * Loads settings from a map. - * @param map map - * @return builder - */ - public Builder loadFromMap(Map map) { - SettingsLoader settingsLoader = new JsonSettingsLoader(); - try { - put(settingsLoader.load(map)); - } catch (Exception e) { - throw new SettingsException("Failed to load settings from [" + map + "]", e); - } - return this; - } - /** * Loads settings from an URL. * @param url url diff --git a/content-core/src/main/java/org/xbib/content/settings/SettingsException.java b/content-settings/src/main/java/org/xbib/content/settings/SettingsException.java similarity index 100% rename from content-core/src/main/java/org/xbib/content/settings/SettingsException.java rename to content-settings/src/main/java/org/xbib/content/settings/SettingsException.java diff --git a/content-core/src/main/java/org/xbib/content/settings/SettingsLoaderService.java b/content-settings/src/main/java/org/xbib/content/settings/SettingsLoaderService.java similarity index 92% rename from content-core/src/main/java/org/xbib/content/settings/SettingsLoaderService.java rename to content-settings/src/main/java/org/xbib/content/settings/SettingsLoaderService.java index 67e5fa9..1b12ff3 100644 --- a/content-core/src/main/java/org/xbib/content/settings/SettingsLoaderService.java +++ b/content-settings/src/main/java/org/xbib/content/settings/SettingsLoaderService.java @@ -1,6 +1,6 @@ package org.xbib.content.settings; -import org.xbib.content.json.JsonSettingsLoader; +import org.xbib.content.SettingsLoader; import java.util.HashMap; import java.util.Map; @@ -38,7 +38,7 @@ public final class SettingsLoaderService { } } } - return new JsonSettingsLoader(); + throw new UnsupportedOperationException(); } /** @@ -52,6 +52,6 @@ public final class SettingsLoaderService { return loader; } } - return new JsonSettingsLoader(); + throw new UnsupportedOperationException(); } } diff --git a/content-core/src/main/java/org/xbib/content/settings/package-info.java b/content-settings/src/main/java/org/xbib/content/settings/package-info.java similarity index 100% rename from content-core/src/main/java/org/xbib/content/settings/package-info.java rename to content-settings/src/main/java/org/xbib/content/settings/package-info.java diff --git a/content-core/src/test/java/org/xbib/content/settings/SettingsTest.java b/content-settings/src/test/java/org/xbib/content/settings/test/SettingsTest.java similarity index 89% rename from content-core/src/test/java/org/xbib/content/settings/SettingsTest.java rename to content-settings/src/test/java/org/xbib/content/settings/test/SettingsTest.java index e28ba9a..4878740 100644 --- a/content-core/src/test/java/org/xbib/content/settings/SettingsTest.java +++ b/content-settings/src/test/java/org/xbib/content/settings/test/SettingsTest.java @@ -1,14 +1,16 @@ -package org.xbib.content.settings; +package org.xbib.content.settings.test; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import org.junit.jupiter.api.Test; -import org.xbib.content.XContentHelper; +import org.xbib.content.SettingsLoader; +import org.xbib.content.core.XContentHelper; import org.xbib.content.io.BytesArray; import org.xbib.content.io.BytesReference; import org.xbib.content.json.JsonSettingsLoader; import org.xbib.content.json.JsonXContent; +import org.xbib.content.settings.Settings; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.StringReader; @@ -82,20 +84,25 @@ public class SettingsTest { } @Test - public void testMapForSettings() { - Map map = new HashMap<>(); + public void testMapForSettings() throws IOException { + Map map = new HashMap<>(); map.put("hello", "world"); Map settingsMap = new HashMap<>(); settingsMap.put("map", map); - Settings settings = Settings.settingsBuilder().loadFromMap(settingsMap).build(); + SettingsLoader settingsLoader = new JsonSettingsLoader(); + Settings settings = Settings.settingsBuilder() + .put(settingsLoader.load(settingsMap)).build(); assertEquals("{map.hello=world}", settings.getAsMap().toString()); } @Test - public void testMapSettingsFromReader() { + public void testMapSettingsFromReader() throws IOException { StringReader reader = new StringReader("{\"map\":{\"hello\":\"world\"}}"); - Map spec = XContentHelper.convertFromJsonToMap(reader); - Settings settings = Settings.settingsBuilder().loadFromMap(spec).build(); + Map map = XContentHelper.convertFromContentToMap(JsonXContent.jsonContent(), reader); + SettingsLoader settingsLoader = new JsonSettingsLoader(); + Settings settings = Settings.settingsBuilder() + .put(settingsLoader.load(map)) + .build(); assertEquals("{map.hello=world}", settings.getAsMap().toString()); } diff --git a/content-core/src/test/resources/settings.json b/content-settings/src/test/resources/settings.json similarity index 100% rename from content-core/src/test/resources/settings.json rename to content-settings/src/test/resources/settings.json diff --git a/content-smile/build.gradle b/content-smile/build.gradle index 6b4f9af..3f8c49e 100644 --- a/content-smile/build.gradle +++ b/content-smile/build.gradle @@ -1,4 +1,4 @@ dependencies { - implementation project(':content-core') - api "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:${project.property('jackson.version')}" + api project(':content-core') + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:${project.property('jackson.version')}" } diff --git a/content-smile/src/main/java/org/xbib/content/smile/SmileXContent.java b/content-smile/src/main/java/org/xbib/content/smile/SmileXContent.java index 17d2155..72d24f8 100644 --- a/content-smile/src/main/java/org/xbib/content/smile/SmileXContent.java +++ b/content-smile/src/main/java/org/xbib/content/smile/SmileXContent.java @@ -6,10 +6,9 @@ import com.fasterxml.jackson.dataformat.smile.SmileFactory; import com.fasterxml.jackson.dataformat.smile.SmileGenerator; import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; +import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.XContentGenerator; import org.xbib.content.XContentParser; -import org.xbib.content.io.BytesReference; -import org.xbib.content.json.JsonXContentParser; import java.io.IOException; import java.io.InputStream; @@ -24,6 +23,7 @@ import java.nio.charset.StandardCharsets; public class SmileXContent implements XContent { private static final SmileXContent smileXContent; + private static final SmileFactory smileFactory; static { @@ -49,11 +49,11 @@ public class SmileXContent implements XContent { } public static XContentBuilder contentBuilder() throws IOException { - return XContentBuilder.builder(smileXContent); + return DefaultXContentBuilder.builder(smileXContent); } public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { - return XContentBuilder.builder(smileXContent, outputStream); + return DefaultXContentBuilder.builder(smileXContent, outputStream); } @Override @@ -66,10 +66,9 @@ public class SmileXContent implements XContent { return new SmileXContentGenerator(smileFactory.createGenerator(os, JsonEncoding.UTF8)); } - @Override public XContentGenerator createGenerator(Writer writer) throws IOException { - return new SmileXContentGenerator(smileFactory.createGenerator(writer)); + throw new UnsupportedOperationException(); // SMILE is binary } @Override @@ -93,24 +92,19 @@ public class SmileXContent implements XContent { return new SmileXContentParser(smileFactory.createParser(data, offset, length)); } - @Override - public XContentParser createParser(BytesReference bytes) throws IOException { - return createParser(bytes.streamInput()); - } - @Override public XContentParser createParser(Reader reader) throws IOException { - return new JsonXContentParser(smileFactory.createParser(reader)); + throw new UnsupportedOperationException(); // SMILE is binary } @Override - public boolean isXContent(BytesReference bytes) { - int length = bytes.length() < 20 ? bytes.length() : 20; + public boolean isXContent(byte[] bytes, int offset, int len) { + int length = Math.min(len, 20); if (length == 0) { return false; } - byte first = bytes.get(0); - return length > 2 && first == SmileConstants.HEADER_BYTE_1 && bytes.get(1) == SmileConstants.HEADER_BYTE_2 - && bytes.get(2) == SmileConstants.HEADER_BYTE_3; + byte first = bytes[offset]; + return length > 2 && first == SmileConstants.HEADER_BYTE_1 && bytes[offset + 1] == SmileConstants.HEADER_BYTE_2 + && bytes[offset + 2] == SmileConstants.HEADER_BYTE_3; } } diff --git a/content-smile/src/main/java/org/xbib/content/smile/SmileXContentGenerator.java b/content-smile/src/main/java/org/xbib/content/smile/SmileXContentGenerator.java index 9842790..29fe10c 100644 --- a/content-smile/src/main/java/org/xbib/content/smile/SmileXContentGenerator.java +++ b/content-smile/src/main/java/org/xbib/content/smile/SmileXContentGenerator.java @@ -1,26 +1,39 @@ package org.xbib.content.smile; import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.dataformat.smile.SmileGenerator; import com.fasterxml.jackson.dataformat.smile.SmileParser; import org.xbib.content.XContent; +import org.xbib.content.XContentBuilder; +import org.xbib.content.XContentGenerator; +import org.xbib.content.XContentParser; +import org.xbib.content.core.AbstractXContentGenerator; +import org.xbib.content.core.DefaultXContentBuilder; +import org.xbib.content.core.XContentHelper; import org.xbib.content.io.BytesReference; -import org.xbib.content.json.JsonXContentGenerator; import java.io.IOException; import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.BigInteger; -/** - * - */ -public class SmileXContentGenerator extends JsonXContentGenerator { +public class SmileXContentGenerator extends AbstractXContentGenerator { - public SmileXContentGenerator(JsonGenerator generator) { - super(generator); + private final SmileGeneratorDelegate delegate; + + public SmileXContentGenerator(SmileGenerator generator) { + this.delegate = new SmileGeneratorDelegate(generator); + super.setGenerator(delegate); } @Override public XContent content() { - return SmileXContent.smileContent(); + return delegate.content(); + } + + @Override + public void usePrettyPrint() { + delegate.usePrettyPrint(); } @Override @@ -32,15 +45,6 @@ public class SmileXContentGenerator extends JsonXContentGenerator { } } - @Override - public void writeRawField(String fieldName, BytesReference content, OutputStream bos) throws IOException { - writeFieldName(fieldName); - try (SmileParser parser = SmileXContent.smileFactory().createParser(content.streamInput())) { - parser.nextToken(); - ((JsonGenerator) generator).copyCurrentStructure(parser); - } - } - @Override public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream bos) throws IOException { writeFieldName(fieldName); @@ -49,4 +53,266 @@ public class SmileXContentGenerator extends JsonXContentGenerator { ((JsonGenerator) generator).copyCurrentStructure(parser); } } + + @Override + public void writeValue(XContentBuilder builder) throws IOException { + delegate.writeValue(builder); + } + + + @Override + public void copyCurrentStructure(XContentParser parser) throws IOException { + delegate.copyCurrentStructure(parser); + } + + @Override + public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { + flush(); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(outputStream); + } + } + + @Override + public void flush() throws IOException { + delegate.flush(); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + + private static class SmileGeneratorDelegate implements XContentGenerator { + + private final SmileGenerator smileGenerator; + + private SmileGeneratorDelegate(SmileGenerator smileGenerator) { + this.smileGenerator = smileGenerator; + } + + @Override + public XContent content() { + return SmileXContent.smileContent(); + } + + @Override + public void usePrettyPrint() { + smileGenerator.useDefaultPrettyPrinter(); + } + + @Override + public void writeStartArray() throws IOException { + smileGenerator.writeStartArray(); + } + + @Override + public void writeEndArray() throws IOException { + smileGenerator.writeEndArray(); + } + + @Override + public void writeStartObject() throws IOException { + smileGenerator.writeStartObject(); + } + + @Override + public void writeEndObject() throws IOException { + smileGenerator.writeEndObject(); + } + + @Override + public void writeFieldName(String name) throws IOException { + smileGenerator.writeFieldName(name); + } + + @Override + public void writeString(String text) throws IOException { + smileGenerator.writeString(text); + } + + @Override + public void writeString(char[] text, int offset, int len) throws IOException { + smileGenerator.writeString(text, offset, len); + } + + @Override + public void writeUTF8String(byte[] text, int offset, int length) throws IOException { + smileGenerator.writeUTF8String(text, offset, length); + } + + @Override + public void writeBinary(byte[] data, int offset, int len) throws IOException { + smileGenerator.writeBinary(data, offset, len); + } + + @Override + public void writeBinary(byte[] data) throws IOException { + smileGenerator.writeBinary(data); + } + + @Override + public void writeNumber(int v) throws IOException { + smileGenerator.writeNumber(v); + } + + @Override + public void writeNumber(long v) throws IOException { + smileGenerator.writeNumber(v); + } + + @Override + public void writeNumber(double d) throws IOException { + smileGenerator.writeNumber(d); + } + + @Override + public void writeNumber(float f) throws IOException { + smileGenerator.writeNumber(f); + } + + @Override + public void writeNumber(BigInteger bi) throws IOException { + smileGenerator.writeNumber(bi); + } + + @Override + public void writeNumber(BigDecimal bd) throws IOException { + smileGenerator.writeNumber(bd); + } + + @Override + public void writeBoolean(boolean b) throws IOException { + smileGenerator.writeBoolean(b); + } + + @Override + public void writeNull() throws IOException { + smileGenerator.writeNull(); + } + + @Override + public void writeStringField(String fieldName, String value) throws IOException { + smileGenerator.writeStringField(fieldName, value); + } + + @Override + public void writeBooleanField(String fieldName, boolean value) throws IOException { + smileGenerator.writeBooleanField(fieldName, value); + } + + @Override + public void writeNullField(String fieldName) throws IOException { + smileGenerator.writeNullField(fieldName); + } + + @Override + public void writeNumberField(String fieldName, int value) throws IOException { + smileGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, long value) throws IOException { + smileGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, double value) throws IOException { + smileGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, float value) throws IOException { + smileGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, BigInteger value) throws IOException { + smileGenerator.writeFieldName(fieldName); + smileGenerator.writeNumber(value); + } + + @Override + public void writeNumberField(String fieldName, BigDecimal value) throws IOException { + smileGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeBinaryField(String fieldName, byte[] data) throws IOException { + smileGenerator.writeBinaryField(fieldName, data); + } + + @Override + public void writeArrayFieldStart(String fieldName) throws IOException { + smileGenerator.writeArrayFieldStart(fieldName); + } + + @Override + public void writeObjectFieldStart(String fieldName) throws IOException { + smileGenerator.writeObjectFieldStart(fieldName); + } + + @Override + public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException { + smileGenerator.writeRaw(",\""); + smileGenerator.writeRaw(fieldName); + smileGenerator.writeRaw("\":"); + flush(); + outputStream.write(content); + } + + @Override + public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) + throws IOException { + smileGenerator.writeRaw(",\""); + smileGenerator.writeRaw(fieldName); + smileGenerator.writeRaw("\":"); + flush(); + outputStream.write(content, offset, length); + } + + public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { + smileGenerator.writeRaw(",\""); + smileGenerator.writeRaw(fieldName); + smileGenerator.writeRaw("\":"); + flush(); + content.streamOutput(outputStream); + } + + @Override + public void writeValue(XContentBuilder builder) throws IOException { + smileGenerator.writeRawValue(builder.string()); + } + + @Override + public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { + flush(); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(outputStream); + } + } + + @Override + public void copyCurrentStructure(XContentParser parser) throws IOException { + if (parser.currentToken() == null) { + parser.nextToken(); + } + XContentHelper.copyCurrentStructure(this, parser); + } + + @Override + public void flush() throws IOException { + smileGenerator.flush(); + } + + @Override + public void close() throws IOException { + if (smileGenerator.isClosed()) { + return; + } + smileGenerator.close(); + } + } } diff --git a/content-smile/src/main/java/org/xbib/content/smile/SmileXContentParser.java b/content-smile/src/main/java/org/xbib/content/smile/SmileXContentParser.java index 5b4a27f..768ca7a 100644 --- a/content-smile/src/main/java/org/xbib/content/smile/SmileXContentParser.java +++ b/content-smile/src/main/java/org/xbib/content/smile/SmileXContentParser.java @@ -1,16 +1,21 @@ package org.xbib.content.smile; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.dataformat.smile.SmileParser; import org.xbib.content.XContent; -import org.xbib.content.json.JsonXContentParser; +import org.xbib.content.XContentParser; +import org.xbib.content.core.AbstractXContentParser; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; -/** - * - */ -public class SmileXContentParser extends JsonXContentParser { +public class SmileXContentParser extends AbstractXContentParser { - public SmileXContentParser(JsonParser parser) { - super(parser); + private final SmileParser parser; + + public SmileXContentParser(SmileParser parser) { + this.parser = parser; } @Override @@ -18,4 +23,166 @@ public class SmileXContentParser extends JsonXContentParser { return SmileXContent.smileContent(); } + @Override + public XContentParser.Token nextToken() throws IOException { + return convertToken(parser.nextToken()); + } + + @Override + public void skipChildren() throws IOException { + parser.skipChildren(); + } + + @Override + public XContentParser.Token currentToken() { + return convertToken(parser.getCurrentToken()); + } + + @Override + public XContentParser.NumberType numberType() throws IOException { + return convertNumberType(parser.getNumberType()); + } + + @Override + public boolean estimatedNumberType() { + return true; + } + + @Override + public String currentName() throws IOException { + return parser.getCurrentName(); + } + + @Override + protected boolean doBooleanValue() throws IOException { + return parser.getBooleanValue(); + } + + @Override + public String text() throws IOException { + return parser.getText(); + } + + @Override + public boolean hasTextCharacters() { + return parser.hasTextCharacters(); + } + + @Override + public char[] textCharacters() throws IOException { + return parser.getTextCharacters(); + } + + @Override + public int textLength() throws IOException { + return parser.getTextLength(); + } + + @Override + public int textOffset() throws IOException { + return parser.getTextOffset(); + } + + @Override + public Number numberValue() throws IOException { + return parser.getNumberValue(); + } + + @Override + public BigInteger bigIntegerValue() throws IOException { + return parser.getBigIntegerValue(); + } + + @Override + public BigDecimal bigDecimalValue() throws IOException { + return parser.getDecimalValue(); + } + + @Override + public short doShortValue() throws IOException { + return parser.getShortValue(); + } + + @Override + public int doIntValue() throws IOException { + return parser.getIntValue(); + } + + @Override + public long doLongValue() throws IOException { + return parser.getLongValue(); + } + + @Override + public float doFloatValue() throws IOException { + return parser.getFloatValue(); + } + + @Override + public double doDoubleValue() throws IOException { + return parser.getDoubleValue(); + } + + @Override + public byte[] binaryValue() throws IOException { + return parser.getBinaryValue(); + } + + @Override + public void close() throws IOException { + parser.close(); + } + + private XContentParser.NumberType convertNumberType(JsonParser.NumberType numberType) { + switch (numberType) { + case INT: + return XContentParser.NumberType.INT; + case LONG: + return XContentParser.NumberType.LONG; + case FLOAT: + return XContentParser.NumberType.FLOAT; + case DOUBLE: + return XContentParser.NumberType.DOUBLE; + case BIG_DECIMAL: + return XContentParser.NumberType.BIG_DECIMAL; + case BIG_INTEGER: + return XContentParser.NumberType.BIG_INTEGER; + default: + break; + } + throw new IllegalStateException("No matching token for number_type [" + numberType + "]"); + } + + private XContentParser.Token convertToken(JsonToken token) { + if (token == null) { + return null; + } + switch (token) { + case FIELD_NAME: + return XContentParser.Token.FIELD_NAME; + case VALUE_FALSE: + case VALUE_TRUE: + return XContentParser.Token.VALUE_BOOLEAN; + case VALUE_STRING: + return XContentParser.Token.VALUE_STRING; + case VALUE_NUMBER_INT: + case VALUE_NUMBER_FLOAT: + return XContentParser.Token.VALUE_NUMBER; + case VALUE_NULL: + return XContentParser.Token.VALUE_NULL; + case START_OBJECT: + return XContentParser.Token.START_OBJECT; + case END_OBJECT: + return XContentParser.Token.END_OBJECT; + case START_ARRAY: + return XContentParser.Token.START_ARRAY; + case END_ARRAY: + return XContentParser.Token.END_ARRAY; + case VALUE_EMBEDDED_OBJECT: + return XContentParser.Token.VALUE_EMBEDDED_OBJECT; + default: + break; + } + throw new IllegalStateException("No matching token for json_token [" + token + "]"); + } } diff --git a/content-xml/build.gradle b/content-xml/build.gradle index 07f88f6..b3e7b8e 100644 --- a/content-xml/build.gradle +++ b/content-xml/build.gradle @@ -1,6 +1,7 @@ dependencies { implementation project(':content-core') implementation project(':content-resource') - api "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${project.property('jackson.version')}" - implementation "com.fasterxml.woodstox:woodstox-core:${project.property('woodstox.version')}" + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${project.property('jackson.version')}" + runtimeOnly "com.fasterxml.woodstox:woodstox-core:${project.property('woodstox.version')}" + testImplementation project(':content-json') // for XContentHelper reading JSON } diff --git a/content-xml/src/main/java/module-info.java b/content-xml/src/main/java/module-info.java index 2ec0337..c261897 100644 --- a/content-xml/src/main/java/module-info.java +++ b/content-xml/src/main/java/module-info.java @@ -1,3 +1,4 @@ +import org.xbib.content.XContent; module org.xbib.content.xml { exports org.xbib.content.xml; exports org.xbib.content.xml.json; @@ -9,6 +10,5 @@ module org.xbib.content.xml { requires transitive org.xbib.content.core; requires transitive org.xbib.content.resource; requires transitive com.fasterxml.jackson.dataformat.xml; - provides org.xbib.content.XContent with - org.xbib.content.xml.XmlXContent; + provides XContent with org.xbib.content.xml.XmlXContent; } diff --git a/content-xml/src/main/java/org/xbib/content/xml/XmlXContent.java b/content-xml/src/main/java/org/xbib/content/xml/XmlXContent.java index 2668f00..f6379bc 100644 --- a/content-xml/src/main/java/org/xbib/content/xml/XmlXContent.java +++ b/content-xml/src/main/java/org/xbib/content/xml/XmlXContent.java @@ -4,9 +4,9 @@ import com.fasterxml.jackson.core.JsonEncoding; import com.fasterxml.jackson.dataformat.xml.XmlFactory; import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; +import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.XContentGenerator; import org.xbib.content.XContentParser; -import org.xbib.content.io.BytesReference; import java.io.IOException; import java.io.InputStream; @@ -36,33 +36,45 @@ public class XmlXContent implements XContent { } public static XContentBuilder contentBuilder() throws IOException { - XContentBuilder builder = XContentBuilder.builder(xmlXContent()); - if (builder.generator() instanceof XmlXContentGenerator) { - ((XmlXContentGenerator) builder.generator()).setParams(XmlXParams.getDefaultParams()); + XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent()); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + if (xContentBuilder.generator() instanceof XmlXContentGenerator) { + ((XmlXContentGenerator) xContentBuilder.generator()).setParams(XmlXParams.getDefaultParams()); + } } return builder; } public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { - XContentBuilder builder = XContentBuilder.builder(xmlXContent(), outputStream); - if (builder.generator() instanceof XmlXContentGenerator) { - ((XmlXContentGenerator) builder.generator()).setParams(XmlXParams.getDefaultParams()); + XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent(), outputStream); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + if (xContentBuilder.generator() instanceof XmlXContentGenerator) { + ((XmlXContentGenerator) xContentBuilder.generator()).setParams(XmlXParams.getDefaultParams()); + } } return builder; } public static XContentBuilder contentBuilder(XmlXParams params) throws IOException { - XContentBuilder builder = XContentBuilder.builder(xmlXContent(params.getXmlFactory())); - if (builder.generator() instanceof XmlXContentGenerator) { - ((XmlXContentGenerator) builder.generator()).setParams(params); + XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent(params.getXmlFactory())); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + if (xContentBuilder.generator() instanceof XmlXContentGenerator) { + ((XmlXContentGenerator) xContentBuilder.generator()).setParams(params); + } } return builder; } public static XContentBuilder contentBuilder(XmlXParams params, OutputStream outputStream) throws IOException { - XContentBuilder builder = XContentBuilder.builder(xmlXContent(params.getXmlFactory()), outputStream); - if (builder.generator() instanceof XmlXContentGenerator) { - ((XmlXContentGenerator) builder.generator()).setParams(params); + XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent(params.getXmlFactory()), outputStream); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + if (xContentBuilder.generator() instanceof XmlXContentGenerator) { + ((XmlXContentGenerator) xContentBuilder.generator()).setParams(params); + } } return builder; } @@ -123,17 +135,12 @@ public class XmlXContent implements XContent { } @Override - public XContentParser createParser(BytesReference bytes) throws IOException { - return createParser(bytes.streamInput()); - } - - @Override - public boolean isXContent(BytesReference bytes) { - int length = bytes.length() < 20 ? bytes.length() : 20; + public boolean isXContent(byte[] bytes, int offset, int len) { + int length = Math.min(len, 20); if (length == 0) { return false; } - byte first = bytes.get(0); - return length > 2 && first == '<' && bytes.get(1) == '?' && bytes.get(2) == 'x'; + byte first = bytes[offset]; + return length > 2 && first == '<' && bytes[offset + 1] == '?' && bytes[offset + 2] == 'x'; } } diff --git a/content-xml/src/main/java/org/xbib/content/xml/XmlXContentGenerator.java b/content-xml/src/main/java/org/xbib/content/xml/XmlXContentGenerator.java index b8c53d9..8ff2300 100644 --- a/content-xml/src/main/java/org/xbib/content/xml/XmlXContentGenerator.java +++ b/content-xml/src/main/java/org/xbib/content/xml/XmlXContentGenerator.java @@ -2,13 +2,13 @@ package org.xbib.content.xml; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; -import org.xbib.content.AbstractXContentGenerator; -import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; +import org.xbib.content.core.AbstractXContentGenerator; +import org.xbib.content.XContent; +import org.xbib.content.core.DefaultXContentBuilder; import org.xbib.content.XContentGenerator; -import org.xbib.content.XContentHelper; +import org.xbib.content.core.XContentHelper; import org.xbib.content.XContentParser; -import org.xbib.content.XContentString; import org.xbib.content.io.BytesReference; import org.xbib.content.xml.util.ISO9075; import org.xbib.content.xml.util.XMLUtil; @@ -29,7 +29,7 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { private final XmlXContentGeneratorDelegate delegate; - private XmlXParams params; + private final XmlXParams params; public XmlXContentGenerator(ToXmlGenerator generator) { this(generator, XmlXParams.getDefaultParams()); @@ -71,11 +71,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { delegate.writeFieldName(name); } - @Override - public void writeFieldName(XContentString name) throws IOException { - delegate.writeFieldName(name); - } - @Override public void writeString(String text) throws IOException { delegate.writeString(text); @@ -90,11 +85,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { delegate.writeRawField(fieldName, content, outputStream); } - @Override - public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { - delegate.writeRawField(fieldName, content, outputStream); - } - @Override public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) throws IOException { @@ -106,6 +96,15 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { delegate.writeValue(builder); } + @Override + public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { + flush(); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(outputStream); + } + } + @Override public void copyCurrentStructure(XContentParser parser) throws IOException { delegate.copyCurrentStructure(parser); @@ -195,11 +194,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { writeFieldNameWithNamespace(name); } - @Override - public void writeFieldName(XContentString name) throws IOException { - writeFieldNameWithNamespace(name); - } - @Override public void writeString(String text) throws IOException { generator.writeString(XMLUtil.sanitize(text)); @@ -271,23 +265,10 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { generator.writeStringField(fieldName, value); } - @Override - public void writeStringField(XContentString fieldName, String value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeString(value); - } - - @Override public void writeBooleanField(String fieldName, boolean value) throws IOException { generator.writeBooleanField(fieldName, value); } - @Override - public void writeBooleanField(XContentString fieldName, boolean value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeBoolean(value); - } - @Override public void writeNullField(String fieldName) throws IOException { generator.writeNullField(fieldName); @@ -298,102 +279,48 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, int value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, long value) throws IOException { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, long value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, double value) throws IOException { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, double value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, float value) throws IOException { generator.writeNumberField(fieldName, value); } - @Override - public void writeNumberField(XContentString fieldName, float value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, BigInteger value) throws IOException { generator.writeFieldName(fieldName); generator.writeNumber(value); } - @Override - public void writeNumberField(XContentString fieldName, BigInteger value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeNumberField(String fieldName, BigDecimal value) throws IOException { generator.writeFieldName(fieldName); generator.writeNumber(value); } - @Override - public void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException { - generator.writeFieldName(fieldName); - generator.writeNumber(value); - } - @Override public void writeBinaryField(String fieldName, byte[] data) throws IOException { generator.writeBinaryField(fieldName, data); } - @Override - public void writeBinaryField(XContentString fieldName, byte[] data) throws IOException { - generator.writeFieldName(fieldName); - generator.writeBinary(data); - } - @Override public void writeArrayFieldStart(String fieldName) throws IOException { generator.writeArrayFieldStart(fieldName); } - @Override - public void writeArrayFieldStart(XContentString fieldName) throws IOException { - generator.writeFieldName(fieldName); - generator.writeStartArray(); - } - @Override public void writeObjectFieldStart(String fieldName) throws IOException { generator.writeObjectFieldStart(fieldName); } - @Override - public void writeObjectFieldStart(XContentString fieldName) throws IOException { - generator.writeFieldName(fieldName); - generator.writeStartObject(); - } - @Override public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException { writeFieldNameWithNamespace(fieldName); @@ -403,7 +330,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { } } - @Override public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { writeFieldNameWithNamespace(fieldName); try (JsonParser parser = params.getXmlFactory().createParser(content.streamInput())) { @@ -430,7 +356,10 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { @Override public void copy(XContentBuilder builder, OutputStream bos) throws IOException { flush(); - builder.bytes().streamOutput(bos); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(bos); + } } @Override @@ -469,10 +398,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator { generator.writeFieldName(qname.getLocalPart()); } - private void writeFieldNameWithNamespace(XContentString name) throws IOException { - writeFieldNameWithNamespace(name.getValue()); - } - private QName toQualifiedName(NamespaceContext context, String string) { String name = string; if (name.startsWith("_") || name.startsWith("@")) { diff --git a/content-xml/src/main/java/org/xbib/content/xml/XmlXContentHelper.java b/content-xml/src/main/java/org/xbib/content/xml/XmlXContentHelper.java index bd5190c..61d76b2 100644 --- a/content-xml/src/main/java/org/xbib/content/xml/XmlXContentHelper.java +++ b/content-xml/src/main/java/org/xbib/content/xml/XmlXContentHelper.java @@ -3,15 +3,12 @@ package org.xbib.content.xml; import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; import org.xbib.content.XContentParser; -import org.xbib.content.XContentService; +import org.xbib.content.core.XContentService; import java.io.IOException; import java.io.Reader; import java.util.Map; -/** - * - */ public class XmlXContentHelper { private XmlXContentHelper() { diff --git a/content-xml/src/main/java/org/xbib/content/xml/XmlXContentParser.java b/content-xml/src/main/java/org/xbib/content/xml/XmlXContentParser.java index e8552b9..09e34d0 100644 --- a/content-xml/src/main/java/org/xbib/content/xml/XmlXContentParser.java +++ b/content-xml/src/main/java/org/xbib/content/xml/XmlXContentParser.java @@ -2,7 +2,7 @@ package org.xbib.content.xml; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; -import org.xbib.content.AbstractXContentParser; +import org.xbib.content.core.AbstractXContentParser; import org.xbib.content.XContent; import org.xbib.content.XContentParser; diff --git a/content-xml/src/test/java/org/xbib/content/xml/XContentXmlBuilderTest.java b/content-xml/src/test/java/org/xbib/content/xml/XContentXmlBuilderTest.java index fe4420c..f194715 100644 --- a/content-xml/src/test/java/org/xbib/content/xml/XContentXmlBuilderTest.java +++ b/content-xml/src/test/java/org/xbib/content/xml/XContentXmlBuilderTest.java @@ -1,9 +1,10 @@ package org.xbib.content.xml; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.xbib.content.xml.XmlXContent.contentBuilder; import org.junit.jupiter.api.Test; import org.xbib.content.XContentBuilder; -import org.xbib.content.XContentHelper; +import org.xbib.content.core.XContentHelper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -25,7 +26,7 @@ public class XContentXmlBuilderTest { @Test public void testEmpty() throws Exception { QName root = new QName("root"); - XContentBuilder builder = XmlXContent.contentBuilder(new XmlXParams(root)); + XContentBuilder builder = contentBuilder(new XmlXParams(root)); builder.startObject().field("Hello", "World").endObject(); assertEquals("World", builder.string()); } @@ -34,14 +35,14 @@ public class XContentXmlBuilderTest { public void testContextNamespace() throws Exception { QName root = new QName("root"); XmlNamespaceContext context = XmlNamespaceContext.newInstance(); - XContentBuilder builder = XmlXContent.contentBuilder(new XmlXParams(root, context)); + XContentBuilder builder = contentBuilder(new XmlXParams(root, context)); builder.startObject().field("Hello", "World").endObject(); assertEquals("World", builder.string()); } @Test public void testXml() throws Exception { - XContentBuilder builder = XmlXContent.contentBuilder(); + XContentBuilder builder = contentBuilder(); builder.startObject().field("Hello", "World").endObject(); assertEquals("World", builder.string()); } @@ -49,7 +50,7 @@ public class XContentXmlBuilderTest { @Test public void testXmlParams() throws Exception { XmlXParams params = new XmlXParams(); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject().field("Hello", "World").endObject(); assertEquals("World", builder.string()); } @@ -58,7 +59,7 @@ public class XContentXmlBuilderTest { public void testXmlObject() throws Exception { QName root = XmlXParams.getDefaultParams().getRoot(); XmlXParams params = new XmlXParams(root); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject() .startObject("author") .field("creator", "John Doe") @@ -78,7 +79,7 @@ public class XContentXmlBuilderTest { public void testXmlAttributes() throws Exception { QName root = XmlXParams.getDefaultParams().getRoot(); XmlXParams params = new XmlXParams(root); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject() .startObject("author") .field("@name", "John Doe") @@ -92,7 +93,7 @@ public class XContentXmlBuilderTest { public void testXmlArrayOfValues() throws Exception { QName root = XmlXParams.getDefaultParams().getRoot(); XmlXParams params = new XmlXParams(root); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject() .array("author", "John Doe", "Joe Smith") .endObject(); @@ -103,7 +104,7 @@ public class XContentXmlBuilderTest { public void testXmlArrayOfObjects() throws Exception { QName root = XmlXParams.getDefaultParams().getRoot(); XmlXParams params = new XmlXParams(root); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject() .startArray("author") .startObject() @@ -132,7 +133,7 @@ public class XContentXmlBuilderTest { ByteArrayOutputStream out = new ByteArrayOutputStream(); copy(in, out); byte[] buf = out.toByteArray(); - Map map = XContentHelper.convertToMap(buf, false); + Map map = XContentHelper.convertToMap(buf, false); assertEquals("{dc:description={xbib:creatorDescription=Otis Gospodnetić ; Erik Hatcher, " + "dcterms:extent=XXXIV, 421 S. : Ill.}, dc:language={xbib:languageISO6392b=eng, " + "xbib:languageISO6391=en}, dc:subject={xbib:rswk={xbib:subjectTopic=Lucene, " @@ -184,7 +185,7 @@ public class XContentXmlBuilderTest { @Test public void testInvalidWhiteSpaceCharacter() throws Exception { QName root = new QName("root"); - XContentBuilder builder = XmlXContent.contentBuilder(new XmlXParams(root)); + XContentBuilder builder = contentBuilder(new XmlXParams(root)); builder.startObject().field("Hello", "World\u001b").endObject(); assertEquals("World", builder.string()); } @@ -194,7 +195,7 @@ public class XContentXmlBuilderTest { XmlNamespaceContext context = XmlNamespaceContext.newInstance(); context.addNamespace("", ""); QName root = new QName("root"); - XContentBuilder builder = XmlXContent.contentBuilder(new XmlXParams(root, context)); + XContentBuilder builder = contentBuilder(new XmlXParams(root, context)); builder.startObject().field("Hello", "World").endObject(); assertEquals("World", builder.string()); } diff --git a/content-xml/src/test/java/org/xbib/content/xml/XmlNamespaceContextTest.java b/content-xml/src/test/java/org/xbib/content/xml/XmlNamespaceContextTest.java index dc37b6f..d45d196 100644 --- a/content-xml/src/test/java/org/xbib/content/xml/XmlNamespaceContextTest.java +++ b/content-xml/src/test/java/org/xbib/content/xml/XmlNamespaceContextTest.java @@ -1,6 +1,7 @@ package org.xbib.content.xml; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.xbib.content.xml.XmlXContent.contentBuilder; import org.junit.jupiter.api.Test; import org.xbib.content.XContentBuilder; import org.xbib.content.xml.transform.StylesheetTransformer; @@ -24,7 +25,7 @@ public class XmlNamespaceContextTest { XmlNamespaceContext.newInstance("org/xbib/content/resource/namespace", Locale.getDefault(), StylesheetTransformer.class.getClassLoader()); XmlXParams params = new XmlXParams(context); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject() .field("dc:creator", "John Doe") .endObject(); @@ -42,7 +43,7 @@ public class XmlNamespaceContextTest { XmlNamespaceContext context = XmlNamespaceContext.newInstance(); context.addNamespace("abc", "http://localhost"); XmlXParams params = new XmlXParams(root, context); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject() .field("abc:creator", "John Doe") .endObject(); @@ -57,7 +58,7 @@ public class XmlNamespaceContextTest { context.addNamespace("", "http://localhost"); context.addNamespace("abc", "http://content"); XmlXParams params = new XmlXParams(root, context); - XContentBuilder builder = XmlXContent.contentBuilder(params); + XContentBuilder builder = contentBuilder(params); builder.startObject() .field("creator", "John Doe") .endObject(); diff --git a/content-yaml/build.gradle b/content-yaml/build.gradle index 68968f0..15be496 100644 --- a/content-yaml/build.gradle +++ b/content-yaml/build.gradle @@ -1,5 +1,6 @@ dependencies { api project(':content-core') - api "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}" - api "org.yaml:snakeyaml:${project.property('snakeyaml.version')}" + api project(':content-settings') + implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}" + implementation "org.yaml:snakeyaml:${project.property('snakeyaml.version')}" } diff --git a/content-yaml/src/main/java/module-info.java b/content-yaml/src/main/java/module-info.java index e8e47f3..ba56bc7 100644 --- a/content-yaml/src/main/java/module-info.java +++ b/content-yaml/src/main/java/module-info.java @@ -1,9 +1,11 @@ +import org.xbib.content.SettingsLoader; +import org.xbib.content.XContent; + module org.xbib.content.yaml { exports org.xbib.content.yaml; requires transitive org.xbib.content.core; + requires transitive org.xbib.content.settings; requires transitive com.fasterxml.jackson.dataformat.yaml; - provides org.xbib.content.XContent with - org.xbib.content.yaml.YamlXContent; - provides org.xbib.content.settings.SettingsLoader with - org.xbib.content.yaml.YamlSettingsLoader; + provides XContent with org.xbib.content.yaml.YamlXContent; + provides SettingsLoader with org.xbib.content.yaml.YamlSettingsLoader; } diff --git a/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContent.java b/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContent.java index 73751e7..6dfb068 100644 --- a/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContent.java +++ b/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContent.java @@ -6,7 +6,7 @@ import org.xbib.content.XContent; import org.xbib.content.XContentBuilder; import org.xbib.content.XContentGenerator; import org.xbib.content.XContentParser; -import org.xbib.content.io.BytesReference; +import org.xbib.content.core.DefaultXContentBuilder; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -36,11 +36,11 @@ public class YamlXContent implements XContent { } public static XContentBuilder contentBuilder() throws IOException { - return XContentBuilder.builder(yamlXContent); + return DefaultXContentBuilder.builder(yamlXContent); } public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { - return XContentBuilder.builder(yamlXContent, outputStream); + return DefaultXContentBuilder.builder(yamlXContent, outputStream); } @Override @@ -84,25 +84,18 @@ public class YamlXContent implements XContent { return new YamlXContentParser(yamlFactory.createParser(data, offset, length)); } - - @Override - public XContentParser createParser(BytesReference bytes) throws IOException { - return createParser(bytes.streamInput()); - } - - @Override public XContentParser createParser(Reader reader) throws IOException { return new YamlXContentParser(yamlFactory.createParser(reader)); } @Override - public boolean isXContent(BytesReference bytes) { - int length = bytes.length() < 20 ? bytes.length() : 20; + public boolean isXContent(byte[] bytes, int offset, int len) { + int length = Math.min(len, 20); if (length == 0) { return false; } - byte first = bytes.get(0); - return length > 2 && first == '-' && bytes.get(1) == '-' && bytes.get(2) == '-'; + byte first = bytes[offset]; + return length > 2 && first == '-' && bytes[offset + 1] == '-' && bytes[offset + 2] == '-'; } } diff --git a/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentGenerator.java b/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentGenerator.java index fcf639f..3c5faa2 100644 --- a/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentGenerator.java +++ b/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentGenerator.java @@ -1,25 +1,37 @@ package org.xbib.content.yaml; -import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; import com.fasterxml.jackson.dataformat.yaml.YAMLParser; import org.xbib.content.XContent; +import org.xbib.content.XContentBuilder; +import org.xbib.content.XContentGenerator; +import org.xbib.content.XContentParser; +import org.xbib.content.core.AbstractXContentGenerator; +import org.xbib.content.core.DefaultXContentBuilder; +import org.xbib.content.core.XContentHelper; import org.xbib.content.io.BytesReference; -import org.xbib.content.json.JsonXContentGenerator; import java.io.IOException; import java.io.OutputStream; +import java.math.BigDecimal; +import java.math.BigInteger; -/** - * - */ -public class YamlXContentGenerator extends JsonXContentGenerator { +public class YamlXContentGenerator extends AbstractXContentGenerator { - public YamlXContentGenerator(JsonGenerator generator) { - super(generator); + private final YAMLGeneratorDelegate delegate; + + public YamlXContentGenerator(YAMLGenerator generator) { + this.delegate = new YAMLGeneratorDelegate(generator); + super.setGenerator(delegate); } @Override public XContent content() { - return YamlXContent.yamlContent(); + return delegate.content(); + } + + @Override + public void usePrettyPrint() { + delegate.usePrettyPrint(); } @Override @@ -31,15 +43,6 @@ public class YamlXContentGenerator extends JsonXContentGenerator { } } - @Override - public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { - writeFieldName(fieldName); - try (YAMLParser parser = YamlXContent.yamlFactory().createParser(content.streamInput())) { - parser.nextToken(); - YamlXContent.yamlFactory().createGenerator(outputStream).copyCurrentStructure(parser); - } - } - @Override public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) throws IOException { @@ -49,4 +52,265 @@ public class YamlXContentGenerator extends JsonXContentGenerator { YamlXContent.yamlFactory().createGenerator(outputStream).copyCurrentStructure(parser); } } + + @Override + public void writeValue(XContentBuilder builder) throws IOException { + delegate.writeValue(builder); + } + + @Override + public void copyCurrentStructure(XContentParser parser) throws IOException { + delegate.copyCurrentStructure(parser); + } + + @Override + public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { + flush(); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(outputStream); + } + } + + @Override + public void flush() throws IOException { + delegate.flush(); + } + + @Override + public void close() throws IOException { + delegate.close(); + } + + private static class YAMLGeneratorDelegate implements XContentGenerator { + + final YAMLGenerator yamlGenerator; + + YAMLGeneratorDelegate(YAMLGenerator yamlGenerator) { + this.yamlGenerator = yamlGenerator; + } + + @Override + public XContent content() { + return YamlXContent.yamlContent(); + } + + @Override + public void usePrettyPrint() { + yamlGenerator.useDefaultPrettyPrinter(); + } + + @Override + public void writeStartArray() throws IOException { + yamlGenerator.writeStartArray(); + } + + @Override + public void writeEndArray() throws IOException { + yamlGenerator.writeEndArray(); + } + + @Override + public void writeStartObject() throws IOException { + yamlGenerator.writeStartObject(); + } + + @Override + public void writeEndObject() throws IOException { + yamlGenerator.writeEndObject(); + } + + @Override + public void writeFieldName(String name) throws IOException { + yamlGenerator.writeFieldName(name); + } + + @Override + public void writeString(String text) throws IOException { + yamlGenerator.writeString(text); + } + + @Override + public void writeString(char[] text, int offset, int len) throws IOException { + yamlGenerator.writeString(text, offset, len); + } + + @Override + public void writeUTF8String(byte[] text, int offset, int length) throws IOException { + yamlGenerator.writeUTF8String(text, offset, length); + } + + @Override + public void writeBinary(byte[] data, int offset, int len) throws IOException { + yamlGenerator.writeBinary(data, offset, len); + } + + @Override + public void writeBinary(byte[] data) throws IOException { + yamlGenerator.writeBinary(data); + } + + @Override + public void writeNumber(int v) throws IOException { + yamlGenerator.writeNumber(v); + } + + @Override + public void writeNumber(long v) throws IOException { + yamlGenerator.writeNumber(v); + } + + @Override + public void writeNumber(double d) throws IOException { + yamlGenerator.writeNumber(d); + } + + @Override + public void writeNumber(float f) throws IOException { + yamlGenerator.writeNumber(f); + } + + @Override + public void writeNumber(BigInteger bi) throws IOException { + yamlGenerator.writeNumber(bi); + } + + @Override + public void writeNumber(BigDecimal bd) throws IOException { + yamlGenerator.writeNumber(bd); + } + + @Override + public void writeBoolean(boolean b) throws IOException { + yamlGenerator.writeBoolean(b); + } + + @Override + public void writeNull() throws IOException { + yamlGenerator.writeNull(); + } + + @Override + public void writeStringField(String fieldName, String value) throws IOException { + yamlGenerator.writeStringField(fieldName, value); + } + + @Override + public void writeBooleanField(String fieldName, boolean value) throws IOException { + yamlGenerator.writeBooleanField(fieldName, value); + } + + @Override + public void writeNullField(String fieldName) throws IOException { + yamlGenerator.writeNullField(fieldName); + } + + @Override + public void writeNumberField(String fieldName, int value) throws IOException { + yamlGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, long value) throws IOException { + yamlGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, double value) throws IOException { + yamlGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, float value) throws IOException { + yamlGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeNumberField(String fieldName, BigInteger value) throws IOException { + yamlGenerator.writeFieldName(fieldName); + yamlGenerator.writeNumber(value); + } + + @Override + public void writeNumberField(String fieldName, BigDecimal value) throws IOException { + yamlGenerator.writeNumberField(fieldName, value); + } + + @Override + public void writeBinaryField(String fieldName, byte[] data) throws IOException { + yamlGenerator.writeBinaryField(fieldName, data); + } + + @Override + public void writeArrayFieldStart(String fieldName) throws IOException { + yamlGenerator.writeArrayFieldStart(fieldName); + } + + @Override + public void writeObjectFieldStart(String fieldName) throws IOException { + yamlGenerator.writeObjectFieldStart(fieldName); + } + + @Override + public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException { + yamlGenerator.writeRaw(",\""); + yamlGenerator.writeRaw(fieldName); + yamlGenerator.writeRaw("\":"); + flush(); + outputStream.write(content); + } + + @Override + public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) + throws IOException { + yamlGenerator.writeRaw(",\""); + yamlGenerator.writeRaw(fieldName); + yamlGenerator.writeRaw("\":"); + flush(); + outputStream.write(content, offset, length); + } + + public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { + yamlGenerator.writeRaw(",\""); + yamlGenerator.writeRaw(fieldName); + yamlGenerator.writeRaw("\":"); + flush(); + content.streamOutput(outputStream); + } + + @Override + public void writeValue(XContentBuilder builder) throws IOException { + yamlGenerator.writeRawValue(builder.string()); + } + + @Override + public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { + flush(); + if (builder instanceof DefaultXContentBuilder) { + DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder; + xContentBuilder.bytes().streamOutput(outputStream); + } + } + + @Override + public void copyCurrentStructure(XContentParser parser) throws IOException { + if (parser.currentToken() == null) { + parser.nextToken(); + } + XContentHelper.copyCurrentStructure(this, parser); + } + + @Override + public void flush() throws IOException { + yamlGenerator.flush(); + } + + @Override + public void close() throws IOException { + if (yamlGenerator.isClosed()) { + return; + } + yamlGenerator.close(); + } + } } diff --git a/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentParser.java b/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentParser.java index 256c0a9..9879213 100644 --- a/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentParser.java +++ b/content-yaml/src/main/java/org/xbib/content/yaml/YamlXContentParser.java @@ -1,20 +1,189 @@ package org.xbib.content.yaml; import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.fasterxml.jackson.dataformat.yaml.YAMLParser; import org.xbib.content.XContent; -import org.xbib.content.json.JsonXContentParser; +import org.xbib.content.XContentParser; +import org.xbib.content.core.AbstractXContentParser; +import java.io.IOException; +import java.math.BigDecimal; +import java.math.BigInteger; -/** - * - */ -public class YamlXContentParser extends JsonXContentParser { +public class YamlXContentParser extends AbstractXContentParser { - public YamlXContentParser(JsonParser parser) { - super(parser); + private final YAMLParser parser; + + public YamlXContentParser(YAMLParser parser) { + this.parser = parser; } @Override public XContent content() { return YamlXContent.yamlContent(); } + + + @Override + public XContentParser.Token nextToken() throws IOException { + return convertToken(parser.nextToken()); + } + + @Override + public void skipChildren() throws IOException { + parser.skipChildren(); + } + + @Override + public XContentParser.Token currentToken() { + return convertToken(parser.getCurrentToken()); + } + + @Override + public XContentParser.NumberType numberType() throws IOException { + return convertNumberType(parser.getNumberType()); + } + + @Override + public boolean estimatedNumberType() { + return true; + } + + @Override + public String currentName() throws IOException { + return parser.getCurrentName(); + } + + @Override + protected boolean doBooleanValue() throws IOException { + return parser.getBooleanValue(); + } + + @Override + public String text() throws IOException { + return parser.getText(); + } + + @Override + public boolean hasTextCharacters() { + return parser.hasTextCharacters(); + } + + @Override + public char[] textCharacters() throws IOException { + return parser.getTextCharacters(); + } + + @Override + public int textLength() throws IOException { + return parser.getTextLength(); + } + + @Override + public int textOffset() throws IOException { + return parser.getTextOffset(); + } + + @Override + public Number numberValue() throws IOException { + return parser.getNumberValue(); + } + + @Override + public BigInteger bigIntegerValue() throws IOException { + return parser.getBigIntegerValue(); + } + + @Override + public BigDecimal bigDecimalValue() throws IOException { + return parser.getDecimalValue(); + } + + @Override + public short doShortValue() throws IOException { + return parser.getShortValue(); + } + + @Override + public int doIntValue() throws IOException { + return parser.getIntValue(); + } + + @Override + public long doLongValue() throws IOException { + return parser.getLongValue(); + } + + @Override + public float doFloatValue() throws IOException { + return parser.getFloatValue(); + } + + @Override + public double doDoubleValue() throws IOException { + return parser.getDoubleValue(); + } + + @Override + public byte[] binaryValue() throws IOException { + return parser.getBinaryValue(); + } + + @Override + public void close() throws IOException { + parser.close(); + } + + private XContentParser.NumberType convertNumberType(JsonParser.NumberType numberType) { + switch (numberType) { + case INT: + return XContentParser.NumberType.INT; + case LONG: + return XContentParser.NumberType.LONG; + case FLOAT: + return XContentParser.NumberType.FLOAT; + case DOUBLE: + return XContentParser.NumberType.DOUBLE; + case BIG_DECIMAL: + return XContentParser.NumberType.BIG_DECIMAL; + case BIG_INTEGER: + return XContentParser.NumberType.BIG_INTEGER; + default: + break; + } + throw new IllegalStateException("No matching token for number_type [" + numberType + "]"); + } + + private XContentParser.Token convertToken(JsonToken token) { + if (token == null) { + return null; + } + switch (token) { + case FIELD_NAME: + return XContentParser.Token.FIELD_NAME; + case VALUE_FALSE: + case VALUE_TRUE: + return XContentParser.Token.VALUE_BOOLEAN; + case VALUE_STRING: + return XContentParser.Token.VALUE_STRING; + case VALUE_NUMBER_INT: + case VALUE_NUMBER_FLOAT: + return XContentParser.Token.VALUE_NUMBER; + case VALUE_NULL: + return XContentParser.Token.VALUE_NULL; + case START_OBJECT: + return XContentParser.Token.START_OBJECT; + case END_OBJECT: + return XContentParser.Token.END_OBJECT; + case START_ARRAY: + return XContentParser.Token.START_ARRAY; + case END_ARRAY: + return XContentParser.Token.END_ARRAY; + case VALUE_EMBEDDED_OBJECT: + return XContentParser.Token.VALUE_EMBEDDED_OBJECT; + default: + break; + } + throw new IllegalStateException("No matching token for json_token [" + token + "]"); + } } diff --git a/content-yaml/src/main/resources/META-INF/services/org.xbib.content.settings.SettingsLoader b/content-yaml/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader similarity index 100% rename from content-yaml/src/main/resources/META-INF/services/org.xbib.content.settings.SettingsLoader rename to content-yaml/src/main/resources/META-INF/services/org.xbib.content.SettingsLoader diff --git a/gradle.properties b/gradle.properties index da69b6b..b2fa058 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,9 +1,8 @@ group = org.xbib name = content -version = 2.6.6 +version = 3.0.0 gradle.wrapper.version = 6.6.1 - xbib.net.version = 2.1.1 xbib-datastructures-tiny.version = 0.1.0 jackson.version = 2.11.4 diff --git a/settings.gradle b/settings.gradle index 33aeeb8..e72b640 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,10 +1,12 @@ +include 'content-api' include 'content-config' include 'content-core' -include 'content-resource' +include 'content-csv' include 'content-language' include 'content-json' -include 'content-csv' -include 'content-smile' -include 'content-yaml' -include 'content-xml' include 'content-rdf' +include 'content-resource' +include 'content-settings' +include 'content-smile' +include 'content-xml' +include 'content-yaml'