public void printUsage() { JCommander jc = new JCommander(this); // print usage in not sorted fields order (by default its sorted by description) PrintStream out = System.out; out.println(); out.println("jadx - dex to java decompiler, version: " + JadxDecompiler.getVersion()); out.println(); out.println("usage: jadx [options] " + jc.getMainParameterDescription()); out.println("options:"); List<ParameterDescription> params = jc.getParameters(); Map<String, ParameterDescription> paramsMap = new LinkedHashMap<String, ParameterDescription>(params.size()); int maxNamesLen = 0; for (ParameterDescription p : params) { paramsMap.put(p.getParameterized().getName(), p); int len = p.getNames().length(); if (len > maxNamesLen) { maxNamesLen = len; } } Field[] fields = JadxCLIArgs.class.getDeclaredFields(); for (Field f : fields) { String name = f.getName(); ParameterDescription p = paramsMap.get(name); if (p == null) { continue; } StringBuilder opt = new StringBuilder(); opt.append(' ').append(p.getNames()); addSpaces(opt, maxNamesLen - opt.length() + 2); opt.append("- ").append(p.getDescription()); out.println(opt); } out.println("Example:"); out.println(" jadx -d out classes.dex"); }
@Override protected void configure() { /* * Instantiate the objects that contain parameters */ Map<Class<?>, Object> parmObjs = new Hashtable<>(); for (Class<?> type : parmObjTypes) { try { parmObjs.put(type, type.newInstance()); } catch (Exception e) { throw new RuntimeException( format("Failed to instantiate a parameter class <%s>", type.getSimpleName())); } } /* * Configure the command line parser */ JCommander cmd = new JCommander(parmObjs.values()); cmd.parse(args); // TODO Add command line parsing error handling. // TODO Add command line Usage handling. /* * Bind parameter class objects to be injected */ for (Map.Entry<Class<?>, Object> entry : parmObjs.entrySet()) { bind((Class) entry.getKey()).toInstance(entry.getValue()); } /* * Bind individual parsed parameters */ for (ParameterDescription parmDesc : cmd.getParameters()) { Object parmObj = parmDesc.getObject(); for (String name : parmDesc.getParameter().names()) { Object value = parmDesc.getParameterized().get(parmObj); Class<?> type = parmDesc.getParameterized().getType(); Type fieldGenericType = parmDesc.getParameterized().findFieldGenericType(); Type genericType = parmDesc.getParameterized().getGenericType(); /* * Create the name this parameters value will be bound as. */ String bindingName = null; if (prefix.isEmpty()) { bindingName = name.replaceFirst("^[\\-]+", ""); } else { bindingName = prefix + "." + name.replaceFirst("^[\\-]+", ""); } log.info( "Name : {}, Generic Type {}, Field Generic Type {}", name, genericType, fieldGenericType); /** Handle the parameter type. */ if (parmDesc.isHelp()) { /* * Do nothing for parameters that are there for causing help displays. */ } else if (parmDesc.getParameterized().findFieldGenericType() == null) { /** It is a simple (Non-generified type) */ if (bindingFxns.containsKey(type)) { BiConsumer consumer = this.bindingFxns.get(type); consumer.accept(bindingName, value); } else { throw new RuntimeException( format( "Cannot bind parameter <%s> for class <%s>", name, parmObj.getClass().getSimpleName())); } } else { /* * It is a generified type */ /* * If the parameter value is null, that indicates that the programmer did not default to an empty * collection and nothing was added as a default */ if (Iterable.class.isAssignableFrom(type) && value == null) { if (Set.class.isAssignableFrom(type)) { value = new HashSet(); } else { value = new ArrayList(); } } /* * Get the generic binding function associated with the type. */ TypeLiteral<?> typeLiteral = TypeLiteral.get(parmDesc.getParameterized().getGenericType()); if (bindingFxnsForGenerics.containsKey(typeLiteral)) { BiConsumer consumer = bindingFxnsForGenerics.get(typeLiteral); consumer.accept(bindingName, value); } else { throw new RuntimeException( format( "Cannot bind parameter <%s> for class <%s>", name, parmObj.getClass().getSimpleName())); } } } } }