Bug 8351: Enforce check-style rules for restconf - sal-rest-connector
[netconf.git] / restconf / sal-rest-connector / src / main / java / org / opendaylight / netconf / sal / rest / impl / XmlNormalizedNodeBodyReader.java
index 27f3e78cbc99327338a4a2946a2091042a510cf5..e8fabe5638f70d26f1124c7fa02a97c44e66b601 100644 (file)
@@ -24,9 +24,6 @@ import javax.ws.rs.core.MediaType;
 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;
@@ -34,8 +31,8 @@ import org.opendaylight.netconf.sal.restconf.impl.NormalizedNodeContext;
 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;
@@ -55,32 +52,15 @@ import org.slf4j.Logger;
 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,
@@ -88,29 +68,22 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
         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);
@@ -120,6 +93,18 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
         }
     }
 
+    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());
@@ -140,10 +125,9 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
         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);
@@ -166,8 +150,9 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
         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()) {
@@ -179,7 +164,8 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
         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);
@@ -229,7 +215,8 @@ public class XmlNormalizedNodeBodyReader extends AbstractIdentifierAwareJaxRsPro
         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());