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

View file

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

View file

@ -1,7 +1,5 @@
package org.xbib.content;
import org.xbib.content.io.BytesReference;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -15,6 +13,8 @@ public interface XContent {
String name();
boolean isXContent(byte[] data, int offset, int length);
/**
* Creates a new generator using the provided output stream.
*
@ -80,19 +80,4 @@ public interface XContent {
*/
XContentParser createParser(byte[] bytes, int offset, int length) throws IOException;
/**
* Creates a parser over the provided bytes.
*
* @param bytes bytes
* @return content parser
* @throws IOException if creation fails
*/
XContentParser createParser(BytesReference bytes) throws IOException;
/**
* Returns true if content can be parsed/generated.
* @param bytes bytes
* @return true if content can be parsed/generated.
*/
boolean isXContent(BytesReference bytes);
}

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

View file

@ -6,9 +6,6 @@ import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
/**
*
*/
public interface XContentParser extends Closeable {
XContent content();
@ -45,11 +42,6 @@ public interface XContentParser extends Closeable {
NumberType numberType() throws IOException;
/**
* Is the number type estimated or not (i.e. an int might actually be a long, its just low enough
* to be an int).
* @return true if number is estimated
*/
boolean estimatedNumberType();
short shortValue() throws IOException;

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
dependencies {
api "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}"
api project(':content-api')
api "org.xbib:datastructures-tiny:${project.property('xbib-datastructures-tiny.version')}"
implementation "com.fasterxml.jackson.core:jackson-core:${project.property('jackson.version')}"
}

View file

@ -1,15 +1,16 @@
import org.xbib.content.SettingsLoader;
import org.xbib.content.properties.PropertiesSettingsLoader;
module org.xbib.content.core {
exports org.xbib.content;
uses org.xbib.content.XContent;
uses SettingsLoader;
exports org.xbib.content.io;
exports org.xbib.content.json;
exports org.xbib.content.settings;
exports org.xbib.content.properties;
exports org.xbib.content.util.geo;
exports org.xbib.content.util.unit;
requires org.xbib.datastructures.tiny;
exports org.xbib.content.core;
requires transitive org.xbib.content;
requires transitive org.xbib.datastructures.tiny;
requires transitive com.fasterxml.jackson.core;
provides org.xbib.content.XContent with
org.xbib.content.json.JsonXContent;
provides org.xbib.content.settings.SettingsLoader with
org.xbib.content.settings.PropertiesSettingsLoader,
org.xbib.content.json.JsonSettingsLoader;
provides SettingsLoader with PropertiesSettingsLoader;
}

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

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

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

View file

@ -1,4 +1,4 @@
/**
* 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.SettingsLoader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
@ -38,7 +39,6 @@ public class PropertiesSettingsLoader implements SettingsLoader {
}
}
@Override
public Map<String, String> load(BytesReference ref) throws IOException {
Properties props = new Properties();
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;

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.
*/
package org.xbib.content;
package org.xbib.content.test;

View file

@ -1,5 +1,7 @@
dependencies {
api "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
api project(':content-core')
api project(':content-settings')
implementation "com.fasterxml.jackson.core:jackson-databind:${project.property('jackson.version')}"
testImplementation("org.mockito:mockito-core:${project.property('mockito.version')}") {
exclude group: 'org.hamcrest'
}

View file

@ -1,9 +1,18 @@
import org.xbib.content.SettingsLoader;
module org.xbib.content.json {
exports org.xbib.content.json;
exports org.xbib.content.json.diff;
exports org.xbib.content.json.jackson;
exports org.xbib.content.json.mergepatch;
exports org.xbib.content.json.patch;
exports org.xbib.content.json.pointer;
requires transitive org.xbib.content.core;
requires transitive org.xbib.content.settings;
requires transitive com.fasterxml.jackson.core;
requires transitive com.fasterxml.jackson.databind;
provides org.xbib.content.XContent with
org.xbib.content.json.JsonXContent;
provides SettingsLoader with
org.xbib.content.json.JsonSettingsLoader;
}

View file

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

View file

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

View file

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

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.assertThrows;
import static org.xbib.content.json.JsonXContent.contentBuilder;
import org.junit.jupiter.api.Test;
import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder;
import org.xbib.content.core.XContentService;
import org.xbib.content.json.JsonXContent;
import java.io.IOException;

View file

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

View file

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

View file

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

View file

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

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

View file

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

View file

@ -1,6 +1,6 @@
package org.xbib.content.settings;
import org.xbib.content.json.JsonSettingsLoader;
import org.xbib.content.SettingsLoader;
import java.util.HashMap;
import java.util.Map;
@ -38,7 +38,7 @@ public final class SettingsLoaderService {
}
}
}
return new JsonSettingsLoader();
throw new UnsupportedOperationException();
}
/**
@ -52,6 +52,6 @@ public final class SettingsLoaderService {
return loader;
}
}
return new JsonSettingsLoader();
throw new UnsupportedOperationException();
}
}

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

View file

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

View file

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

View file

@ -1,26 +1,39 @@
package org.xbib.content.smile;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.dataformat.smile.SmileGenerator;
import com.fasterxml.jackson.dataformat.smile.SmileParser;
import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder;
import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser;
import org.xbib.content.core.AbstractXContentGenerator;
import org.xbib.content.core.DefaultXContentBuilder;
import org.xbib.content.core.XContentHelper;
import org.xbib.content.io.BytesReference;
import org.xbib.content.json.JsonXContentGenerator;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
*
*/
public class SmileXContentGenerator extends JsonXContentGenerator {
public class SmileXContentGenerator extends AbstractXContentGenerator {
public SmileXContentGenerator(JsonGenerator generator) {
super(generator);
private final SmileGeneratorDelegate delegate;
public SmileXContentGenerator(SmileGenerator generator) {
this.delegate = new SmileGeneratorDelegate(generator);
super.setGenerator(delegate);
}
@Override
public XContent content() {
return SmileXContent.smileContent();
return delegate.content();
}
@Override
public void usePrettyPrint() {
delegate.usePrettyPrint();
}
@Override
@ -32,15 +45,6 @@ public class SmileXContentGenerator extends JsonXContentGenerator {
}
}
@Override
public void writeRawField(String fieldName, BytesReference content, OutputStream bos) throws IOException {
writeFieldName(fieldName);
try (SmileParser parser = SmileXContent.smileFactory().createParser(content.streamInput())) {
parser.nextToken();
((JsonGenerator) generator).copyCurrentStructure(parser);
}
}
@Override
public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream bos) throws IOException {
writeFieldName(fieldName);
@ -49,4 +53,266 @@ public class SmileXContentGenerator extends JsonXContentGenerator {
((JsonGenerator) generator).copyCurrentStructure(parser);
}
}
@Override
public void writeValue(XContentBuilder builder) throws IOException {
delegate.writeValue(builder);
}
@Override
public void copyCurrentStructure(XContentParser parser) throws IOException {
delegate.copyCurrentStructure(parser);
}
@Override
public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException {
flush();
if (builder instanceof DefaultXContentBuilder) {
DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
xContentBuilder.bytes().streamOutput(outputStream);
}
}
@Override
public void flush() throws IOException {
delegate.flush();
}
@Override
public void close() throws IOException {
delegate.close();
}
private static class SmileGeneratorDelegate implements XContentGenerator {
private final SmileGenerator smileGenerator;
private SmileGeneratorDelegate(SmileGenerator smileGenerator) {
this.smileGenerator = smileGenerator;
}
@Override
public XContent content() {
return SmileXContent.smileContent();
}
@Override
public void usePrettyPrint() {
smileGenerator.useDefaultPrettyPrinter();
}
@Override
public void writeStartArray() throws IOException {
smileGenerator.writeStartArray();
}
@Override
public void writeEndArray() throws IOException {
smileGenerator.writeEndArray();
}
@Override
public void writeStartObject() throws IOException {
smileGenerator.writeStartObject();
}
@Override
public void writeEndObject() throws IOException {
smileGenerator.writeEndObject();
}
@Override
public void writeFieldName(String name) throws IOException {
smileGenerator.writeFieldName(name);
}
@Override
public void writeString(String text) throws IOException {
smileGenerator.writeString(text);
}
@Override
public void writeString(char[] text, int offset, int len) throws IOException {
smileGenerator.writeString(text, offset, len);
}
@Override
public void writeUTF8String(byte[] text, int offset, int length) throws IOException {
smileGenerator.writeUTF8String(text, offset, length);
}
@Override
public void writeBinary(byte[] data, int offset, int len) throws IOException {
smileGenerator.writeBinary(data, offset, len);
}
@Override
public void writeBinary(byte[] data) throws IOException {
smileGenerator.writeBinary(data);
}
@Override
public void writeNumber(int v) throws IOException {
smileGenerator.writeNumber(v);
}
@Override
public void writeNumber(long v) throws IOException {
smileGenerator.writeNumber(v);
}
@Override
public void writeNumber(double d) throws IOException {
smileGenerator.writeNumber(d);
}
@Override
public void writeNumber(float f) throws IOException {
smileGenerator.writeNumber(f);
}
@Override
public void writeNumber(BigInteger bi) throws IOException {
smileGenerator.writeNumber(bi);
}
@Override
public void writeNumber(BigDecimal bd) throws IOException {
smileGenerator.writeNumber(bd);
}
@Override
public void writeBoolean(boolean b) throws IOException {
smileGenerator.writeBoolean(b);
}
@Override
public void writeNull() throws IOException {
smileGenerator.writeNull();
}
@Override
public void writeStringField(String fieldName, String value) throws IOException {
smileGenerator.writeStringField(fieldName, value);
}
@Override
public void writeBooleanField(String fieldName, boolean value) throws IOException {
smileGenerator.writeBooleanField(fieldName, value);
}
@Override
public void writeNullField(String fieldName) throws IOException {
smileGenerator.writeNullField(fieldName);
}
@Override
public void writeNumberField(String fieldName, int value) throws IOException {
smileGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, long value) throws IOException {
smileGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, double value) throws IOException {
smileGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, float value) throws IOException {
smileGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, BigInteger value) throws IOException {
smileGenerator.writeFieldName(fieldName);
smileGenerator.writeNumber(value);
}
@Override
public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
smileGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeBinaryField(String fieldName, byte[] data) throws IOException {
smileGenerator.writeBinaryField(fieldName, data);
}
@Override
public void writeArrayFieldStart(String fieldName) throws IOException {
smileGenerator.writeArrayFieldStart(fieldName);
}
@Override
public void writeObjectFieldStart(String fieldName) throws IOException {
smileGenerator.writeObjectFieldStart(fieldName);
}
@Override
public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException {
smileGenerator.writeRaw(",\"");
smileGenerator.writeRaw(fieldName);
smileGenerator.writeRaw("\":");
flush();
outputStream.write(content);
}
@Override
public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream)
throws IOException {
smileGenerator.writeRaw(",\"");
smileGenerator.writeRaw(fieldName);
smileGenerator.writeRaw("\":");
flush();
outputStream.write(content, offset, length);
}
public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException {
smileGenerator.writeRaw(",\"");
smileGenerator.writeRaw(fieldName);
smileGenerator.writeRaw("\":");
flush();
content.streamOutput(outputStream);
}
@Override
public void writeValue(XContentBuilder builder) throws IOException {
smileGenerator.writeRawValue(builder.string());
}
@Override
public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException {
flush();
if (builder instanceof DefaultXContentBuilder) {
DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
xContentBuilder.bytes().streamOutput(outputStream);
}
}
@Override
public void copyCurrentStructure(XContentParser parser) throws IOException {
if (parser.currentToken() == null) {
parser.nextToken();
}
XContentHelper.copyCurrentStructure(this, parser);
}
@Override
public void flush() throws IOException {
smileGenerator.flush();
}
@Override
public void close() throws IOException {
if (smileGenerator.isClosed()) {
return;
}
smileGenerator.close();
}
}
}

