cz.lbenda.dataman.rc.DatamanHeadless.java Source code

Java tutorial

Introduction

Here is the source code for cz.lbenda.dataman.rc.DatamanHeadless.java

Source

/*
 * Copyright 2014 Lukas Benda <lbenda at lbenda.cz>.
 *
 * 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 cz.lbenda.dataman.rc;

import cz.lbenda.dataman.db.DbConfig;
import cz.lbenda.dataman.db.ExportTableData;
import cz.lbenda.dataman.db.SQLQueryResult;
import cz.lbenda.dataman.db.sql.SQLSExecutor;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemManager;
import org.apache.commons.vfs2.VFS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/** Created by Lukas Benda <lbenda @ lbenda.cz> on 24.10.15.
 * Headless version of dataman */
public class DatamanHeadless {

    private static final Logger LOG = LoggerFactory.getLogger(DatamanHeadless.class);

    /** Append new option to Options object which is used for parse command line arguments
     * @param options object to which is append options */
    public static void setCommandLineOptions(Options options) {
        options.addOption("i", "script", true, "Input script which is executes.");
        options.addOption("is", "scripts", true, "Input scripts which is executes separated by comma");
        options.addOption("c", "config", true, "Name of configuration on which is executed script");
        options.addOption("o", "output", true, "Output file to which is data written");
        options.addOption("os", "outputs", true,
                "Output files to which is data written separated by comma. In order as input file.");
        options.addOption("f", "format", true,
                "Format which is used for formatting the returned data. CSV, SQL, TXT, XMLv1, XMLv2. Default is TXT.");
        options.addOption(null, "nos", false, "Flag which switch of write SQL header to output.");
    }

    private @Nonnull List<FileObject> scripts(CommandLine cmd) throws FileSystemException {
        return files(cmd, "i", "is");
    }

    private @Nonnull List<FileObject> outputs(CommandLine cmd) throws FileSystemException {
        return files(cmd, "o", "os");
    }

    private @Nonnull List<FileObject> files(CommandLine cmd, String singleFileOption, String multipleFileOption)
            throws FileSystemException {
        if (!cmd.hasOption(singleFileOption) && !cmd.hasOption(multipleFileOption)) {
            return Collections.emptyList();
        }
        String script = cmd.getOptionValue(singleFileOption);
        FileSystemManager fsm = VFS.getManager();
        if (script != null) {
            return Collections.singletonList(fsm.resolveFile((FileObject) null, script));
        }
        String scripts = cmd.getOptionValue(multipleFileOption);
        String[] scrs = scripts.split(",");
        List<FileObject> result = new ArrayList<>();
        for (String scr : scrs) {
            result.add(fsm.resolveFile((FileObject) null, scr));
        }
        return result;
    }

    private @Nonnull ExportTableData.SpreadsheetFormat format(@Nonnull CommandLine cmd) {
        if (cmd.hasOption("f")) {
            return ExportTableData.SpreadsheetFormat.valueOf(cmd.getOptionValue("f").toUpperCase());
        }
        return ExportTableData.SpreadsheetFormat.TXT;
    }

    public void launch(@Nonnull CommandLine cmd) {
        DbConfig dbConfig = DbConfigFactory.getConfiguration(cmd.getOptionValue("c"));
        if (dbConfig == null) {
            LOG.error("Configuration with name " + cmd.getOptionValue("c") + " not exist.");
            System.exit(1);
        }

        try {
            List<FileObject> scripts = scripts(cmd);
            List<FileObject> outputs = outputs(cmd);
            if (scripts.size() == 0) {
                LOG.error("The scripts isn't defined");
                System.exit(3);
            } else {
                SQLSExecutorConsumerClass sqlEditorController = new SQLSExecutorConsumerClass(!cmd.hasOption("nos"),
                        format(cmd));
                SQLSExecutor executor = new SQLSExecutor(dbConfig, sqlEditorController, null);
                dbConfig.getConnectionProvider().getConnection();
                int i = 0;
                for (FileObject file : scripts) {
                    if (outputs.size() > i) {
                        sqlEditorController.setOutputFile(outputs.get(i));
                    } else {
                        sqlEditorController.setOutputFile(null);
                    }
                    i++;
                    try {
                        InputStream is = file.getContent().getInputStream();
                        Reader reader = new InputStreamReader(is);
                        char[] buff = new char[262144];
                        int l;
                        String rest = "";
                        while ((l = reader.read(buff)) != -1) {
                            String str = rest + new String(buff, 0, l);
                            String[] strs = SQLSExecutor.splitSQLS(str);
                            if (strs.length == 1) {
                                rest = str;
                            } else {
                                rest = strs[strs.length - 1];
                                if (!str.endsWith("\n") && rest.endsWith("\n")) {
                                    rest = rest.substring(0, rest.length() - 1);
                                    rest = str.substring(str.lastIndexOf(rest), str.length());
                                }
                                String[] sqls = new String[strs.length - 1];
                                System.arraycopy(strs, 0, sqls, 0, strs.length - 1);
                                executor.executeBlocking(sqls);
                            }
                        }
                        executor.executeBlocking(SQLSExecutor.splitSQLS(rest));
                    } catch (IOException e) {
                        LOG.error("Problem with read script file", e);
                        System.exit(4);
                    }
                }
            }
        } catch (FileSystemException e) {
            LOG.error("Problem with read script data", e);
            System.exit(2);
        }
    }

    public static class SQLSExecutorConsumerClass implements SQLSExecutor.SQLSExecutorConsumer {
        private ExportTableData.SpreadsheetFormat format;
        private PrintStream printStream;
        private boolean writeSQLHeaders;

        public void setOutputFile(FileObject outputFile) {
            printStream = currentWriter(outputFile);
        }

        SQLSExecutorConsumerClass(boolean writeSQLHeaders, ExportTableData.SpreadsheetFormat format) {
            this.format = format;
            this.writeSQLHeaders = writeSQLHeaders;
        }

        private PrintStream currentWriter(FileObject outputFile) {
            if (outputFile == null) {
                return System.out;
            }
            try {
                if (!outputFile.isWriteable()) {
                    LOG.error("The output file isn't writable", outputFile.getName());
                    System.exit(10);
                }
                return new PrintStream(outputFile.getContent().getOutputStream(), true);
            } catch (IOException e) {
                LOG.error("The error when output file is open", e);
                System.exit(11);
                throw new RuntimeException("The error when output file is open", e);
            }
        }

        @Override
        public void addQueryResult(SQLQueryResult result) {
            if (writeSQLHeaders) {
                printStream.println("------");
                printStream.println(result.getSql());
                printStream.println("------");
            }
            if (!StringUtils.isBlank(result.getErrorMsg())) {
                LOG.error(result.getErrorMsg());
            } else {
                if (result.getSqlQueryRows() != null) {
                    try {
                        /* Writer writer = new StringWriter(); */
                        PrintWriter writer = new PrintWriter(printStream);
                        ExportTableData.writeSqlQueryRows(format, result.getSqlQueryRows(), null, writer);
                        writer.flush();
                        // printStream.println(writer.toString());
                    } catch (IOException e) {
                        LOG.error("Error when result of table is write as CSV", e);
                    }
                } else if (result.getAffectedRow() != null) {
                    printStream.println("Affected rows <" + result.getAffectedRow() + ">");
                }
            }
        }

        @Override
        public boolean isStopOnFirstError() {
            return true;
        }
    }
}