Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
52 changes: 52 additions & 0 deletions boon/src/main/java/org/boon/core/Conversions.java
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,8 @@ public static <T> T coerce(TypeType coerceTo, Class<T> clz, Object value) {

case TIME_ZONE:
return (T) toTimeZone( value);
case LOCALE:
return (T) toLocale( value);



Expand Down Expand Up @@ -747,6 +749,8 @@ public static <T> T coerceWithFlag(TypeType coerceTo, Class<T> clz, boolean [] f
case TIME_ZONE:
return (T) toTimeZone(flag, value);

case LOCALE:
return (T) toLocale(value);

case UUID:
return (T) toUUID(flag, value);
Expand Down Expand Up @@ -779,6 +783,54 @@ public static TimeZone toTimeZone(Object value) {
return TimeZone.getTimeZone(id);
}

public static Locale toLocale(Object value) {
String locId = value.toString();
return toLocale(locId);
}

//(C) LocaleUtils from commons-lang
public static Locale toLocale(String str) {
if(str == null) {
return null;
} else {
int len = str.length();
if(len != 2 && len != 5 && len < 7) {
throw new IllegalArgumentException("Invalid locale format: " + str);
} else {
char ch0 = str.charAt(0);
char ch1 = str.charAt(1);
if(ch0 >= 97 && ch0 <= 122 && ch1 >= 97 && ch1 <= 122) {
if(len == 2) {
return new Locale(str, "");
} else if(str.charAt(2) != 95) {
throw new IllegalArgumentException("Invalid locale format: " + str);
} else {
char ch3 = str.charAt(3);
if(ch3 == 95) {
return new Locale(str.substring(0, 2), "", str.substring(4));
} else {
char ch4 = str.charAt(4);
if(ch3 >= 65 && ch3 <= 90 && ch4 >= 65 && ch4 <= 90) {
if(len == 5) {
return new Locale(str.substring(0, 2), str.substring(3, 5));
} else if(str.charAt(5) != 95) {
throw new IllegalArgumentException("Invalid locale format: " + str);
} else {
return new Locale(str.substring(0, 2), str.substring(3, 5), str.substring(6));
}
} else {
throw new IllegalArgumentException("Invalid locale format: " + str);
}
}
}
} else {
throw new IllegalArgumentException("Invalid locale format: " + str);
}
}
}
}


@SuppressWarnings("unchecked")
public static <T> T coerceClassic(Class<T> clz, Object value) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ private static Annotation[] extractAllAnnotationsForProperty( Class<?> clazz, St
/* In the land of dynamic proxied AOP classes,
* this class could be a proxy. This seems like a bug
* waiting to happen. So far it has worked... */
if ( annotations.length == 0 ) {
if ( annotations.length == 0 && clazz.getSuperclass() != null) {
annotations = findPropertyAnnotations( clazz.getSuperclass(), propertyName, useRead );
}
return annotations;
Expand Down
24 changes: 18 additions & 6 deletions boon/src/main/java/org/boon/core/reflection/MapperComplex.java
Original file line number Diff line number Diff line change
Expand Up @@ -180,14 +180,15 @@ public <T> List<T> convertListOfMapsToObjects(List<Map> list, Class<T> componen
/**
* fromMap converts a map into a java object
* @param map map to create the object from.
* @param cls class type of new object
* @param c class type of new object
* @param <T> map to create teh object from.
* @return new object of type cls <T>
*/
@Override
public <T> T fromMap(final Map<String, Object> map, final Class<T> cls) {
public <T> T fromMap(final Map<String, Object> map, final Class<T> c) {


final Class<T> cls = MapperSimple.handleAbstractReplacement(map, c);
T toObject = Reflection.newInstance( cls );
Map<String, FieldAccess> fields = fieldsAccessor.getFields( toObject.getClass() );
Set<Map.Entry<String, Object>> mapKeyValuesEntrySet = map.entrySet();
Expand Down Expand Up @@ -1171,14 +1172,15 @@ public Object fromValueMap(final Map<String, Value> valueMap
* This does some special handling to take advantage of us using the value map so it avoids creating
* a bunch of array objects and collections. Things you have to worry about when writing a
* high-speed JSON serializer.
* @param cls the new type
* @param c the new type
* @return new object from value map
*/
@Override
@SuppressWarnings("unchecked")
public <T> T fromValueMap(final Map<String, Value> valueMap,
final Class<T> cls) {
final Class<T> c) {

final Class<T> cls = MapperSimple.handleAbstractReplacement(valueMap, c);
T newInstance = Reflection.newInstance( cls );
ValueMap map = ( ValueMap ) ( Map ) valueMap;

Expand Down Expand Up @@ -1372,8 +1374,18 @@ private <T> void fromValueMapHandleValueCase(
evalue = ((ValueContainer) evalue).toValue();
}



key = Conversions.coerce( keyType, key );
evalue = Conversions.coerce( valueType, evalue );


Class actualType = valueType;
if ( valueType.isInterface() || Typ.isAbstract( valueType ) && evalue instanceof Map && ((Map)evalue).containsKey("class")) {
String className = ((Map)evalue)
.get("class").toString();
actualType = Reflection.loadClass( className );
}
evalue = Conversions.coerce( actualType, evalue );
newMap.put( key, evalue );
}

Expand Down Expand Up @@ -1842,4 +1854,4 @@ public List<?> toList(Object object) {
}


}
}
59 changes: 44 additions & 15 deletions boon/src/main/java/org/boon/core/reflection/MapperSimple.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,36 @@ public <T> List<T> convertListOfMapsToObjects(List<Map> list, Class<T> componen
return ( List<T> ) newList;
}

static <T> Class<T> handleAbstractReplacement(final Map<String, ?> map, final Class<T> cls) {
if (cls.isInterface() && Typ.isAbstract(cls)) {
if(map.containsKey("class")) {
String className = map.get("class").toString();
if (className != null) {
Class c = Reflection.loadClass(className);
if (cls.isAssignableFrom(c)) {
return c;
}
}

}
}
return cls;

}

/**
* fromMap converts a map into a java object
* @param map map to create the object from.
* @param cls class type of new object
* @param <T> map to create teh object from.
* @return new object of type cls <T>
*/
@Override
public <T> T fromMap(final Map<String, Object> map, final Class<T> cls) {




/**
* fromMap converts a map into a java object
* @param map map to create the object from.
* @param <T> map to create teh object from.
* @return new object of type cls <T>
*/
@Override
public <T> T fromMap(final Map<String, Object> map, final Class<T> c) {
final Class<T> cls = handleAbstractReplacement(map, c);
T toObject = Reflection.newInstance( cls );
Map<String, FieldAccess> fields = fieldsAccessor.getFields( toObject.getClass() );
Set<Map.Entry<String, Object>> mapKeyValuesEntrySet = map.entrySet();
Expand Down Expand Up @@ -1042,8 +1059,7 @@ private void handleCollectionOfValues(
*/
@Override
@SuppressWarnings("unchecked")
public Object fromValueMap(final Map<String, Value> valueMap
) {
public Object fromValueMap(final Map<String, Value> valueMap) {


try {
Expand All @@ -1063,14 +1079,15 @@ public Object fromValueMap(final Map<String, Value> valueMap
* This does some special handling to take advantage of us using the value map so it avoids creating
* a bunch of array objects and collections. Things you have to worry about when writing a
* high-speed JSON serializer.
* @param cls the new type
* @param c the new type
* @return new object from value map
*/
@Override
@SuppressWarnings("unchecked")
public <T> T fromValueMap(final Map<String, Value> valueMap,
final Class<T> cls) {
final Class<T> c) {

final Class<T> cls = handleAbstractReplacement(valueMap, c);
T newInstance = Reflection.newInstance( cls );
ValueMap map = ( ValueMap ) ( Map ) valueMap;

Expand Down Expand Up @@ -1259,7 +1276,13 @@ private <T> void fromValueMapHandleValueCase(
}

key = Conversions.coerce( keyType, key );
evalue = Conversions.coerce( valueType, evalue );
Class actualType = valueType;
if ( valueType.isInterface() || Typ.isAbstract( valueType ) && evalue instanceof Map && ((Map)evalue).containsKey("class")) {
String className = ((Map)evalue)
.get("class").toString();
actualType = Reflection.loadClass( className );
}
evalue = Conversions.coerce( actualType, evalue );
newMap.put( key, evalue );
}

Expand Down Expand Up @@ -1352,7 +1375,13 @@ private void setFieldValueFromMap( final Object parentObject,
}

key = Conversions.coerce(keyType, key);
evalue = Conversions.coerce( valueType, evalue );
Class actualType = valueType;
if ( valueType.isInterface() || Typ.isAbstract( valueType ) && evalue instanceof Map && ((Map)evalue).containsKey("class")) {
String className = ((Map)evalue)
.get("class").toString();
actualType = Reflection.loadClass( className );
}
evalue = Conversions.coerce( actualType, evalue );
newMap.put( key, evalue );
}

Expand Down
9 changes: 6 additions & 3 deletions boon/src/test/java/org/boon/bugs/BugReport165AndIssue169.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@



import org.boon.Boon;
import org.boon.IO;
import org.boon.json.JsonFactory;
import org.boon.json.ObjectMapper;
Expand Down Expand Up @@ -112,10 +113,10 @@ public Sample() {
e.printStackTrace();
}

file =new File("/usr/local/bin/vertx");
//file =new File("/usr/local/bin/vertx");

date = new Date();
path = file.toPath();
//path = file.toPath();
locale = Locale.CANADA;
timeZone = TimeZone.getTimeZone("PST");
}
Expand Down Expand Up @@ -194,6 +195,8 @@ public void test4() {
puts(json);
puts (sample1);

puts(Boon.toJson(Locale.CANADA_FRENCH));

ok = json.contains("\"effectiveDate\"") || die();

Sample sample2 = JsonFactory.fromJson(json, Sample.class);
Expand All @@ -202,7 +205,7 @@ public void test4() {

puts ("sample2", JsonFactory.toJson(sample2));

ok = sample1.equals(sample2);
ok = sample1.equals(sample2) || die();

}

Expand Down
13 changes: 13 additions & 0 deletions boon/src/test/java/org/boon/json/code/InterfaceB.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.boon.json.code;


/**
* Created by piyush.goyal on 9/22/16.
*/
public interface InterfaceB {

String getPiyush();

void setPiyush(String piyush);

}
88 changes: 88 additions & 0 deletions boon/src/test/java/org/boon/json/code/JsonAbstractClassesTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package org.boon.json.code;

import org.boon.json.JsonFactory;
import org.boon.json.JsonParserFactory;
import org.boon.json.JsonSerializer;
import org.boon.json.JsonSerializerFactory;
import org.boon.json.ObjectMapper;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by piyush.goyal on 8/17/17.
*/
public class JsonAbstractClassesTest {



private ObjectMapper mapper;

@Test
public void testAbstracTClassesWSimpleMapper() {
mapper = JsonFactory.create(new JsonParserFactory().useAnnotations(),
new JsonSerializerFactory().useAnnotations());
testAbstracTClasses();
}
@Test
public void testAbstracTClassesWComplexMapper() {
mapper = JsonFactory.create(new JsonParserFactory().setRespectIgnore(false).useAnnotations(),
new JsonSerializerFactory().useAnnotations());
testAbstracTClasses();
}

public void testAbstracTClasses() {


JsonClassC c = new JsonClassC();
c.setPiyush("Tosheer");

JsonClassD d = new JsonClassD();
d.setPiyush("VIvek");

Map<String, InterfaceB> map = new HashMap<>();
map.put("c", c);
map.put("d", d);

List<InterfaceB> list = new ArrayList<>();
list.add(c);
list.add(d);

JsonClassA jsonClassA = new JsonClassA();

jsonClassA.setTextValue("aa");
jsonClassA.setXx(map);
jsonClassA.setYy(list);

JsonSerializer serializer = new JsonSerializerFactory().setOutputType(true).create();

String s = serializer.serialize(jsonClassA).toString();
System.out.println(s);

//String json = "{\"class\":\"com.akqa.some.code.JsonClassA\",\"xx\":{\"c\":{\"class\":\"com.akqa.some.code.JsonClassC\",\"piyush\":\"Tosheer\"},\"d\":{\"class\":\"com.akqa.some.code.JsonClassD\",\"piyush\":\"VIvek\"}},\"textValue\":\"aa\"}";
String json = s;
JsonClassA jsonClassA1 = mapper.fromJson(json, JsonClassA.class);


assertEquals("aa", jsonClassA1.getTextValue());
Map<String, InterfaceB> xx = jsonClassA1.getXx();
InterfaceB c1 = xx.get("c");
InterfaceB d1 = xx.get("d");
assertEquals("Tosheer", c1.getPiyush());
assertEquals("VIvek", d1.getPiyush());
assertEquals(c.getClass(), c1.getClass());
assertEquals(d.getClass(), d1.getClass());
List<InterfaceB> list1= jsonClassA1.getYy();
c1 = list1.get(0);
d1 = list1.get(1);
assertEquals("Tosheer", c1.getPiyush());
assertEquals("VIvek", d1.getPiyush());
assertEquals(c.getClass(), c1.getClass());
assertEquals(d.getClass(), d1.getClass());
}
}
Loading