Last active
March 30, 2017 22:16
-
-
Save cwensel/5dd45db17d36858f820b9fa77d6b6cd7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.IOException; | |
import java.lang.reflect.Type; | |
import java.util.List; | |
import java.util.Map; | |
import cascading.CascadingException; | |
import cascading.tuple.coerce.Coercions; | |
import cascading.tuple.type.CoercibleType; | |
import cascading.util.Util; | |
import com.fasterxml.jackson.core.JsonProcessingException; | |
import com.fasterxml.jackson.databind.JsonNode; | |
import com.fasterxml.jackson.databind.ObjectMapper; | |
import com.fasterxml.jackson.databind.node.JsonNodeType; | |
/** | |
* | |
*/ | |
public class JSONCoercibleType implements CoercibleType<JsonNode> | |
{ | |
public static final JSONCoercibleType TYPE = new JSONCoercibleType(); | |
private static ObjectMapper mapper = JSONFactory.getObjectMapper(); | |
public JSONCoercibleType() | |
{ | |
} | |
@Override | |
public Class<JsonNode> getCanonicalType() | |
{ | |
return JsonNode.class; | |
} | |
@Override | |
public JsonNode canonical( Object value ) | |
{ | |
if( value == null ) | |
return null; | |
Class from = value.getClass(); | |
if( JsonNode.class.isAssignableFrom( from ) ) | |
return (JsonNode) value; | |
if( from == String.class ) | |
return parse( (String) value ); | |
throw new CascadingException( "unknown type coercion requested from: " + Util.getTypeName( from ) ); | |
} | |
@Override | |
public <Coerce> Coerce coerce( Object value, Type to ) | |
{ | |
if( to == null || to.getClass() == JSONCoercibleType.class ) | |
return (Coerce) value; | |
if( value == null ) | |
return null; | |
Class from = value.getClass(); | |
if( !JsonNode.class.isAssignableFrom( from ) ) | |
throw new IllegalStateException( "was not normalized" ); | |
JsonNode node = (JsonNode) value; | |
JsonNodeType nodeType = node.getNodeType(); | |
if( nodeType == JsonNodeType.NULL ) | |
return null; | |
if( to == String.class ) | |
return nodeType == JsonNodeType.STRING ? (Coerce) node.textValue() : (Coerce) write( value ); | |
if( to == Integer.class || to == Integer.TYPE ) | |
return nodeType == JsonNodeType.NUMBER ? (Coerce) Integer.valueOf( node.intValue() ) : (Coerce) Coercions.coerce( write( value ), to ); | |
if( to == Boolean.class || to == Boolean.TYPE ) | |
return nodeType == JsonNodeType.BOOLEAN ? (Coerce) Boolean.valueOf( node.booleanValue() ) : (Coerce) Coercions.coerce( write( value ), to ); | |
if( Map.class.isAssignableFrom( (Class<?>) to ) ) | |
return (Coerce) convert( value, (Class) to ); | |
if( List.class.isAssignableFrom( (Class<?>) to ) ) | |
return (Coerce) convert( value, (Class) to ); | |
throw new CascadingException( "unknown type coercion requested, from: " + Util.getTypeName( from ) + " to: " + Util.getTypeName( to ) ); | |
} | |
private Object convert( Object value, Class to ) | |
{ | |
return mapper.convertValue( value, to ); | |
} | |
private String write( Object value ) | |
{ | |
try | |
{ | |
return mapper.writeValueAsString( value ); | |
} | |
catch( JsonProcessingException exception ) | |
{ | |
throw new CascadingException( "unable to write value as json", exception ); | |
} | |
} | |
private JsonNode parse( String value ) | |
{ | |
try | |
{ | |
return mapper.readTree( value ); | |
} | |
catch( IOException exception ) | |
{ | |
throw new CascadingException( "unable to parse json", exception ); | |
} | |
} | |
@Override | |
public String toString() | |
{ | |
return getClass().getName(); | |
} | |
@Override | |
public int hashCode() | |
{ | |
return getCanonicalType().hashCode(); | |
} | |
@Override | |
public boolean equals( Object object ) | |
{ | |
if( this == object ) | |
return true; | |
if( !( object instanceof CoercibleType ) ) | |
return false; | |
return getCanonicalType().equals( ( (CoercibleType) object ).getCanonicalType() ); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment