Skip to content

Instantly share code, notes, and snippets.

@cwensel
Last active March 30, 2017 22:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cwensel/5dd45db17d36858f820b9fa77d6b6cd7 to your computer and use it in GitHub Desktop.
Save cwensel/5dd45db17d36858f820b9fa77d6b6cd7 to your computer and use it in GitHub Desktop.
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