at.favre.tools.dconvert.ui.CLIInterpreter.java Source code

Java tutorial

Introduction

Here is the source code for at.favre.tools.dconvert.ui.CLIInterpreter.java

Source

/*
 * Copyright (C) 2016 Patrick Favre-Bulle
 *
 * 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 at.favre.tools.dconvert.ui;

import at.favre.tools.dconvert.arg.*;
import org.apache.commons.cli.*;

import java.io.File;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.Set;

/**
 * Handles parsing of command line arguments
 */
public class CLIInterpreter {
    public static final String COMPRESSION_QUALITY_ARG = "compressionQuality";
    public static final String THREADS_ARG = "threads";
    public final static String SOURCE_ARG = "src";
    public final static String SCALE_ARG = "scale";
    public final static String PLATFORM_ARG = "platform";
    public final static String UPSCALING_ALGO_ARG = "algorithmUpscaling";
    public final static String DOWNSCALING_ALGO_ARG = "algorithmDownscaling";
    public static final String OUT_COMPRESSION_ARG = "outCompression";
    public static final String ROUNDING_MODE_ARG = "roundingMode";
    public static final String DST_ARG = "dst";
    public static final String VERBOSE_ARG = "verbose";
    public static final String SKIP_EXISTING_ARG = "skipExisting";
    public static final String SCALE_IS_HEIGHT_DP_ARG = "scaleIsHeightDp";

    public static Arguments parse(String[] args) {
        ResourceBundle strings = ResourceBundle.getBundle("bundles.strings", Locale.getDefault());
        Options options = setupOptions(strings);
        CommandLineParser parser = new DefaultParser();

        Arguments.Builder builder;
        try {
            CommandLine commandLine = parser.parse(options, args);

            if (commandLine.hasOption("gui")) {
                return Arguments.START_GUI;
            }

            if (commandLine.hasOption("h") || commandLine.hasOption("help")) {
                printHelp(options);
                return null;
            }

            if (commandLine.hasOption("v") || commandLine.hasOption("version")) {
                System.out.println("Version: " + CLIInterpreter.class.getPackage().getImplementationVersion());
                return null;
            }

            String scaleRawParam = commandLine.getOptionValue(SCALE_ARG).toLowerCase();

            boolean dp = false;

            if (scaleRawParam.contains("dp")) {
                dp = true;
                scaleRawParam = scaleRawParam.replace("dp", "").trim();
            }

            builder = new Arguments.Builder(new File(commandLine.getOptionValue(SOURCE_ARG)),
                    Float.parseFloat(scaleRawParam));

            if (dp && commandLine.hasOption(SCALE_IS_HEIGHT_DP_ARG)) {
                builder.scaleMode(EScaleMode.DP_HEIGHT);
            } else if (dp && !commandLine.hasOption(SCALE_IS_HEIGHT_DP_ARG)) {
                builder.scaleMode(EScaleMode.DP_WIDTH);
            } else {
                builder.scaleMode(EScaleMode.FACTOR);
            }

            if (commandLine.hasOption(DST_ARG)) {
                builder.dstFolder(new File(commandLine.getOptionValue(DST_ARG)));
            }

            float compressionQuality = Arguments.DEFAULT_COMPRESSION_QUALITY;
            if (commandLine.hasOption(COMPRESSION_QUALITY_ARG)) {
                compressionQuality = Float.valueOf(commandLine.getOptionValue(COMPRESSION_QUALITY_ARG));
            }

            if (commandLine.hasOption(OUT_COMPRESSION_ARG)) {
                switch (commandLine.getOptionValue(OUT_COMPRESSION_ARG)) {
                case "strict":
                    builder.compression(EOutputCompressionMode.SAME_AS_INPUT_STRICT);
                    break;
                case "png":
                    builder.compression(EOutputCompressionMode.AS_PNG);
                    break;
                case "jpg":
                    builder.compression(EOutputCompressionMode.AS_JPG, compressionQuality);
                    break;
                case "gif":
                    builder.compression(EOutputCompressionMode.AS_GIF);
                    break;
                case "bmp":
                    builder.compression(EOutputCompressionMode.AS_BMP);
                    break;
                case "png+jpg":
                    builder.compression(EOutputCompressionMode.AS_JPG_AND_PNG, compressionQuality);
                    break;
                default:
                    System.err.println(
                            "unknown compression type: " + commandLine.getOptionValue(OUT_COMPRESSION_ARG));
                }
            }

            Set<EPlatform> platformSet = new HashSet<>(EPlatform.values().length);
            if (commandLine.hasOption(PLATFORM_ARG)) {
                switch (commandLine.getOptionValue(PLATFORM_ARG)) {
                case "all":
                    platformSet = EPlatform.getAll();
                    break;
                case "android":
                    platformSet.add(EPlatform.ANDROID);
                    break;
                case "ios":
                    platformSet.add(EPlatform.IOS);
                    break;
                case "win":
                    platformSet.add(EPlatform.WINDOWS);
                    break;
                case "web":
                    platformSet.add(EPlatform.WEB);
                    break;
                default:
                    System.err.println("unknown mode: " + commandLine.getOptionValue(PLATFORM_ARG));
                }
                builder.platform(platformSet);
            }

            if (commandLine.hasOption(UPSCALING_ALGO_ARG)) {
                builder.upScaleAlgorithm(
                        EScalingAlgorithm.getByName(commandLine.getOptionValue(UPSCALING_ALGO_ARG)));
            }

            if (commandLine.hasOption(DOWNSCALING_ALGO_ARG)) {
                builder.upScaleAlgorithm(
                        EScalingAlgorithm.getByName(commandLine.getOptionValue(DOWNSCALING_ALGO_ARG)));
            }

            if (commandLine.hasOption(ROUNDING_MODE_ARG)) {
                switch (commandLine.getOptionValue(ROUNDING_MODE_ARG)) {
                case "round":
                    builder.scaleRoundingStragy(RoundingHandler.Strategy.ROUND_HALF_UP);
                    break;
                case "ceil":
                    builder.scaleRoundingStragy(RoundingHandler.Strategy.CEIL);
                    break;
                case "floor":
                    builder.scaleRoundingStragy(RoundingHandler.Strategy.FLOOR);
                    break;
                default:
                    System.err.println("unknown mode: " + commandLine.getOptionValue(ROUNDING_MODE_ARG));
                }
            }

            if (commandLine.hasOption(THREADS_ARG)) {
                builder.threadCount(Integer.valueOf(commandLine.getOptionValue(THREADS_ARG)));
            }

            builder.skipUpscaling(commandLine.hasOption("skipUpscaling"));
            builder.skipExistingFiles(commandLine.hasOption(SKIP_EXISTING_ARG));
            builder.includeAndroidLdpiTvdpi(commandLine.hasOption("androidIncludeLdpiTvdpi"));
            builder.verboseLog(commandLine.hasOption(VERBOSE_ARG));
            builder.haltOnError(commandLine.hasOption("haltOnError"));
            builder.createMipMapInsteadOfDrawableDir(commandLine.hasOption("androidMipmapInsteadOfDrawable"));
            builder.antiAliasing(commandLine.hasOption("antiAliasing"));
            builder.enablePngCrush(commandLine.hasOption("postProcessorPngCrush"));
            builder.postConvertWebp(commandLine.hasOption("postProcessorWebp"));
            builder.dryRun(commandLine.hasOption("dryRun"));
            builder.enableMozJpeg(commandLine.hasOption("postProcessorMozJpeg"));
            builder.keepUnoptimizedFilesPostProcessor(commandLine.hasOption("keepOriginalPostProcessedFiles"));
            builder.iosCreateImagesetFolders(commandLine.hasOption("iosCreateImagesetFolders"));
            builder.clearDirBeforeConvert(commandLine.hasOption("clean"));

            return builder.build();
        } catch (Exception e) {
            System.err.println("Could not parse args: " + e.getMessage());
        }
        return null;
    }

