lanchon.dexpatcher.Parser.java Source code

Java tutorial

Introduction

Here is the source code for lanchon.dexpatcher.Parser.java

Source

/*
 * DexPatcher - Copyright 2015, 2016 Rodrigo Balerdi
 * (GNU General Public License version 3 or later)
 *
 * DexPatcher is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License,
 * or (at your option) any later version.
 */

package lanchon.dexpatcher;

import java.util.List;

import lanchon.dexpatcher.core.Context;
import lanchon.multidexlib2.DexIO;
import lanchon.multidexlib2.MultiDexIO;

import org.apache.commons.cli.CommandLine;
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.apache.commons.cli.PosixParser;

import static lanchon.dexpatcher.core.logger.Logger.Level.*;

public class Parser {

    public static Configuration parseCommandLine(String[] args) throws ParseException {

        Configuration config = new Configuration();

        Options options = getOptions();
        CommandLine cl = new PosixParser().parse(options, args);

        if (cl.hasOption("help")) {
            printUsage();
            return null;
        }

        if (cl.hasOption("version")) {
            System.out.println(Main.getVersion());
            return null;
        }

        @SuppressWarnings("unchecked")
        List<String> files = cl.getArgList();
        if (files.isEmpty())
            throw new ParseException("Missing argument: <source-dex-apk-or-dir>");
        config.sourceFile = files.remove(0);
        config.patchFiles = files;
        config.patchedFile = cl.getOptionValue("output");

        Number apiLevel = (Number) cl.getParsedOptionValue("api-level");
        if (apiLevel != null)
            config.apiLevel = apiLevel.intValue();

        config.multiDex = cl.hasOption("multi-dex");
        if (cl.hasOption("multi-dex-threaded")) {
            config.multiDex = true;
            config.multiDexJobs = 0;
        }
        Number multiDexJobs = (Number) cl.getParsedOptionValue("multi-dex-jobs");
        if (multiDexJobs != null) {
            config.multiDex = true;
            config.multiDexJobs = multiDexJobs.intValue();
        }

        Number maxDexPoolSize = (Number) cl.getParsedOptionValue("max-dex-pool-size");
        if (maxDexPoolSize != null)
            config.maxDexPoolSize = maxDexPoolSize.intValue();

        config.annotationPackage = cl.getOptionValue("annotations", Context.DEFAULT_ANNOTATION_PACKAGE);
        config.dexTagSupported = cl.hasOption("compat-dextag");

        config.logLevel = WARN;
        if (cl.hasOption("quiet"))
            config.logLevel = ERROR;
        if (cl.hasOption("verbose"))
            config.logLevel = INFO;
        if (cl.hasOption("debug"))
            config.logLevel = DEBUG;

        if (cl.hasOption("path"))
            config.sourceCodeRoot = "";
        config.sourceCodeRoot = cl.getOptionValue("path-root", config.sourceCodeRoot);
        config.timingStats = cl.hasOption("stats");

        config.dryRun = cl.hasOption("dry-run");

        return config;

    }

    public static void printUsage() {
        System.out.println("DexPatcher Version " + Main.getVersion() + " by Lanchon");
        System.out.println("           https://dexpatcher.github.io/");
        String usage = "dexpatcher [<option> ...] [--output <patched-dex-or-dir>] "
                + "<source-dex-apk-or-dir> [<patch-dex-apk-or-dir> ...]";
        new HelpFormatter().printHelp(usage, getOptions());
    }

    private static Options getOptions() {

        Options options = new Options();
        Option o;

        o = new Option("o", "output", true, "name of output file or directory");
        o.setArgName("dex-or-dir");
        options.addOption(o);

        o = new Option("a", "api-level", true, "android api level (default: auto-detect)");
        o.setArgName("n");
        o.setType(Number.class);
        options.addOption(o);

        options.addOption(new Option("m", "multi-dex", false, "enable multi-dex support"));
        options.addOption(new Option("M", "multi-dex-threaded", false, "multi-threaded multi-dex (implies: -m)"));
        o = new Option("J", "multi-dex-jobs", true, "multi-dex thread count (implies: -m -M) (default: "
                + "available processors up to " + MultiDexIO.DEFAULT_MAX_THREADS + ")");
        o.setArgName("n");
        o.setType(Number.class);
        options.addOption(o);

        o = new Option(null, "max-dex-pool-size", true,
                "maximum size of dex pools (default: " + DexIO.DEFAULT_MAX_DEX_POOL_SIZE + ")");
        o.setArgName("n");
        o.setType(Number.class);
        options.addOption(o);

        o = new Option(null, "annotations", true,
                "package name of DexPatcher annotations (default: '" + Context.DEFAULT_ANNOTATION_PACKAGE + "')");
        o.setArgName("package");
        options.addOption(o);
        options.addOption(new Option(null, "compat-dextag", false, "enable support for the deprecated DexTag"));

        options.addOption(new Option("q", "quiet", false, "do not output warnings"));
        options.addOption(new Option("v", "verbose", false, "output extra information"));
        options.addOption(new Option(null, "debug", false, "output debugging information"));

        options.addOption(new Option("p", "path", false, "output relative paths of source code files"));
        o = new Option(null, "path-root", true, "output absolute paths of source code files");
        o.setArgName("root");
        options.addOption(o);
        options.addOption(new Option(null, "stats", false, "output timing statistics"));

        options.addOption(new Option(null, "dry-run", false, "do not write output files (much faster)"));

        options.addOption(new Option(null, "version", false, "print version information and exit"));
        options.addOption(new Option("?", "help", false, "print this help message and exit"));

        return options;

    }

}