/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.rest.converters;
import java.io.IOException;
import org.geoserver.config.util.XStreamPersister;
import org.geoserver.rest.wrapper.RestHttpInputWrapper;
import org.geoserver.rest.wrapper.RestListWrapper;
import org.geoserver.rest.wrapper.RestWrapper;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.json.JettisonMappedXmlDriver;
/**
* Message converter implementation for JSON serialization via XStream
*/
public class XStreamJSONMessageConverter extends XStreamMessageConverter<Object> {
static final MediaType TEXT_JSON = MediaType.valueOf("text/json");
public XStreamJSONMessageConverter() {
super(MediaType.APPLICATION_JSON, TEXT_JSON);
}
@Override
public String getExtension() {
return "json";
}
@Override
public String getMediaType() {
return MediaType.APPLICATION_JSON_VALUE;
}
@Override
protected boolean supports(Class<?> clazz) {
// if( RestWrapper.class.isAssignableFrom(clazz) ){
// return !RestListWrapper.class.isAssignableFrom(clazz); // we can only write RestWrapper, not RestListWrapper
// }
return true; // reading objects is fine
}
//
// reading
//
@Override
public Object readInternal(Class<?> clazz, HttpInputMessage inputMessage)
throws IOException, HttpMessageNotReadableException
{
XStreamPersister p = xpf.createJSONPersister();
p.setCatalog(catalog);
if (inputMessage instanceof RestHttpInputWrapper) {
((RestHttpInputWrapper) inputMessage).configurePersister(p, this);
}
return p.load(inputMessage.getBody(), clazz);
}
//
// writing
//
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
// we can only write RestWrapper, not RestListWrapper
return !RestListWrapper.class.isAssignableFrom(clazz) && RestWrapper.class.isAssignableFrom(clazz) && canWrite(mediaType);
}
@Override
public void writeInternal(Object o, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
XStreamPersister xmlPersister = xpf.createJSONPersister();
xmlPersister.setCatalog(catalog);
xmlPersister.setReferenceByName(true);
xmlPersister.setExcludeIds();
if (o instanceof RestWrapper) {
((RestWrapper<?>) o).configurePersister(xmlPersister, this);
o = ((RestWrapper<?>) o).getObject();
}
xmlPersister.save(o, outputMessage.getBody());
}
@Override
public void encodeLink(String link, HierarchicalStreamWriter writer) {
writer.startNode( "href" );
writer.setValue(href(link));
writer.endNode();
}
@Override
public void encodeCollectionLink(String link, HierarchicalStreamWriter writer) {
writer.setValue(href(link));
}
@Override
protected XStream createXStreamInstance() {
return new XStream(new JettisonMappedXmlDriver());
}
}