package org.jboss.resteasy.plugins.providers;
import org.jboss.resteasy.plugins.providers.yaml.i18n.LogMessages;
import org.jboss.resteasy.plugins.providers.yaml.i18n.Messages;
import org.jboss.resteasy.spi.ReaderException;
import org.jboss.resteasy.spi.WriterException;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.CustomClassLoaderConstructor;
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.StreamingOutput;
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.Type;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Provider for YAML <-> Object marshalling. Uses the following mime
* types:<pre><code>
* text/yaml
* text/x-yaml
* application/x-yaml</code></pre>
*
* @author Martin Algesten
*/
@Provider
@Consumes({"text/yaml", "text/x-yaml", "application/x-yaml"})
@Produces({"text/yaml", "text/x-yaml", "application/x-yaml"})
public class YamlProvider extends AbstractEntityProvider<Object> {
// MessageBodyReader
public boolean isReadable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return true;
}
public Object readFrom(Class<Object> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream) throws IOException,
WebApplicationException {
try {
LogMessages.LOGGER.debugf("Provider : %s, Method : readFrom", getClass().getName());
if (isValidInternalType(type)) {
return new Yaml().load(entityStream);
} else {
CustomClassLoaderConstructor customClassLoaderConstructor = new CustomClassLoaderConstructor(type.getClassLoader());
return new Yaml(customClassLoaderConstructor).loadAs(entityStream, type);
}
} catch (Exception e) {
LogMessages.LOGGER.debug(Messages.MESSAGES.failedToDecodeYamlMessage(e.getMessage()));
throw new ReaderException(Messages.MESSAGES.failedToDecodeYaml(), e);
}
}
// MessageBodyWriter
protected boolean isValidInternalType(Class type) {
if (List.class.isAssignableFrom(type)
|| Set.class.isAssignableFrom(type)
|| Map.class.isAssignableFrom(type)
|| type.isArray()) {
return true;
} else {
return false;
}
}
protected boolean isValidType(Class type) {
if (isValidInternalType(type)) {
return true;
}
if (StreamingOutput.class.isAssignableFrom(type)) return false;
String className = type.getName();
if (className.startsWith("java.")) return false;
if (className.startsWith("javax.")) return false;
if (type.isPrimitive()) return false;
return true;
}
public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isValidType(type);
}
public void writeTo(Object t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream) throws IOException,
WebApplicationException {
try {
LogMessages.LOGGER.debugf("Provider : %s, Method : writeTo", getClass().getName());
entityStream.write(new Yaml().dump(t).getBytes());
} catch (Exception e) {
LogMessages.LOGGER.debug(Messages.MESSAGES.failedToEncodeYaml(t.toString()));
throw new WriterException(e);
}
}
}