Created
December 10, 2014 22:52
-
-
Save brianv0/f34169345b86c6fbd174 to your computer and use it in GitHub Desktop.
YAML provider
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.lang.annotation.Annotation; | |
import javax.ws.rs.*; | |
import javax.ws.rs.core.*; | |
import javax.ws.rs.ext.*; | |
import com.fasterxml.jackson.core.*; | |
import com.fasterxml.jackson.databind.*; | |
import com.fasterxml.jackson.databind.cfg.PackageVersion; | |
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; | |
import com.fasterxml.jackson.jaxrs.base.ProviderBase; | |
import com.fasterxml.jackson.jaxrs.cfg.Annotations; | |
import com.fasterxml.jackson.jaxrs.cfg.EndpointConfigBase; | |
import com.fasterxml.jackson.jaxrs.cfg.MapperConfiguratorBase; | |
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory; | |
import java.util.ArrayList; | |
//import YamlEndpointConfig; | |
//import YamlMapperConfigurator; | |
/** | |
* | |
* @author bvan | |
*/ | |
@Provider | |
@Consumes({"application/yaml", "text/yaml"}) | |
@Produces({"application/yaml", "text/yaml"}) | |
public class JacksonYamlProvider | |
extends ProviderBase<JacksonYamlProvider, ObjectMapper, YamlEndpointConfig, YamlMapperConfigurator> { | |
public static class YamlMapperConfigurator | |
extends MapperConfiguratorBase<YamlMapperConfigurator, ObjectMapper> { | |
public YamlMapperConfigurator(ObjectMapper mapper, Annotations[] defAnnotations){ | |
super(mapper, defAnnotations); | |
} | |
/** | |
* Method that locates, configures and returns {@link ObjectMapper} to use | |
*/ | |
@Override | |
public synchronized ObjectMapper getConfiguredMapper(){ | |
/* important: should NOT call mapper(); needs to return null | |
* if no instance has been passed or constructed | |
*/ | |
return _mapper; | |
} | |
@Override | |
public synchronized ObjectMapper getDefaultMapper(){ | |
if(_defaultMapper == null){ | |
_defaultMapper = new ObjectMapper(new YAMLFactory()); | |
_setAnnotations(_defaultMapper, _defaultAnnotationsToUse); | |
} | |
return _defaultMapper; | |
} | |
@Override | |
protected ObjectMapper mapper(){ | |
if(_mapper == null){ | |
_mapper = new ObjectMapper(new YAMLFactory()); | |
_setAnnotations(_mapper, _defaultAnnotationsToUse); | |
} | |
return _mapper; | |
} | |
@Override | |
protected AnnotationIntrospector _resolveIntrospectors(Annotations[] annotationsToUse){ | |
// Let's ensure there are no dups there first, filter out nulls | |
ArrayList<AnnotationIntrospector> intr = new ArrayList<>(); | |
for(Annotations a: annotationsToUse){ | |
if(a != null){ | |
intr.add(_resolveIntrospector(a)); | |
} | |
} | |
int count = intr.size(); | |
if(count == 0){ | |
return AnnotationIntrospector.nopInstance(); | |
} | |
AnnotationIntrospector curr = intr.get(0); | |
for(int i = 1, len = intr.size(); i < len; ++i){ | |
curr = AnnotationIntrospector.pair(curr, intr.get(i)); | |
} | |
return curr; | |
} | |
protected AnnotationIntrospector _resolveIntrospector(Annotations ann){ | |
switch(ann){ | |
case JACKSON: | |
return new JacksonAnnotationIntrospector(); | |
default: | |
throw new IllegalStateException(); | |
} | |
} | |
} | |
public static class YamlEndpointConfig | |
extends EndpointConfigBase<YamlEndpointConfig> { | |
protected YamlEndpointConfig(){ | |
} | |
public static YamlEndpointConfig forReading(ObjectReader reader, | |
Annotation[] annotations){ | |
return new YamlEndpointConfig() | |
.add(annotations, false) | |
.initReader(reader); | |
} | |
public static YamlEndpointConfig forWriting(ObjectWriter writer, | |
Annotation[] annotations){ | |
YamlEndpointConfig config = new YamlEndpointConfig(); | |
return config | |
.add(annotations, true) | |
.initWriter(writer); | |
} | |
@Override | |
public Object modifyBeforeWrite(Object value){ | |
// nothing to add | |
return value; | |
} | |
} | |
public final static Annotations[] BASIC_ANNOTATIONS = { | |
Annotations.JACKSON | |
}; | |
@Context | |
protected Providers _providers; | |
public JacksonYamlProvider(){ | |
this(null, BASIC_ANNOTATIONS); | |
} | |
public JacksonYamlProvider(Annotations... annotationsToUse){ | |
this(null, annotationsToUse); | |
} | |
public JacksonYamlProvider(ObjectMapper mapper){ | |
this(mapper, BASIC_ANNOTATIONS); | |
} | |
public JacksonYamlProvider(ObjectMapper mapper, Annotations[] annotationsToUse){ | |
super(new YamlMapperConfigurator(mapper, annotationsToUse)); | |
} | |
@Override | |
public Version version(){ | |
return PackageVersion.VERSION; | |
} | |
@Override | |
protected boolean hasMatchingMediaType(MediaType mediaType){ | |
if(mediaType != null){ | |
String subtype = mediaType.getSubtype(); | |
return "yaml".equalsIgnoreCase(subtype) || subtype.endsWith("+yaml"); | |
} | |
return false; | |
} | |
@Override | |
protected ObjectMapper _locateMapperViaProvider(Class<?> type, MediaType mediaType){ | |
if(_providers != null){ | |
ContextResolver<ObjectMapper> resolver = _providers. | |
getContextResolver(ObjectMapper.class, mediaType); | |
if(resolver == null){ | |
resolver = _providers.getContextResolver(ObjectMapper.class, null); | |
} | |
if(resolver != null){ | |
return resolver.getContext(type); | |
} | |
} | |
return null; | |
} | |
@Override | |
protected YamlEndpointConfig _configForReading(ObjectReader reader, | |
Annotation[] annotations){ | |
return YamlEndpointConfig.forReading(reader, annotations); | |
} | |
@Override | |
protected YamlEndpointConfig _configForWriting(ObjectWriter writer, | |
Annotation[] annotations){ | |
return YamlEndpointConfig.forWriting(writer, annotations); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment