Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.jboss.resteasy.plugins.providers.jaxb.MapProvider Maven / Gradle / Ivy
package org.jboss.resteasy.plugins.providers.jaxb;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamSource;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.WebApplicationException;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.MultivaluedMap;
import jakarta.ws.rs.ext.ContextResolver;
import jakarta.ws.rs.ext.MessageBodyReader;
import jakarta.ws.rs.ext.Provider;
import jakarta.ws.rs.ext.Providers;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
import jakarta.xml.bind.Unmarshaller;
import jakarta.xml.bind.annotation.XmlRootElement;
import jakarta.xml.bind.annotation.XmlSeeAlso;
import jakarta.xml.bind.annotation.XmlType;
import org.jboss.resteasy.annotations.providers.jaxb.DoNotUseJAXBProvider;
import org.jboss.resteasy.annotations.providers.jaxb.WrappedMap;
import org.jboss.resteasy.core.ResteasyContext;
import org.jboss.resteasy.core.messagebody.AsyncBufferedMessageBodyWriter;
import org.jboss.resteasy.plugins.providers.jaxb.i18n.LogMessages;
import org.jboss.resteasy.plugins.providers.jaxb.i18n.Messages;
import org.jboss.resteasy.spi.ResteasyConfiguration;
import org.jboss.resteasy.spi.util.FindAnnotation;
import org.jboss.resteasy.spi.util.Types;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.xml.sax.InputSource;
/**
* @author Bill Burke
* @version $Revision: 1 $
*/
@Provider
@Produces({ "application/xml", "application/*+xml", "text/xml", "text/*+xml" })
@Consumes({ "application/xml", "application/*+xml", "text/xml", "text/*+xml" })
public class MapProvider implements MessageBodyReader, AsyncBufferedMessageBodyWriter {
@Context
protected Providers providers;
private boolean disableExternalEntities = true;
private boolean enableSecureProcessingFeature = true;
private boolean disableDTDs = true;
public MapProvider() {
ResteasyConfiguration context = ResteasyContext.getContextData(ResteasyConfiguration.class);
if (context != null) {
String s = context.getParameter("resteasy.document.expand.entity.references");
if (s != null) {
setDisableExternalEntities(!Boolean.parseBoolean(s));
}
s = context.getParameter("resteasy.document.secure.processing.feature");
if (s != null) {
setEnableSecureProcessingFeature(Boolean.parseBoolean(s));
}
s = context.getParameter("resteasy.document.secure.disableDTDs");
if (s != null) {
setDisableDTDs(Boolean.parseBoolean(s));
}
}
}
protected JAXBContextFinder getFinder(MediaType type) {
ContextResolver resolver = providers.getContextResolver(JAXBContextFinder.class, type);
if (resolver == null)
return null;
return resolver.getContext(null);
}
public boolean isReadable(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isWrapped(type, genericType, annotations, mediaType);
}
protected boolean isWrapped(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
if (Map.class.isAssignableFrom(type) && genericType != null) {
Class> keyType = Types.getMapKeyType(genericType);
if (keyType == null)
return false;
if (!CharSequence.class.isAssignableFrom(keyType) && !Number.class.isAssignableFrom(keyType))
return false;
Class> valueType = Types.getMapValueType(genericType);
if (valueType == null)
return false;
valueType = XmlAdapterWrapper.xmlAdapterValueType(valueType, annotations);
return (valueType.isAnnotationPresent(XmlRootElement.class) || valueType.isAnnotationPresent(XmlType.class)
|| valueType.isAnnotationPresent(XmlSeeAlso.class) || JAXBElement.class.equals(valueType))
&& (FindAnnotation.findAnnotation(valueType, annotations, DoNotUseJAXBProvider.class) == null)
&& !IgnoredMediaTypes.ignored(valueType, annotations, mediaType);
}
return false;
}
public Object getJAXBObject(JAXBContextFinder finder, MediaType mediaType, Class> clazz, Element element)
throws JAXBException {
JAXBContext ctx = finder.findCachedContext(clazz, mediaType, null);
return ctx.createUnmarshaller().unmarshal(element);
}
public Object readFrom(Class type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap httpHeaders, InputStream entityStream) throws IOException, WebApplicationException {
LogMessages.LOGGER.debugf("Provider : %s, Method : readFrom", getClass().getName());
JAXBContextFinder finder = getFinder(mediaType);
if (finder == null) {
throw new JAXBUnmarshalException(Messages.MESSAGES.unableToFindJAXBContext(mediaType));
}
Class valueType = Types.getMapValueType(genericType);
XmlAdapterWrapper xmlAdapter = XmlAdapterWrapper.getXmlAdapter(valueType, annotations);
if (xmlAdapter != null) {
valueType = xmlAdapter.getValueType();
}
JaxbMap jaxbMap = null;
JAXBElement ele = null;
try {
JAXBContext ctx = finder.findCacheContext(mediaType, annotations, JaxbMap.class, JaxbMap.Entry.class, valueType);
if (needsSecurity()) {
SAXSource source = null;
if (getCharset(mediaType) == null) {
source = new SAXSource(new InputSource(new InputStreamReader(entityStream, StandardCharsets.UTF_8)));
} else {
source = new SAXSource(new InputSource(entityStream));
}
Unmarshaller unmarshaller = ctx.createUnmarshaller();
unmarshaller = new SecureUnmarshaller(unmarshaller, disableExternalEntities, enableSecureProcessingFeature,
disableDTDs);
ele = unmarshaller.unmarshal(source, JaxbMap.class);
} else {
StreamSource source = null;
if (getCharset(mediaType) == null) {
source = new StreamSource(new InputStreamReader(entityStream, StandardCharsets.UTF_8));
} else {
source = new StreamSource(entityStream);
}
ele = ctx.createUnmarshaller().unmarshal(source, JaxbMap.class);
}
WrappedMap wrapped = FindAnnotation.findAnnotation(annotations, WrappedMap.class);
if (wrapped != null) {
if (!wrapped.map().equals(ele.getName().getLocalPart())) {
throw new JAXBUnmarshalException(
Messages.MESSAGES.mapWrappingFailedLocalPart(wrapped.map(), ele.getName().getLocalPart()));
}
if (!wrapped.namespace().equals(ele.getName().getNamespaceURI())) {
throw new JAXBUnmarshalException(
Messages.MESSAGES.mapWrappingFailedNamespace(wrapped.namespace(), ele.getName().getNamespaceURI()));
}
}
jaxbMap = ele.getValue();
HashMap map = new HashMap();
Unmarshaller unmarshaller = ctx.createUnmarshaller();
unmarshaller = AbstractJAXBProvider.decorateUnmarshaller(valueType, annotations, mediaType, unmarshaller);
for (int i = 0; i < jaxbMap.getValue().size(); i++) {
Element element = (Element) jaxbMap.getValue().get(i);
NamedNodeMap attributeMap = element.getAttributes();
String keyValue = null;
if (wrapped != null) {
keyValue = element.getAttribute(wrapped.key());
} else {
if (attributeMap.getLength() == 0)
throw new JAXBUnmarshalException(Messages.MESSAGES.mapWrappedFailedKeyAttribute());
for (int j = 0; j < attributeMap.getLength(); j++) {
Attr key = (Attr) attributeMap.item(j);
if (!key.getName().startsWith("xmlns")) {
keyValue = key.getValue();
break;
}
}
}
Object value = unmarshaller.unmarshal(element.getFirstChild());
if (xmlAdapter != null) {
try {
value = xmlAdapter.unmarshal(value);
} catch (Exception e) {
throw new JAXBUnmarshalException(e);
}
}
map.put(keyValue, value);
}
return map;
} catch (JAXBException e) {
throw new JAXBUnmarshalException(e);
}
}
public boolean isWriteable(Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return isWrapped(type, genericType, annotations, mediaType);
}
public long getSize(Object entry, Class> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
return -1;
}
public void writeTo(Object target, Class> type, Type genericType, Annotation[] annotations, MediaType mediaType,
MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException {
LogMessages.LOGGER.debugf("Provider : %s, Method : writeTo", getClass().getName());
JAXBContextFinder finder = getFinder(mediaType);
if (finder == null) {
throw new JAXBMarshalException(Messages.MESSAGES.unableToFindJAXBContext(mediaType));
}
Class valueType = Types.getMapValueType(genericType);
XmlAdapterWrapper xmlAdapter = XmlAdapterWrapper.getXmlAdapter(valueType, annotations);
if (xmlAdapter != null) {
valueType = xmlAdapter.getValueType();
}
try {
JAXBContext ctx = finder.findCacheContext(mediaType, annotations, JaxbMap.class, JaxbMap.Entry.class, valueType);
String mapName = "map";
String entryName = "entry";
String keyName = "key";
String namespaceURI = "";
String prefix = "";
WrappedMap wrapped = FindAnnotation.findAnnotation(annotations, WrappedMap.class);
if (wrapped != null) {
mapName = wrapped.map();
entryName = wrapped.entry();
namespaceURI = wrapped.namespace();
prefix = wrapped.prefix();
keyName = wrapped.key();
}
JaxbMap map = new JaxbMap(entryName, keyName, namespaceURI);
@SuppressWarnings("unchecked")
Map targetMap = (Map) target;
for (Map.Entry mapEntry : targetMap.entrySet()) {
Object value = mapEntry.getValue();
if (xmlAdapter != null) {
try {
value = xmlAdapter.marshal(value);
} catch (Exception e) {
throw new JAXBMarshalException(e);
}
}
map.addEntry(mapEntry.getKey().toString(), value);
}
JAXBElement jaxbMap = new JAXBElement(new QName(namespaceURI, mapName, prefix), JaxbMap.class,
map);
Marshaller marshaller = ctx.createMarshaller();
marshaller = AbstractJAXBProvider.decorateMarshaller(valueType, annotations, mediaType, marshaller);
marshaller.marshal(jaxbMap, entityStream);
} catch (JAXBException e) {
throw new JAXBMarshalException(e);
}
}
public boolean isDisableExternalEntities() {
return disableExternalEntities;
}
public void setDisableExternalEntities(boolean disableExternalEntities) {
this.disableExternalEntities = disableExternalEntities;
}
public boolean isEnableSecureProcessingFeature() {
return enableSecureProcessingFeature;
}
public void setEnableSecureProcessingFeature(boolean enableSecureProcessingFeature) {
this.enableSecureProcessingFeature = enableSecureProcessingFeature;
}
public boolean isDisableDTDs() {
return disableDTDs;
}
public void setDisableDTDs(boolean disableDTDs) {
this.disableDTDs = disableDTDs;
}
public static String getCharset(final MediaType mediaType) {
if (mediaType != null) {
return mediaType.getParameters().get("charset");
}
return null;
}
protected boolean needsSecurity() {
return true;
}
}