/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.tool.transpose; import java.io.File; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.CommandLineParser; import org.apache.commons.cli.DefaultParser; import org.apache.commons.cli.HelpFormatter; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import org.apache.commons.cli.ParseException; import org.diqube.loader.CsvLoader; import org.diqube.loader.JsonLoader; import org.diqube.loader.Loader; import org.diqube.tool.ToolFunction; import org.diqube.tool.ToolFunctionName; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * {@link ToolFunction} which transposes a data file and creates a .diqube file. * * <p> * Transpose reads input data of all supported formats and outputs .diqube files (= serialized data from diqube-data * classes, which is already tranposed and compressed and simply needs to be de-serialized by the diqube-server * process). * * @author Bastian Gloeckle */ @ToolFunctionName(Transpose.FUNCTION_NAME) public class Transpose implements ToolFunction { private static final Logger logger = LoggerFactory.getLogger(Transpose.class); public static final String FUNCTION_NAME = "transpose"; private static final String OPT_HELP = "h"; private static final String OPT_INPUT = "i"; private static final String OPT_OUTPUT = "o"; private static final String OPT_TYPE = "t"; private static final String OPT_COLINFO = "c"; private static final String TYPE_JSON = "json"; private static final String TYPE_CSV = "csv"; @Override public void execute(String[] args) { Options cliOpt = createCliOptions(); CommandLineParser parser = new DefaultParser(); CommandLine cmd = null; boolean showHelp = false; try { cmd = parser.parse(cliOpt, args); showHelp |= cmd.hasOption(OPT_HELP); } catch (ParseException e) { logger.error(e.getMessage()); showHelp = true; } if (showHelp) { HelpFormatter formatter = new HelpFormatter(); formatter.printHelp(Transpose.FUNCTION_NAME + " [options]", "\nTransposes and compresses input data and creates a .diqube file out of it. This enables the diqube " + "server process to more easily load the data and not take up a lot of memory when doing it.\n\n", cliOpt, ""); return; } File inputFile = new File(cmd.getOptionValue(OPT_INPUT)); File outputFile = new File(cmd.getOptionValue(OPT_OUTPUT)); String inputType = cmd.getOptionValue(OPT_TYPE).toLowerCase(); String colInfoFileString = cmd.getOptionValue(OPT_COLINFO); File colInfoFile = null; if (!inputFile.isFile() || !inputFile.exists()) { logger.error("{} does not exist or is a directory.", inputFile.getAbsolutePath()); return; } if (outputFile.exists() && outputFile.isDirectory()) { logger.error("{} exists and is a directory.", outputFile.getAbsolutePath()); return; } if (colInfoFileString != null) { colInfoFile = new File(colInfoFileString); if (!colInfoFile.isFile() || !colInfoFile.exists()) { logger.error("{} does not exist or is a directory.", colInfoFile.getAbsolutePath()); return; } } Class<? extends Loader> loaderClass = null; switch (inputType) { case TYPE_JSON: loaderClass = JsonLoader.class; break; case TYPE_CSV: loaderClass = CsvLoader.class; break; } if (loaderClass == null) { logger.error("Unkown input type: {}", inputType); return; } new TransposeImplementation(inputFile, outputFile, colInfoFile, loaderClass).transpose(); } private Options createCliOptions() { Options res = new Options(); res.addOption(Option.builder(OPT_INPUT).longOpt("input").numberOfArgs(1).argName("file") .desc("The input file to read from (required).").required().build()); res.addOption(Option.builder(OPT_TYPE).longOpt("type").numberOfArgs(1).argName("type") .desc("Type of the input data. One of \"" + TYPE_JSON + "\", \"" + TYPE_CSV + "\" (required).").required() .build()); res.addOption(Option.builder(OPT_OUTPUT).longOpt("output").numberOfArgs(1).argName("file") .desc("Output file name (required).").required().build()); res.addOption(Option.builder(OPT_COLINFO).longOpt("colinfo").numberOfArgs(1).argName("file") .desc("File containing information about the columns to be created.").build()); res.addOption(Option.builder(OPT_HELP).longOpt("help").desc("Show this help.").build()); return res; } }