large refactoring, new subprojects api, settings; json parser/generator moved to json; cleaned up methods and helper classes

This commit is contained in:
Jörg Prante 2021-05-15 20:03:23 +02:00
parent eee2eb0d0c
commit 65769e5c1c
72 changed files with 1620 additions and 1049 deletions

View file

@ -0,0 +1,3 @@
module org.xbib.content {
exports org.xbib.content;
}

View file

@ -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.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -25,8 +24,6 @@ public interface SettingsLoader {
*/ */
Map<String, String> load(String source) throws IOException; Map<String, String> load(String source) throws IOException;
Map<String, String> load(BytesReference bytesReference) throws IOException;
Map<String, String> load(Map<String, Object> source) throws IOException; Map<String, String> load(Map<String, Object> source) throws IOException;
boolean canLoad(String source); boolean canLoad(String source);

View file

@ -25,9 +25,6 @@ public interface ToXContent {
}; };
/**
*
*/
interface Params { interface Params {
String param(String key); String param(String key);

View file

@ -1,7 +1,5 @@
package org.xbib.content; package org.xbib.content;
import org.xbib.content.io.BytesReference;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -15,6 +13,8 @@ public interface XContent {
String name(); String name();
boolean isXContent(byte[] data, int offset, int length);
/** /**
* Creates a new generator using the provided output stream. * 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; 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);
} }

View file

@ -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<XContentBuilder> 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<String, Object> 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<String, Object> map) throws IOException;
XContentBuilder flatMap(Map<String, String> map) throws IOException;
XContentBuilder timeseriesMap(Map<Instant, Object> map) throws IOException;
String string() throws IOException;
}

View file

@ -1,7 +1,5 @@
package org.xbib.content; package org.xbib.content;
import org.xbib.content.io.BytesReference;
import java.io.Closeable; import java.io.Closeable;
import java.io.Flushable; import java.io.Flushable;
import java.io.IOException; import java.io.IOException;
@ -9,9 +7,6 @@ import java.io.OutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
/**
*
*/
public interface XContentGenerator extends Flushable, Closeable { public interface XContentGenerator extends Flushable, Closeable {
XContent content(); XContent content();
@ -28,8 +23,6 @@ public interface XContentGenerator extends Flushable, Closeable {
void writeFieldName(String name) throws IOException; void writeFieldName(String name) throws IOException;
void writeFieldName(XContentString name) throws IOException;
void writeString(String text) throws IOException; void writeString(String text) throws IOException;
void writeString(char[] text, int offset, int len) 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(String fieldName, String value) throws IOException;
void writeStringField(XContentString fieldName, String value) throws IOException;
void writeBooleanField(String fieldName, boolean 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 writeNullField(String fieldName) throws IOException;
void writeNumberField(String fieldName, int value) 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(String fieldName, long value) throws IOException;
void writeNumberField(XContentString fieldName, long value) throws IOException;
void writeNumberField(String fieldName, double 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(String fieldName, float value) throws IOException;
void writeNumberField(XContentString fieldName, float value) throws IOException;
void writeNumberField(String fieldName, BigInteger 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(String fieldName, BigDecimal value) throws IOException;
void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException;
void writeBinaryField(String fieldName, byte[] data) 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(String fieldName) throws IOException;
void writeArrayFieldStart(XContentString fieldName) throws IOException;
void writeObjectFieldStart(String fieldName) throws IOException; void writeObjectFieldStart(String fieldName) throws IOException;
void writeObjectFieldStart(XContentString fieldName) throws IOException;
void writeRawField(String fieldName, byte[] content, OutputStream outputStream) void writeRawField(String fieldName, byte[] content, OutputStream outputStream)
throws IOException; throws IOException;
void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream)
throws IOException; throws IOException;
void writeRawField(String fieldName, BytesReference content, OutputStream outputStream)
throws IOException;
void writeValue(XContentBuilder builder) throws IOException; void writeValue(XContentBuilder builder) throws IOException;
void copy(XContentBuilder builder, OutputStream outputStream) throws IOException; void copy(XContentBuilder builder, OutputStream outputStream) throws IOException;

View file

@ -6,9 +6,6 @@ import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.Map; import java.util.Map;
/**
*
*/
public interface XContentParser extends Closeable { public interface XContentParser extends Closeable {
XContent content(); XContent content();
@ -45,11 +42,6 @@ public interface XContentParser extends Closeable {
NumberType numberType() throws IOException; 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(); boolean estimatedNumberType();
short shortValue() throws IOException; short shortValue() throws IOException;

View file

@ -1,3 +1,5 @@
dependencies { dependencies {
api project(':content-json')
api project(':content-yaml') api project(':content-yaml')
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}"
} }

View file

@ -1,4 +1,5 @@
module org.xbib.content.config { module org.xbib.content.config {
exports org.xbib.content.config; exports org.xbib.content.config;
requires transitive org.xbib.content.json;
requires transitive org.xbib.content.yaml; requires transitive org.xbib.content.yaml;
} }

View file

@ -2,7 +2,7 @@ package org.xbib.content.config;
import org.xbib.content.json.JsonSettingsLoader; import org.xbib.content.json.JsonSettingsLoader;
import org.xbib.content.settings.Settings; import org.xbib.content.settings.Settings;
import org.xbib.content.settings.SettingsLoader; import org.xbib.content.SettingsLoader;
import org.xbib.content.yaml.YamlSettingsLoader; import org.xbib.content.yaml.YamlSettingsLoader;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;

View file

@ -1,4 +1,5 @@
dependencies { 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')}" api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures-tiny.version')}"
implementation "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}"
} }

View file

@ -1,15 +1,16 @@
import org.xbib.content.SettingsLoader;
import org.xbib.content.properties.PropertiesSettingsLoader;
module org.xbib.content.core { 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.io;
exports org.xbib.content.json; exports org.xbib.content.properties;
exports org.xbib.content.settings;
exports org.xbib.content.util.geo; exports org.xbib.content.util.geo;
exports org.xbib.content.util.unit; 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; requires transitive com.fasterxml.jackson.core;
provides org.xbib.content.XContent with provides SettingsLoader with PropertiesSettingsLoader;
org.xbib.content.json.JsonXContent;
provides org.xbib.content.settings.SettingsLoader with
org.xbib.content.settings.PropertiesSettingsLoader,
org.xbib.content.json.JsonSettingsLoader;
} }

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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.IOException;
import java.io.OutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
@ -42,11 +42,6 @@ public abstract class AbstractXContentGenerator implements XContentGenerator {
generator.writeFieldName(name); generator.writeFieldName(name);
} }
@Override
public void writeFieldName(XContentString name) throws IOException {
generator.writeFieldName(name);
}
@Override @Override
public void writeString(String text) throws IOException { public void writeString(String text) throws IOException {
generator.writeString(text); generator.writeString(text);
@ -117,22 +112,11 @@ public abstract class AbstractXContentGenerator implements XContentGenerator {
generator.writeStringField(fieldName, value); generator.writeStringField(fieldName, value);
} }
@Override
public void writeStringField(XContentString fieldName, String value) throws IOException {
generator.writeFieldName(fieldName);
}
@Override @Override
public void writeBooleanField(String fieldName, boolean value) throws IOException { public void writeBooleanField(String fieldName, boolean value) throws IOException {
generator.writeBooleanField(fieldName, value); generator.writeBooleanField(fieldName, value);
} }
@Override
public void writeBooleanField(XContentString fieldName, boolean value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeBoolean(value);
}
@Override @Override
public void writeNullField(String fieldName) throws IOException { public void writeNullField(String fieldName) throws IOException {
generator.writeNullField(fieldName); generator.writeNullField(fieldName);
@ -143,104 +127,44 @@ public abstract class AbstractXContentGenerator implements XContentGenerator {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, int value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, long value) throws IOException { public void writeNumberField(String fieldName, long value) throws IOException {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, long value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, double value) throws IOException { public void writeNumberField(String fieldName, double value) throws IOException {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, double value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, float value) throws IOException { public void writeNumberField(String fieldName, float value) throws IOException {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, float value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, BigInteger value) throws IOException { public void writeNumberField(String fieldName, BigInteger value) throws IOException {
generator.writeFieldName(fieldName); generator.writeFieldName(fieldName);
generator.writeNumber(value); generator.writeNumber(value);
} }
@Override
public void writeNumberField(XContentString fieldName, BigInteger value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, BigDecimal value) throws IOException { public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeBinaryField(String fieldName, byte[] data) throws IOException { public void writeBinaryField(String fieldName, byte[] data) throws IOException {
generator.writeBinaryField(fieldName, data); generator.writeBinaryField(fieldName, data);
} }
@Override
public void writeBinaryField(XContentString fieldName, byte[] data) throws IOException {
generator.writeFieldName(fieldName);
generator.writeBinary(data);
}
@Override @Override
public void writeArrayFieldStart(String fieldName) throws IOException { public void writeArrayFieldStart(String fieldName) throws IOException {
generator.writeArrayFieldStart(fieldName); generator.writeArrayFieldStart(fieldName);
} }
@Override
public void writeArrayFieldStart(XContentString fieldName) throws IOException {
generator.writeFieldName(fieldName);
generator.writeStartArray();
}
@Override @Override
public void writeObjectFieldStart(String fieldName) throws IOException { public void writeObjectFieldStart(String fieldName) throws IOException {
generator.writeObjectFieldStart(fieldName); 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);
}
} }

View file

@ -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 org.xbib.datastructures.tiny.TinyMap;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;

View file

@ -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.io.BytesReference;
import org.xbib.content.json.JsonXContent;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
/**
*
*/
public class XContentHelper { public class XContentHelper {
private static final String UNKNOWN_FORMAT = "unknown format"; private static final String UNKNOWN_FORMAT = "unknown format";
@ -19,7 +18,7 @@ public class XContentHelper {
} }
public static XContentParser createParser(BytesReference bytes) throws IOException { 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) { if (content == null) {
throw new IOException(UNKNOWN_FORMAT); throw new IOException(UNKNOWN_FORMAT);
} }
@ -30,25 +29,24 @@ public class XContentHelper {
return XContentService.xContent(data, offset, length).createParser(data, offset, length); return XContentService.xContent(data, offset, length).createParser(data, offset, length);
} }
public static Map<String, Object> convertFromJsonToMap(Reader reader) { public static Map<String, Object> convertFromContentToMap(XContent content, Reader reader) {
try { try {
return JsonXContent.jsonContent().createParser(reader).mapOrderedAndClose(); return content.createParser(reader).mapOrderedAndClose();
} catch (IOException e) { } catch (IOException e) {
throw new IllegalArgumentException("Failed to parse content to map", e); throw new IllegalArgumentException("Failed to parse content to map", e);
} }
} }
public static Map<String, Object> convertToMap(String data) { public static Map<String, ?> convertToMap(String data) {
try { try {
XContent content = XContentService.xContent(data); return XContentService.xContent(data).createParser(data).mapOrderedAndClose();
return content.createParser(data).mapOrderedAndClose();
} catch (IOException e) { } catch (IOException e) {
throw new IllegalArgumentException("failed to parse content to map", e); throw new IllegalArgumentException("failed to parse content to map", e);
} }
} }
public static Map<String, Object> convertToMap(BytesReference bytes, boolean ordered) { public static Map<String, ?> convertToMap(BytesReference bytes, boolean ordered) {
XContent content = XContentService.xContent(bytes); XContent content = XContentService.xContent(bytes.toBytes(), 0, bytes.length());
if (content == null) { if (content == null) {
throw new IllegalArgumentException(UNKNOWN_FORMAT); throw new IllegalArgumentException(UNKNOWN_FORMAT);
} }
@ -64,12 +62,15 @@ public class XContentHelper {
} }
} }
public static Map<String, Object> convertToMap(byte[] data, boolean ordered) throws IOException { public static Map<String, ?> convertToMap(byte[] data, boolean ordered) throws IOException {
return convertToMap(data, 0, data.length, ordered); return convertToMap(data, 0, data.length, ordered);
} }
public static Map<String, Object> convertToMap(byte[] data, int offset, int length, boolean ordered) throws IOException { public static Map<String, ?> convertToMap(byte[] data, int offset, int length, boolean ordered) throws IOException {
XContent content = XContentService.xContent(data, offset, length); XContent content = XContentService.xContent(data, offset, length);
if (content == null) {
throw new IOException("no xcontent found");
}
XContentParser parser = content.createParser(data, offset, length); XContentParser parser = content.createParser(data, offset, length);
if (ordered) { if (ordered) {
return parser.mapOrderedAndClose(); return parser.mapOrderedAndClose();
@ -78,16 +79,14 @@ public class XContentHelper {
} }
} }
public static String convertToJson(BytesReference bytes, boolean reformatJson, boolean prettyPrint) throws IOException { public static String parseToString(BytesReference bytes,
XContent xContent = XContentService.xContent(bytes); boolean prettyPrint) throws IOException {
XContent xContent = XContentService.xContent(bytes.toBytes(), 0, bytes.length());
if (xContent == null) { if (xContent == null) {
throw new IOException(UNKNOWN_FORMAT); throw new IOException(UNKNOWN_FORMAT);
} }
if (xContent == JsonXContent.jsonContent() && !reformatJson) {
return bytes.toUtf8();
}
try (XContentParser parser = xContent.createParser(bytes.streamInput()); try (XContentParser parser = xContent.createParser(bytes.streamInput());
XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonContent())) { XContentBuilder builder = DefaultXContentBuilder.builder(xContent)) {
parser.nextToken(); parser.nextToken();
if (prettyPrint) { if (prettyPrint) {
builder.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 { throws IOException {
XContent xContent = XContentService.xContent(data, offset, length); 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); try (XContentParser parser = xContent.createParser(data, offset, length);
XContentBuilder builder = XContentBuilder.builder(JsonXContent.jsonContent())) { XContentBuilder builder = DefaultXContentBuilder.builder(xContent)) {
parser.nextToken(); parser.nextToken();
if (prettyPrint) { if (prettyPrint) {
builder.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(); XContentParser.Token t = parser.currentToken();
if (t == XContentParser.Token.FIELD_NAME) { if (t == XContentParser.Token.FIELD_NAME) {
generator.writeFieldName(parser.currentName()); 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()) { switch (parser.currentToken()) {
case START_OBJECT: case START_OBJECT:
generator.writeStartObject(); generator.writeStartObject();
@ -243,5 +244,4 @@ public class XContentHelper {
} }
return -1; return -1;
} }
} }

View file

@ -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.BytesArray;
import org.xbib.content.io.BytesReference;
import java.io.IOException; import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
@ -9,9 +10,6 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.ServiceLoader; import java.util.ServiceLoader;
/**
*
*/
public class XContentService { public class XContentService {
private static final Map<String, XContent> xcontents = new HashMap<>(); private static final Map<String, XContent> xcontents = new HashMap<>();
@ -26,20 +24,17 @@ public class XContentService {
} }
public static XContentBuilder builder(String name) throws IOException { public static XContentBuilder builder(String name) throws IOException {
return xcontents.containsKey(name) ? XContentBuilder.builder(xcontents.get(name)) : null; return xcontents.containsKey(name) ? DefaultXContentBuilder.builder(xcontents.get(name)) : null;
}
public static XContent xContent(byte[] data, int offset, int length) {
return xContent(new BytesArray(data, offset, length));
} }
public static XContent xContent(String charSequence) { 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()) { for (XContent xcontent : xcontents.values()) {
if (xcontent.isXContent(bytes)) { if (xcontent.isXContent(data, offset, length)) {
return xcontent; return xcontent;
} }
} }

View file

@ -1,4 +1,4 @@
/** /**
* Classes for content parsing and generating. * Classes for content parsing and generating.
*/ */
package org.xbib.content; package org.xbib.content.core;

View file

@ -1,4 +0,0 @@
/**
* Classes for JSON content.
*/
package org.xbib.content.json;

View file

@ -1,6 +1,7 @@
package org.xbib.content.settings; package org.xbib.content.properties;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import org.xbib.content.SettingsLoader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader; import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
@ -38,7 +39,6 @@ public class PropertiesSettingsLoader implements SettingsLoader {
} }
} }
@Override
public Map<String, String> load(BytesReference ref) throws IOException { public Map<String, String> load(BytesReference ref) throws IOException {
Properties props = new Properties(); Properties props = new Properties();
try (Reader reader = new InputStreamReader(ref.streamInput(), StandardCharsets.UTF_8)) { try (Reader reader = new InputStreamReader(ref.streamInput(), StandardCharsets.UTF_8)) {

View file

@ -0,0 +1,4 @@
/**
* Classes for properties-based content.
*/
package org.xbib.content.properties;

View file

@ -1,4 +1,4 @@
/** /**
* Utility classes for cotent. * Utility classes for content.
*/ */
package org.xbib.content.util; package org.xbib.content.util;

View file

@ -0,0 +1 @@
org.xbib.content.properties.PropertiesSettingsLoader

View file

@ -1,2 +0,0 @@
org.xbib.content.json.JsonSettingsLoader
org.xbib.content.settings.PropertiesSettingsLoader

View file

@ -1,4 +0,0 @@
/**
* Classes for testing settings parsing and generating.
*/
package org.xbib.content.settings;

View file

@ -1,4 +1,4 @@
/** /**
* Classes for testing content parsing and generating. * Classes for testing content parsing and generating.
*/ */
package org.xbib.content; package org.xbib.content.test;

View file

@ -1,5 +1,7 @@
dependencies { 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')}") { testImplementation("org.mockito:mockito-core:${project.property('mockito.version')}") {
exclude group: 'org.hamcrest' exclude group: 'org.hamcrest'
} }

View file

@ -1,9 +1,18 @@
import org.xbib.content.SettingsLoader;
module org.xbib.content.json { module org.xbib.content.json {
exports org.xbib.content.json;
exports org.xbib.content.json.diff; exports org.xbib.content.json.diff;
exports org.xbib.content.json.jackson; exports org.xbib.content.json.jackson;
exports org.xbib.content.json.mergepatch; exports org.xbib.content.json.mergepatch;
exports org.xbib.content.json.patch; exports org.xbib.content.json.patch;
exports org.xbib.content.json.pointer; 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.core;
requires transitive com.fasterxml.jackson.databind; 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;
} }

View file

@ -5,9 +5,9 @@ import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.core.DefaultXContentBuilder;
import org.xbib.content.XContentGenerator; import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.io.BytesReference;
import org.xbib.content.io.BytesStreamInput; import org.xbib.content.io.BytesStreamInput;
import java.io.IOException; import java.io.IOException;
@ -40,11 +40,11 @@ public class JsonXContent implements XContent {
} }
public static XContentBuilder contentBuilder() throws IOException { public static XContentBuilder contentBuilder() throws IOException {
return XContentBuilder.builder(jsonXContent); return DefaultXContentBuilder.builder(jsonXContent);
} }
public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException {
return XContentBuilder.builder(jsonXContent, outputStream); return DefaultXContentBuilder.builder(jsonXContent, outputStream);
} }
@Override @Override
@ -83,28 +83,23 @@ public class JsonXContent implements XContent {
return new JsonXContentParser(jsonFactory.createParser(data, offset, length)); return new JsonXContentParser(jsonFactory.createParser(data, offset, length));
} }
@Override
public XContentParser createParser(BytesReference bytes) throws IOException {
return createParser(bytes.streamInput());
}
@Override @Override
public XContentParser createParser(Reader reader) throws IOException { public XContentParser createParser(Reader reader) throws IOException {
return new JsonXContentParser(jsonFactory.createParser(reader)); return new JsonXContentParser(jsonFactory.createParser(reader));
} }
@Override @Override
public boolean isXContent(BytesReference bytes) { public boolean isXContent(byte[] bytes, int offset, int len) {
int length = Math.min(bytes.length(), 20); int length = Math.min(len, 20);
if (length == 0) { if (length == 0) {
return false; return false;
} }
byte first = bytes.get(0); byte first = bytes[offset];
if (first == '{') { if (first == '{') {
return true; return true;
} }
for (int i = 0; i < length; i++) { for (int i = offset; i < offset + length; i++) {
if (bytes.get(i) == '{') { if (bytes[i] == '{') {
return true; return true;
} }
} }

View file

@ -1,13 +1,13 @@
package org.xbib.content.json; package org.xbib.content.json;
import com.fasterxml.jackson.core.JsonGenerator; 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.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.XContentGenerator;
import org.xbib.content.XContentHelper; import org.xbib.content.core.XContentHelper;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.XContentString;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import java.io.IOException; import java.io.IOException;
@ -15,9 +15,6 @@ import java.io.OutputStream;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
/**
*
*/
public class JsonXContentGenerator extends AbstractXContentGenerator { public class JsonXContentGenerator extends AbstractXContentGenerator {
private final JsonGeneratorDelegate delegate; private final JsonGeneratorDelegate delegate;
@ -48,11 +45,6 @@ public class JsonXContentGenerator extends AbstractXContentGenerator {
delegate.writeRawField(fieldName, content, offset, length, outputStream); 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 @Override
public void writeValue(XContentBuilder builder) throws IOException { public void writeValue(XContentBuilder builder) throws IOException {
delegate.writeValue(builder); delegate.writeValue(builder);
@ -63,6 +55,15 @@ public class JsonXContentGenerator extends AbstractXContentGenerator {
delegate.copyCurrentStructure(parser); 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 @Override
public void flush() throws IOException { public void flush() throws IOException {
delegate.flush(); delegate.flush();
@ -117,11 +118,6 @@ public class JsonXContentGenerator extends AbstractXContentGenerator {
jsonGenerator.writeFieldName(name); jsonGenerator.writeFieldName(name);
} }
@Override
public void writeFieldName(XContentString name) throws IOException {
jsonGenerator.writeFieldName(name);
}
@Override @Override
public void writeString(String text) throws IOException { public void writeString(String text) throws IOException {
jsonGenerator.writeString(text); jsonGenerator.writeString(text);
@ -192,22 +188,11 @@ public class JsonXContentGenerator extends AbstractXContentGenerator {
jsonGenerator.writeStringField(fieldName, value); jsonGenerator.writeStringField(fieldName, value);
} }
@Override
public void writeStringField(XContentString fieldName, String value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
}
@Override @Override
public void writeBooleanField(String fieldName, boolean value) throws IOException { public void writeBooleanField(String fieldName, boolean value) throws IOException {
jsonGenerator.writeBooleanField(fieldName, value); jsonGenerator.writeBooleanField(fieldName, value);
} }
@Override
public void writeBooleanField(XContentString fieldName, boolean value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeBoolean(value);
}
@Override @Override
public void writeNullField(String fieldName) throws IOException { public void writeNullField(String fieldName) throws IOException {
jsonGenerator.writeNullField(fieldName); jsonGenerator.writeNullField(fieldName);
@ -218,101 +203,47 @@ public class JsonXContentGenerator extends AbstractXContentGenerator {
jsonGenerator.writeNumberField(fieldName, value); jsonGenerator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, int value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, long value) throws IOException { public void writeNumberField(String fieldName, long value) throws IOException {
jsonGenerator.writeNumberField(fieldName, value); jsonGenerator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, long value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, double value) throws IOException { public void writeNumberField(String fieldName, double value) throws IOException {
jsonGenerator.writeNumberField(fieldName, value); jsonGenerator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, double value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, float value) throws IOException { public void writeNumberField(String fieldName, float value) throws IOException {
jsonGenerator.writeNumberField(fieldName, value); jsonGenerator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, float value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, BigInteger value) throws IOException { public void writeNumberField(String fieldName, BigInteger value) throws IOException {
jsonGenerator.writeFieldName(fieldName); jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeNumber(value); jsonGenerator.writeNumber(value);
} }
@Override
public void writeNumberField(XContentString fieldName, BigInteger value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, BigDecimal value) throws IOException { public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
jsonGenerator.writeNumberField(fieldName, value); jsonGenerator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeNumber(value);
}
@Override @Override
public void writeBinaryField(String fieldName, byte[] data) throws IOException { public void writeBinaryField(String fieldName, byte[] data) throws IOException {
jsonGenerator.writeBinaryField(fieldName, data); jsonGenerator.writeBinaryField(fieldName, data);
} }
@Override
public void writeBinaryField(XContentString fieldName, byte[] data) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeBinary(data);
}
@Override @Override
public void writeArrayFieldStart(String fieldName) throws IOException { public void writeArrayFieldStart(String fieldName) throws IOException {
jsonGenerator.writeArrayFieldStart(fieldName); jsonGenerator.writeArrayFieldStart(fieldName);
} }
@Override
public void writeArrayFieldStart(XContentString fieldName) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeStartArray();
}
@Override @Override
public void writeObjectFieldStart(String fieldName) throws IOException { public void writeObjectFieldStart(String fieldName) throws IOException {
jsonGenerator.writeObjectFieldStart(fieldName); jsonGenerator.writeObjectFieldStart(fieldName);
} }
@Override
public void writeObjectFieldStart(XContentString fieldName) throws IOException {
jsonGenerator.writeFieldName(fieldName);
jsonGenerator.writeStartObject();
}
@Override @Override
public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException { public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException {
jsonGenerator.writeRaw(",\""); jsonGenerator.writeRaw(",\"");
@ -332,7 +263,6 @@ public class JsonXContentGenerator extends AbstractXContentGenerator {
outputStream.write(content, offset, length); outputStream.write(content, offset, length);
} }
@Override
public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException {
jsonGenerator.writeRaw(",\""); jsonGenerator.writeRaw(",\"");
jsonGenerator.writeRaw(fieldName); jsonGenerator.writeRaw(fieldName);
@ -349,7 +279,10 @@ public class JsonXContentGenerator extends AbstractXContentGenerator {
@Override @Override
public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException { public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException {
flush(); flush();
builder.bytes().streamOutput(outputStream); if (builder instanceof DefaultXContentBuilder) {
DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
xContentBuilder.bytes().streamOutput(outputStream);
}
} }
@Override @Override

View file

@ -2,7 +2,7 @@ package org.xbib.content.json;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; 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.XContent;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
@ -10,9 +10,6 @@ import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.BigInteger; import java.math.BigInteger;
/**
*
*/
public class JsonXContentParser extends AbstractXContentParser { public class JsonXContentParser extends AbstractXContentParser {
protected final JsonParser parser; protected final JsonParser parser;

View file

@ -0,0 +1 @@
org.xbib.content.json.JsonSettingsLoader

View file

@ -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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.xbib.content.json.JsonXContent.contentBuilder; import static org.xbib.content.json.JsonXContent.contentBuilder;
import org.junit.jupiter.api.Test; 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 org.xbib.content.json.JsonXContent;
import java.io.IOException; import java.io.IOException;

View file

@ -1,8 +1,8 @@
package org.xbib.content; package org.xbib.content.json;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.json.JsonXContent; import org.xbib.content.XContentParser;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;
import java.util.logging.Level; import java.util.logging.Level;

View file

@ -2,4 +2,6 @@ dependencies {
implementation project(':content-core') implementation project(':content-core')
implementation project(':content-resource') implementation project(':content-resource')
implementation project(':content-xml') implementation project(':content-xml')
implementation project(':content-json')
implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${project.property('jackson.version')}"
} }

View file

@ -13,4 +13,5 @@ module org.xbib.content.rdf {
requires transitive org.xbib.content.core; requires transitive org.xbib.content.core;
requires transitive org.xbib.content.resource; requires transitive org.xbib.content.resource;
requires transitive org.xbib.content.xml; requires transitive org.xbib.content.xml;
requires transitive org.xbib.content.json;
} }

View file

@ -1,6 +1,7 @@
package org.xbib.content.rdf; package org.xbib.content.rdf;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.core.DefaultXContentBuilder;
import org.xbib.content.json.JsonXContent; import org.xbib.content.json.JsonXContent;
import org.xbib.content.rdf.internal.DefaultAnonymousResource; import org.xbib.content.rdf.internal.DefaultAnonymousResource;
import org.xbib.content.rdf.internal.DefaultResource; import org.xbib.content.rdf.internal.DefaultResource;
@ -101,7 +102,8 @@ public class RdfXContentGenerator<P extends RdfXContentParams> implements RdfCon
return; return;
} }
flushed = true; flushed = true;
builder = XContentBuilder.builder(JsonXContent.jsonContent(), out); // JSON output
builder = DefaultXContentBuilder.builder(JsonXContent.jsonContent(), out);
builder.startObject(); builder.startObject();
build(this.resource); build(this.resource);
builder.endObject(); builder.endObject();

View file

@ -0,0 +1,5 @@
dependencies {
api project(':content-core')
implementation "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}"
testImplementation project(":content-json")
}

View file

@ -0,0 +1,5 @@
module org.xbib.content.settings {
exports org.xbib.content.settings;
requires org.xbib.content.core;
}

View file

@ -1,7 +1,9 @@
package org.xbib.content.settings; package org.xbib.content.settings;
import org.xbib.content.SettingsLoader;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.core.DefaultXContentBuilder;
import org.xbib.content.XContentGenerator; import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
@ -27,15 +29,9 @@ public abstract class AbstractSettingsLoader implements SettingsLoader {
} }
} }
public Map<String, String> load(BytesReference bytesReference) throws IOException {
try (XContentParser parser = content().createParser(bytesReference)) {
return load(parser);
}
}
@Override @Override
public Map<String, String> load(Map<String, Object> map) throws IOException { public Map<String, String> load(Map<String, Object> map) throws IOException {
XContentBuilder builder = XContentBuilder.builder(content()); XContentBuilder builder = DefaultXContentBuilder.builder(content());
builder.map(map); builder.map(map);
return load(builder.string()); return load(builder.string());
} }
@ -53,7 +49,7 @@ public abstract class AbstractSettingsLoader implements SettingsLoader {
} }
public String flatMapAsString(BytesReference bytesReference) throws IOException { public String flatMapAsString(BytesReference bytesReference) throws IOException {
try (XContentParser parser = content().createParser(bytesReference); try (XContentParser parser = content().createParser(bytesReference.toBytes());
BytesStreamOutput bytesStreamOutput = new BytesStreamOutput(); BytesStreamOutput bytesStreamOutput = new BytesStreamOutput();
XContentGenerator generator = content().createGenerator(bytesStreamOutput)) { XContentGenerator generator = content().createGenerator(bytesStreamOutput)) {
return flatMapAsString(parser, bytesStreamOutput, generator); return flatMapAsString(parser, bytesStreamOutput, generator);

View file

@ -1,8 +1,6 @@
package org.xbib.content.settings; package org.xbib.content.settings;
import static org.xbib.content.util.unit.ByteSizeValue.parseBytesSizeValue; import org.xbib.content.SettingsLoader;
import static org.xbib.content.util.unit.TimeValue.parseTimeValue;
import org.xbib.content.json.JsonSettingsLoader;
import org.xbib.datastructures.tiny.TinyMap; import org.xbib.datastructures.tiny.TinyMap;
import org.xbib.content.util.unit.ByteSizeValue; import org.xbib.content.util.unit.ByteSizeValue;
import org.xbib.content.util.unit.TimeValue; import org.xbib.content.util.unit.TimeValue;
@ -252,11 +250,11 @@ public class Settings implements AutoCloseable {
} }
public TimeValue getAsTime(String setting, TimeValue defaultValue) { 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) { public ByteSizeValue getAsBytesSize(String setting, ByteSizeValue defaultValue) {
return parseBytesSizeValue(get(setting), defaultValue); return ByteSizeValue.parseBytesSizeValue(get(setting), defaultValue);
} }
public String[] getAsArray(String settingPrefix) { public String[] getAsArray(String settingPrefix) {
@ -627,21 +625,6 @@ public class Settings implements AutoCloseable {
return this; return this;
} }
/**
* Loads settings from a map.
* @param map map
* @return builder
*/
public Builder loadFromMap(Map<String, Object> 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. * Loads settings from an URL.
* @param url url * @param url url

View file

@ -1,6 +1,6 @@
package org.xbib.content.settings; package org.xbib.content.settings;
import org.xbib.content.json.JsonSettingsLoader; import org.xbib.content.SettingsLoader;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; 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 loader;
} }
} }
return new JsonSettingsLoader(); throw new UnsupportedOperationException();
} }
} }

View file

@ -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.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test; 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.BytesArray;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import org.xbib.content.json.JsonSettingsLoader; import org.xbib.content.json.JsonSettingsLoader;
import org.xbib.content.json.JsonXContent; import org.xbib.content.json.JsonXContent;
import org.xbib.content.settings.Settings;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
@ -82,20 +84,25 @@ public class SettingsTest {
} }
@Test @Test
public void testMapForSettings() { public void testMapForSettings() throws IOException {
Map<String, Object> map = new HashMap<>(); Map<String, String> map = new HashMap<>();
map.put("hello", "world"); map.put("hello", "world");
Map<String, Object> settingsMap = new HashMap<>(); Map<String, Object> settingsMap = new HashMap<>();
settingsMap.put("map", map); 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()); assertEquals("{map.hello=world}", settings.getAsMap().toString());
} }
@Test @Test
public void testMapSettingsFromReader() { public void testMapSettingsFromReader() throws IOException {
StringReader reader = new StringReader("{\"map\":{\"hello\":\"world\"}}"); StringReader reader = new StringReader("{\"map\":{\"hello\":\"world\"}}");
Map<String, Object> spec = XContentHelper.convertFromJsonToMap(reader); Map<String, Object> map = XContentHelper.convertFromContentToMap(JsonXContent.jsonContent(), reader);
Settings settings = Settings.settingsBuilder().loadFromMap(spec).build(); SettingsLoader settingsLoader = new JsonSettingsLoader();
Settings settings = Settings.settingsBuilder()
.put(settingsLoader.load(map))
.build();
assertEquals("{map.hello=world}", settings.getAsMap().toString()); assertEquals("{map.hello=world}", settings.getAsMap().toString());
} }

View file

@ -1,4 +1,4 @@
dependencies { dependencies {
implementation project(':content-core') api project(':content-core')
api "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:${project.property('jackson.version')}" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:${project.property('jackson.version')}"
} }

View file

@ -6,10 +6,9 @@ import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import com.fasterxml.jackson.dataformat.smile.SmileGenerator; import com.fasterxml.jackson.dataformat.smile.SmileGenerator;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.core.DefaultXContentBuilder;
import org.xbib.content.XContentGenerator; import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.io.BytesReference;
import org.xbib.content.json.JsonXContentParser;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -24,6 +23,7 @@ import java.nio.charset.StandardCharsets;
public class SmileXContent implements XContent { public class SmileXContent implements XContent {
private static final SmileXContent smileXContent; private static final SmileXContent smileXContent;
private static final SmileFactory smileFactory; private static final SmileFactory smileFactory;
static { static {
@ -49,11 +49,11 @@ public class SmileXContent implements XContent {
} }
public static XContentBuilder contentBuilder() throws IOException { public static XContentBuilder contentBuilder() throws IOException {
return XContentBuilder.builder(smileXContent); return DefaultXContentBuilder.builder(smileXContent);
} }
public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException {
return XContentBuilder.builder(smileXContent, outputStream); return DefaultXContentBuilder.builder(smileXContent, outputStream);
} }
@Override @Override
@ -66,10 +66,9 @@ public class SmileXContent implements XContent {
return new SmileXContentGenerator(smileFactory.createGenerator(os, JsonEncoding.UTF8)); return new SmileXContentGenerator(smileFactory.createGenerator(os, JsonEncoding.UTF8));
} }
@Override @Override
public XContentGenerator createGenerator(Writer writer) throws IOException { public XContentGenerator createGenerator(Writer writer) throws IOException {
return new SmileXContentGenerator(smileFactory.createGenerator(writer)); throw new UnsupportedOperationException(); // SMILE is binary
} }
@Override @Override
@ -93,24 +92,19 @@ public class SmileXContent implements XContent {
return new SmileXContentParser(smileFactory.createParser(data, offset, length)); return new SmileXContentParser(smileFactory.createParser(data, offset, length));
} }
@Override
public XContentParser createParser(BytesReference bytes) throws IOException {
return createParser(bytes.streamInput());
}
@Override @Override
public XContentParser createParser(Reader reader) throws IOException { public XContentParser createParser(Reader reader) throws IOException {
return new JsonXContentParser(smileFactory.createParser(reader)); throw new UnsupportedOperationException(); // SMILE is binary
} }
@Override @Override
public boolean isXContent(BytesReference bytes) { public boolean isXContent(byte[] bytes, int offset, int len) {
int length = bytes.length() < 20 ? bytes.length() : 20; int length = Math.min(len, 20);
if (length == 0) { if (length == 0) {
return false; return false;
} }
byte first = bytes.get(0); byte first = bytes[offset];
return length > 2 && first == SmileConstants.HEADER_BYTE_1 && bytes.get(1) == SmileConstants.HEADER_BYTE_2 return length > 2 && first == SmileConstants.HEADER_BYTE_1 && bytes[offset + 1] == SmileConstants.HEADER_BYTE_2
&& bytes.get(2) == SmileConstants.HEADER_BYTE_3; && bytes[offset + 2] == SmileConstants.HEADER_BYTE_3;
} }
} }

View file

@ -1,26 +1,39 @@
package org.xbib.content.smile; package org.xbib.content.smile;
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.dataformat.smile.SmileGenerator;
import com.fasterxml.jackson.dataformat.smile.SmileParser; import com.fasterxml.jackson.dataformat.smile.SmileParser;
import org.xbib.content.XContent; 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.io.BytesReference;
import org.xbib.content.json.JsonXContentGenerator;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
/** public class SmileXContentGenerator extends AbstractXContentGenerator {
*
*/
public class SmileXContentGenerator extends JsonXContentGenerator {
public SmileXContentGenerator(JsonGenerator generator) { private final SmileGeneratorDelegate delegate;
super(generator);
public SmileXContentGenerator(SmileGenerator generator) {
this.delegate = new SmileGeneratorDelegate(generator);
super.setGenerator(delegate);
} }
@Override @Override
public XContent content() { public XContent content() {
return SmileXContent.smileContent(); return delegate.content();
}
@Override
public void usePrettyPrint() {
delegate.usePrettyPrint();
} }
@Override @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 @Override
public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream bos) throws IOException { public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream bos) throws IOException {
writeFieldName(fieldName); writeFieldName(fieldName);
@ -49,4 +53,266 @@ public class SmileXContentGenerator extends JsonXContentGenerator {
((JsonGenerator) generator).copyCurrentStructure(parser); ((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();
}
}
} }

View file

@ -1,16 +1,21 @@
package org.xbib.content.smile; package org.xbib.content.smile;
import com.fasterxml.jackson.core.JsonParser; 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.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 AbstractXContentParser {
*
*/
public class SmileXContentParser extends JsonXContentParser {
public SmileXContentParser(JsonParser parser) { private final SmileParser parser;
super(parser);
public SmileXContentParser(SmileParser parser) {
this.parser = parser;
} }
@Override @Override
@ -18,4 +23,166 @@ public class SmileXContentParser extends JsonXContentParser {
return SmileXContent.smileContent(); 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 + "]");
}
} }

View file

@ -1,6 +1,7 @@
dependencies { dependencies {
implementation project(':content-core') implementation project(':content-core')
implementation project(':content-resource') implementation project(':content-resource')
api "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${project.property('jackson.version')}" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-xml:${project.property('jackson.version')}"
implementation "com.fasterxml.woodstox:woodstox-core:${project.property('woodstox.version')}" runtimeOnly "com.fasterxml.woodstox:woodstox-core:${project.property('woodstox.version')}"
testImplementation project(':content-json') // for XContentHelper reading JSON
} }

View file

@ -1,3 +1,4 @@
import org.xbib.content.XContent;
module org.xbib.content.xml { module org.xbib.content.xml {
exports org.xbib.content.xml; exports org.xbib.content.xml;
exports org.xbib.content.xml.json; 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.core;
requires transitive org.xbib.content.resource; requires transitive org.xbib.content.resource;
requires transitive com.fasterxml.jackson.dataformat.xml; requires transitive com.fasterxml.jackson.dataformat.xml;
provides org.xbib.content.XContent with provides XContent with org.xbib.content.xml.XmlXContent;
org.xbib.content.xml.XmlXContent;
} }

View file

@ -4,9 +4,9 @@ import com.fasterxml.jackson.core.JsonEncoding;
import com.fasterxml.jackson.dataformat.xml.XmlFactory; import com.fasterxml.jackson.dataformat.xml.XmlFactory;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.core.DefaultXContentBuilder;
import org.xbib.content.XContentGenerator; import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.io.BytesReference;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -36,33 +36,45 @@ public class XmlXContent implements XContent {
} }
public static XContentBuilder contentBuilder() throws IOException { public static XContentBuilder contentBuilder() throws IOException {
XContentBuilder builder = XContentBuilder.builder(xmlXContent()); XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent());
if (builder.generator() instanceof XmlXContentGenerator) { if (builder instanceof DefaultXContentBuilder) {
((XmlXContentGenerator) builder.generator()).setParams(XmlXParams.getDefaultParams()); DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
if (xContentBuilder.generator() instanceof XmlXContentGenerator) {
((XmlXContentGenerator) xContentBuilder.generator()).setParams(XmlXParams.getDefaultParams());
}
} }
return builder; return builder;
} }
public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException {
XContentBuilder builder = XContentBuilder.builder(xmlXContent(), outputStream); XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent(), outputStream);
if (builder.generator() instanceof XmlXContentGenerator) { if (builder instanceof DefaultXContentBuilder) {
((XmlXContentGenerator) builder.generator()).setParams(XmlXParams.getDefaultParams()); DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
if (xContentBuilder.generator() instanceof XmlXContentGenerator) {
((XmlXContentGenerator) xContentBuilder.generator()).setParams(XmlXParams.getDefaultParams());
}
} }
return builder; return builder;
} }
public static XContentBuilder contentBuilder(XmlXParams params) throws IOException { public static XContentBuilder contentBuilder(XmlXParams params) throws IOException {
XContentBuilder builder = XContentBuilder.builder(xmlXContent(params.getXmlFactory())); XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent(params.getXmlFactory()));
if (builder.generator() instanceof XmlXContentGenerator) { if (builder instanceof DefaultXContentBuilder) {
((XmlXContentGenerator) builder.generator()).setParams(params); DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
if (xContentBuilder.generator() instanceof XmlXContentGenerator) {
((XmlXContentGenerator) xContentBuilder.generator()).setParams(params);
}
} }
return builder; return builder;
} }
public static XContentBuilder contentBuilder(XmlXParams params, OutputStream outputStream) throws IOException { public static XContentBuilder contentBuilder(XmlXParams params, OutputStream outputStream) throws IOException {
XContentBuilder builder = XContentBuilder.builder(xmlXContent(params.getXmlFactory()), outputStream); XContentBuilder builder = DefaultXContentBuilder.builder(xmlXContent(params.getXmlFactory()), outputStream);
if (builder.generator() instanceof XmlXContentGenerator) { if (builder instanceof DefaultXContentBuilder) {
((XmlXContentGenerator) builder.generator()).setParams(params); DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
if (xContentBuilder.generator() instanceof XmlXContentGenerator) {
((XmlXContentGenerator) xContentBuilder.generator()).setParams(params);
}
} }
return builder; return builder;
} }
@ -123,17 +135,12 @@ public class XmlXContent implements XContent {
} }
@Override @Override
public XContentParser createParser(BytesReference bytes) throws IOException { public boolean isXContent(byte[] bytes, int offset, int len) {
return createParser(bytes.streamInput()); int length = Math.min(len, 20);
}
@Override
public boolean isXContent(BytesReference bytes) {
int length = bytes.length() < 20 ? bytes.length() : 20;
if (length == 0) { if (length == 0) {
return false; return false;
} }
byte first = bytes.get(0); byte first = bytes[offset];
return length > 2 && first == '<' && bytes.get(1) == '?' && bytes.get(2) == 'x'; return length > 2 && first == '<' && bytes[offset + 1] == '?' && bytes[offset + 2] == 'x';
} }
} }

View file

@ -2,13 +2,13 @@ package org.xbib.content.xml;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.dataformat.xml.ser.ToXmlGenerator; 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.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.XContentGenerator;
import org.xbib.content.XContentHelper; import org.xbib.content.core.XContentHelper;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.XContentString;
import org.xbib.content.io.BytesReference; import org.xbib.content.io.BytesReference;
import org.xbib.content.xml.util.ISO9075; import org.xbib.content.xml.util.ISO9075;
import org.xbib.content.xml.util.XMLUtil; import org.xbib.content.xml.util.XMLUtil;
@ -29,7 +29,7 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
private final XmlXContentGeneratorDelegate delegate; private final XmlXContentGeneratorDelegate delegate;
private XmlXParams params; private final XmlXParams params;
public XmlXContentGenerator(ToXmlGenerator generator) { public XmlXContentGenerator(ToXmlGenerator generator) {
this(generator, XmlXParams.getDefaultParams()); this(generator, XmlXParams.getDefaultParams());
@ -71,11 +71,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
delegate.writeFieldName(name); delegate.writeFieldName(name);
} }
@Override
public void writeFieldName(XContentString name) throws IOException {
delegate.writeFieldName(name);
}
@Override @Override
public void writeString(String text) throws IOException { public void writeString(String text) throws IOException {
delegate.writeString(text); delegate.writeString(text);
@ -90,11 +85,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
delegate.writeRawField(fieldName, content, outputStream); delegate.writeRawField(fieldName, content, outputStream);
} }
@Override
public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException {
delegate.writeRawField(fieldName, content, outputStream);
}
@Override @Override
public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream)
throws IOException { throws IOException {
@ -106,6 +96,15 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
delegate.writeValue(builder); 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 @Override
public void copyCurrentStructure(XContentParser parser) throws IOException { public void copyCurrentStructure(XContentParser parser) throws IOException {
delegate.copyCurrentStructure(parser); delegate.copyCurrentStructure(parser);
@ -195,11 +194,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
writeFieldNameWithNamespace(name); writeFieldNameWithNamespace(name);
} }
@Override
public void writeFieldName(XContentString name) throws IOException {
writeFieldNameWithNamespace(name);
}
@Override @Override
public void writeString(String text) throws IOException { public void writeString(String text) throws IOException {
generator.writeString(XMLUtil.sanitize(text)); generator.writeString(XMLUtil.sanitize(text));
@ -271,23 +265,10 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
generator.writeStringField(fieldName, value); 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 { public void writeBooleanField(String fieldName, boolean value) throws IOException {
generator.writeBooleanField(fieldName, value); generator.writeBooleanField(fieldName, value);
} }
@Override
public void writeBooleanField(XContentString fieldName, boolean value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeBoolean(value);
}
@Override @Override
public void writeNullField(String fieldName) throws IOException { public void writeNullField(String fieldName) throws IOException {
generator.writeNullField(fieldName); generator.writeNullField(fieldName);
@ -298,102 +279,48 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, int value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, long value) throws IOException { public void writeNumberField(String fieldName, long value) throws IOException {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, long value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, double value) throws IOException { public void writeNumberField(String fieldName, double value) throws IOException {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, double value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, float value) throws IOException { public void writeNumberField(String fieldName, float value) throws IOException {
generator.writeNumberField(fieldName, value); generator.writeNumberField(fieldName, value);
} }
@Override
public void writeNumberField(XContentString fieldName, float value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, BigInteger value) throws IOException { public void writeNumberField(String fieldName, BigInteger value) throws IOException {
generator.writeFieldName(fieldName); generator.writeFieldName(fieldName);
generator.writeNumber(value); generator.writeNumber(value);
} }
@Override
public void writeNumberField(XContentString fieldName, BigInteger value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeNumberField(String fieldName, BigDecimal value) throws IOException { public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
generator.writeFieldName(fieldName); generator.writeFieldName(fieldName);
generator.writeNumber(value); generator.writeNumber(value);
} }
@Override
public void writeNumberField(XContentString fieldName, BigDecimal value) throws IOException {
generator.writeFieldName(fieldName);
generator.writeNumber(value);
}
@Override @Override
public void writeBinaryField(String fieldName, byte[] data) throws IOException { public void writeBinaryField(String fieldName, byte[] data) throws IOException {
generator.writeBinaryField(fieldName, data); generator.writeBinaryField(fieldName, data);
} }
@Override
public void writeBinaryField(XContentString fieldName, byte[] data) throws IOException {
generator.writeFieldName(fieldName);
generator.writeBinary(data);
}
@Override @Override
public void writeArrayFieldStart(String fieldName) throws IOException { public void writeArrayFieldStart(String fieldName) throws IOException {
generator.writeArrayFieldStart(fieldName); generator.writeArrayFieldStart(fieldName);
} }
@Override
public void writeArrayFieldStart(XContentString fieldName) throws IOException {
generator.writeFieldName(fieldName);
generator.writeStartArray();
}
@Override @Override
public void writeObjectFieldStart(String fieldName) throws IOException { public void writeObjectFieldStart(String fieldName) throws IOException {
generator.writeObjectFieldStart(fieldName); generator.writeObjectFieldStart(fieldName);
} }
@Override
public void writeObjectFieldStart(XContentString fieldName) throws IOException {
generator.writeFieldName(fieldName);
generator.writeStartObject();
}
@Override @Override
public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException { public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException {
writeFieldNameWithNamespace(fieldName); writeFieldNameWithNamespace(fieldName);
@ -403,7 +330,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
} }
} }
@Override
public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException { public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException {
writeFieldNameWithNamespace(fieldName); writeFieldNameWithNamespace(fieldName);
try (JsonParser parser = params.getXmlFactory().createParser(content.streamInput())) { try (JsonParser parser = params.getXmlFactory().createParser(content.streamInput())) {
@ -430,7 +356,10 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
@Override @Override
public void copy(XContentBuilder builder, OutputStream bos) throws IOException { public void copy(XContentBuilder builder, OutputStream bos) throws IOException {
flush(); flush();
builder.bytes().streamOutput(bos); if (builder instanceof DefaultXContentBuilder) {
DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
xContentBuilder.bytes().streamOutput(bos);
}
} }
@Override @Override
@ -469,10 +398,6 @@ public class XmlXContentGenerator extends AbstractXContentGenerator {
generator.writeFieldName(qname.getLocalPart()); generator.writeFieldName(qname.getLocalPart());
} }
private void writeFieldNameWithNamespace(XContentString name) throws IOException {
writeFieldNameWithNamespace(name.getValue());
}
private QName toQualifiedName(NamespaceContext context, String string) { private QName toQualifiedName(NamespaceContext context, String string) {
String name = string; String name = string;
if (name.startsWith("_") || name.startsWith("@")) { if (name.startsWith("_") || name.startsWith("@")) {

View file

@ -3,15 +3,12 @@ package org.xbib.content.xml;
import org.xbib.content.XContent; import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.XContentService; import org.xbib.content.core.XContentService;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.util.Map; import java.util.Map;
/**
*
*/
public class XmlXContentHelper { public class XmlXContentHelper {
private XmlXContentHelper() { private XmlXContentHelper() {

View file

@ -2,7 +2,7 @@ package org.xbib.content.xml;
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken; 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.XContent;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;

View file

@ -1,9 +1,10 @@
package org.xbib.content.xml; package org.xbib.content.xml;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.xbib.content.xml.XmlXContent.contentBuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.XContentHelper; import org.xbib.content.core.XContentHelper;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -25,7 +26,7 @@ public class XContentXmlBuilderTest {
@Test @Test
public void testEmpty() throws Exception { public void testEmpty() throws Exception {
QName root = new QName("root"); QName root = new QName("root");
XContentBuilder builder = XmlXContent.contentBuilder(new XmlXParams(root)); XContentBuilder builder = contentBuilder(new XmlXParams(root));
builder.startObject().field("Hello", "World").endObject(); builder.startObject().field("Hello", "World").endObject();
assertEquals("<root><Hello>World</Hello></root>", builder.string()); assertEquals("<root><Hello>World</Hello></root>", builder.string());
} }
@ -34,14 +35,14 @@ public class XContentXmlBuilderTest {
public void testContextNamespace() throws Exception { public void testContextNamespace() throws Exception {
QName root = new QName("root"); QName root = new QName("root");
XmlNamespaceContext context = XmlNamespaceContext.newInstance(); 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(); builder.startObject().field("Hello", "World").endObject();
assertEquals("<root><Hello>World</Hello></root>", builder.string()); assertEquals("<root><Hello>World</Hello></root>", builder.string());
} }
@Test @Test
public void testXml() throws Exception { public void testXml() throws Exception {
XContentBuilder builder = XmlXContent.contentBuilder(); XContentBuilder builder = contentBuilder();
builder.startObject().field("Hello", "World").endObject(); builder.startObject().field("Hello", "World").endObject();
assertEquals("<root><Hello>World</Hello></root>", builder.string()); assertEquals("<root><Hello>World</Hello></root>", builder.string());
} }
@ -49,7 +50,7 @@ public class XContentXmlBuilderTest {
@Test @Test
public void testXmlParams() throws Exception { public void testXmlParams() throws Exception {
XmlXParams params = new XmlXParams(); XmlXParams params = new XmlXParams();
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject().field("Hello", "World").endObject(); builder.startObject().field("Hello", "World").endObject();
assertEquals("<root><Hello>World</Hello></root>", builder.string()); assertEquals("<root><Hello>World</Hello></root>", builder.string());
} }
@ -58,7 +59,7 @@ public class XContentXmlBuilderTest {
public void testXmlObject() throws Exception { public void testXmlObject() throws Exception {
QName root = XmlXParams.getDefaultParams().getRoot(); QName root = XmlXParams.getDefaultParams().getRoot();
XmlXParams params = new XmlXParams(root); XmlXParams params = new XmlXParams(root);
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject() builder.startObject()
.startObject("author") .startObject("author")
.field("creator", "John Doe") .field("creator", "John Doe")
@ -78,7 +79,7 @@ public class XContentXmlBuilderTest {
public void testXmlAttributes() throws Exception { public void testXmlAttributes() throws Exception {
QName root = XmlXParams.getDefaultParams().getRoot(); QName root = XmlXParams.getDefaultParams().getRoot();
XmlXParams params = new XmlXParams(root); XmlXParams params = new XmlXParams(root);
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject() builder.startObject()
.startObject("author") .startObject("author")
.field("@name", "John Doe") .field("@name", "John Doe")
@ -92,7 +93,7 @@ public class XContentXmlBuilderTest {
public void testXmlArrayOfValues() throws Exception { public void testXmlArrayOfValues() throws Exception {
QName root = XmlXParams.getDefaultParams().getRoot(); QName root = XmlXParams.getDefaultParams().getRoot();
XmlXParams params = new XmlXParams(root); XmlXParams params = new XmlXParams(root);
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject() builder.startObject()
.array("author", "John Doe", "Joe Smith") .array("author", "John Doe", "Joe Smith")
.endObject(); .endObject();
@ -103,7 +104,7 @@ public class XContentXmlBuilderTest {
public void testXmlArrayOfObjects() throws Exception { public void testXmlArrayOfObjects() throws Exception {
QName root = XmlXParams.getDefaultParams().getRoot(); QName root = XmlXParams.getDefaultParams().getRoot();
XmlXParams params = new XmlXParams(root); XmlXParams params = new XmlXParams(root);
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject() builder.startObject()
.startArray("author") .startArray("author")
.startObject() .startObject()
@ -132,7 +133,7 @@ public class XContentXmlBuilderTest {
ByteArrayOutputStream out = new ByteArrayOutputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream();
copy(in, out); copy(in, out);
byte[] buf = out.toByteArray(); byte[] buf = out.toByteArray();
Map<String, Object> map = XContentHelper.convertToMap(buf, false); Map<String, ?> map = XContentHelper.convertToMap(buf, false);
assertEquals("{dc:description={xbib:creatorDescription=Otis Gospodnetić ; Erik Hatcher, " assertEquals("{dc:description={xbib:creatorDescription=Otis Gospodnetić ; Erik Hatcher, "
+ "dcterms:extent=XXXIV, 421 S. : Ill.}, dc:language={xbib:languageISO6392b=eng, " + "dcterms:extent=XXXIV, 421 S. : Ill.}, dc:language={xbib:languageISO6392b=eng, "
+ "xbib:languageISO6391=en}, dc:subject={xbib:rswk={xbib:subjectTopic=Lucene, " + "xbib:languageISO6391=en}, dc:subject={xbib:rswk={xbib:subjectTopic=Lucene, "
@ -184,7 +185,7 @@ public class XContentXmlBuilderTest {
@Test @Test
public void testInvalidWhiteSpaceCharacter() throws Exception { public void testInvalidWhiteSpaceCharacter() throws Exception {
QName root = new QName("root"); 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(); builder.startObject().field("Hello", "World\u001b").endObject();
assertEquals("<root><Hello>World</Hello></root>", builder.string()); assertEquals("<root><Hello>World</Hello></root>", builder.string());
} }
@ -194,7 +195,7 @@ public class XContentXmlBuilderTest {
XmlNamespaceContext context = XmlNamespaceContext.newInstance(); XmlNamespaceContext context = XmlNamespaceContext.newInstance();
context.addNamespace("", ""); context.addNamespace("", "");
QName root = new QName("root"); 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(); builder.startObject().field("Hello", "World").endObject();
assertEquals("<root><Hello>World</Hello></root>", builder.string()); assertEquals("<root><Hello>World</Hello></root>", builder.string());
} }

View file

@ -1,6 +1,7 @@
package org.xbib.content.xml; package org.xbib.content.xml;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.xbib.content.xml.XmlXContent.contentBuilder;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.xml.transform.StylesheetTransformer; import org.xbib.content.xml.transform.StylesheetTransformer;
@ -24,7 +25,7 @@ public class XmlNamespaceContextTest {
XmlNamespaceContext.newInstance("org/xbib/content/resource/namespace", XmlNamespaceContext.newInstance("org/xbib/content/resource/namespace",
Locale.getDefault(), StylesheetTransformer.class.getClassLoader()); Locale.getDefault(), StylesheetTransformer.class.getClassLoader());
XmlXParams params = new XmlXParams(context); XmlXParams params = new XmlXParams(context);
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject() builder.startObject()
.field("dc:creator", "John Doe") .field("dc:creator", "John Doe")
.endObject(); .endObject();
@ -42,7 +43,7 @@ public class XmlNamespaceContextTest {
XmlNamespaceContext context = XmlNamespaceContext.newInstance(); XmlNamespaceContext context = XmlNamespaceContext.newInstance();
context.addNamespace("abc", "http://localhost"); context.addNamespace("abc", "http://localhost");
XmlXParams params = new XmlXParams(root, context); XmlXParams params = new XmlXParams(root, context);
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject() builder.startObject()
.field("abc:creator", "John Doe") .field("abc:creator", "John Doe")
.endObject(); .endObject();
@ -57,7 +58,7 @@ public class XmlNamespaceContextTest {
context.addNamespace("", "http://localhost"); context.addNamespace("", "http://localhost");
context.addNamespace("abc", "http://content"); context.addNamespace("abc", "http://content");
XmlXParams params = new XmlXParams(root, context); XmlXParams params = new XmlXParams(root, context);
XContentBuilder builder = XmlXContent.contentBuilder(params); XContentBuilder builder = contentBuilder(params);
builder.startObject() builder.startObject()
.field("creator", "John Doe") .field("creator", "John Doe")
.endObject(); .endObject();

View file

@ -1,5 +1,6 @@
dependencies { dependencies {
api project(':content-core') api project(':content-core')
api "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}" api project(':content-settings')
api "org.yaml:snakeyaml:${project.property('snakeyaml.version')}" implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${project.property('jackson.version')}"
implementation "org.yaml:snakeyaml:${project.property('snakeyaml.version')}"
} }

View file

@ -1,9 +1,11 @@
import org.xbib.content.SettingsLoader;
import org.xbib.content.XContent;
module org.xbib.content.yaml { module org.xbib.content.yaml {
exports org.xbib.content.yaml; exports org.xbib.content.yaml;
requires transitive org.xbib.content.core; requires transitive org.xbib.content.core;
requires transitive org.xbib.content.settings;
requires transitive com.fasterxml.jackson.dataformat.yaml; requires transitive com.fasterxml.jackson.dataformat.yaml;
provides org.xbib.content.XContent with provides XContent with org.xbib.content.yaml.YamlXContent;
org.xbib.content.yaml.YamlXContent; provides SettingsLoader with org.xbib.content.yaml.YamlSettingsLoader;
provides org.xbib.content.settings.SettingsLoader with
org.xbib.content.yaml.YamlSettingsLoader;
} }

View file

@ -6,7 +6,7 @@ import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder; import org.xbib.content.XContentBuilder;
import org.xbib.content.XContentGenerator; import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser; import org.xbib.content.XContentParser;
import org.xbib.content.io.BytesReference; import org.xbib.content.core.DefaultXContentBuilder;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
@ -36,11 +36,11 @@ public class YamlXContent implements XContent {
} }
public static XContentBuilder contentBuilder() throws IOException { public static XContentBuilder contentBuilder() throws IOException {
return XContentBuilder.builder(yamlXContent); return DefaultXContentBuilder.builder(yamlXContent);
} }
public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException { public static XContentBuilder contentBuilder(OutputStream outputStream) throws IOException {
return XContentBuilder.builder(yamlXContent, outputStream); return DefaultXContentBuilder.builder(yamlXContent, outputStream);
} }
@Override @Override
@ -84,25 +84,18 @@ public class YamlXContent implements XContent {
return new YamlXContentParser(yamlFactory.createParser(data, offset, length)); return new YamlXContentParser(yamlFactory.createParser(data, offset, length));
} }
@Override
public XContentParser createParser(BytesReference bytes) throws IOException {
return createParser(bytes.streamInput());
}
@Override @Override
public XContentParser createParser(Reader reader) throws IOException { public XContentParser createParser(Reader reader) throws IOException {
return new YamlXContentParser(yamlFactory.createParser(reader)); return new YamlXContentParser(yamlFactory.createParser(reader));
} }
@Override @Override
public boolean isXContent(BytesReference bytes) { public boolean isXContent(byte[] bytes, int offset, int len) {
int length = bytes.length() < 20 ? bytes.length() : 20; int length = Math.min(len, 20);
if (length == 0) { if (length == 0) {
return false; return false;
} }
byte first = bytes.get(0); byte first = bytes[offset];
return length > 2 && first == '-' && bytes.get(1) == '-' && bytes.get(2) == '-'; return length > 2 && first == '-' && bytes[offset + 1] == '-' && bytes[offset + 2] == '-';
} }
} }

View file

@ -1,25 +1,37 @@
package org.xbib.content.yaml; 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 com.fasterxml.jackson.dataformat.yaml.YAMLParser;
import org.xbib.content.XContent; 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.io.BytesReference;
import org.xbib.content.json.JsonXContentGenerator;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
/** public class YamlXContentGenerator extends AbstractXContentGenerator {
*
*/
public class YamlXContentGenerator extends JsonXContentGenerator {
public YamlXContentGenerator(JsonGenerator generator) { private final YAMLGeneratorDelegate delegate;
super(generator);
public YamlXContentGenerator(YAMLGenerator generator) {
this.delegate = new YAMLGeneratorDelegate(generator);
super.setGenerator(delegate);
} }
@Override @Override
public XContent content() { public XContent content() {
return YamlXContent.yamlContent(); return delegate.content();
}
@Override
public void usePrettyPrint() {
delegate.usePrettyPrint();
} }
@Override @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 @Override
public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream) public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream)
throws IOException { throws IOException {
@ -49,4 +52,265 @@ public class YamlXContentGenerator extends JsonXContentGenerator {
YamlXContent.yamlFactory().createGenerator(outputStream).copyCurrentStructure(parser); 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();
}
}
} }

View file

@ -1,20 +1,189 @@
package org.xbib.content.yaml; package org.xbib.content.yaml;
import com.fasterxml.jackson.core.JsonParser; 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.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 AbstractXContentParser {
*
*/
public class YamlXContentParser extends JsonXContentParser {
public YamlXContentParser(JsonParser parser) { private final YAMLParser parser;
super(parser);
public YamlXContentParser(YAMLParser parser) {
this.parser = parser;
} }
@Override @Override
public XContent content() { public XContent content() {
return YamlXContent.yamlContent(); 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 + "]");
}
} }

View file

@ -1,9 +1,8 @@
group = org.xbib group = org.xbib
name = content name = content
version = 2.6.6 version = 3.0.0
gradle.wrapper.version = 6.6.1 gradle.wrapper.version = 6.6.1
xbib.net.version = 2.1.1 xbib.net.version = 2.1.1
xbib-datastructures-tiny.version = 0.1.0 xbib-datastructures-tiny.version = 0.1.0
jackson.version = 2.11.4 jackson.version = 2.11.4

View file

@ -1,10 +1,12 @@
include 'content-api'
include 'content-config' include 'content-config'
include 'content-core' include 'content-core'
include 'content-resource' include 'content-csv'
include 'content-language' include 'content-language'
include 'content-json' include 'content-json'
include 'content-csv'
include 'content-smile'
include 'content-yaml'
include 'content-xml'
include 'content-rdf' include 'content-rdf'
include 'content-resource'
include 'content-settings'
include 'content-smile'
include 'content-xml'
include 'content-yaml'