|
|
@@ -14,6 +14,7 @@ import java.io.IOException;
|
|
|
import java.util.*;
|
|
|
import java.util.Map.Entry;
|
|
|
import net.ranides.assira.collection.ArrayUtils;
|
|
|
+import net.ranides.assira.enums.EnumUtils;
|
|
|
import net.ranides.assira.generic.Function;
|
|
|
import net.ranides.assira.generic.TypeToken;
|
|
|
import net.ranides.assira.time.DateQuickFormat;
|
|
|
@@ -21,41 +22,41 @@ import net.ranides.assira.time.DateQuickFormat;
|
|
|
/**
|
|
|
* Klasa używana tylko do prezentowania obiektów jako tekst bardziej
|
|
|
* reprezentatywnie niż za pomocą wbudowanych metod "toString".
|
|
|
- *
|
|
|
+ *
|
|
|
* @author ranides
|
|
|
*/
|
|
|
public final class LexicalCast {
|
|
|
-
|
|
|
+
|
|
|
private static final TypeFactory TYPE_FACTORY = TypeFactory.defaultInstance();
|
|
|
private static final ObjectMapper MAPPER;
|
|
|
-
|
|
|
+
|
|
|
static {
|
|
|
MAPPER = new ObjectMapper();
|
|
|
MAPPER.configure(SerializationFeature.INDENT_OUTPUT, true);
|
|
|
}
|
|
|
|
|
|
private LexicalCast() { }
|
|
|
-
|
|
|
+
|
|
|
public static final Function<String, Object> SIMPLE = new SimpleFunction();
|
|
|
|
|
|
public static <T> List<String> asList(Iterable<T> values) {
|
|
|
return asList(values, SIMPLE);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static <T> List<String> asList(Iterable<T> values, Function<String,? super T> converter) {
|
|
|
List<String> result = makeList(values);
|
|
|
for(T value : values) { result.add( converter.apply(value) ); }
|
|
|
return result;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static <T> List<String> asList(T[] values) {
|
|
|
return asList(ArrayUtils.wrap(values));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static <T> List<String> asList(T[] values, Function<String,? super T> converter) {
|
|
|
return asList(ArrayUtils.wrap(values), converter);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static <K,V> List<String> asList(Map<K,V> map) {
|
|
|
List<String> result = new ArrayList<String>(map.size());
|
|
|
for(Entry<K,V> entry : map.entrySet()) {
|
|
|
@@ -63,7 +64,7 @@ public final class LexicalCast {
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static <K,V> List<String> asList(Map<K,V> map, Function<String,Entry<K,V>> converter) {
|
|
|
List<String> result = new ArrayList<String>(map.size());
|
|
|
for(Entry<K,V> entry : map.entrySet()) {
|
|
|
@@ -71,7 +72,7 @@ public final class LexicalCast {
|
|
|
}
|
|
|
return result;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
private static <T> List<String> makeList(Iterable<T> values) {
|
|
|
if( values instanceof Collection) {
|
|
|
return new ArrayList<String>( ((Collection)values).size() );
|
|
|
@@ -79,13 +80,13 @@ public final class LexicalCast {
|
|
|
return new LinkedList<String>();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-/* ************************************************************************** */
|
|
|
+
|
|
|
+/* ************************************************************************** */
|
|
|
|
|
|
public static <K,V> String asText(Map<K,V> map) {
|
|
|
return StringUtils.join(asList(map), "\n");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static String asText(Collection<?> values) {
|
|
|
List<String> list = asList(values, new FromObject(){
|
|
|
@Override
|
|
|
@@ -95,13 +96,13 @@ public final class LexicalCast {
|
|
|
});
|
|
|
return StringUtils.join(list, "\n");
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static <T> String apply(T value) {
|
|
|
return SIMPLE.apply(value);
|
|
|
}
|
|
|
-
|
|
|
-/* ************************************************************************** */
|
|
|
-
|
|
|
+
|
|
|
+/* ************************************************************************** */
|
|
|
+
|
|
|
public static String object2json(Object value) throws LexicalCastException {
|
|
|
try {
|
|
|
return MAPPER.writeValueAsString(value);
|
|
|
@@ -109,7 +110,7 @@ public final class LexicalCast {
|
|
|
throw new LexicalCastException(value.getClass()+" cannot be converted to JSON", cause);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static <T> T json2object(String value, Class<T> clazz) throws LexicalCastException {
|
|
|
try {
|
|
|
return MAPPER.readValue(value, clazz);
|
|
|
@@ -117,7 +118,7 @@ public final class LexicalCast {
|
|
|
throw new LexicalCastException(clazz + " cannot be created from JSON", cause);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("unchecked")
|
|
|
public static <T> T json2object(String value, TypeToken<T> token) throws LexicalCastException {
|
|
|
try {
|
|
|
@@ -126,19 +127,19 @@ public final class LexicalCast {
|
|
|
throw new LexicalCastException(token + " cannot be created from JSON", cause);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("unchecked")
|
|
|
public static <T> T cast(Object value, Class<T> clazz) throws ClassCastException {
|
|
|
return (T)rawCast(value, null, clazz);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("unchecked")
|
|
|
public static <T> T cast(Object value, TypeToken<T> token) throws LexicalCastException {
|
|
|
return (T)rawCast(value, token, TYPE_FACTORY.constructType( token.type() ).getRawClass());
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
@SuppressWarnings("PMD")
|
|
|
- private static Object rawCast(Object value, TypeToken<?> token, Class<?> clazz) {
|
|
|
+ private static Object rawCast(Object value, TypeToken<?> token, Class<?> clazz) {
|
|
|
// brak konwersji null
|
|
|
if(value==null) {
|
|
|
return null;
|
|
|
@@ -146,12 +147,20 @@ public final class LexicalCast {
|
|
|
if(clazz.equals(value.getClass()) && clazz.getTypeParameters().length==0) {
|
|
|
return value;
|
|
|
}
|
|
|
+ // konwersja EnumSet<?> -> String
|
|
|
+ if( value instanceof EnumSet && clazz.equals(String.class) ) {
|
|
|
+ return EnumUtils.encodeText((Set)value);
|
|
|
+ }
|
|
|
// konwersja Bool -> String
|
|
|
if(value instanceof Boolean && clazz.equals(String.class) ) {
|
|
|
return ((Boolean)value).toString();
|
|
|
}
|
|
|
// najpopularniejsze konwersje String -> Number / Bool / char[]
|
|
|
if(value instanceof String) {
|
|
|
+ // konwersja String -> Set<Enum<?>>
|
|
|
+ if( EnumSet.class.isAssignableFrom(clazz) ) {
|
|
|
+ return EnumUtils.decodeText((Class)token.params()[0].rawType(), (String)value );
|
|
|
+ }
|
|
|
if( clazz.equals(long.class) || clazz.equals(Long.class)) {
|
|
|
return Double.valueOf((String)value).longValue();
|
|
|
}
|
|
|
@@ -209,27 +218,19 @@ public final class LexicalCast {
|
|
|
error.initCause(cause);
|
|
|
throw error;
|
|
|
}
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- public static <E extends Enum<E>> EnumSet<E> splitEnum(Class<E> clazz, String values) throws IllegalArgumentException {
|
|
|
- EnumSet<E> result = EnumSet.noneOf(clazz);
|
|
|
- for(String mode : values.split(" ")) {
|
|
|
- if(Strings.isAssigned(mode)) { result.add( Enum.valueOf(clazz, mode) ); }
|
|
|
- }
|
|
|
- return result;
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
-/* ************************************************************************** */
|
|
|
-
|
|
|
- private static class SimpleFunction implements Function<String, Object> {
|
|
|
-
|
|
|
+
|
|
|
+/* ************************************************************************** */
|
|
|
+
|
|
|
+ private static class SimpleFunction implements Function<String, Object> {
|
|
|
+
|
|
|
@SuppressWarnings({"PMD.NPathComplexity", "PMD.CyclomaticComplexity"})
|
|
|
@Override
|
|
|
public String apply(Object value) {
|
|
|
if(value == null) {
|
|
|
return "";
|
|
|
- }
|
|
|
+ }
|
|
|
if( value instanceof String || value instanceof Character ) {
|
|
|
return StringCompiler.quote(value);
|
|
|
}
|
|
|
@@ -254,19 +255,19 @@ public final class LexicalCast {
|
|
|
return value.toString();
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public static abstract class FromObject implements Function<String, Object> {
|
|
|
+
|
|
|
+ public static abstract class FromObject implements Function<String, Object> {
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static abstract class FromEntry<K,V> implements Function<String, Entry<K,V>> {
|
|
|
-
|
|
|
+
|
|
|
public abstract String apply(K key, V value);
|
|
|
|
|
|
@Override
|
|
|
public String apply(Entry<K, V> source) {
|
|
|
return apply(source.getKey(), source.getValue());
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
}
|