org.pentaho.di.ui.trans.steps.getxmldata.LoopNodesImportProgressDialog.java Source code

Java tutorial

Introduction

Here is the source code for org.pentaho.di.ui.trans.steps.getxmldata.LoopNodesImportProgressDialog.java

Source

/*! ******************************************************************************
 *
 * Pentaho Data Integration
 *
 * Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com
 *
 *******************************************************************************
 *
 * Licensed 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.pentaho.di.ui.trans.steps.getxmldata;

import java.io.InputStream;
import java.io.StringReader;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.ProgressMonitorDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.swt.widgets.Shell;
import org.pentaho.di.core.util.Utils;
import org.pentaho.di.core.vfs.KettleVFS;
import org.pentaho.di.core.xml.XMLParserFactoryProducer;
import org.pentaho.di.i18n.BaseMessages;
import org.pentaho.di.trans.steps.getxmldata.GetXMLDataMeta;
import org.pentaho.di.trans.steps.getxmldata.IgnoreDTDEntityResolver;
import org.pentaho.di.ui.core.dialog.ErrorDialog;

/**
 * Takes care of displaying a dialog that will handle the wait while we're finding out loop nodes for an XML file
 * 
 * @author Samatar
 * @since 07-apr-2010
 */
public class LoopNodesImportProgressDialog {
    private static Class<?> PKG = GetXMLDataMeta.class; // for i18n purposes, needed by Translator2!!

    private Shell shell;

    private GetXMLDataMeta meta;

    private String[] Xpaths;

    private String filename;
    private String xml;
    private String url;
    private String encoding;

    private ArrayList<String> listpath;

    private int nr;

    /**
     * Creates a new dialog that will handle the wait while we're finding out loop nodes for an XML file
     */
    public LoopNodesImportProgressDialog(Shell shell, GetXMLDataMeta meta, String filename, String encoding) {
        this.shell = shell;
        this.meta = meta;
        this.Xpaths = null;
        this.filename = filename;
        this.encoding = encoding;
        this.listpath = new ArrayList<String>();
        this.nr = 0;
        this.xml = null;
        this.url = null;
    }

    public LoopNodesImportProgressDialog(Shell shell, GetXMLDataMeta meta, String xmlSource, boolean useUrl) {
        this.shell = shell;
        this.meta = meta;
        this.Xpaths = null;
        this.filename = null;
        this.encoding = null;
        this.listpath = new ArrayList<String>();
        this.nr = 0;
        if (useUrl) {
            this.xml = null;
            this.url = xmlSource;
        } else {
            this.xml = xmlSource;
            this.url = null;
        }
    }

    public String[] open() {
        IRunnableWithProgress op = new IRunnableWithProgress() {
            public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
                try {
                    Xpaths = doScan(monitor);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new InvocationTargetException(e,
                            BaseMessages.getString(PKG,
                                    "GetXMLDateLoopNodesImportProgressDialog.Exception.ErrorScanningFile", filename,
                                    e.toString()));
                }
            }
        };

        try {
            ProgressMonitorDialog pmd = new ProgressMonitorDialog(shell);
            pmd.run(true, true, op);
        } catch (InvocationTargetException e) {
            new ErrorDialog(shell,
                    BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.ErrorScanningFile.Title"),
                    BaseMessages.getString(PKG,
                            "GetXMLDateLoopNodesImportProgressDialog.ErrorScanningFile.Message"),
                    e);
        } catch (InterruptedException e) {
            new ErrorDialog(shell,
                    BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.ErrorScanningFile.Title"),
                    BaseMessages.getString(PKG,
                            "GetXMLDateLoopNodesImportProgressDialog.ErrorScanningFile.Message"),
                    e);
        }

        return Xpaths;
    }

    @SuppressWarnings("unchecked")
    private String[] doScan(IProgressMonitor monitor) throws Exception {
        monitor.beginTask(
                BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.Task.ScanningFile", filename),
                1);

        SAXReader reader = XMLParserFactoryProducer.getSAXReader(null);
        monitor.worked(1);
        if (monitor.isCanceled()) {
            return null;
        }
        // Validate XML against specified schema?
        if (meta.isValidating()) {
            reader.setValidation(true);
            reader.setFeature("http://apache.org/xml/features/validation/schema", true);
        } else {
            // Ignore DTD
            reader.setEntityResolver(new IgnoreDTDEntityResolver());
        }
        monitor.worked(1);
        monitor.beginTask(
                BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.Task.ReadingDocument"), 1);
        if (monitor.isCanceled()) {
            return null;
        }
        InputStream is = null;
        try {
            Document document = null;
            if (!Utils.isEmpty(filename)) {
                is = KettleVFS.getInputStream(filename);
                document = reader.read(is, encoding);
            } else {
                if (!Utils.isEmpty(xml)) {
                    document = reader.read(new StringReader(xml));
                } else {
                    document = reader.read(new URL(url));
                }
            }
            monitor.worked(1);
            monitor.beginTask(
                    BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.Task.DocumentOpened"), 1);
            monitor.worked(1);
            monitor.beginTask(
                    BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.Task.ReadingNode"), 1);

            if (monitor.isCanceled()) {
                return null;
            }
            List<Node> nodes = document.selectNodes(document.getRootElement().getName());
            monitor.worked(1);
            monitor.subTask(BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.Task.FetchNodes"));

            if (monitor.isCanceled()) {
                return null;
            }
            for (Node node : nodes) {
                if (monitor.isCanceled()) {
                    return null;
                }
                if (!listpath.contains(node.getPath())) {
                    nr++;
                    monitor.subTask(BaseMessages.getString(PKG,
                            "GetXMLDateLoopNodesImportProgressDialog.Task.FetchNodes", String.valueOf(nr)));
                    monitor.subTask(BaseMessages.getString(PKG,
                            "GetXMLDateLoopNodesImportProgressDialog.Task.AddingNode", node.getPath()));
                    listpath.add(node.getPath());
                    addLoopXPath(node, monitor);
                }
            }
            monitor.worked(1);
        } finally {
            try {
                if (is != null) {
                    is.close();
                }
            } catch (Exception e) { /* Ignore */
            }
        }
        String[] list_xpath = listpath.toArray(new String[listpath.size()]);

        monitor.setTaskName(
                BaseMessages.getString(PKG, "GetXMLDateLoopNodesImportProgressDialog.Task.NodesReturned"));

        monitor.done();

        return list_xpath;

    }

    private void addLoopXPath(Node node, IProgressMonitor monitor) {
        Element ce = (Element) node;
        monitor.worked(1);
        // List child
        for (int j = 0; j < ce.nodeCount(); j++) {
            if (monitor.isCanceled()) {
                return;
            }
            Node cnode = ce.node(j);

            if (!Utils.isEmpty(cnode.getName())) {
                Element cce = (Element) cnode;
                if (!listpath.contains(cnode.getPath())) {
                    nr++;
                    monitor.subTask(BaseMessages.getString(PKG,
                            "GetXMLDateLoopNodesImportProgressDialog.Task.FetchNodes", String.valueOf(nr)));
                    monitor.subTask(BaseMessages.getString(PKG,
                            "GetXMLDateLoopNodesImportProgressDialog.Task.AddingNode", cnode.getPath()));
                    listpath.add(cnode.getPath());
                }
                // let's get child nodes
                if (cce.nodeCount() > 1) {
                    addLoopXPath(cnode, monitor);
                }
            }
        }
    }

}