This is an automated email from the ASF dual-hosted git repository.
greyp pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new b288810316 NIFI-9943 Added Transform Provider to nifi-xml-processing
b288810316 is described below
commit b288810316f7ecbc3ec943f64284f0494379b371
Author: exceptionfactory <[email protected]>
AuthorDate: Wed Apr 20 19:13:23 2022 -0500
NIFI-9943 Added Transform Provider to nifi-xml-processing
- Refactored TransformerFactory references using StandardTransformerProvider
This closes #5986
Signed-off-by: Paul Grey <[email protected]>
---
.../minifi/bootstrap/util/ConfigTransformer.java | 20 ++--
.../nifi/xml/processing/ProcessingAttribute.java | 47 ++++++++
.../transform/StandardTransformProvider.java | 118 +++++++++++++++++++++
.../processing/transform/TransformProvider.java | 33 ++++++
.../transform/StandardTransformProviderTest.java | 88 +++++++++++++++
.../org/apache/nifi/controller/TemplateUtils.java | 9 +-
.../serialization/StandardFlowSerializer.java | 18 ++--
.../main/java/org/apache/nifi/util/FlowParser.java | 11 +-
.../authorization/ManagedRangerAuthorizer.java | 11 +-
.../nifi-standard-content-viewer/pom.xml | 5 +
.../nifi/web/StandardContentViewerController.java | 17 ++-
.../nifi/processors/standard/EvaluateXPath.java | 63 ++---------
.../nifi/processors/standard/EvaluateXQuery.java | 60 +++++------
.../processors/standard/TestEvaluateXQuery.java | 18 ----
.../nifi/registry/ranger/RangerAuthorizer.java | 11 +-
15 files changed, 364 insertions(+), 165 deletions(-)
diff --git
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
index d3dc8eb382..04f903e192 100644
---
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
+++
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/ConfigTransformer.java
@@ -48,17 +48,13 @@ import
org.apache.nifi.minifi.commons.schema.serialization.SchemaLoader;
import org.apache.nifi.util.NiFiProperties;
import org.apache.nifi.xml.processing.ProcessingException;
import org.apache.nifi.xml.processing.parsers.StandardDocumentProvider;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.FileOutputStream;
@@ -147,20 +143,18 @@ public final class ConfigTransformer {
}
}
- protected static void writeFlowXmlFile(ConfigSchema configSchema,
OutputStream outputStream) throws TransformerException,
ConfigTransformerException {
+ protected static void writeFlowXmlFile(ConfigSchema configSchema,
OutputStream outputStream) throws ConfigTransformerException {
final StreamResult streamResult = new StreamResult(outputStream);
// configure the transformer and convert the DOM
- final TransformerFactory transformFactory =
TransformerFactory.newInstance();
- final Transformer transformer = transformFactory.newTransformer();
-
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ final StandardTransformProvider transformProvider = new
StandardTransformProvider();
+ transformProvider.setIndent(true);
// transform the document to byte stream
- transformer.transform(createFlowXml(configSchema), streamResult);
+ transformProvider.transform(createFlowXml(configSchema), streamResult);
}
- protected static void writeFlowXmlFile(ConfigSchema configSchema, String
path) throws IOException, TransformerException, ConfigurationChangeException,
ConfigTransformerException {
+ protected static void writeFlowXmlFile(ConfigSchema configSchema, String
path) throws IOException, ConfigTransformerException {
try (OutputStream fileOut = Files.newOutputStream(Paths.get(path,
"flow.xml.gz"))) {
try (OutputStream outStream = new GZIPOutputStream(fileOut)) {
writeFlowXmlFile(configSchema, outStream);
@@ -362,7 +356,7 @@ public final class ConfigTransformer {
}
return new DOMSource(doc);
- } catch (final ProcessingException | DOMException |
TransformerFactoryConfigurationError | IllegalArgumentException e) {
+ } catch (final ProcessingException | DOMException |
IllegalArgumentException e) {
throw new ConfigTransformerException(e);
} catch (Exception e) {
throw new ConfigTransformerException("Failed to parse the config
YAML while writing the top level of the flow xml", e);
diff --git
a/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/ProcessingAttribute.java
b/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/ProcessingAttribute.java
new file mode 100644
index 0000000000..0b50c430ee
--- /dev/null
+++
b/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/ProcessingAttribute.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.xml.processing;
+
+import javax.xml.XMLConstants;
+
+/**
+ * XML Processing Attributes
+ */
+public enum ProcessingAttribute {
+ /** Access External Document Type Declaration with an empty string to deny
all access to external references */
+ ACCESS_EXTERNAL_DTD(XMLConstants.ACCESS_EXTERNAL_DTD, ""),
+
+ /** Access External Stylesheet with an empty string to deny all access to
external references */
+ ACCESS_EXTERNAL_STYLESHEET(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, "");
+
+ private final String attribute;
+
+ private final Object value;
+
+ ProcessingAttribute(final String attribute, final Object value) {
+ this.attribute = attribute;
+ this.value = value;
+ }
+
+ public String getAttribute() {
+ return attribute;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+}
diff --git
a/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/transform/StandardTransformProvider.java
b/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/transform/StandardTransformProvider.java
new file mode 100644
index 0000000000..63ce2cb46b
--- /dev/null
+++
b/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/transform/StandardTransformProvider.java
@@ -0,0 +1,118 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.xml.processing.transform;
+
+import org.apache.nifi.xml.processing.ProcessingAttribute;
+import org.apache.nifi.xml.processing.ProcessingException;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import java.util.Objects;
+
+/**
+ * Standard implementation of Transform Provider with secure processing enabled
+ */
+public class StandardTransformProvider implements TransformProvider {
+ private static final boolean SECURE_PROCESSING_ENABLED = true;
+
+ private static final String ENABLED_PROPERTY = "yes";
+
+ private static final String INDENT_AMOUNT_OUTPUT_KEY =
"{http://xml.apache.org/xslt}indent-amount";
+
+ private static final String INDENT_AMOUNT = "2";
+
+ private boolean indent;
+
+ private boolean omitXmlDeclaration;
+
+ private String method;
+
+ /**
+ * Set Indent Status
+ *
+ * @param indent Indent Status
+ */
+ public void setIndent(final boolean indent) {
+ this.indent = indent;
+ }
+
+ /**
+ * Set Output Method
+ *
+ * @param method Method or null when default configuration should be used
+ */
+ public void setMethod(final String method) {
+ this.method = method;
+ }
+
+ /**
+ * Set Omit XML Declaration
+ *
+ * @param omitXmlDeclaration Omit XML Declaration
+ */
+ public void setOmitXmlDeclaration(final boolean omitXmlDeclaration) {
+ this.omitXmlDeclaration = omitXmlDeclaration;
+ }
+
+ /**
+ * Transform Source to Result
+ *
+ * @param source Source to be transformed
+ * @param result Result containing transformed information
+ */
+ @Override
+ public void transform(final Source source, final Result result) {
+ Objects.requireNonNull(source, "Source required");
+ Objects.requireNonNull(result, "Result required");
+
+ final TransformerFactory transformerFactory =
TransformerFactory.newInstance();
+ final Transformer transformer;
+ try {
+ transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD,
ProcessingAttribute.ACCESS_EXTERNAL_DTD.getValue());
+
transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET,
ProcessingAttribute.ACCESS_EXTERNAL_STYLESHEET.getValue());
+
transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING,
SECURE_PROCESSING_ENABLED);
+ transformer = transformerFactory.newTransformer();
+ } catch (final TransformerConfigurationException e) {
+ throw new ProcessingException("Transformer configuration failed",
e);
+ }
+
+ if (indent) {
+ transformer.setOutputProperty(OutputKeys.INDENT, ENABLED_PROPERTY);
+ transformer.setOutputProperty(INDENT_AMOUNT_OUTPUT_KEY,
INDENT_AMOUNT);
+ }
+
+ if (method != null) {
+ transformer.setOutputProperty(OutputKeys.METHOD, method);
+ }
+
+ if (omitXmlDeclaration) {
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,
ENABLED_PROPERTY);
+ }
+
+ try {
+ transformer.transform(source, result);
+ } catch (final TransformerException e) {
+ throw new ProcessingException("Transform failed", e);
+ }
+ }
+}
diff --git
a/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/transform/TransformProvider.java
b/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/transform/TransformProvider.java
new file mode 100644
index 0000000000..689f87fbe4
--- /dev/null
+++
b/nifi-commons/nifi-xml-processing/src/main/java/org/apache/nifi/xml/processing/transform/TransformProvider.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.xml.processing.transform;
+
+import javax.xml.transform.Result;
+import javax.xml.transform.Source;
+
+/**
+ * XML Transformation Provider
+ */
+public interface TransformProvider {
+ /**
+ * Transform Source to Result
+ *
+ * @param source Source to be transformed
+ * @param result Result containing transformed information
+ */
+ void transform(Source source, Result result);
+}
diff --git
a/nifi-commons/nifi-xml-processing/src/test/java/org/apache/nifi/xml/processing/transform/StandardTransformProviderTest.java
b/nifi-commons/nifi-xml-processing/src/test/java/org/apache/nifi/xml/processing/transform/StandardTransformProviderTest.java
new file mode 100644
index 0000000000..fa00901724
--- /dev/null
+++
b/nifi-commons/nifi-xml-processing/src/test/java/org/apache/nifi/xml/processing/transform/StandardTransformProviderTest.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.nifi.xml.processing.transform;
+
+import org.apache.nifi.xml.processing.ProcessingException;
+import org.apache.nifi.xml.processing.ResourceProvider;
+import org.junit.jupiter.api.Test;
+import org.w3c.dom.Node;
+
+import javax.xml.transform.Source;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.stream.StreamSource;
+import java.io.IOException;
+import java.io.InputStream;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class StandardTransformProviderTest {
+ private static final String METHOD = "xml";
+
+ @Test
+ void testTransformStandard() throws IOException {
+ final StandardTransformProvider provider = new
StandardTransformProvider();
+
+ final DOMResult result = new DOMResult();
+
+ try (final InputStream inputStream =
ResourceProvider.getStandardDocument()) {
+ final Source source = new StreamSource(inputStream);
+ provider.transform(source, result);
+ }
+
+ assertDocumentNodeFound(result);
+ }
+
+ @Test
+ void testTransformStandardDocumentTypeDeclaration() throws IOException {
+ final StandardTransformProvider provider = new
StandardTransformProvider();
+ provider.setIndent(true);
+ provider.setOmitXmlDeclaration(true);
+ provider.setMethod(METHOD);
+
+ final DOMResult result = new DOMResult();
+
+ try (final InputStream inputStream =
ResourceProvider.getStandardDocumentDocType()) {
+ final Source source = new StreamSource(inputStream);
+ provider.transform(source, result);
+ }
+
+ assertDocumentNodeFound(result);
+ }
+
+ @Test
+ void testTransformStandardExternalEntityException() throws IOException {
+ final StandardTransformProvider provider = new
StandardTransformProvider();
+
+ final DOMResult result = new DOMResult();
+
+ try (final InputStream inputStream =
ResourceProvider.getStandardDocumentDocTypeEntity()) {
+ final Source source = new StreamSource(inputStream);
+ final ProcessingException processingException =
assertThrows(ProcessingException.class, () -> provider.transform(source,
result));
+ assertInstanceOf(TransformerException.class,
processingException.getCause());
+ }
+ }
+
+ private void assertDocumentNodeFound(final DOMResult result) {
+ final Node node = result.getNode();
+ assertNotNull(node);
+ assertEquals(Node.DOCUMENT_NODE, node.getNodeType());
+ }
+}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java
index 26db5c8d6d..6297f390c5 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/TemplateUtils.java
@@ -32,10 +32,10 @@ import org.apache.nifi.web.api.dto.PropertyDescriptorDTO;
import org.apache.nifi.web.api.dto.RelationshipDTO;
import org.apache.nifi.web.api.dto.RemoteProcessGroupDTO;
import org.apache.nifi.web.api.dto.TemplateDTO;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
+import org.apache.nifi.xml.processing.transform.TransformProvider;
import org.w3c.dom.Element;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
@@ -58,9 +58,8 @@ public class TemplateUtils {
// need to stream the template element as the
TemplateDeserializer.deserialize operation needs to re-parse
// in order to apply explicit properties on the XMLInputFactory
- final TransformerFactory transformerFactory =
TransformerFactory.newInstance();
- final Transformer transformer =
transformerFactory.newTransformer();
- transformer.transform(domSource, streamResult);
+ final TransformProvider transformProvider = new
StandardTransformProvider();
+ transformProvider.transform(domSource, streamResult);
return parseDto(baos.toByteArray());
} catch (final Exception e) {
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/StandardFlowSerializer.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/StandardFlowSerializer.java
index 549b3b4f4b..e76797827b 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/StandardFlowSerializer.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/controller/serialization/StandardFlowSerializer.java
@@ -52,16 +52,12 @@ import org.apache.nifi.util.CharacterFilterUtils;
import org.apache.nifi.util.StringUtils;
import org.apache.nifi.xml.processing.ProcessingException;
import org.apache.nifi.xml.processing.parsers.StandardDocumentProvider;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.BufferedOutputStream;
@@ -127,7 +123,7 @@ public class StandardFlowSerializer implements
FlowSerializer<Document> {
}
return doc;
- } catch (final ProcessingException | DOMException |
TransformerFactoryConfigurationError | IllegalArgumentException e) {
+ } catch (final ProcessingException | DOMException |
IllegalArgumentException e) {
throw new FlowSerializationException(e);
}
}
@@ -139,15 +135,13 @@ public class StandardFlowSerializer implements
FlowSerializer<Document> {
final StreamResult streamResult = new StreamResult(new
BufferedOutputStream(os));
// configure the transformer and convert the DOM
- final TransformerFactory transformFactory =
TransformerFactory.newInstance();
- final Transformer transformer = transformFactory.newTransformer();
-
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ final StandardTransformProvider transformProvider = new
StandardTransformProvider();
+ transformProvider.setIndent(true);
// transform the document to byte stream
- transformer.transform(domSource, streamResult);
+ transformProvider.transform(domSource, streamResult);
- } catch (final DOMException | TransformerFactoryConfigurationError |
IllegalArgumentException | TransformerException e) {
+ } catch (final DOMException | IllegalArgumentException |
ProcessingException e) {
throw new FlowSerializationException(e);
}
}
diff --git
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/FlowParser.java
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/FlowParser.java
index cc1d652eac..a1302500e5 100644
---
a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/FlowParser.java
+++
b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-framework-core/src/main/java/org/apache/nifi/util/FlowParser.java
@@ -27,6 +27,8 @@ import org.apache.nifi.web.api.dto.PortDTO;
import org.apache.nifi.web.api.dto.PositionDTO;
import org.apache.nifi.xml.processing.ProcessingException;
import org.apache.nifi.xml.processing.parsers.StandardDocumentProvider;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
+import org.apache.nifi.xml.processing.transform.TransformProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
@@ -40,8 +42,6 @@ import javax.xml.XMLConstants;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.validation.Schema;
@@ -278,13 +278,14 @@ public class FlowParser {
* @param flowDocument flowDocument of the associated XML content to write
to disk
* @param flowXmlPath path on disk to write the flow
* @throws IOException if there are issues in accessing the target
destination for the flow
- * @throws TransformerException if there are issues in the xml
transformation process
*/
- public void writeFlow(final Document flowDocument, final Path flowXmlPath)
throws IOException, TransformerException {
+ public void writeFlow(final Document flowDocument, final Path flowXmlPath)
throws IOException {
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final Source xmlSource = new DOMSource(flowDocument);
final Result outputTarget = new StreamResult(outputStream);
- TransformerFactory.newInstance().newTransformer().transform(xmlSource,
outputTarget);
+
+ final TransformProvider transformProvider = new
StandardTransformProvider();
+ transformProvider.transform(xmlSource, outputTarget);
final InputStream is = new
ByteArrayInputStream(outputStream.toByteArray());
try (final OutputStream output = Files.newOutputStream(flowXmlPath,
StandardOpenOption.WRITE, StandardOpenOption.CREATE);
diff --git
a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/ManagedRangerAuthorizer.java
b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/ManagedRangerAuthorizer.java
index 4f5f340ff6..376f1e55ca 100644
---
a/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/ManagedRangerAuthorizer.java
+++
b/nifi-nar-bundles/nifi-ranger-bundle/nifi-ranger-plugin/src/main/java/org/apache/nifi/ranger/authorization/ManagedRangerAuthorizer.java
@@ -23,9 +23,6 @@ import java.io.IOException;
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Set;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang.StringUtils;
@@ -45,6 +42,8 @@ import
org.apache.nifi.authorization.exception.AuthorizerDestructionException;
import
org.apache.nifi.authorization.exception.UninheritableAuthorizationsException;
import org.apache.nifi.xml.processing.ProcessingException;
import org.apache.nifi.xml.processing.parsers.StandardDocumentProvider;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
+import org.apache.nifi.xml.processing.transform.TransformProvider;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -142,9 +141,9 @@ public class ManagedRangerAuthorizer extends
RangerNiFiAuthorizer implements Man
userGroupProviderElement.appendChild(document.createTextNode(((ConfigurableUserGroupProvider)
userGroupProvider).getFingerprint()));
}
- final Transformer transformer =
TransformerFactory.newInstance().newTransformer();
- transformer.transform(new DOMSource(document), new
StreamResult(out));
- } catch (final ProcessingException | TransformerException e) {
+ final TransformProvider transformProvider = new
StandardTransformProvider();
+ transformProvider.transform(new DOMSource(document), new
StreamResult(out));
+ } catch (final ProcessingException e) {
throw new AuthorizationAccessException("Unable to generate
fingerprint", e);
}
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
index df1b21947d..a0ecda0357 100644
--- a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
+++ b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/pom.xml
@@ -34,6 +34,11 @@
<version>1.17.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.nifi</groupId>
+ <artifactId>nifi-xml-processing</artifactId>
+ <version>1.17.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
index 405b11c007..ce0e719612 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-content-viewer/src/main/java/org/apache/nifi/web/StandardContentViewerController.java
@@ -25,6 +25,8 @@ import org.apache.avro.generic.GenericData;
import org.apache.avro.generic.GenericDatumReader;
import org.apache.avro.io.DatumReader;
import org.apache.nifi.web.ViewableContent.DisplayMode;
+import org.apache.nifi.xml.processing.ProcessingException;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
import org.joda.time.DateTime;
import org.joda.time.LocalDate;
import org.joda.time.LocalTime;
@@ -33,11 +35,6 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.IOException;
@@ -94,13 +91,11 @@ public class StandardContentViewerController extends
HttpServlet {
final StreamSource source = new
StreamSource(content.getContentStream());
final StreamResult result = new StreamResult(writer);
- final TransformerFactory transformFactory =
TransformerFactory.newInstance();
- final Transformer transformer =
transformFactory.newTransformer();
-
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
- transformer.setOutputProperty(OutputKeys.INDENT,
"yes");
+ final StandardTransformProvider transformProvider =
new StandardTransformProvider();
+ transformProvider.setIndent(true);
- transformer.transform(source, result);
- } catch (final TransformerFactoryConfigurationError |
TransformerException te) {
+ transformProvider.transform(source, result);
+ } catch (final ProcessingException te) {
throw new IOException("Unable to transform content as
XML: " + te, te);
}
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXPath.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXPath.java
index de1c05424b..2250b4c4c2 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXPath.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXPath.java
@@ -32,18 +32,11 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import javax.xml.namespace.QName;
-import javax.xml.transform.ErrorListener;
-import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPathExpression;
@@ -77,7 +70,9 @@ import
org.apache.nifi.processor.ProcessorInitializationContext;
import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.exception.ProcessException;
import
org.apache.nifi.processors.standard.xml.DocumentTypeAllowedDocumentProvider;
+import org.apache.nifi.xml.processing.ProcessingException;
import org.apache.nifi.xml.processing.parsers.StandardDocumentProvider;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
import org.w3c.dom.Document;
import net.sf.saxon.xpath.XPathEvaluator;
@@ -278,6 +273,8 @@ public class EvaluateXPath extends AbstractProcessor {
final boolean validatingDeclaration =
context.getProperty(VALIDATE_DTD).asBoolean();
+ final StandardTransformProvider transformProvider = new
StandardTransformProvider();
+ transformProvider.setIndent(true);
flowFileLoop:
for (FlowFile flowFile : flowFiles) {
final AtomicReference<Throwable> error = new
AtomicReference<>(null);
@@ -331,17 +328,19 @@ public class EvaluateXPath extends AbstractProcessor {
if (DESTINATION_ATTRIBUTE.equals(destination)) {
try {
ByteArrayOutputStream baos = new
ByteArrayOutputStream();
- doTransform(sourceNode, baos);
+ final StreamResult streamResult = new
StreamResult(baos);
+ transformProvider.transform(sourceNode,
streamResult);
xpathResults.put(entry.getKey(), new
String(baos.toByteArray(), StandardCharsets.UTF_8));
- } catch (TransformerException e) {
+ } catch (final ProcessingException e) {
error.set(e);
}
} else if (DESTINATION_CONTENT.equals(destination)) {
flowFile = session.write(flowFile, rawOut -> {
try (final OutputStream out = new
BufferedOutputStream(rawOut)) {
- doTransform(sourceNode, out);
- } catch (TransformerException e) {
+ final StreamResult streamResult = new
StreamResult(out);
+ transformProvider.transform(sourceNode,
streamResult);
+ } catch (final ProcessingException e) {
error.set(e);
}
});
@@ -381,48 +380,6 @@ public class EvaluateXPath extends AbstractProcessor {
}
}
- private void doTransform(final Source sourceNode, OutputStream out) throws
TransformerFactoryConfigurationError, TransformerException {
- final Transformer transformer;
- try {
- transformer = TransformerFactory.newInstance().newTransformer();
- } catch (final Exception e) {
- throw new ProcessException(e);
- }
-
- final Properties props = new Properties();
- props.setProperty(OutputKeys.METHOD, "xml");
- props.setProperty(OutputKeys.INDENT, "no");
- props.setProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
- transformer.setOutputProperties(props);
-
- final ComponentLog logger = getLogger();
-
- final AtomicReference<TransformerException> error = new
AtomicReference<>(null);
- transformer.setErrorListener(new ErrorListener() {
- @Override
- public void warning(final TransformerException exception) {
- logger.warn("Encountered warning from XPath Engine",
exception);
- }
-
- @Override
- public void error(final TransformerException exception) {
- logger.error("Encountered error from XPath Engine", exception);
- error.set(exception);
- }
-
- @Override
- public void fatalError(final TransformerException exception) {
- logger.error("Encountered warning from XPath Engine",
exception);
- error.set(exception);
- }
- });
-
- transformer.transform(sourceNode, new StreamResult(out));
- if (error.get() != null) {
- throw error.get();
- }
- }
-
private static class XPathValidator implements Validator {
@Override
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXQuery.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXQuery.java
index 7db4fdb280..059185df39 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXQuery.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/main/java/org/apache/nifi/processors/standard/EvaluateXQuery.java
@@ -30,14 +30,8 @@ import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import net.sf.saxon.s9api.Processor;
@@ -75,7 +69,9 @@ import org.apache.nifi.processor.Relationship;
import org.apache.nifi.processor.exception.ProcessException;
import org.apache.nifi.processor.util.StandardValidators;
import
org.apache.nifi.processors.standard.xml.DocumentTypeAllowedDocumentProvider;
+import org.apache.nifi.xml.processing.ProcessingException;
import org.apache.nifi.xml.processing.parsers.StandardDocumentProvider;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
import org.w3c.dom.Document;
@EventDriven
@@ -315,9 +311,9 @@ public class EvaluateXQuery extends AbstractProcessor {
final XdmItem item = result.itemAt(0);
flowFile = session.write(flowFile, rawOut -> {
try (final OutputStream out = new
BufferedOutputStream(rawOut)) {
- writeformattedItem(item, context, out);
- } catch (TransformerFactoryConfigurationError
| TransformerException e) {
- throw new IOException(e);
+ writeFormattedItem(item, context, out);
+ } catch (final ProcessingException e) {
+ throw new IOException("Writing Formatted
Output failed", e);
}
});
} else {
@@ -326,9 +322,9 @@ public class EvaluateXQuery extends AbstractProcessor {
ff = session.write(ff, rawOut -> {
try (final OutputStream out = new
BufferedOutputStream(rawOut)) {
try {
- writeformattedItem(item, context,
out);
- } catch
(TransformerFactoryConfigurationError | TransformerException e) {
- throw new IOException(e);
+ writeFormattedItem(item, context,
out);
+ } catch (final ProcessingException e) {
+ throw new IOException("Writing
Formatted Output failed", e);
}
}
});
@@ -341,7 +337,7 @@ public class EvaluateXQuery extends AbstractProcessor {
session.transfer(flowFile, REL_FAILURE);
session.remove(childrenFlowFiles);
continue flowFileLoop;
- } catch (TransformerFactoryConfigurationError |
TransformerException | IOException e) {
+ } catch (final IOException e) {
logger.error("XQuery Property [{}] configuration failed",
entry.getKey(), e);
session.transfer(flowFile, REL_FAILURE);
session.remove(childrenFlowFiles);
@@ -369,14 +365,13 @@ public class EvaluateXQuery extends AbstractProcessor {
} // end flowFileLoop
}
- private String formatItem(XdmItem item, ProcessContext context) throws
TransformerFactoryConfigurationError, TransformerException, IOException {
+ private String formatItem(XdmItem item, ProcessContext context) throws
IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
- writeformattedItem(item, context, baos);
+ writeFormattedItem(item, context, baos);
return baos.toString();
}
- void writeformattedItem(XdmItem item, ProcessContext context, OutputStream
out)
- throws TransformerFactoryConfigurationError, TransformerException,
IOException {
+ void writeFormattedItem(XdmItem item, ProcessContext context, OutputStream
out) throws IOException {
if (item.isAtomicValue()) {
out.write(item.getStringValue().getBytes(StandardCharsets.UTF_8));
@@ -385,10 +380,18 @@ public class EvaluateXQuery extends AbstractProcessor {
switch (node.getNodeKind()) {
case DOCUMENT:
case ELEMENT:
- Transformer transformer =
TransformerFactory.newInstance().newTransformer();
- final Properties props = getTransformerProperties(context);
- transformer.setOutputProperties(props);
- transformer.transform(node.asSource(), new
StreamResult(out));
+ final StandardTransformProvider transformProvider = new
StandardTransformProvider();
+ final String method =
context.getProperty(XML_OUTPUT_METHOD).getValue();
+ transformProvider.setMethod(method);
+
+ final boolean indentEnabled =
context.getProperty(XML_OUTPUT_INDENT).asBoolean();
+ transformProvider.setIndent(indentEnabled);
+
+ final boolean omitXmlDeclaration =
context.getProperty(XML_OUTPUT_OMIT_XML_DECLARATION).asBoolean();
+
transformProvider.setOmitXmlDeclaration(omitXmlDeclaration);
+
+ final StreamResult result = new StreamResult(out);
+ transformProvider.transform(node.asSource(), result);
break;
default:
out.write(node.getStringValue().getBytes(StandardCharsets.UTF_8));
@@ -396,21 +399,6 @@ public class EvaluateXQuery extends AbstractProcessor {
}
}
- private Properties getTransformerProperties(ProcessContext context) {
- final String method =
context.getProperty(XML_OUTPUT_METHOD).getValue();
- boolean indent = context.getProperty(XML_OUTPUT_INDENT).asBoolean();
- boolean omitDeclaration =
context.getProperty(XML_OUTPUT_OMIT_XML_DECLARATION).asBoolean();
- return getTransformerProperties(method, indent, omitDeclaration);
- }
-
- static Properties getTransformerProperties(final String method, final
boolean indent, final boolean omitDeclaration) {
- final Properties props = new Properties();
- props.setProperty(OutputKeys.METHOD, method);
- props.setProperty(OutputKeys.INDENT, indent ? "yes" : "no");
- props.setProperty(OutputKeys.OMIT_XML_DECLARATION, omitDeclaration ?
"yes" : "no");
- return props;
- }
-
private static class XQueryValidator implements Validator {
@Override
diff --git
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEvaluateXQuery.java
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEvaluateXQuery.java
index 7282f07244..5eb665cb96 100644
---
a/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEvaluateXQuery.java
+++
b/nifi-nar-bundles/nifi-standard-bundle/nifi-standard-processors/src/test/java/org/apache/nifi/processors/standard/TestEvaluateXQuery.java
@@ -32,9 +32,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.Properties;
-
-import javax.xml.transform.OutputKeys;
import org.apache.nifi.util.MockFlowFile;
import org.apache.nifi.util.TestRunner;
@@ -53,21 +50,6 @@ public class TestEvaluateXQuery {
private static final String[] methods = {EvaluateXQuery.OUTPUT_METHOD_XML,
EvaluateXQuery.OUTPUT_METHOD_HTML, EvaluateXQuery.OUTPUT_METHOD_TEXT};
private static final boolean[] booleans = {true, false};
- @Test
- public void testSetTransformerProperties() {
- for (final String method : methods) {
- for (final boolean indent : booleans) {
- for (final boolean omitDeclaration : booleans) {
- Properties props =
EvaluateXQuery.getTransformerProperties(method, indent, omitDeclaration);
- assertEquals(3, props.size());
- assertEquals(method, props.getProperty(OutputKeys.METHOD));
- assertEquals(indent ? "yes" : "no",
props.getProperty(OutputKeys.INDENT));
- assertEquals(omitDeclaration ? "yes" : "no",
props.getProperty(OutputKeys.OMIT_XML_DECLARATION));
- }
- }
- }
- }
-
@Test
public void testFormatting() throws Exception {
diff --git
a/nifi-registry/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/main/java/org/apache/nifi/registry/ranger/RangerAuthorizer.java
b/nifi-registry/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/main/java/org/apache/nifi/registry/ranger/RangerAuthorizer.java
index 134b792e70..987148f0d9 100644
---
a/nifi-registry/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/main/java/org/apache/nifi/registry/ranger/RangerAuthorizer.java
+++
b/nifi-registry/nifi-registry-extensions/nifi-registry-ranger/nifi-registry-ranger-plugin/src/main/java/org/apache/nifi/registry/ranger/RangerAuthorizer.java
@@ -42,6 +42,8 @@ import org.apache.nifi.registry.util.PropertyValue;
import org.apache.nifi.xml.processing.ProcessingException;
import org.apache.nifi.xml.processing.parsers.DocumentProvider;
import org.apache.nifi.xml.processing.parsers.StandardDocumentProvider;
+import org.apache.nifi.xml.processing.transform.StandardTransformProvider;
+import org.apache.nifi.xml.processing.transform.TransformProvider;
import org.apache.ranger.audit.model.AuthzAuditEvent;
import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
import org.apache.ranger.authorization.hadoop.config.RangerPluginConfig;
@@ -56,9 +58,6 @@ import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
@@ -339,9 +338,9 @@ public class RangerAuthorizer implements ManagedAuthorizer,
AuthorizationAuditor
userGroupProviderElement.appendChild(document.createTextNode(((ConfigurableUserGroupProvider)
userGroupProvider).getFingerprint()));
}
- final Transformer transformer =
TransformerFactory.newInstance().newTransformer();
- transformer.transform(new DOMSource(document), new
StreamResult(out));
- } catch (final ProcessingException | TransformerException e) {
+ final TransformProvider transformProvider = new
StandardTransformProvider();
+ transformProvider.transform(new DOMSource(document), new
StreamResult(out));
+ } catch (final ProcessingException e) {
throw new AuthorizationAccessException("Unable to generate
fingerprint", e);
}