Github user phrocker commented on a diff in the pull request:

    https://github.com/apache/nifi-minifi/pull/99#discussion_r150915720
  
    --- Diff: 
minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-runtime/src/main/java/org/apache/nifi/minifi/FlowParser.java
 ---
    @@ -0,0 +1,154 @@
    +/*
    + * 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.minifi;
    +
    +import org.apache.commons.io.IOUtils;
    +import org.apache.nifi.util.LoggingXmlParserErrorHandler;
    +import org.apache.nifi.util.file.FileUtils;
    +import org.slf4j.Logger;
    +import org.slf4j.LoggerFactory;
    +import org.w3c.dom.Document;
    +import org.w3c.dom.Element;
    +import org.w3c.dom.Node;
    +import org.w3c.dom.NodeList;
    +import org.xml.sax.SAXException;
    +
    +import javax.xml.parsers.DocumentBuilder;
    +import javax.xml.parsers.DocumentBuilderFactory;
    +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 java.io.ByteArrayInputStream;
    +import java.io.ByteArrayOutputStream;
    +import java.io.File;
    +import java.io.IOException;
    +import java.io.InputStream;
    +import java.io.OutputStream;
    +import java.nio.file.Files;
    +import java.nio.file.Path;
    +import java.nio.file.StandardOpenOption;
    +import java.util.ArrayList;
    +import java.util.List;
    +import java.util.zip.GZIPInputStream;
    +import java.util.zip.GZIPOutputStream;
    +
    +/**
    + * Parses a flow from its xml.gz format into an XML {@link Document}.  
This class is primarily toward utilities for assisting
    + * with the handling of component bundles.
    + * <p>
    + * Provides auxiliary methods to aid in evaluating and manipulating the 
flow.
    + */
    +public class FlowParser {
    +
    +    private static final Logger logger = 
LoggerFactory.getLogger(FlowParser.class);
    +
    +    /**
    +     * Generates a {@link Document} from the flow configuration file 
provided
    +     */
    +    public Document parse(final File flowConfigurationFile) {
    +        if (flowConfigurationFile == null) {
    +            logger.debug("Flow Configuration file was null");
    +            return null;
    +        }
    +
    +        // if the flow doesn't exist or is 0 bytes, then return null
    +        final Path flowPath = flowConfigurationFile.toPath();
    +        try {
    +            if (!Files.exists(flowPath) || Files.size(flowPath) == 0) {
    +                logger.warn("Flow Configuration does not exist or was 
empty");
    +                return null;
    +            }
    +        } catch (IOException e) {
    +            logger.error("An error occurred determining the size of the 
Flow Configuration file");
    +            return null;
    +        }
    +
    +        // otherwise create the appropriate input streams to read the file
    +        try (final InputStream in = Files.newInputStream(flowPath, 
StandardOpenOption.READ);
    +             final InputStream gzipIn = new GZIPInputStream(in)) {
    +
    +            final byte[] flowBytes = IOUtils.toByteArray(gzipIn);
    +            if (flowBytes == null || flowBytes.length == 0) {
    +                logger.warn("Could not extract root group id because Flow 
Configuration File was empty");
    +                return null;
    +            }
    +
    +            final DocumentBuilderFactory docFactory = 
DocumentBuilderFactory.newInstance();
    +            docFactory.setNamespaceAware(true);
    +
    +            // parse the flow
    +            final DocumentBuilder docBuilder = 
docFactory.newDocumentBuilder();
    +            docBuilder.setErrorHandler(new 
LoggingXmlParserErrorHandler("Flow Configuration", logger));
    +            final Document document = docBuilder.parse(new 
ByteArrayInputStream(flowBytes));
    +            return document;
    +
    +        } catch (final SAXException | ParserConfigurationException | 
IOException ex) {
    +            logger.error("Unable to parse flow {} due to {}", new 
Object[]{flowPath.toAbsolutePath(), ex});
    +            return null;
    +        }
    +    }
    +
    +
    +    /**
    +     * Writes a given XML Flow out to the specified path.
    +     *
    +     * @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 {
    +        final ByteArrayOutputStream outputStream = new 
ByteArrayOutputStream();
    +        final Source xmlSource = new DOMSource(flowDocument);
    +        final Result outputTarget = new StreamResult(outputStream);
    +        
TransformerFactory.newInstance().newTransformer().transform(xmlSource, 
outputTarget);
    +        final InputStream is = new 
ByteArrayInputStream(outputStream.toByteArray());
    +
    +        try (final OutputStream output = 
Files.newOutputStream(flowXmlPath, StandardOpenOption.WRITE, 
StandardOpenOption.CREATE);
    +             final OutputStream gzipOut = new GZIPOutputStream(output);) {
    +            FileUtils.copy(is, gzipOut);
    +        }
    +    }
    +
    +    /**
    +     * Finds child elements with the given tagName.
    +     *
    +     * @param element the parent element
    +     * @param tagName the child element name to find
    +     * @return a list of matching child elements
    +     */
    +    public static List<Element> getChildrenByTagName(final Element 
element, final String tagName) {
    +        final List<Element> matches = new ArrayList<>();
    --- End diff --
    
    Could this be a little cleaner with IntStream, range, and filter? 


---

Reply via email to