View file

@ -1,16 +1,21 @@
package org.xbib.content.smile;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.dataformat.smile.SmileParser;
import org.xbib.content.XContent;
import org.xbib.content.json.JsonXContentParser;
import org.xbib.content.XContentParser;
import org.xbib.content.core.AbstractXContentParser;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
*
*/
public class SmileXContentParser extends JsonXContentParser {
public class SmileXContentParser extends AbstractXContentParser {
public SmileXContentParser(JsonParser parser) {
super(parser);
private final SmileParser parser;
public SmileXContentParser(SmileParser parser) {
this.parser = parser;
}
@Override
@ -18,4 +23,166 @@ public class SmileXContentParser extends JsonXContentParser {
return SmileXContent.smileContent();
}
@Override
public XContentParser.Token nextToken() throws IOException {
return convertToken(parser.nextToken());
}
@Override
public void skipChildren() throws IOException {
parser.skipChildren();
}
@Override
public XContentParser.Token currentToken() {
return convertToken(parser.getCurrentToken());
}
@Override
public XContentParser.NumberType numberType() throws IOException {
return convertNumberType(parser.getNumberType());
}
@Override
public boolean estimatedNumberType() {
return true;
}
@Override
public String currentName() throws IOException {
return parser.getCurrentName();
}
@Override
protected boolean doBooleanValue() throws IOException {
return parser.getBooleanValue();
}
@Override
public String text() throws IOException {
return parser.getText();
}
@Override
public boolean hasTextCharacters() {
return parser.hasTextCharacters();
}
@Override
public char[] textCharacters() throws IOException {
return parser.getTextCharacters();
}
@Override
public int textLength() throws IOException {
return parser.getTextLength();
}
@Override
public int textOffset() throws IOException {
return parser.getTextOffset();
}
@Override
public Number numberValue() throws IOException {
return parser.getNumberValue();
}
@Override
public BigInteger bigIntegerValue() throws IOException {
return parser.getBigIntegerValue();
}
@Override
public BigDecimal bigDecimalValue() throws IOException {
return parser.getDecimalValue();
}
@Override
public short doShortValue() throws IOException {
return parser.getShortValue();
}
@Override
public int doIntValue() throws IOException {
return parser.getIntValue();
}
@Override
public long doLongValue() throws IOException {
return parser.getLongValue();
}
@Override
public float doFloatValue() throws IOException {
return parser.getFloatValue();
}
@Override
public double doDoubleValue() throws IOException {
return parser.getDoubleValue();
}
@Override
public byte[] binaryValue() throws IOException {
return parser.getBinaryValue();
}
@Override
public void close() throws IOException {
parser.close();
}
private XContentParser.NumberType convertNumberType(JsonParser.NumberType numberType) {
switch (numberType) {
case INT:
return XContentParser.NumberType.INT;
case LONG:
return XContentParser.NumberType.LONG;
case FLOAT:
return XContentParser.NumberType.FLOAT;
case DOUBLE:
return XContentParser.NumberType.DOUBLE;
case BIG_DECIMAL:
return XContentParser.NumberType.BIG_DECIMAL;
case BIG_INTEGER:
return XContentParser.NumberType.BIG_INTEGER;
default:
break;
}
throw new IllegalStateException("No matching token for number_type [" + numberType + "]");
}
private XContentParser.Token convertToken(JsonToken token) {
if (token == null) {
return null;
}
switch (token) {
case FIELD_NAME:
return XContentParser.Token.FIELD_NAME;
case VALUE_FALSE:
case VALUE_TRUE:
return XContentParser.Token.VALUE_BOOLEAN;
case VALUE_STRING:
return XContentParser.Token.VALUE_STRING;
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
return XContentParser.Token.VALUE_NUMBER;
case VALUE_NULL:
return XContentParser.Token.VALUE_NULL;
case START_OBJECT:
return XContentParser.Token.START_OBJECT;
case END_OBJECT:
return XContentParser.Token.END_OBJECT;
case START_ARRAY:
return XContentParser.Token.START_ARRAY;
case END_ARRAY:
return XContentParser.Token.END_ARRAY;
case VALUE_EMBEDDED_OBJECT:
return XContentParser.Token.VALUE_EMBEDDED_OBJECT;
default:
break;
}
throw new IllegalStateException("No matching token for json_token [" + token + "]");
}
}

View file

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

View file

@ -1,3 +1,4 @@
import org.xbib.content.XContent;
module org.xbib.content.xml {
exports org.xbib.content.xml;
exports org.xbib.content.xml.json;
@ -9,6 +10,5 @@ module org.xbib.content.xml {
requires transitive org.xbib.content.core;
requires transitive org.xbib.content.resource;
requires transitive com.fasterxml.jackson.dataformat.xml;
provides org.xbib.content.XContent with
org.xbib.content.xml.XmlXContent;
provides XContent with org.xbib.content.xml.XmlXContent;
}

View file

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

View file

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

View file

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

View file

@ -2,7 +2,7 @@ package org.xbib.content.xml;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import org.xbib.content.AbstractXContentParser;
import org.xbib.content.core.AbstractXContentParser;
import org.xbib.content.XContent;
import org.xbib.content.XContentParser;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,25 +1,37 @@
package org.xbib.content.yaml;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
import org.xbib.content.XContent;
import org.xbib.content.XContentBuilder;
import org.xbib.content.XContentGenerator;
import org.xbib.content.XContentParser;
import org.xbib.content.core.AbstractXContentGenerator;
import org.xbib.content.core.DefaultXContentBuilder;
import org.xbib.content.core.XContentHelper;
import org.xbib.content.io.BytesReference;
import org.xbib.content.json.JsonXContentGenerator;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
*
*/
public class YamlXContentGenerator extends JsonXContentGenerator {
public class YamlXContentGenerator extends AbstractXContentGenerator {
public YamlXContentGenerator(JsonGenerator generator) {
super(generator);
private final YAMLGeneratorDelegate delegate;
public YamlXContentGenerator(YAMLGenerator generator) {
this.delegate = new YAMLGeneratorDelegate(generator);
super.setGenerator(delegate);
}
@Override
public XContent content() {
return YamlXContent.yamlContent();
return delegate.content();
}
@Override
public void usePrettyPrint() {
delegate.usePrettyPrint();
}
@Override
@ -31,15 +43,6 @@ public class YamlXContentGenerator extends JsonXContentGenerator {
}
}
@Override
public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException {
writeFieldName(fieldName);
try (YAMLParser parser = YamlXContent.yamlFactory().createParser(content.streamInput())) {
parser.nextToken();
YamlXContent.yamlFactory().createGenerator(outputStream).copyCurrentStructure(parser);
}
}
@Override
public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream)
throws IOException {
@ -49,4 +52,265 @@ public class YamlXContentGenerator extends JsonXContentGenerator {
YamlXContent.yamlFactory().createGenerator(outputStream).copyCurrentStructure(parser);
}
}
@Override
public void writeValue(XContentBuilder builder) throws IOException {
delegate.writeValue(builder);
}
@Override
public void copyCurrentStructure(XContentParser parser) throws IOException {
delegate.copyCurrentStructure(parser);
}
@Override
public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException {
flush();
if (builder instanceof DefaultXContentBuilder) {
DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
xContentBuilder.bytes().streamOutput(outputStream);
}
}
@Override
public void flush() throws IOException {
delegate.flush();
}
@Override
public void close() throws IOException {
delegate.close();
}
private static class YAMLGeneratorDelegate implements XContentGenerator {
final YAMLGenerator yamlGenerator;
YAMLGeneratorDelegate(YAMLGenerator yamlGenerator) {
this.yamlGenerator = yamlGenerator;
}
@Override
public XContent content() {
return YamlXContent.yamlContent();
}
@Override
public void usePrettyPrint() {
yamlGenerator.useDefaultPrettyPrinter();
}
@Override
public void writeStartArray() throws IOException {
yamlGenerator.writeStartArray();
}
@Override
public void writeEndArray() throws IOException {
yamlGenerator.writeEndArray();
}
@Override
public void writeStartObject() throws IOException {
yamlGenerator.writeStartObject();
}
@Override
public void writeEndObject() throws IOException {
yamlGenerator.writeEndObject();
}
@Override
public void writeFieldName(String name) throws IOException {
yamlGenerator.writeFieldName(name);
}
@Override
public void writeString(String text) throws IOException {
yamlGenerator.writeString(text);
}
@Override
public void writeString(char[] text, int offset, int len) throws IOException {
yamlGenerator.writeString(text, offset, len);
}
@Override
public void writeUTF8String(byte[] text, int offset, int length) throws IOException {
yamlGenerator.writeUTF8String(text, offset, length);
}
@Override
public void writeBinary(byte[] data, int offset, int len) throws IOException {
yamlGenerator.writeBinary(data, offset, len);
}
@Override
public void writeBinary(byte[] data) throws IOException {
yamlGenerator.writeBinary(data);
}
@Override
public void writeNumber(int v) throws IOException {
yamlGenerator.writeNumber(v);
}
@Override
public void writeNumber(long v) throws IOException {
yamlGenerator.writeNumber(v);
}
@Override
public void writeNumber(double d) throws IOException {
yamlGenerator.writeNumber(d);
}
@Override
public void writeNumber(float f) throws IOException {
yamlGenerator.writeNumber(f);
}
@Override
public void writeNumber(BigInteger bi) throws IOException {
yamlGenerator.writeNumber(bi);
}
@Override
public void writeNumber(BigDecimal bd) throws IOException {
yamlGenerator.writeNumber(bd);
}
@Override
public void writeBoolean(boolean b) throws IOException {
yamlGenerator.writeBoolean(b);
}
@Override
public void writeNull() throws IOException {
yamlGenerator.writeNull();
}
@Override
public void writeStringField(String fieldName, String value) throws IOException {
yamlGenerator.writeStringField(fieldName, value);
}
@Override
public void writeBooleanField(String fieldName, boolean value) throws IOException {
yamlGenerator.writeBooleanField(fieldName, value);
}
@Override
public void writeNullField(String fieldName) throws IOException {
yamlGenerator.writeNullField(fieldName);
}
@Override
public void writeNumberField(String fieldName, int value) throws IOException {
yamlGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, long value) throws IOException {
yamlGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, double value) throws IOException {
yamlGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, float value) throws IOException {
yamlGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeNumberField(String fieldName, BigInteger value) throws IOException {
yamlGenerator.writeFieldName(fieldName);
yamlGenerator.writeNumber(value);
}
@Override
public void writeNumberField(String fieldName, BigDecimal value) throws IOException {
yamlGenerator.writeNumberField(fieldName, value);
}
@Override
public void writeBinaryField(String fieldName, byte[] data) throws IOException {
yamlGenerator.writeBinaryField(fieldName, data);
}
@Override
public void writeArrayFieldStart(String fieldName) throws IOException {
yamlGenerator.writeArrayFieldStart(fieldName);
}
@Override
public void writeObjectFieldStart(String fieldName) throws IOException {
yamlGenerator.writeObjectFieldStart(fieldName);
}
@Override
public void writeRawField(String fieldName, byte[] content, OutputStream outputStream) throws IOException {
yamlGenerator.writeRaw(",\"");
yamlGenerator.writeRaw(fieldName);
yamlGenerator.writeRaw("\":");
flush();
outputStream.write(content);
}
@Override
public void writeRawField(String fieldName, byte[] content, int offset, int length, OutputStream outputStream)
throws IOException {
yamlGenerator.writeRaw(",\"");
yamlGenerator.writeRaw(fieldName);
yamlGenerator.writeRaw("\":");
flush();
outputStream.write(content, offset, length);
}
public void writeRawField(String fieldName, BytesReference content, OutputStream outputStream) throws IOException {
yamlGenerator.writeRaw(",\"");
yamlGenerator.writeRaw(fieldName);
yamlGenerator.writeRaw("\":");
flush();
content.streamOutput(outputStream);
}
@Override
public void writeValue(XContentBuilder builder) throws IOException {
yamlGenerator.writeRawValue(builder.string());
}
@Override
public void copy(XContentBuilder builder, OutputStream outputStream) throws IOException {
flush();
if (builder instanceof DefaultXContentBuilder) {
DefaultXContentBuilder xContentBuilder = (DefaultXContentBuilder) builder;
xContentBuilder.bytes().streamOutput(outputStream);
}
}
@Override
public void copyCurrentStructure(XContentParser parser) throws IOException {
if (parser.currentToken() == null) {
parser.nextToken();
}
XContentHelper.copyCurrentStructure(this, parser);
}
@Override
public void flush() throws IOException {
yamlGenerator.flush();
}
@Override
public void close() throws IOException {
if (yamlGenerator.isClosed()) {
return;
}
yamlGenerator.close();
}
}
}

View file

@ -1,20 +1,189 @@
package org.xbib.content.yaml;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.dataformat.yaml.YAMLParser;
import org.xbib.content.XContent;
import org.xbib.content.json.JsonXContentParser;
import org.xbib.content.XContentParser;
import org.xbib.content.core.AbstractXContentParser;
import java.io.IOException;
import java.math.BigDecimal;
import java.math.BigInteger;
/**
*
*/
public class YamlXContentParser extends JsonXContentParser {
public class YamlXContentParser extends AbstractXContentParser {
public YamlXContentParser(JsonParser parser) {
super(parser);
private final YAMLParser parser;
public YamlXContentParser(YAMLParser parser) {
this.parser = parser;
}
@Override
public XContent content() {
return YamlXContent.yamlContent();
}
@Override
public XContentParser.Token nextToken() throws IOException {
return convertToken(parser.nextToken());
}
@Override
public void skipChildren() throws IOException {
parser.skipChildren();
}
@Override
public XContentParser.Token currentToken() {
return convertToken(parser.getCurrentToken());
}
@Override
public XContentParser.NumberType numberType() throws IOException {
return convertNumberType(parser.getNumberType());
}
@Override
public boolean estimatedNumberType() {
return true;
}
@Override
public String currentName() throws IOException {
return parser.getCurrentName();
}
@Override
protected boolean doBooleanValue() throws IOException {
return parser.getBooleanValue();
}
@Override
public String text() throws IOException {
return parser.getText();
}
@Override
public boolean hasTextCharacters() {
return parser.hasTextCharacters();
}
@Override
public char[] textCharacters() throws IOException {
return parser.getTextCharacters();
}
@Override
public int textLength() throws IOException {
return parser.getTextLength();
}
@Override
public int textOffset() throws IOException {
return parser.getTextOffset();
}
@Override
public Number numberValue() throws IOException {
return parser.getNumberValue();
}
@Override
public BigInteger bigIntegerValue() throws IOException {
return parser.getBigIntegerValue();
}
@Override
public BigDecimal bigDecimalValue() throws IOException {
return parser.getDecimalValue();
}
@Override
public short doShortValue() throws IOException {
return parser.getShortValue();
}
@Override
public int doIntValue() throws IOException {
return parser.getIntValue();
}
@Override
public long doLongValue() throws IOException {
return parser.getLongValue();
}
@Override
public float doFloatValue() throws IOException {
return parser.getFloatValue();
}
@Override
public double doDoubleValue() throws IOException {
return parser.getDoubleValue();
}
@Override
public byte[] binaryValue() throws IOException {
return parser.getBinaryValue();
}
@Override
public void close() throws IOException {
parser.close();
}
private XContentParser.NumberType convertNumberType(JsonParser.NumberType numberType) {
switch (numberType) {
case INT:
return XContentParser.NumberType.INT;
case LONG:
return XContentParser.NumberType.LONG;
case FLOAT:
return XContentParser.NumberType.FLOAT;
case DOUBLE:
return XContentParser.NumberType.DOUBLE;
case BIG_DECIMAL:
return XContentParser.NumberType.BIG_DECIMAL;
case BIG_INTEGER:
return XContentParser.NumberType.BIG_INTEGER;
default:
break;
}
throw new IllegalStateException("No matching token for number_type [" + numberType + "]");
}
private XContentParser.Token convertToken(JsonToken token) {
if (token == null) {
return null;
}
switch (token) {
case FIELD_NAME:
return XContentParser.Token.FIELD_NAME;
case VALUE_FALSE:
case VALUE_TRUE:
return XContentParser.Token.VALUE_BOOLEAN;
case VALUE_STRING:
return XContentParser.Token.VALUE_STRING;
case VALUE_NUMBER_INT:
case VALUE_NUMBER_FLOAT:
return XContentParser.Token.VALUE_NUMBER;
case VALUE_NULL:
return XContentParser.Token.VALUE_NULL;
case START_OBJECT:
return XContentParser.Token.START_OBJECT;
case END_OBJECT:
return XContentParser.Token.END_OBJECT;
case START_ARRAY:
return XContentParser.Token.START_ARRAY;
case END_ARRAY:
return XContentParser.Token.END_ARRAY;
case VALUE_EMBEDDED_OBJECT:
return XContentParser.Token.VALUE_EMBEDDED_OBJECT;
default:
break;
}
throw new IllegalStateException("No matching token for json_token [" + token + "]");
}
}

View file

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

View file

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