diff --git a/jadx-gui/src/main/java/jadx/gui/device/debugger/BreakpointManager.java b/jadx-gui/src/main/java/jadx/gui/device/debugger/BreakpointManager.java index c10ea404e8f1d2f5a1e7e12c698bdf8180af0d38..e78459c2793d0cea5f33bb6a9dd4aef0ca56476e 100644 --- a/jadx-gui/src/main/java/jadx/gui/device/debugger/BreakpointManager.java +++ b/jadx-gui/src/main/java/jadx/gui/device/debugger/BreakpointManager.java @@ -1,9 +1,11 @@ package jadx.gui.device.debugger; +import java.io.Reader; import java.lang.reflect.Type; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Collections; @@ -14,6 +16,8 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Objects; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,52 +32,39 @@ import jadx.gui.treemodel.JClass; public class BreakpointManager { private static final Logger LOG = LoggerFactory.getLogger(BreakpointManager.class); - private static Gson gson = null; + private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create(); private static final Type TYPE_TOKEN = new TypeToken>>() { }.getType(); - private static Map> bpm; - private static Path savePath; + private static @NotNull Map> bpm = Collections.emptyMap(); + private static @Nullable Path savePath; private static DebugController debugController; private static Map> listeners = Collections.emptyMap(); // class full name as key public static void saveAndExit() { - if (bpm != null) { - if (bpm.size() == 0 && !Files.exists(savePath)) { - return; // user didn't do anything with breakpoint so don't output breakpoint file. - } - sync(); - bpm = null; - savePath = null; - listeners = Collections.emptyMap(); - } + sync(); + bpm = Collections.emptyMap(); + savePath = null; + listeners = Collections.emptyMap(); } - public static void init(Path dirPath) { - if (gson == null) { - gson = new GsonBuilder() - .setPrettyPrinting() - .create(); - } - savePath = dirPath.resolve("breakpoints.json"); + public static void init(@Nullable Path baseDir) { + Path saveDir = baseDir != null ? baseDir : Paths.get("."); + savePath = saveDir.resolve("breakpoints.json"); // TODO: move into project file or same dir as project file if (Files.exists(savePath)) { - try { - byte[] bytes = Files.readAllBytes(savePath); - bpm = gson.fromJson(new String(bytes, StandardCharsets.UTF_8), TYPE_TOKEN); + try (Reader reader = Files.newBufferedReader(savePath, StandardCharsets.UTF_8)) { + bpm = GSON.fromJson(reader, TYPE_TOKEN); } catch (Exception e) { LOG.error("Failed to read breakpoints config: {}", savePath, e); } } - if (bpm == null) { - bpm = Collections.emptyMap(); - } } /** * @param listener When breakpoint is failed to set during debugging, this listener will be called. */ public static void addListener(JClass topCls, Listener listener) { - if (listeners == Collections.EMPTY_MAP) { + if (listeners.isEmpty()) { listeners = new HashMap<>(); } listeners.put(DbgUtils.getRawFullName(topCls), @@ -149,8 +140,15 @@ public class BreakpointManager { } private static void sync() { + if (savePath == null) { + return; + } + if (bpm.isEmpty() && !Files.exists(savePath)) { + // user didn't do anything with breakpoint so don't output breakpoint file. + return; + } try { - Files.write(savePath, gson.toJson(bpm).getBytes(StandardCharsets.UTF_8)); + Files.write(savePath, GSON.toJson(bpm).getBytes(StandardCharsets.UTF_8)); } catch (Exception e) { LOG.error("Failed to write breakpoints config: {}", savePath, e); }