package org.gillius.Resources; import com.sun.jersey.core.provider.AbstractMessageReaderWriterProvider; import javax.ws.rs.Consumes; import javax.ws.rs.Produces; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * NumberProvider allows to read and write primitive types from resource methods as text/plain * format. * * @author Jason Winnebeck */ @Provider @Produces( { "text/plain" } ) @Consumes( { "text/plain" } ) public final class NumberProvider extends AbstractMessageReaderWriterProvider { private static final Map, Method> types; private static final Set> nullableTypes; static { types = new HashMap, Method>(); try { types.put( Long.class, Long.class.getMethod( "parseLong", String.class ) ); types.put( Integer.class, Integer.class.getMethod( "parseInt", String.class ) ); types.put( Short.class, Short.class.getMethod( "parseShort", String.class ) ); types.put( Byte.class, Byte.class.getMethod( "parseByte", String.class ) ); types.put( Float.class, Float.class.getMethod( "parseFloat", String.class ) ); types.put( Double.class, Double.class.getMethod( "parseDouble", String.class ) ); nullableTypes = new HashSet>( types.keySet() ); types.put( long.class, Long.class.getMethod( "parseLong", String.class ) ); types.put( int.class, Integer.class.getMethod( "parseInt", String.class ) ); types.put( short.class, Short.class.getMethod( "parseShort", String.class ) ); types.put( byte.class, Byte.class.getMethod( "parseByte", String.class ) ); types.put( float.class, Float.class.getMethod( "parseFloat", String.class ) ); types.put( double.class, Double.class.getMethod( "parseDouble", String.class ) ); } catch ( NoSuchMethodException e ) { throw new RuntimeException( "Missing core JDK method", e ); } } public boolean isReadable( Class type, Type genericType, Annotation annotations[], MediaType mediaType ) { return types.containsKey( type ); } public T readFrom( Class type, Type genericType, Annotation annotations[], MediaType mediaType, MultivaluedMap httpHeaders, InputStream entityStream ) throws IOException { String raw = readFromAsString( entityStream, mediaType ); try { if ( nullableTypes.contains( type ) && "null".equals( raw ) ) return null; else return (T) types.get( type ).invoke( null, raw ); } catch ( InvocationTargetException e ) { if ( e.getCause() instanceof NumberFormatException ) { throw new WebApplicationException( Response .status( Response.Status.BAD_REQUEST ) .entity( e.getCause().getMessage() ) .type( MediaType.TEXT_PLAIN_TYPE ).build() ); } else { throw new IOException( e ); } } catch ( Exception e ) { throw new IOException( e ); } } public boolean isWriteable( Class type, Type genericType, Annotation annotations[], MediaType mediaType ) { return types.containsKey( type ); } public void writeTo( T t, Class type, Type genericType, Annotation annotations[], MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream ) throws IOException { writeToAsString( String.valueOf( t ), entityStream, mediaType ); } }