import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.Provider;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
import org.opendaylight.netconf.sal.rest.api.Draft02;
import org.opendaylight.netconf.sal.rest.api.RestconfService;
import org.opendaylight.netconf.sal.restconf.impl.InstanceIdentifierContext;
import org.opendaylight.netconf.sal.restconf.impl.RestconfDocumentedException;
import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorTag;
import org.opendaylight.netconf.sal.restconf.impl.RestconfError.ErrorType;
-import org.opendaylight.restconf.Draft16;
import org.opendaylight.restconf.utils.RestconfConstants;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
+import org.xml.sax.SAXException;
@Provider
@Consumes({ Draft02.MediaTypes.DATA + RestconfService.XML, Draft02.MediaTypes.OPERATION + RestconfService.XML,
- Draft16.MediaTypes.DATA + RestconfConstants.XML_ORIG, MediaType.APPLICATION_XML, MediaType.TEXT_XML })
-public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider implements MessageBodyReader<NormalizedNodeContext> {
+ MediaType.APPLICATION_XML, MediaType.TEXT_XML })
+public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsProvider
+ implements MessageBodyReader<NormalizedNodeContext> {
- private final static Logger LOG = LoggerFactory.getLogger(XmlNormalizedNodeBodyReader.class);
- private static final DocumentBuilderFactory BUILDERFACTORY;
-
- static {
- final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- try {
- factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
- factory.setFeature("http://xml.org/sax/features/external-general-entities", false);
- factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
- factory.setXIncludeAware(false);
- factory.setExpandEntityReferences(false);
- } catch (final ParserConfigurationException e) {
- throw new ExceptionInInitializerError(e);
- }
- factory.setNamespaceAware(true);
- factory.setCoalescing(true);
- factory.setIgnoringElementContentWhitespace(true);
- factory.setIgnoringComments(true);
- BUILDERFACTORY = factory;
- }
+ private static final Logger LOG = LoggerFactory.getLogger(XmlNormalizedNodeBodyReader.class);
@Override
public boolean isReadable(final Class<?> type, final Type genericType, final Annotation[] annotations,
return true;
}
+ @SuppressWarnings("checkstyle:IllegalCatch")
@Override
public NormalizedNodeContext readFrom(final Class<NormalizedNodeContext> type, final Type genericType,
final Annotation[] annotations, final MediaType mediaType,
final MultivaluedMap<String, String> httpHeaders, final InputStream entityStream) throws IOException,
WebApplicationException {
try {
- final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
-
- if (entityStream.available() < 1) {
- // represent empty nopayload input
- return new NormalizedNodeContext(path, null);
- }
-
- final DocumentBuilder dBuilder;
- try {
- dBuilder = BUILDERFACTORY.newDocumentBuilder();
- } catch (final ParserConfigurationException e) {
- throw new RuntimeException("Failed to parse XML document", e);
+ if (getUriInfo().getAbsolutePath().getPath().contains(RestconfConstants.DRAFT_PATTERN)) {
+ final org.opendaylight.restconf.jersey.providers.XmlNormalizedNodeBodyReader xmlReaderNewRest =
+ new org.opendaylight.restconf.jersey.providers.XmlNormalizedNodeBodyReader();
+ xmlReaderNewRest.injectParams(getUriInfo(), getRequest());
+ return xmlReaderNewRest.readFrom(type, genericType, annotations, mediaType, httpHeaders, entityStream);
+ } else {
+ return readFrom(entityStream);
}
- final Document doc = dBuilder.parse(entityStream);
-
- return parse(path,doc);
- } catch (final RestconfDocumentedException e){
+ } catch (final RestconfDocumentedException e) {
throw e;
} catch (final Exception e) {
LOG.debug("Error parsing xml input", e);
}
}
+ private NormalizedNodeContext readFrom(final InputStream entityStream) throws IOException, SAXException {
+ final InstanceIdentifierContext<?> path = getInstanceIdentifierContext();
+
+ if (entityStream.available() < 1) {
+ // represent empty nopayload input
+ return new NormalizedNodeContext(path, null);
+ }
+
+ final Document doc = UntrustedXML.newDocumentBuilder().parse(entityStream);
+ return parse(path, doc);
+ }
+
private NormalizedNodeContext parse(final InstanceIdentifierContext<?> pathContext,final Document doc) {
final List<Element> elements = Collections.singletonList(doc.getDocumentElement());
final List<YangInstanceIdentifier.PathArgument> iiToDataList = new ArrayList<>();
InstanceIdentifierContext<? extends SchemaNode> outIIContext;
-
// FIXME the factory instance should be cached if the schema context is the same
- final DomToNormalizedNodeParserFactory parserFactory =
- DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, pathContext.getSchemaContext());
+ final DomToNormalizedNodeParserFactory parserFactory = DomToNormalizedNodeParserFactory
+ .getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, pathContext.getSchemaContext());
if (isPost() && !isRpc) {
final Deque<Object> foundSchemaNodes = findPathToSchemaNodeByName(schemaNode, docRootElm, docRootNamespace);
NormalizedNode<?, ?> parsed = null;
if (schemaNode instanceof ContainerSchemaNode) {
- parsed = parserFactory.getContainerNodeParser().parse(Collections.singletonList(doc.getDocumentElement()), (ContainerSchemaNode) schemaNode);
- } else if(schemaNode instanceof ListSchemaNode) {
+ parsed = parserFactory.getContainerNodeParser().parse(Collections.singletonList(doc.getDocumentElement()),
+ (ContainerSchemaNode) schemaNode);
+ } else if (schemaNode instanceof ListSchemaNode) {
final ListSchemaNode casted = (ListSchemaNode) schemaNode;
parsed = parserFactory.getMapEntryNodeParser().parse(elements, casted);
if (isPost()) {
final YangInstanceIdentifier fullIIToData = YangInstanceIdentifier.create(Iterables.concat(
pathContext.getInstanceIdentifier().getPathArguments(), iiToDataList));
- outIIContext = new InstanceIdentifierContext<>(fullIIToData, pathContext.getSchemaNode(), pathContext.getMountPoint(),
+ outIIContext = new InstanceIdentifierContext<>(fullIIToData, pathContext.getSchemaNode(),
+ pathContext.getMountPoint(),
pathContext.getSchemaContext());
return new NormalizedNodeContext(outIIContext, parsed);
return result;
}
- private static AugmentationSchema findCorrespondingAugment(final DataSchemaNode parent, final DataSchemaNode child) {
+ private static AugmentationSchema findCorrespondingAugment(final DataSchemaNode parent,
+ final DataSchemaNode child) {
if ((parent instanceof AugmentationTarget) && !(parent instanceof ChoiceSchemaNode)) {
for (final AugmentationSchema augmentation : ((AugmentationTarget) parent).getAvailableAugmentations()) {
final DataSchemaNode childInAugmentation = augmentation.getDataChildByName(child.getQName());