Skip to content

Commit

Permalink
fix(gui): override settings by cmd options
Browse files Browse the repository at this point in the history
  • Loading branch information
skylot committed Oct 29, 2018
1 parent bc62933 commit 6b3e8f0
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 81 deletions.
105 changes: 105 additions & 0 deletions jadx-cli/src/main/java/jadx/cli/JCommanderWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package jadx.cli;

import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.beust.jcommander.JCommander;
import com.beust.jcommander.ParameterDescription;
import com.beust.jcommander.ParameterException;
import com.beust.jcommander.Parameterized;

import jadx.api.JadxDecompiler;

public class JCommanderWrapper<T> {
private final JCommander jc;

public JCommanderWrapper(T obj) {
this.jc = JCommander.newBuilder().addObject(obj).build();
}

public boolean parse(String[] args) {
try {
jc.parse(args);
return true;
} catch (ParameterException e) {
System.err.println("Arguments parse error: " + e.getMessage());
printUsage();
return false;
}
}

public void overrideProvided(T obj) {
List<ParameterDescription> fieldsParams = jc.getParameters();
List<ParameterDescription> parameters = new ArrayList<>(1 + fieldsParams.size());
parameters.add(jc.getMainParameterValue());
parameters.addAll(fieldsParams);
for (ParameterDescription parameter : parameters) {
if (parameter.isAssigned()) {
// copy assigned field value to obj
Parameterized parameterized = parameter.getParameterized();
Object val = parameterized.get(parameter.getObject());
parameterized.set(obj, val);
}
}
}

public void printUsage() {
// 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<>(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;
}
}
JadxCLIArgs args = new JadxCLIArgs();
Field[] fields = args.getClass().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() + 3);
opt.append("- ").append(p.getDescription());
addDefaultValue(args, f, opt);
out.println(opt);
}
out.println("Example:");
out.println(" jadx -d out classes.dex");
}

private void addDefaultValue(JadxCLIArgs args, Field f, StringBuilder opt) {
Class<?> fieldType = f.getType();
if (fieldType == int.class) {
try {
int val = f.getInt(args);
opt.append(" (default: ").append(val).append(")");
} catch (Exception e) {
// ignore
}
}
}

private static void addSpaces(StringBuilder str, int count) {
for (int i = 0; i < count; i++) {
str.append(' ');
}
}
}
93 changes: 14 additions & 79 deletions jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
package jadx.cli;

import java.io.PrintStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.Appender;
import com.beust.jcommander.JCommander;
import com.beust.jcommander.Parameter;
import com.beust.jcommander.ParameterDescription;
import com.beust.jcommander.ParameterException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -94,27 +87,26 @@ public class JadxCLIArgs {
protected boolean printHelp = false;

public boolean processArgs(String[] args) {
return parse(args) && process();
JCommanderWrapper<JadxCLIArgs> jcw = new JCommanderWrapper<>(this);
return jcw.parse(args) && process(jcw);
}

private boolean parse(String[] args) {
try {
makeJCommander().parse(args);
return true;
} catch (ParameterException e) {
System.err.println("Arguments parse error: " + e.getMessage());
printUsage();
/**
* Set values only for options provided in cmd.
* Used to merge saved options and options passed in command line.
*/
public boolean overrideProvided(String[] args) {
JCommanderWrapper<JadxCLIArgs> jcw = new JCommanderWrapper<>(new JadxCLIArgs());
if (!jcw.parse(args)) {
return false;
}
jcw.overrideProvided(this);
return process(jcw);
}

private JCommander makeJCommander() {
return JCommander.newBuilder().addObject(this).build();
}

private boolean process() {
private boolean process(JCommanderWrapper jcw) {
if (printHelp) {
printUsage();
jcw.printUsage();
return false;
}
if (printVersion) {
Expand All @@ -136,69 +128,12 @@ private boolean process() {
}
} catch (JadxException e) {
System.err.println("ERROR: " + e.getMessage());
printUsage();
jcw.printUsage();
return false;
}
return true;
}

public void printUsage() {
JCommander jc = makeJCommander();
// 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<>(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;
}
}
JadxCLIArgs args = new JadxCLIArgs();
Field[] fields = args.getClass().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() + 3);
opt.append("- ").append(p.getDescription());
addDefaultValue(args, f, opt);
out.println(opt);
}
out.println("Example:");
out.println(" jadx -d out classes.dex");
}

private void addDefaultValue(JadxCLIArgs args, Field f, StringBuilder opt) {
Class<?> fieldType = f.getType();
if (fieldType == int.class) {
try {
int val = f.getInt(args);
opt.append(" (default: ").append(val).append(")");
} catch (Exception e) {
// ignore
}
}
}

private static void addSpaces(StringBuilder str, int count) {
for (int i = 0; i < count; i++) {
str.append(' ');
}
}

public JadxArgs toJadxArgs() {
JadxArgs args = new JadxArgs();
args.setInputFiles(files.stream().map(FileUtils::toFile).collect(Collectors.toList()));
Expand Down
26 changes: 25 additions & 1 deletion jadx-cli/src/test/java/jadx/cli/JadxCLIArgsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,35 @@ public void testSrcOption() {
assertThat(parse("").isSkipSources(), is(false));
}

@Test
public void testOptionsOverride() {
assertThat(override(new JadxCLIArgs(), "--no-imports").isUseImports(), is(false));
assertThat(override(new JadxCLIArgs(), "").isUseImports(), is(true));

JadxCLIArgs args = new JadxCLIArgs();
args.useImports = false;
assertThat(override(args, "--no-imports").isUseImports(), is(false));

args = new JadxCLIArgs();
args.useImports = false;
assertThat(override(args, "").isUseImports(), is(false));
}

private JadxCLIArgs parse(String... args) {
JadxCLIArgs jadxArgs = new JadxCLIArgs();
return parse(new JadxCLIArgs(), args);
}

private JadxCLIArgs parse(JadxCLIArgs jadxArgs, String... args) {
boolean res = jadxArgs.processArgs(args);
assertThat(res, is(true));
LOG.info("Jadx args: {}", jadxArgs.toJadxArgs());
return jadxArgs;
}

private JadxCLIArgs override(JadxCLIArgs jadxArgs, String... args) {
boolean res = jadxArgs.overrideProvided(args);
assertThat(res, is(true));
LOG.info("Jadx args: {}", jadxArgs.toJadxArgs());
return jadxArgs;
}
}
2 changes: 1 addition & 1 deletion jadx-gui/src/main/java/jadx/gui/JadxGUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static void main(String[] args) {
LogCollector.register();
final JadxSettings settings = JadxSettingsAdapter.load();
// overwrite loaded settings by command line arguments
if (!settings.processArgs(args)) {
if (!settings.overrideProvided(args)) {
return;
}
if (!tryDefaultLookAndFeel()) {
Expand Down

0 comments on commit 6b3e8f0

Please sign in to comment.