#165 - Removed support for Jackson 1.x.
This commit is contained in:
@@ -141,7 +141,6 @@ public class Link implements Serializable {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@org.codehaus.jackson.annotate.JsonIgnore
|
||||
@JsonIgnore
|
||||
public List<String> getVariableNames() {
|
||||
return getUriTemplate().getVariableNames();
|
||||
@@ -152,7 +151,6 @@ public class Link implements Serializable {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@org.codehaus.jackson.annotate.JsonIgnore
|
||||
@JsonIgnore
|
||||
public List<TemplateVariable> getVariables() {
|
||||
return getUriTemplate().getVariables();
|
||||
@@ -163,7 +161,6 @@ public class Link implements Serializable {
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@org.codehaus.jackson.annotate.JsonIgnore
|
||||
public boolean isTemplated() {
|
||||
return !getUriTemplate().getVariables().isEmpty();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* DTO to implement binding response representations of pageable collections.
|
||||
*
|
||||
@@ -71,8 +74,7 @@ public class PagedResources<T> extends Resources<T> {
|
||||
*
|
||||
* @return the metadata
|
||||
*/
|
||||
@org.codehaus.jackson.annotate.JsonProperty("page")
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("page")
|
||||
@JsonProperty("page")
|
||||
public PageMetadata getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
@@ -103,8 +105,7 @@ public class PagedResources<T> extends Resources<T> {
|
||||
* @see #addPaginationLinks(Link)
|
||||
* @return
|
||||
*/
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@org.codehaus.jackson.annotate.JsonIgnore
|
||||
@JsonIgnore
|
||||
public Link getNextLink() {
|
||||
return getLink(Link.REL_NEXT);
|
||||
}
|
||||
@@ -115,8 +116,7 @@ public class PagedResources<T> extends Resources<T> {
|
||||
* @see #addPaginationLinks(Link)
|
||||
* @return
|
||||
*/
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@org.codehaus.jackson.annotate.JsonIgnore
|
||||
@JsonIgnore
|
||||
public Link getPreviousLink() {
|
||||
return getLink(Link.REL_PREVIOUS);
|
||||
}
|
||||
@@ -170,25 +170,10 @@ public class PagedResources<T> extends Resources<T> {
|
||||
*/
|
||||
public static class PageMetadata {
|
||||
|
||||
@XmlAttribute//
|
||||
@org.codehaus.jackson.annotate.JsonProperty//
|
||||
@com.fasterxml.jackson.annotation.JsonProperty//
|
||||
private long size;
|
||||
|
||||
@XmlAttribute//
|
||||
@org.codehaus.jackson.annotate.JsonProperty//
|
||||
@com.fasterxml.jackson.annotation.JsonProperty//
|
||||
private long totalElements;
|
||||
|
||||
@XmlAttribute//
|
||||
@org.codehaus.jackson.annotate.JsonProperty//
|
||||
@com.fasterxml.jackson.annotation.JsonProperty//
|
||||
private long totalPages;
|
||||
|
||||
@XmlAttribute//
|
||||
@org.codehaus.jackson.annotate.JsonProperty//
|
||||
@com.fasterxml.jackson.annotation.JsonProperty//
|
||||
private long number;
|
||||
@XmlAttribute @JsonProperty private long size;
|
||||
@XmlAttribute @JsonProperty private long totalElements;
|
||||
@XmlAttribute @JsonProperty private long totalPages;
|
||||
@XmlAttribute @JsonProperty private long number;
|
||||
|
||||
protected PageMetadata() {
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonUnwrapped;
|
||||
|
||||
/**
|
||||
* A simple {@link Resource} wrapping a domain object and adding links to it.
|
||||
*
|
||||
@@ -69,8 +71,7 @@ public class Resource<T> extends ResourceSupport {
|
||||
*
|
||||
* @return the content
|
||||
*/
|
||||
@org.codehaus.jackson.annotate.JsonUnwrapped
|
||||
@com.fasterxml.jackson.annotation.JsonUnwrapped
|
||||
@JsonUnwrapped
|
||||
@XmlAnyElement
|
||||
public T getContent() {
|
||||
return content;
|
||||
|
||||
@@ -22,6 +22,9 @@ import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* Base class for DTOs to collect links.
|
||||
*
|
||||
@@ -38,8 +41,7 @@ public class ResourceSupport implements Identifiable<Link> {
|
||||
/**
|
||||
* Returns the {@link Link} with a rel of {@link Link#REL_SELF}.
|
||||
*/
|
||||
@org.codehaus.jackson.annotate.JsonIgnore
|
||||
@com.fasterxml.jackson.annotation.JsonIgnore
|
||||
@JsonIgnore
|
||||
public Link getId() {
|
||||
return getLink(Link.REL_SELF);
|
||||
}
|
||||
@@ -91,8 +93,7 @@ public class ResourceSupport implements Identifiable<Link> {
|
||||
* @return
|
||||
*/
|
||||
@XmlElement(name = "link", namespace = Link.ATOM_NAMESPACE)
|
||||
@org.codehaus.jackson.annotate.JsonProperty("links")
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("links")
|
||||
@JsonProperty("links")
|
||||
public List<Link> getLinks() {
|
||||
return links;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
|
||||
/**
|
||||
* General helper to easily create a wrapper for a collection of entities.
|
||||
*
|
||||
@@ -98,8 +100,7 @@ public class Resources<T> extends ResourceSupport implements Iterable<T> {
|
||||
*/
|
||||
@XmlAnyElement
|
||||
@XmlElementWrapper
|
||||
@org.codehaus.jackson.annotate.JsonProperty("content")
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("content")
|
||||
@JsonProperty("content")
|
||||
public Collection<T> getContent() {
|
||||
return Collections.unmodifiableCollection(content);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,10 @@ import javax.xml.bind.annotation.XmlType;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonValue;
|
||||
|
||||
/**
|
||||
* A representation model class to be rendered as specified for the media type {@code application/vnd.error}.
|
||||
*
|
||||
@@ -72,8 +76,7 @@ public class VndErrors implements Iterable<VndErrors.VndError> {
|
||||
*
|
||||
* @param errors must not be {@literal null} or empty.
|
||||
*/
|
||||
@com.fasterxml.jackson.annotation.JsonCreator
|
||||
@org.codehaus.jackson.annotate.JsonCreator
|
||||
@JsonCreator
|
||||
public VndErrors(List<VndError> errors) {
|
||||
|
||||
Assert.notNull(errors, "Errors must not be null!");
|
||||
@@ -103,8 +106,7 @@ public class VndErrors implements Iterable<VndErrors.VndError> {
|
||||
*
|
||||
* @return the vndErrors
|
||||
*/
|
||||
@com.fasterxml.jackson.annotation.JsonValue
|
||||
@org.codehaus.jackson.annotate.JsonValue
|
||||
@JsonValue
|
||||
private List<VndError> getErrors() {
|
||||
return vndErrors;
|
||||
}
|
||||
@@ -163,15 +165,8 @@ public class VndErrors implements Iterable<VndErrors.VndError> {
|
||||
@XmlType
|
||||
public static class VndError extends ResourceSupport {
|
||||
|
||||
@com.fasterxml.jackson.annotation.JsonProperty//
|
||||
@org.codehaus.jackson.annotate.JsonProperty//
|
||||
@XmlAttribute//
|
||||
private final String logref;
|
||||
|
||||
@com.fasterxml.jackson.annotation.JsonProperty//
|
||||
@org.codehaus.jackson.annotate.JsonProperty//
|
||||
@XmlElement//
|
||||
private final String message;
|
||||
@XmlAttribute @JsonProperty private final String logref;
|
||||
@XmlElement @JsonProperty private final String message;
|
||||
|
||||
/**
|
||||
* Creates a new {@link VndError} with the given logref, a message as well as some {@link Link}s.
|
||||
|
||||
@@ -51,11 +51,9 @@ import org.springframework.hateoas.core.DelegatingRelProvider;
|
||||
import org.springframework.hateoas.core.EvoInflectorRelProvider;
|
||||
import org.springframework.hateoas.hal.CurieProvider;
|
||||
import org.springframework.hateoas.hal.HalLinkDiscoverer;
|
||||
import org.springframework.hateoas.hal.Jackson1HalModule;
|
||||
import org.springframework.hateoas.hal.Jackson2HalModule;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.plugin.core.PluginRegistry;
|
||||
import org.springframework.plugin.core.support.PluginRegistryFactoryBean;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -78,7 +76,6 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
private static final String LINK_DISCOVERER_REGISTRY_BEAN_NAME = "_linkDiscovererRegistry";
|
||||
private static final String HAL_OBJECT_MAPPER_BEAN_NAME = "_halObjectMapper";
|
||||
|
||||
private static final boolean JACKSON1_PRESENT = ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", null);
|
||||
private static final boolean JACKSON2_PRESENT = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper",
|
||||
null);
|
||||
private static final boolean JSONPATH_PRESENT = ClassUtils.isPresent("com.jayway.jsonpath.JsonPath", null);
|
||||
@@ -119,11 +116,6 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
BeanDefinitionBuilder builder = rootBeanDefinition(Jackson2ModuleRegisteringBeanPostProcessor.class);
|
||||
registerSourcedBeanDefinition(builder, metadata, registry);
|
||||
}
|
||||
|
||||
if (JACKSON1_PRESENT) {
|
||||
BeanDefinitionBuilder builder = rootBeanDefinition(Jackson1ModuleRegisteringBeanPostProcessor.class);
|
||||
registerSourcedBeanDefinition(builder, metadata, registry);
|
||||
}
|
||||
}
|
||||
|
||||
if (!types.isEmpty()) {
|
||||
@@ -306,76 +298,4 @@ class HypermediaSupportBeanDefinitionRegistrar implements ImportBeanDefinitionRe
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link BeanPostProcessor} to register the {@link Jackson1HalModule} with
|
||||
* {@link org.codehaus.jackson.map.ObjectMapper} beans registered in the {@link ApplicationContext}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
private static class Jackson1ModuleRegisteringBeanPostProcessor implements BeanPostProcessor, BeanFactoryAware {
|
||||
|
||||
private RelProvider relProvider;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
|
||||
*/
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
this.relProvider = beanFactory.getBean(DELEGATING_REL_PROVIDER_BEAN_NAME, RelProvider.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
|
||||
|
||||
if (bean instanceof RequestMappingHandlerAdapter) {
|
||||
|
||||
RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean;
|
||||
adapter.setMessageConverters(registerModule(adapter.getMessageConverters()));
|
||||
}
|
||||
|
||||
if (bean instanceof AnnotationMethodHandlerAdapter) {
|
||||
|
||||
AnnotationMethodHandlerAdapter adapter = (AnnotationMethodHandlerAdapter) bean;
|
||||
List<HttpMessageConverter<?>> augmentedConverters = registerModule(Arrays
|
||||
.asList(adapter.getMessageConverters()));
|
||||
adapter
|
||||
.setMessageConverters(augmentedConverters.toArray(new HttpMessageConverter<?>[augmentedConverters.size()]));
|
||||
}
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
|
||||
private List<HttpMessageConverter<?>> registerModule(List<HttpMessageConverter<?>> converters) {
|
||||
|
||||
org.codehaus.jackson.map.ObjectMapper objectMapper = new org.codehaus.jackson.map.ObjectMapper();
|
||||
|
||||
objectMapper.registerModule(new Jackson1HalModule());
|
||||
objectMapper.setHandlerInstantiator(new Jackson1HalModule.HalHandlerInstantiator(relProvider));
|
||||
|
||||
MappingJacksonHttpMessageConverter halConverter = new MappingJacksonHttpMessageConverter();
|
||||
halConverter.setSupportedMediaTypes(Arrays.asList(HAL_JSON));
|
||||
halConverter.setObjectMapper(objectMapper);
|
||||
|
||||
List<HttpMessageConverter<?>> result = new ArrayList<HttpMessageConverter<?>>(converters.size());
|
||||
result.add(halConverter);
|
||||
result.addAll(converters);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,505 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.hateoas.hal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.codehaus.jackson.JsonGenerationException;
|
||||
import org.codehaus.jackson.JsonGenerator;
|
||||
import org.codehaus.jackson.JsonParseException;
|
||||
import org.codehaus.jackson.JsonParser;
|
||||
import org.codehaus.jackson.JsonProcessingException;
|
||||
import org.codehaus.jackson.JsonToken;
|
||||
import org.codehaus.jackson.Version;
|
||||
import org.codehaus.jackson.map.BeanProperty;
|
||||
import org.codehaus.jackson.map.ContextualDeserializer;
|
||||
import org.codehaus.jackson.map.ContextualSerializer;
|
||||
import org.codehaus.jackson.map.DeserializationConfig;
|
||||
import org.codehaus.jackson.map.DeserializationContext;
|
||||
import org.codehaus.jackson.map.HandlerInstantiator;
|
||||
import org.codehaus.jackson.map.JsonDeserializer;
|
||||
import org.codehaus.jackson.map.JsonMappingException;
|
||||
import org.codehaus.jackson.map.JsonSerializer;
|
||||
import org.codehaus.jackson.map.KeyDeserializer;
|
||||
import org.codehaus.jackson.map.MapperConfig;
|
||||
import org.codehaus.jackson.map.SerializationConfig;
|
||||
import org.codehaus.jackson.map.SerializerProvider;
|
||||
import org.codehaus.jackson.map.TypeSerializer;
|
||||
import org.codehaus.jackson.map.deser.std.ContainerDeserializerBase;
|
||||
import org.codehaus.jackson.map.introspect.Annotated;
|
||||
import org.codehaus.jackson.map.jsontype.TypeIdResolver;
|
||||
import org.codehaus.jackson.map.jsontype.TypeResolverBuilder;
|
||||
import org.codehaus.jackson.map.module.SimpleModule;
|
||||
import org.codehaus.jackson.map.ser.std.ContainerSerializerBase;
|
||||
import org.codehaus.jackson.map.ser.std.MapSerializer;
|
||||
import org.codehaus.jackson.map.type.TypeFactory;
|
||||
import org.codehaus.jackson.type.JavaType;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.RelProvider;
|
||||
import org.springframework.hateoas.Resource;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
import org.springframework.hateoas.Resources;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Jackson 1 module implementation to render {@link Link} and {@link ResourceSupport} instances in HAL compatible JSON.
|
||||
*
|
||||
* @deprecated use Jackson 2 instead
|
||||
* @author Alexander Baetz
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@Deprecated
|
||||
public class Jackson1HalModule extends SimpleModule {
|
||||
|
||||
/**
|
||||
* Creates a new {@link Jackson1HalModule}.
|
||||
*/
|
||||
public Jackson1HalModule() {
|
||||
|
||||
super("json-hal-module", new Version(1, 0, 0, null));
|
||||
|
||||
setMixInAnnotation(Link.class, LinkMixin.class);
|
||||
setMixInAnnotation(ResourceSupport.class, ResourceSupportMixin.class);
|
||||
setMixInAnnotation(Resources.class, ResourcesMixin.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link JsonSerializer} to render Link instances in HAL compatible JSON. Renders the list as a map, where
|
||||
* links are sorted based on their relation.
|
||||
*
|
||||
* @author Alexander Baetz
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class HalLinkListSerializer extends ContainerSerializerBase<List<Link>> implements
|
||||
ContextualSerializer<List<Link>> {
|
||||
|
||||
private final BeanProperty property;
|
||||
|
||||
/**
|
||||
* Creates a new {@link HalLinkListSerializer}.
|
||||
*/
|
||||
public HalLinkListSerializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public HalLinkListSerializer(BeanProperty property) {
|
||||
super(List.class, false);
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ser.std.SerializerBase#serialize(java.lang.Object, org.codehaus.jackson.JsonGenerator, org.codehaus.jackson.map.SerializerProvider)
|
||||
*/
|
||||
@Override
|
||||
public void serialize(List<Link> value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
|
||||
JsonGenerationException {
|
||||
|
||||
// sort links according to their relation
|
||||
Map<String, List<Link>> sortedLinks = new LinkedHashMap<String, List<Link>>();
|
||||
|
||||
for (Link link : value) {
|
||||
|
||||
if (sortedLinks.get(link.getRel()) == null) {
|
||||
sortedLinks.put(link.getRel(), new ArrayList<Link>());
|
||||
}
|
||||
|
||||
sortedLinks.get(link.getRel()).add(link);
|
||||
}
|
||||
|
||||
TypeFactory typeFactory = provider.getConfig().getTypeFactory();
|
||||
JavaType keyType = typeFactory.uncheckedSimpleType(String.class);
|
||||
JavaType valueType = typeFactory.constructCollectionType(ArrayList.class, Link.class);
|
||||
JavaType mapType = typeFactory.constructMapType(HashMap.class, keyType, valueType);
|
||||
|
||||
MapSerializer serializer = MapSerializer.construct(new String[] {}, mapType, true, null, null,
|
||||
provider.findKeySerializer(keyType, null), new OptionalListSerializer(property));
|
||||
|
||||
serializer.serialize(sortedLinks, jgen, provider);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ContextualSerializer#createContextual(org.codehaus.jackson.map.SerializationConfig, org.codehaus.jackson.map.BeanProperty)
|
||||
*/
|
||||
@Override
|
||||
public JsonSerializer<List<Link>> createContextual(SerializationConfig config, BeanProperty property)
|
||||
throws JsonMappingException {
|
||||
return new HalLinkListSerializer(property);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ser.std.ContainerSerializerBase#_withValueTypeSerializer(org.codehaus.jackson.map.TypeSerializer)
|
||||
*/
|
||||
@Override
|
||||
public ContainerSerializerBase<?> _withValueTypeSerializer(TypeSerializer vts) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link JsonSerializer} to render {@link Resource}-Lists in HAL compatible JSON. Renders the list as a Map.
|
||||
*
|
||||
* @author Alexander Baetz
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class HalResourcesSerializer extends ContainerSerializerBase<Collection<?>> implements
|
||||
ContextualSerializer<Collection<?>> {
|
||||
|
||||
private final BeanProperty property;
|
||||
private final RelProvider relProvider;
|
||||
|
||||
/**
|
||||
* Creates a new {@link HalLinkListSerializer}.
|
||||
*/
|
||||
public HalResourcesSerializer(RelProvider relProvider) {
|
||||
this(null, relProvider);
|
||||
}
|
||||
|
||||
public HalResourcesSerializer(BeanProperty property, RelProvider relProvider) {
|
||||
|
||||
super(Collection.class, false);
|
||||
this.property = property;
|
||||
this.relProvider = relProvider;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ser.std.SerializerBase#serialize(java.lang.Object, org.codehaus.jackson.JsonGenerator, org.codehaus.jackson.map.SerializerProvider)
|
||||
*/
|
||||
@Override
|
||||
public void serialize(Collection<?> value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
|
||||
JsonGenerationException {
|
||||
|
||||
HalEmbeddedBuilder builder = new HalEmbeddedBuilder(relProvider, false);
|
||||
|
||||
for (Object resource : value) {
|
||||
builder.add(resource);
|
||||
}
|
||||
|
||||
TypeFactory typeFactory = provider.getConfig().getTypeFactory();
|
||||
JavaType keyType = typeFactory.uncheckedSimpleType(String.class);
|
||||
JavaType valueType = typeFactory.constructCollectionType(ArrayList.class, Resource.class);
|
||||
JavaType mapType = typeFactory.constructMapType(HashMap.class, keyType, valueType);
|
||||
|
||||
MapSerializer serializer = MapSerializer.construct(new String[] {}, mapType, true, null, null,
|
||||
provider.findKeySerializer(keyType, null), new OptionalListSerializer(property));
|
||||
|
||||
serializer.serialize(builder.asMap(), jgen, provider);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ContextualSerializer#createContextual(org.codehaus.jackson.map.SerializationConfig, org.codehaus.jackson.map.BeanProperty)
|
||||
*/
|
||||
@Override
|
||||
public JsonSerializer<Collection<?>> createContextual(SerializationConfig config, BeanProperty property)
|
||||
throws JsonMappingException {
|
||||
return new HalResourcesSerializer(property, relProvider);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.codehaus.jackson.map.ser.std.ContainerSerializerBase#_withValueTypeSerializer(org.codehaus.jackson.map.TypeSerializer)
|
||||
*/
|
||||
@Override
|
||||
public ContainerSerializerBase<?> _withValueTypeSerializer(TypeSerializer vts) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom {@link JsonSerializer} to render Objects in HAL compatible JSON. Renders the Object as immediate object if
|
||||
* we have a single one or as array if we have multiple ones.
|
||||
*
|
||||
* @author Alexander Baetz
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public static class OptionalListSerializer extends ContainerSerializerBase<Object> {
|
||||
|
||||
private final BeanProperty property;
|
||||
private JsonSerializer<Object> serializer;
|
||||
|
||||
public OptionalListSerializer() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public OptionalListSerializer(BeanProperty property) {
|
||||
|
||||
super(List.class, false);
|
||||
this.property = property;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ser.std.ContainerSerializerBase#_withValueTypeSerializer(org.codehaus.jackson.map.TypeSerializer)
|
||||
*/
|
||||
@Override
|
||||
public ContainerSerializerBase<?> _withValueTypeSerializer(TypeSerializer vts) {
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ser.std.SerializerBase#serialize(java.lang.Object, org.codehaus.jackson.JsonGenerator, org.codehaus.jackson.map.SerializerProvider)
|
||||
*/
|
||||
@Override
|
||||
public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException,
|
||||
JsonGenerationException {
|
||||
|
||||
List<?> list = (List<?>) value;
|
||||
|
||||
if (list.size() == 1) {
|
||||
serializeContents(list.iterator(), jgen, provider);
|
||||
return;
|
||||
}
|
||||
|
||||
jgen.writeStartArray();
|
||||
serializeContents(list.iterator(), jgen, provider);
|
||||
jgen.writeEndArray();
|
||||
}
|
||||
|
||||
private void serializeContents(Iterator<?> value, JsonGenerator jgen, SerializerProvider provider)
|
||||
throws IOException, JsonGenerationException {
|
||||
|
||||
while (value.hasNext()) {
|
||||
Object elem = value.next();
|
||||
if (elem == null) {
|
||||
provider.defaultSerializeNull(jgen);
|
||||
} else {
|
||||
if (serializer == null) {
|
||||
serializer = provider.findValueSerializer(elem.getClass(), property);
|
||||
}
|
||||
serializer.serialize(elem, jgen, provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class HalLinkListDeserializer extends ContainerDeserializerBase<List<Link>> {
|
||||
|
||||
public HalLinkListDeserializer() {
|
||||
super(List.class);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.deser.std.ContainerDeserializerBase#getContentType()
|
||||
*/
|
||||
@Override
|
||||
public JavaType getContentType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.deser.std.ContainerDeserializerBase#getContentDeserializer()
|
||||
*/
|
||||
@Override
|
||||
public JsonDeserializer<Object> getContentDeserializer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.JsonDeserializer#deserialize(org.codehaus.jackson.JsonParser, org.codehaus.jackson.map.DeserializationContext)
|
||||
*/
|
||||
@Override
|
||||
public List<Link> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
|
||||
JsonProcessingException {
|
||||
|
||||
List<Link> result = new ArrayList<Link>();
|
||||
|
||||
// links is an object, so we parse till we find its end.
|
||||
while (!JsonToken.END_OBJECT.equals(jp.nextToken())) {
|
||||
|
||||
if (!JsonToken.FIELD_NAME.equals(jp.getCurrentToken())) {
|
||||
throw new JsonParseException("Expected relation name", jp.getCurrentLocation());
|
||||
}
|
||||
|
||||
// save the relation in case the link does not contain it
|
||||
String relation = jp.getText();
|
||||
|
||||
if (JsonToken.START_ARRAY.equals(jp.nextToken())) {
|
||||
while (!JsonToken.END_ARRAY.equals(jp.nextToken())) {
|
||||
result.add(getDefaultedLink(jp, relation));
|
||||
}
|
||||
} else {
|
||||
result.add(getDefaultedLink(jp, relation));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Link getDefaultedLink(JsonParser parser, String relation) throws JsonProcessingException, IOException {
|
||||
|
||||
Link link = parser.readValueAs(Link.class);
|
||||
return StringUtils.hasText(link.getRel()) ? link : new Link(link.getHref(), relation);
|
||||
}
|
||||
}
|
||||
|
||||
public static class HalResourcesDeserializer extends ContainerDeserializerBase<List<Object>> implements
|
||||
ContextualDeserializer<List<Object>> {
|
||||
|
||||
private final JavaType contentType;
|
||||
|
||||
public HalResourcesDeserializer() {
|
||||
this(List.class, null);
|
||||
}
|
||||
|
||||
public HalResourcesDeserializer(JavaType vc) {
|
||||
this(null, vc);
|
||||
}
|
||||
|
||||
private HalResourcesDeserializer(Class<?> type, JavaType contentType) {
|
||||
|
||||
super(type);
|
||||
this.contentType = contentType;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.deser.std.ContainerDeserializerBase#getContentType()
|
||||
*/
|
||||
@Override
|
||||
public JavaType getContentType() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.deser.std.ContainerDeserializerBase#getContentDeserializer()
|
||||
*/
|
||||
@Override
|
||||
public JsonDeserializer<Object> getContentDeserializer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.JsonDeserializer#deserialize(org.codehaus.jackson.JsonParser, org.codehaus.jackson.map.DeserializationContext)
|
||||
*/
|
||||
@Override
|
||||
public List<Object> deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
|
||||
JsonProcessingException {
|
||||
|
||||
List<Object> result = new ArrayList<Object>();
|
||||
JsonDeserializer<Object> deser = ctxt.getDeserializerProvider().findTypedValueDeserializer(ctxt.getConfig(),
|
||||
contentType, null);
|
||||
Object object;
|
||||
|
||||
// links is an object, so we parse till we find its end.
|
||||
while (!JsonToken.END_OBJECT.equals(jp.nextToken())) {
|
||||
|
||||
if (!JsonToken.FIELD_NAME.equals(jp.getCurrentToken())) {
|
||||
throw new JsonParseException("Expected relation name", jp.getCurrentLocation());
|
||||
}
|
||||
|
||||
if (JsonToken.START_ARRAY.equals(jp.nextToken())) {
|
||||
while (!JsonToken.END_ARRAY.equals(jp.nextToken())) {
|
||||
object = deser.deserialize(jp, ctxt);
|
||||
result.add(object);
|
||||
}
|
||||
} else {
|
||||
object = deser.deserialize(jp, ctxt);
|
||||
result.add(object);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.codehaus.jackson.map.ContextualDeserializer#createContextual(org.codehaus.jackson.map.DeserializationConfig, org.codehaus.jackson.map.BeanProperty)
|
||||
*/
|
||||
@Override
|
||||
public JsonDeserializer<List<Object>> createContextual(DeserializationConfig config, BeanProperty property)
|
||||
throws JsonMappingException {
|
||||
|
||||
JavaType vc = property.getType().getContentType();
|
||||
HalResourcesDeserializer des = new HalResourcesDeserializer(vc);
|
||||
return des;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HalHandlerInstantiator extends HandlerInstantiator {
|
||||
|
||||
private final Map<Class<?>, Object> instanceMap = new HashMap<Class<?>, Object>();
|
||||
|
||||
public HalHandlerInstantiator(RelProvider relProvider) {
|
||||
|
||||
Assert.notNull(relProvider, "RelProvider must not be null!");
|
||||
this.instanceMap.put(HalResourcesSerializer.class, new HalResourcesSerializer(null, relProvider));
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonDeserializer<?> deserializerInstance(DeserializationConfig config, Annotated annotated,
|
||||
Class<? extends JsonDeserializer<?>> deserClass) {
|
||||
return (JsonDeserializer<?>) findInstance(deserClass, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public KeyDeserializer keyDeserializerInstance(DeserializationConfig config, Annotated annotated,
|
||||
Class<? extends KeyDeserializer> keyDeserClass) {
|
||||
return (KeyDeserializer) findInstance(keyDeserClass, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonSerializer<?> serializerInstance(SerializationConfig config, Annotated annotated,
|
||||
Class<? extends JsonSerializer<?>> serClass) {
|
||||
// there is a know bug in jackson that will not create a serializer instance if the handler instantiator returns
|
||||
// null!
|
||||
return (JsonSerializer<?>) findInstance(serClass, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeResolverBuilder<?> typeResolverBuilderInstance(MapperConfig<?> config, Annotated annotated,
|
||||
Class<? extends TypeResolverBuilder<?>> builderClass) {
|
||||
return (TypeResolverBuilder<?>) findInstance(builderClass, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeIdResolver typeIdResolverInstance(MapperConfig<?> config, Annotated annotated,
|
||||
Class<? extends TypeIdResolver> resolverClass) {
|
||||
return (TypeIdResolver) findInstance(resolverClass, false);
|
||||
}
|
||||
|
||||
private Object findInstance(Class<?> type, boolean createInstance) {
|
||||
|
||||
Object result = instanceMap.get(type);
|
||||
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return createInstance ? BeanUtils.instantiateClass(type) : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.springframework.hateoas.hal;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.hal.Jackson2HalModule.TrueOnlyBooleanSerializer;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
@@ -28,8 +29,7 @@ import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
* @author Alexander Baetz
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@org.codehaus.jackson.annotate.JsonIgnoreProperties(value = "rel")
|
||||
@com.fasterxml.jackson.annotation.JsonIgnoreProperties(value = "rel")
|
||||
@JsonIgnoreProperties(value = "rel")
|
||||
abstract class LinkMixin extends Link {
|
||||
|
||||
private static final long serialVersionUID = 4720588561299667409L;
|
||||
|
||||
@@ -22,22 +22,16 @@ import javax.xml.bind.annotation.XmlElement;
|
||||
import org.springframework.hateoas.Link;
|
||||
import org.springframework.hateoas.ResourceSupport;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
abstract class ResourceSupportMixin extends ResourceSupport {
|
||||
|
||||
@Override
|
||||
@XmlElement(name = "link")
|
||||
@org.codehaus.jackson.annotate.JsonProperty("_links")
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("_links")
|
||||
@org.codehaus.jackson.map.annotate.JsonSerialize(
|
||||
include = org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_EMPTY,
|
||||
using = org.springframework.hateoas.hal.Jackson1HalModule.HalLinkListSerializer.class)
|
||||
@org.codehaus.jackson.map.annotate.JsonDeserialize(
|
||||
using = org.springframework.hateoas.hal.Jackson1HalModule.HalLinkListDeserializer.class)
|
||||
@com.fasterxml.jackson.databind.annotation.JsonSerialize(
|
||||
include = com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion.NON_EMPTY,
|
||||
using = org.springframework.hateoas.hal.Jackson2HalModule.HalLinkListSerializer.class)
|
||||
@com.fasterxml.jackson.databind.annotation.JsonDeserialize(
|
||||
using = org.springframework.hateoas.hal.Jackson2HalModule.HalLinkListDeserializer.class)
|
||||
@JsonProperty("_links")
|
||||
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY, using = Jackson2HalModule.HalLinkListSerializer.class)
|
||||
@JsonDeserialize(using = Jackson2HalModule.HalLinkListDeserializer.class)
|
||||
public abstract List<Link> getLinks();
|
||||
}
|
||||
|
||||
@@ -21,23 +21,17 @@ import javax.xml.bind.annotation.XmlElement;
|
||||
|
||||
import org.springframework.hateoas.Resources;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
|
||||
public abstract class ResourcesMixin<T> extends Resources<T> {
|
||||
|
||||
@Override
|
||||
@XmlElement(name = "embedded")
|
||||
@org.codehaus.jackson.annotate.JsonProperty("_embedded")
|
||||
@com.fasterxml.jackson.annotation.JsonProperty("_embedded")
|
||||
@org.codehaus.jackson.map.annotate.JsonSerialize(
|
||||
include = org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion.NON_EMPTY,
|
||||
using = org.springframework.hateoas.hal.Jackson1HalModule.HalResourcesSerializer.class)
|
||||
@org.codehaus.jackson.map.annotate.JsonDeserialize(
|
||||
using = org.springframework.hateoas.hal.Jackson1HalModule.HalResourcesDeserializer.class)
|
||||
@com.fasterxml.jackson.databind.annotation.JsonSerialize(
|
||||
include = com.fasterxml.jackson.databind.annotation.JsonSerialize.Inclusion.NON_EMPTY,
|
||||
using = org.springframework.hateoas.hal.Jackson2HalModule.HalResourcesSerializer.class)
|
||||
@com.fasterxml.jackson.databind.annotation.JsonDeserialize(
|
||||
using = org.springframework.hateoas.hal.Jackson2HalModule.HalResourcesDeserializer.class)
|
||||
@JsonProperty("_embedded")
|
||||
@JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY, using = Jackson2HalModule.HalResourcesSerializer.class)
|
||||
@JsonDeserialize(using = Jackson2HalModule.HalResourcesDeserializer.class)
|
||||
public abstract Collection<T> getContent();
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user