Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e710641
Merge pull request #4 from JavaWebStack/feature/implement-own-mapper
JanHolger Jan 4, 2022
401ea2c
Hopefully fixed errors with private fields
JanHolger Jan 4, 2022
ed13ef7
Merge pull request #8 from JavaWebStack/fix-private-fields
JanHolger Jan 4, 2022
d160336
Hopefully fixed errors with private fields
JanHolger Jan 4, 2022
99003a9
Merge pull request #9 from JavaWebStack/fix-private-fields
JanHolger Jan 4, 2022
73288a1
Added support for the Number type
JanHolger Jan 4, 2022
28d426c
Merge pull request #10 from JavaWebStack/add-mapping-for-number
JanHolger Jan 4, 2022
4b18bc5
Added fix for url encoded form data keys
JanHolger Jan 17, 2022
f7317ff
Fixed issue with Boolean mapping
JanHolger Jan 18, 2022
014585a
Fixed error when the constructor is private
JanHolger Jan 18, 2022
2ee930e
made transient fields hidden
JanHolger Jan 18, 2022
0a5ed38
Added UUID support
JanHolger Jan 18, 2022
8099092
Throwing the ParseException in fromJson now
JanHolger Jan 18, 2022
9925769
Deprecated AbstractMapper, made empty objects and arrays shorter, act…
JanHolger Jan 19, 2022
f2240d5
Added Bson support
JanHolger Jan 19, 2022
07cee57
Added Bson support
JanHolger Jan 19, 2022
bd8cce5
Cleanup of the default mapper registration
JanHolger Jan 19, 2022
6effa44
Implemented char support
JanHolger Jan 19, 2022
588bf19
Implemented Stream API Collectors for AbstractObject and AbstractArray
JanHolger Jan 19, 2022
8b3f9b9
Optimized imports
JanHolger Jan 19, 2022
c8df0bf
Fixed wrong type check and added support for Vector and Stack
JanHolger Jan 19, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@
<artifactId>snakeyaml</artifactId>
<version>1.29</version>
</dependency>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>bson</artifactId>
<version>4.4.1</version>
<optional>true</optional>
</dependency>
</dependencies>

<build>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/org/javawebstack/abstractdata/AbstractArray.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package org.javawebstack.abstractdata;

import org.javawebstack.abstractdata.collector.AbstractArrayCollector;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;

public class AbstractArray implements AbstractElement, Iterable<AbstractElement> {
Expand Down Expand Up @@ -289,4 +293,12 @@ public AbstractElement clone() {
return array;
}

public static <T> Collector<T, ?, AbstractArray> collect(Function<T, AbstractElement> mappingFunction) {
return new AbstractArrayCollector<>(mappingFunction);
}

public static <T extends AbstractElement> Collector<T, ?, AbstractArray> collect() {
return new AbstractArrayCollector<>(e -> e);
}

}
23 changes: 21 additions & 2 deletions src/main/java/org/javawebstack/abstractdata/AbstractElement.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.javawebstack.abstractdata;

import org.bson.BsonValue;
import org.javawebstack.abstractdata.bson.BsonConverter;
import org.javawebstack.abstractdata.bson.BsonTypeAdapter;
import org.javawebstack.abstractdata.json.JsonDumper;
import org.javawebstack.abstractdata.json.JsonParser;
import org.javawebstack.abstractdata.util.QueryString;
Expand Down Expand Up @@ -73,6 +76,14 @@ default Number number() {
return primitive().number();
}

default BsonValue toBson() {
return new BsonConverter().toBson(this);
}

default byte[] toBsonBytes() {
return (byte[]) new BsonTypeAdapter().fromAbstract(null, this, byte[].class);
}

default String toJsonString(boolean pretty) {
return new JsonDumper().setPretty(pretty).dump(this);
}
Expand Down Expand Up @@ -154,6 +165,14 @@ default String toFormDataString() {
return toFormData().toString();
}

static AbstractElement fromBson(BsonValue value) {
return new BsonConverter().toAbstract(value);
}

static AbstractElement fromBson(byte[] value) {
return new BsonTypeAdapter().toAbstract(null, value);
}

AbstractElement clone();

Map<String[], Object> toTree();
Expand All @@ -162,8 +181,7 @@ static AbstractElement fromJson(String json) {
try {
return new JsonParser().parse(json);
} catch (ParseException e) {
e.printStackTrace();
return null;
throw new RuntimeException(e);
}
}

Expand Down Expand Up @@ -212,4 +230,5 @@ public boolean isPrimitive() {
return this == NUMBER || this == BOOLEAN || this == STRING;
}
}

}
14 changes: 11 additions & 3 deletions src/main/java/org/javawebstack/abstractdata/AbstractMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,39 @@

import org.javawebstack.abstractdata.mapper.Mapper;

@Deprecated
public class AbstractMapper {

private final Mapper mapper = new Mapper();
private NamingPolicy namingPolicy = NamingPolicy.NONE;
private String dateFormat = "yyyy-MM-dd HH:mm:ss";
private boolean exposeRequired = false;

public AbstractMapper setNamingPolicy(NamingPolicy namingPolicy) {
this.namingPolicy = namingPolicy;
mapper.namingPolicy(namingPolicy.getMapperPolicy());
return this;
}

public boolean shouldOmitNull() {
return mapper.shouldOmitNull();
}

public AbstractMapper setOmitNull(boolean omitNull) {
this.mapper.omitNull(omitNull);
return this;
}

public NamingPolicy getNamingPolicy() {
return namingPolicy;
}

public AbstractMapper setExposeRequired(boolean exposeRequired) {
this.exposeRequired = exposeRequired;
mapper.requireExpose(exposeRequired);
return this;
}

public boolean isExposeRequired() {
return exposeRequired;
return mapper.isExposeRequired();
}

public AbstractMapper setDateFormat(String dateFormat) {
Expand Down
13 changes: 13 additions & 0 deletions src/main/java/org/javawebstack/abstractdata/AbstractObject.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
package org.javawebstack.abstractdata;

import org.javawebstack.abstractdata.collector.AbstractObjectCollector;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Stream;

public class AbstractObject implements AbstractElement {

Expand Down Expand Up @@ -207,10 +212,18 @@ public AbstractArray values() {
return AbstractArray.fromList(entries.values());
}

public Stream<Map.Entry<String, AbstractElement>> stream() {
return entries().stream();
}

public AbstractElement clone() {
AbstractObject object = new AbstractObject();
forEach((k, v) -> object.set(k, v.clone()));
return object;
}

public static <T> Collector<T, ?, AbstractObject> collect(Function<T, String> keyFunction, Function<T, AbstractElement> valueFunction) {
return new AbstractObjectCollector<>(keyFunction, valueFunction);
}

}
169 changes: 169 additions & 0 deletions src/main/java/org/javawebstack/abstractdata/bson/BsonConverter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
package org.javawebstack.abstractdata.bson;

import org.bson.*;
import org.bson.internal.Base64;
import org.bson.types.Decimal128;
import org.bson.types.ObjectId;
import org.javawebstack.abstractdata.*;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class BsonConverter {

private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public BsonConverter dateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
return this;
}

public BsonConverter dateFormat(String format) {
return dateFormat(new SimpleDateFormat(format));
}

public AbstractObject toAbstract(ObjectId value) {
return new AbstractObject().set("$oid", value.toHexString());
}

public AbstractObject toAbstract(Decimal128 value) {
return new AbstractObject().set("$numberDecimal", value.toString());
}

public AbstractElement toAbstract(BsonValue value) {
switch (value.getBsonType()) {
case NULL:
return AbstractNull.INSTANCE;
case STRING:
return new AbstractPrimitive(value.asString().getValue());
case BOOLEAN:
return new AbstractPrimitive(value.asBoolean().getValue());
case INT32:
return new AbstractPrimitive(value.asInt32().getValue());
case INT64:
return new AbstractPrimitive(value.asInt64().getValue());
case DOUBLE:
return new AbstractPrimitive(value.asDouble().getValue());
case OBJECT_ID:
return toAbstract(value.asObjectId().getValue());
case DATE_TIME:
return new AbstractObject().set("$date", dateFormat.format(new Date(value.asDateTime().getValue())));
case UNDEFINED:
return new AbstractObject().set("$undefined", true);
case SYMBOL:
return new AbstractObject().set("$symbol", value.asSymbol().getSymbol());
case MIN_KEY:
return new AbstractObject().set("$minKey", 1);
case MAX_KEY:
return new AbstractObject().set("$maxKey", 1);
case JAVASCRIPT:
return new AbstractObject().set("$code", value.asJavaScript().getCode());
case JAVASCRIPT_WITH_SCOPE:
return new AbstractObject()
.set("$code", value.asJavaScriptWithScope().getCode())
.set("$scope", toAbstract(value.asJavaScriptWithScope().getScope()));
case DECIMAL128:
return toAbstract(value.asDecimal128().getValue());
case REGULAR_EXPRESSION:
return new AbstractObject().set("$regularExpression", new AbstractObject()
.set("pattern", value.asRegularExpression().getPattern())
.set("options", value.asRegularExpression().getOptions())
);
case TIMESTAMP:
return new AbstractObject().set("$timestamp", new AbstractObject()
.set("t", Integer.toUnsignedLong(value.asTimestamp().getTime()))
.set("i", Integer.toUnsignedLong(value.asTimestamp().getInc()))
);
case BINARY:
return new AbstractObject().set("$binary", new AbstractObject()
.set("base64", Base64.encode(value.asBinary().getData()))
.set("subType", String.format("%02x", value.asBinary().getType()))
);
case ARRAY: {
AbstractArray a = new AbstractArray();
value.asArray().forEach(v -> a.add(toAbstract(v)));
return a;
}
case DOCUMENT: {
AbstractObject o = new AbstractObject();
value.asDocument().forEach((k, v) -> o.set(k, toAbstract(v)));
return o;
}
}
throw new UnsupportedOperationException("Unsupported Bson Type: " + value.getBsonType().name());
}

public BsonValue toBson(AbstractElement element) {
if(element == null || element.isNull())
return BsonNull.VALUE;
if(element.isString())
return new BsonString(element.string());
if(element.isBoolean())
return new BsonBoolean(element.bool());
if(element.isNumber()) {
Number n = element.number();
if(n instanceof Integer || n instanceof Short || n instanceof Byte) {
return new BsonInt32(n.intValue());
} else if(n instanceof Long) {
return new BsonInt64(n.longValue());
} else if(n instanceof Float || n instanceof Double) {
return new BsonDouble(n.doubleValue());
}
}
if(element.isArray()) {
BsonArray a = new BsonArray();
for(AbstractElement e : element.array())
a.add(toBson(e));
return a;
}
AbstractObject o = element.object();
if(o.size() == 1 && o.has("$oid") && o.get("$oid").isString())
return new BsonObjectId(new ObjectId(o.string("$oid")));
if(o.size() == 1 && o.has("$undefined") && o.get("$undefined").isBoolean())
return new BsonUndefined();
if(o.size() == 1 && o.has("$date") && o.get("$date").isString()) {
try {
return new BsonDateTime(dateFormat.parse(o.string("$date")).getTime());
} catch (ParseException ignored) {}
}
if(o.size() == 1 && o.has("$numberDecimal") && o.get("$numberDecimal").isString())
return new BsonDecimal128(Decimal128.parse(o.string("$numberDecimal")));
if(o.size() == 1 && o.has("$minKey") && o.get("$minKey").isNumber())
return new BsonMinKey();
if(o.size() == 1 && o.has("$maxKey") && o.get("$maxKey").isNumber())
return new BsonMinKey();
if(o.size() == 1 && o.has("$symbol") && o.get("$symbol").isString())
return new BsonSymbol(o.string("$symbol"));
if(o.size() == 1 && o.has("$code") && o.get("$code").isString())
return new BsonJavaScript(o.string("$code"));
if(o.size() == 2 && o.has("$code") && o.has("$scope") && o.get("$code").isString() && o.get("$scope").isObject())
return new BsonJavaScriptWithScope(o.string("$code"), toBson(o.get("$scope")).asDocument());
if(o.size() == 1 && o.has("$timestamp") && o.get("$timestamp").isObject()) {
AbstractObject ts = o.object("$timestamp");
if(ts.has("t") && ts.has("i") && ts.get("t").isNumber() && ts.get("i").isNumber()) {
return new BsonTimestamp((int) ts.number("t").longValue(), (int) ts.number("i").longValue());
}
}
if(o.size() == 1 && o.has("$regularExpression") && o.get("$regularExpression").isObject()) {
AbstractObject re = o.object("$regularExpression");
if(re.has("pattern") && re.has("options") && re.get("pattern").isString() && (re.get("options").isString() || re.get("options").isNull())) {
return new BsonRegularExpression(re.string("pattern"), (String) re.toObject());
}
}
if(o.size() == 1 && o.has("$binary") && o.get("$binary").isObject()) {
AbstractObject bin = o.object("$binary");
if(bin.has("base64") && bin.has("subType") && bin.get("base64").isString() && bin.get("subType").isString()) {
byte[] data = Base64.decode(bin.string("base64"));
byte type = (byte) Integer.parseInt(bin.string("subType"), 16);
return new BsonBinary(type, data);
}
}
BsonDocument doc = new BsonDocument(o.size());
for(String k : o.keys())
doc.put(k, toBson(o.get(k)));
return doc;
}

}
Loading