    private static void printHelp(Options options) {
        HelpFormatter help = new HelpFormatter();
        help.setWidth(110);
        help.setLeftPadding(4);
        help.printHelp("converter", "version: " + CLIInterpreter.class.getPackage().getImplementationVersion(),
                options, "", true);
    }

    private static Options setupOptions(ResourceBundle bundle) {
        Options options = new Options();

        Option srcOpt = Option.builder(SOURCE_ARG).required().argName("path to file or folder").hasArg(true)
                .desc(bundle.getString("arg.descr.cmd.src")).build();
        Option srcScaleOpt = Option.builder(SCALE_ARG).argName("[float]|[int]dp").hasArg(true)
                .desc(bundle.getString("arg.descr.cmd.scale")).build();
        Option dstOpt = Option.builder(DST_ARG).hasArg(true).argName("path")
                .desc(bundle.getString("arg.descr.cmd.dst")).build();

        Option platform = Option.builder(PLATFORM_ARG).hasArg(true).argName("all|android|ios|win|web")
                .desc(MessageFormat.format(bundle.getString("arg.descr.cmd.platform"), Arguments.DEFAULT_PLATFORM))
                .build();
        Option threadCount = Option.builder(THREADS_ARG).argName("1-8").hasArg(true).desc(MessageFormat
                .format(bundle.getString("arg.descr.cmd.threads"), String.valueOf(Arguments.DEFAULT_THREAD_COUNT)))
                .build();
        Option roundingHandler = Option
                .builder(ROUNDING_MODE_ARG).argName("round|ceil|floor").hasArg(true).desc(MessageFormat
                        .format(bundle.getString("arg.descr.cmd.rounding"), Arguments.DEFAULT_ROUNDING_STRATEGY))
                .build();
        Option compression = Option.builder(OUT_COMPRESSION_ARG).hasArg(true).argName("png|jpg|gif|bmp")
                .desc(bundle.getString("arg.descr.cmd.outcompression")).build();
        Option compressionQuality = Option.builder(COMPRESSION_QUALITY_ARG).hasArg(true).argName("0.0-1.0")
                .desc(MessageFormat.format(bundle.getString("arg.descr.cmd.compression"),
                        String.valueOf(Arguments.DEFAULT_COMPRESSION_QUALITY)))
                .build();
        Option upScalingAlgo = Option.builder(UPSCALING_ALGO_ARG).hasArg(true)
                .argName(EScalingAlgorithm.getCliArgString(EScalingAlgorithm.Type.UPSCALING))
                .desc(MessageFormat.format(bundle.getString("arg.descr.scalingalgo"), Arguments.DEFAULT_PLATFORM))
                .build();
        Option downScalingAlgo = Option.builder(DOWNSCALING_ALGO_ARG).hasArg(true)
                .argName(EScalingAlgorithm.getCliArgString(EScalingAlgorithm.Type.DOWNSCALING))
                .desc(MessageFormat.format(bundle.getString("arg.descr.scalingalgo"), Arguments.DEFAULT_PLATFORM))
                .build();

        Option skipExistingFiles = Option.builder(SKIP_EXISTING_ARG)
                .desc(bundle.getString("arg.descr.skipexisting")).build();
        Option androidIncludeLdpiTvdpi = Option.builder("androidIncludeLdpiTvdpi")
                .desc(bundle.getString("arg.descr.androidmipmap")).build();
        Option mipmapInsteadOfDrawable = Option.builder("androidMipmapInsteadOfDrawable")
                .desc(bundle.getString("arg.descr.androidldpi")).build();
        Option iosCreateImagesetFolders = Option.builder("iosCreateImagesetFolders")
                .desc(bundle.getString("arg.descr.iosimageset")).build();
        Option skipUpscaling = Option.builder("skipUpscaling").desc(bundle.getString("arg.descr.skipupscaling"))
                .build();
        Option verboseLog = Option.builder(VERBOSE_ARG).desc(bundle.getString("arg.descr.cmd.verbose")).build();
        Option haltOnError = Option.builder("haltOnError").desc(bundle.getString("arg.descr.halterror")).build();
        Option antiAliasing = Option.builder("antiAliasing").desc(bundle.getString("arg.descr.antialiasing"))
                .build();
        Option enablePngCrush = Option.builder("postProcessorPngCrush").desc(bundle.getString("arg.descr.pngcrush"))
                .build();
        Option postWebpConvert = Option.builder("postProcessorWebp").desc(bundle.getString("arg.descr.webp"))
                .build();
        Option keepUnPostProcessed = Option.builder("keepOriginalPostProcessedFiles")
                .desc(bundle.getString("arg.descr.keeporiginal")).build();
        Option dpScaleIsHeight = Option.builder(SCALE_IS_HEIGHT_DP_ARG)
                .desc(bundle.getString("arg.descr.cmd.dpIsHeight")).build();
        Option dryRun = Option.builder("dryRun").desc(bundle.getString("arg.descr.dryrun")).build();
        Option enableMozJpeg = Option.builder("postProcessorMozJpeg").desc(bundle.getString("arg.descr.mozjpeg"))
                .build();
        Option cleanBeforeConvert = Option.builder("clean").desc(bundle.getString("arg.descr.clean")).build();

        Option help = Option.builder("h").longOpt("help").desc(bundle.getString("arg.descr.cmd.help")).build();
        Option version = Option.builder("v").longOpt("version").desc(bundle.getString("arg.descr.cmd.version"))
                .build();
        Option gui = Option.builder("gui").desc(bundle.getString("arg.descr.cmd.gui")).build();

        OptionGroup mainArgs = new OptionGroup();
        mainArgs.addOption(srcOpt).addOption(help).addOption(version).addOption(gui);
        mainArgs.setRequired(true);

        options.addOption(srcScaleOpt).addOption(dstOpt);
        options.addOption(platform).addOption(compression).addOption(compressionQuality).addOption(threadCount)
                .addOption(roundingHandler).addOption(upScalingAlgo).addOption(downScalingAlgo);
        options.addOption(skipExistingFiles).addOption(skipUpscaling).addOption(androidIncludeLdpiTvdpi)
                .addOption(verboseLog).addOption(antiAliasing).addOption(dryRun).addOption(haltOnError)
                .addOption(mipmapInsteadOfDrawable).addOption(enablePngCrush).addOption(postWebpConvert)
                .addOption(dpScaleIsHeight).addOption(enableMozJpeg).addOption(keepUnPostProcessed)
                .addOption(iosCreateImagesetFolders).addOption(cleanBeforeConvert);

        options.addOptionGroup(mainArgs);

        return options;
    }
}