Commit bcaca781 authored by Skylot's avatar Skylot

style(gui): reformat code and fix some warnings

parent ffedaea5
......@@ -67,7 +67,6 @@ public class JadxWrapper {
/**
* Get the complete list of classes
* @return
*/
public List<JavaClass> getClasses() {
return decompiler.getClasses();
......@@ -75,19 +74,20 @@ public class JadxWrapper {
/**
* Get all classes that are not excluded by the excluded packages settings
* @return
*/
public List<JavaClass> getIncludedClasses() {
List<JavaClass> classList = decompiler.getClasses();
String excludedPackages = settings.getExcludedPackages().trim();
if (excludedPackages.length() == 0)
if (excludedPackages.length() == 0) {
return classList;
}
String[] excluded = excludedPackages.split("[ ]+");
return classList.stream().filter(cls -> {
for (String exclude : excluded) {
if (cls.getFullName().startsWith(exclude))
if (cls.getFullName().startsWith(exclude)) {
return false;
}
}
return true;
}).collect(Collectors.toList());
......
......@@ -3,12 +3,12 @@ package jadx.gui.jobs;
import javax.swing.*;
import java.util.concurrent.Future;
import jadx.gui.utils.NLS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.gui.ui.ProgressPanel;
import jadx.gui.utils.CacheObject;
import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils;
import jadx.gui.utils.search.TextSearchIndex;
......@@ -27,12 +27,7 @@ public class BackgroundWorker extends SwingWorker<Void, Void> {
if (isDone()) {
return;
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
progressPane.setVisible(true);
}
});
SwingUtilities.invokeLater(() -> progressPane.setVisible(true));
addPropertyChangeListener(progressPane);
execute();
}
......@@ -46,7 +41,7 @@ public class BackgroundWorker extends SwingWorker<Void, Void> {
}
@Override
protected Void doInBackground() throws Exception {
protected Void doInBackground() {
try {
System.gc();
LOG.debug("Memory usage: Before decompile: {}", Utils.memoryInfo());
......
......@@ -11,12 +11,7 @@ public class DecompileJob extends BackgroundJob {
protected void runJob() {
for (final JavaClass cls : wrapper.getIncludedClasses()) {
addTask(new Runnable() {
@Override
public void run() {
cls.decompile();
}
});
addTask(cls::decompile);
}
}
......
......@@ -150,7 +150,6 @@ public class JadxSettings extends JadxCLIArgs {
return true;
}
public boolean isShowHeapUsageBar() {
return showHeapUsageBar;
}
......
......@@ -21,7 +21,7 @@ public class JadxSettingsAdapter {
private static final Preferences PREFS = Preferences.userNodeForPackage(JadxGUI.class);
private static ExclusionStrategy EXCLUDE_FIELDS = new ExclusionStrategy() {
private static final ExclusionStrategy EXCLUDE_FIELDS = new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return JadxSettings.SKIP_FIELDS.contains(f.getName())
......
package jadx.gui.settings;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.MouseAdapter;
......@@ -245,11 +243,11 @@ public class JadxSettingsWindow extends JDialog {
});
JButton editExcludedPackages = new JButton(NLS.str("preferences.excludedPackages.button"));
editExcludedPackages.addActionListener( event -> {
editExcludedPackages.addActionListener(event -> {
String result = JOptionPane.showInputDialog(this, NLS.str("preferences.excludedPackages.editDialog"),
settings.getExcludedPackages());
if (result !=null) {
if (result != null) {
settings.setExcludedPackages(result);
}
});
......
package jadx.gui.treemodel;
import javax.swing.*;
import java.io.File;
import java.security.cert.Certificate;
import java.util.List;
import java.util.stream.Collectors;
import com.android.apksig.ApkVerifier;
import jadx.api.ResourceType;
import jadx.gui.JadxWrapper;
import jadx.gui.utils.CertificateManager;
import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.*;
import java.io.File;
import java.security.cert.Certificate;
import java.util.List;
import java.util.stream.Collectors;
import jadx.gui.JadxWrapper;
import jadx.gui.utils.CertificateManager;
import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils;
public class ApkSignature extends JNode {
private static final long serialVersionUID = -9121321926113143407L;
private static final Logger LOG = LoggerFactory.getLogger(ApkSignature.class);
private static final Logger log = LoggerFactory.getLogger(ApkSignature.class);
private static final ImageIcon CERTIFICATE_ICON = Utils.openIcon("certificate_obj");
private final transient File openFile;
private String content = null;
private String content;
public static ApkSignature getApkSignature(JadxWrapper wrapper) {
// Only show the ApkSignature node if an AndroidManifest.xml is present.
// Without a manifest the Google ApkVerifier refuses to work.
if (!wrapper.getResources().stream().anyMatch(r -> "AndroidManifest.xml".equals(r.getName()))) {
if (wrapper.getResources().stream().noneMatch(r -> "AndroidManifest.xml".equals(r.getName()))) {
return null;
}
File openFile = wrapper.getOpenFile();
......@@ -56,8 +58,9 @@ public class ApkSignature extends JNode {
@Override
public String getContent() {
if (content != null)
if (content != null) {
return this.content;
}
ApkVerifier verifier = new ApkVerifier.Builder(openFile).build();
try {
ApkVerifier.Result result = verifier.verify();
......@@ -80,7 +83,7 @@ public class ApkSignature extends JNode {
writeIssues(builder, err, result.getErrors());
writeIssues(builder, warn, result.getWarnings());
if (result.getV1SchemeSigners().size() > 0) {
if (!result.getV1SchemeSigners().isEmpty()) {
builder.append("<h2>");
builder.escape(String.format(result.isVerifiedUsingV1Scheme() ? sigSucc : sigFail, 1));
builder.append("</h2>\n");
......@@ -101,7 +104,7 @@ public class ApkSignature extends JNode {
}
builder.append("</blockquote>");
}
if (result.getV2SchemeSigners().size() > 0) {
if (!result.getV2SchemeSigners().isEmpty()) {
builder.append("<h2>");
builder.escape(String.format(result.isVerifiedUsingV2Scheme() ? sigSucc : sigFail, 2));
builder.append("</h2>\n");
......@@ -121,7 +124,7 @@ public class ApkSignature extends JNode {
}
this.content = builder.toString();
} catch (Exception e) {
log.error(e.getMessage(), e);
LOG.error(e.getMessage(), e);
StringEscapeUtils.Builder builder = StringEscapeUtils.builder(StringEscapeUtils.ESCAPE_HTML4);
builder.append("<h1>");
builder.escape(NLS.str("apkSignature.exception"));
......@@ -147,7 +150,7 @@ public class ApkSignature extends JNode {
}
private void writeIssues(StringEscapeUtils.Builder builder, String issueType, List<ApkVerifier.IssueWithParams> issueList) {
if (issueList.size() > 0) {
if (!issueList.isEmpty()) {
builder.append("<h3>");
builder.escape(issueType);
builder.append("</h3>");
......@@ -155,7 +158,7 @@ public class ApkSignature extends JNode {
// Unprotected Zip entry issues are very common, handle them separately
List<ApkVerifier.IssueWithParams> unprotIssues = issueList.stream().filter(i ->
i.getIssue() == ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY).collect(Collectors.toList());
if (unprotIssues.size() > 0) {
if (!unprotIssues.isEmpty()) {
builder.append("<h4>");
builder.escape(NLS.str("apkSignature.unprotectedEntry"));
builder.append("</h4><blockquote>");
......@@ -167,7 +170,7 @@ public class ApkSignature extends JNode {
}
List<ApkVerifier.IssueWithParams> remainingIssues = issueList.stream().filter(i ->
i.getIssue() != ApkVerifier.Issue.JAR_SIG_UNPROTECTED_ZIP_ENTRY).collect(Collectors.toList());
if (remainingIssues.size() > 0) {
if (!remainingIssues.isEmpty()) {
builder.append("<pre>\n");
for (ApkVerifier.IssueWithParams issue : remainingIssues) {
builder.escape(issue.toString());
......@@ -177,8 +180,5 @@ public class ApkSignature extends JNode {
}
builder.append("</blockquote>");
}
}
}
......@@ -85,7 +85,7 @@ public class JSources extends JNode {
}
}
// use identity set for collect inner packages
Set<JPackage> innerPackages = Collections.newSetFromMap(new IdentityHashMap<JPackage, Boolean>());
Set<JPackage> innerPackages = Collections.newSetFromMap(new IdentityHashMap<>());
for (JPackage pkg : pkgMap.values()) {
innerPackages.addAll(pkg.getInnerPackages());
}
......
......@@ -2,8 +2,6 @@ package jadx.gui.ui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import jadx.api.JadxDecompiler;
import jadx.gui.utils.NLS;
......@@ -42,11 +40,7 @@ class AboutDialog extends JDialog {
textPane.add(Box.createRigidArea(new Dimension(0, 20)));
JButton close = new JButton(NLS.str("tabs.close"));
close.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
dispose();
}
});
close.addActionListener(event -> dispose());
close.setAlignmentX(0.5f);
Container contentPane = getContentPane();
......
......@@ -33,14 +33,14 @@ import jadx.gui.jobs.DecompileJob;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.codearea.CodeArea;
import jadx.gui.utils.CacheObject;
import jadx.gui.utils.NLS;
import jadx.gui.utils.JumpPosition;
import jadx.gui.utils.NLS;
import jadx.gui.utils.search.TextSearchIndex;
public abstract class CommonSearchDialog extends JDialog {
private static final long serialVersionUID = 8939332306115370276L;
private static final Logger LOG = LoggerFactory.getLogger(CommonSearchDialog.class);
private static final long serialVersionUID = 8939332306115370276L;
public static final int RESULTS_PER_PAGE = 100;
......@@ -399,7 +399,7 @@ public abstract class CommonSearchDialog extends JDialog {
private final JLabel emptyLabel = new JLabel();
private final Color codeSelectedColor;
private final Color codeBackground;
private Map<Integer, Component> componentCache = new HashMap<>();
private final Map<Integer, Component> componentCache = new HashMap<>();
public ResultsTableCellRenderer() {
RSyntaxTextArea area = CodeArea.getDefaultArea(mainWindow);
......
package jadx.gui.ui;
import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class HeapUsageBar extends JProgressBar implements ActionListener {
private static final double TWO_TO_20 = 1048576d; // 1024 * 1024
private final Color GREEN = new Color(0, 180, 0);
private final Color RED = new Color(200, 0, 0);
import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils;
private final Runtime r;
public class HeapUsageBar extends JProgressBar implements ActionListener {
private static final long serialVersionUID = -8739563124249884967L;
private String maxHeapStr;
private static final double TWO_TO_20 = 1048576d;
private final Timer timer;
private static final Color GREEN = new Color(0, 180, 0);
private static final Color RED = new Color(200, 0, 0);
private final double maxGB;
private final transient Runtime runtime = Runtime.getRuntime();
private final transient Timer timer;
private final String textFormat;
private final double maxGB;
public HeapUsageBar() {
super();
textFormat = NLS.str("heapUsage.text");
r = Runtime.getRuntime();
this.textFormat = NLS.str("heapUsage.text");
setBorderPainted(false);
setStringPainted(true);
setValue(10);
int maxKB = (int) (r.maxMemory() / 1024);
int maxKB = (int) (runtime.maxMemory() / 1024);
setMaximum(maxKB);
maxGB = maxKB / TWO_TO_20;
update();
......@@ -40,12 +35,12 @@ public class HeapUsageBar extends JProgressBar implements ActionListener {
}
public void update() {
long used = r.totalMemory() - r.freeMemory();
long used = runtime.totalMemory() - runtime.freeMemory();
int usedKB = (int) (used / 1024);
setValue(usedKB);
setString(String.format(textFormat, (usedKB / TWO_TO_20), maxGB));
if ((used + Utils.MIN_FREE_MEMORY) > r.maxMemory()) {
if ((used + Utils.MIN_FREE_MEMORY) > runtime.maxMemory()) {
setForeground(RED);
} else {
setForeground(GREEN);
......
package jadx.gui.ui;
import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JNode;
import jadx.gui.ui.codearea.CodeArea;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.PanelUI;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import jadx.gui.settings.JadxSettings;
import jadx.gui.treemodel.JNode;
public final class HtmlPanel extends ContentPanel {
private static final long serialVersionUID = -6251262855835426245L;
......@@ -36,14 +29,14 @@ public final class HtmlPanel extends ContentPanel {
textArea.setFont(settings.getFont());
}
private static class JHtmlPane extends JEditorPane {
boolean antiAliasingEnabled;
private static final class JHtmlPane extends JEditorPane {
private static final long serialVersionUID = 6886040384052136157L;
public JHtmlPane() {
setContentType("text/html");
}
@Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
try {
......@@ -53,6 +46,5 @@ public final class HtmlPanel extends ContentPanel {
g2d.dispose();
}
}
}
}
......@@ -59,7 +59,7 @@ public class MainDropTarget implements DropTargetListener {
try {
Transferable transferable = dtde.getTransferable();
List<File> transferData = (List<File>) transferable.getTransferData(DataFlavor.javaFileListFlavor);
if (transferData != null && transferData.size() > 0) {
if (!transferData.isEmpty()) {
dtde.dropComplete(true);
// load first file
mainWindow.openFile(transferData.get(0));
......
......@@ -9,7 +9,6 @@ import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
......@@ -28,7 +27,6 @@ import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;
import jadx.gui.treemodel.*;
import org.fife.ui.rsyntaxtextarea.Theme;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -40,13 +38,20 @@ import jadx.gui.jobs.DecompileJob;
import jadx.gui.jobs.IndexJob;
import jadx.gui.settings.JadxSettings;
import jadx.gui.settings.JadxSettingsWindow;
import jadx.gui.treemodel.ApkSignature;
import jadx.gui.treemodel.JCertificate;
import jadx.gui.treemodel.JClass;
import jadx.gui.treemodel.JLoadableNode;
import jadx.gui.treemodel.JNode;
import jadx.gui.treemodel.JResource;
import jadx.gui.treemodel.JRoot;
import jadx.gui.update.JadxUpdate;
import jadx.gui.update.JadxUpdate.IUpdateCallback;
import jadx.gui.update.data.Release;
import jadx.gui.utils.CacheObject;
import jadx.gui.utils.JumpPosition;
import jadx.gui.utils.Link;
import jadx.gui.utils.NLS;
import jadx.gui.utils.JumpPosition;
import jadx.gui.utils.Utils;
import static javax.swing.KeyStroke.getKeyStroke;
......@@ -90,7 +95,6 @@ public class MainWindow extends JFrame {
private boolean isFlattenPackage;
private JToggleButton flatPkgButton;
private JCheckBoxMenuItem flatPkgMenuItem;
private JCheckBoxMenuItem heapUsageBarMenuItem;
private JToggleButton deobfToggleBtn;
private JCheckBoxMenuItem deobfMenuItem;
......@@ -382,7 +386,7 @@ public class MainWindow extends JFrame {
flatPkgMenuItem = new JCheckBoxMenuItem(NLS.str("menu.flatten"), ICON_FLAT_PKG);
flatPkgMenuItem.setState(isFlattenPackage);
heapUsageBarMenuItem = new JCheckBoxMenuItem(NLS.str("menu.heapUsageBar"));
JCheckBoxMenuItem heapUsageBarMenuItem = new JCheckBoxMenuItem(NLS.str("menu.heapUsageBar"));
heapUsageBarMenuItem.setState(settings.isShowHeapUsageBar());
heapUsageBarMenuItem.addActionListener(event -> {
settings.setShowHeapUsageBar(!settings.isShowHeapUsageBar());
......@@ -589,7 +593,7 @@ public class MainWindow extends JFrame {
});
tree.addTreeWillExpandListener(new TreeWillExpandListener() {
@Override
public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
public void treeWillExpand(TreeExpansionEvent event) {
TreePath path = event.getPath();
Object node = path.getLastPathComponent();
if (node instanceof JLoadableNode) {
......@@ -598,7 +602,8 @@ public class MainWindow extends JFrame {
}
@Override
public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
public void treeWillCollapse(TreeExpansionEvent event) {
// ignore
}
});
......
package jadx.gui.ui;
import javax.swing.*;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.text.BadLocationException;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import jadx.api.ResourceFile;
import jadx.api.ResourceType;
import jadx.gui.treemodel.ApkSignature;
......@@ -13,29 +28,6 @@ import jadx.gui.utils.JumpManager;
import jadx.gui.utils.JumpPosition;
import jadx.gui.utils.NLS;
import jadx.gui.utils.Utils;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.SwingUtilities;
import javax.swing.plaf.basic.BasicButtonUI;
import javax.swing.text.BadLocationException;
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
public class TabbedPane extends JTabbedPane {
......
......@@ -32,16 +32,16 @@ public class LineNumbers extends JPanel implements CaretListener {
private static final int NUM_HEIGHT = Integer.MAX_VALUE - 1000000;
private static final Map<?, ?> DESKTOP_HINTS = (Map<?, ?>) Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints");
private CodeArea codeArea;
private final CodeArea codeArea;
private boolean useSourceLines = true;
private int lastDigits;
private int lastLine;
private Map<String, FontMetrics> fonts;
private transient final Color numberColor;
private transient final Color currentColor;
private transient final Border border;
private final transient Color numberColor;
private final transient Color currentColor;
private final transient Border border;
public LineNumbers(CodeArea component) {
this.codeArea = component;
......@@ -199,12 +199,10 @@ public class LineNumbers extends JPanel implements CaretListener {
String fontFamily = (String) as.getAttribute(StyleConstants.FontFamily);
Integer fontSize = (Integer) as.getAttribute(StyleConstants.FontSize);
String key = fontFamily + fontSize;
FontMetrics fm = fonts.get(key);
if (fm == null) {
FontMetrics fm = fonts.computeIfAbsent(key, k -> {
Font font = new Font(fontFamily, Font.PLAIN, fontSize);
fm = codeArea.getFontMetrics(font);
fonts.put(key, fm);
}
return codeArea.getFontMetrics(font);
});
descent = Math.max(descent, fm.getDescent());
}
}
......
......@@ -6,9 +6,8 @@ import java.io.Reader;
import java.lang.reflect.Type;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Collections;
import java.nio.charset.StandardCharsets;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import com.google.gson.Gson;
......@@ -32,12 +31,8 @@ public class JadxUpdate {
private static final Type RELEASES_LIST_TYPE = new TypeToken<List<Release>>() {
}.getType();
private static final Comparator<Release> RELEASE_COMPARATOR = new Comparator<Release>() {
@Override
public int compare(Release o1, Release o2) {
return VersionComparator.checkAndCompare(o1.getName(), o2.getName());
}
};
private static final Comparator<Release> RELEASE_COMPARATOR = (o1, o2) ->
VersionComparator.checkAndCompare(o1.getName(), o2.getName());
public interface IUpdateCallback {
void onUpdate(Release r);
......@@ -47,17 +42,14 @@ public class JadxUpdate {
}
public static void check(final IUpdateCallback callback) {
Runnable run = new Runnable() {
@Override
public void run() {
try {
Release release = checkForNewRelease();
if (release != null) {
callback.onUpdate(release);
}
} catch (Exception e) {
LOG.debug("Jadx update error", e);
Runnable run = () -> {
try {
Release release = checkForNewRelease();
if (release != null) {
callback.onUpdate(release);
}
} catch (Exception e) {
LOG.debug("Jadx update error", e);
}
};
Thread thread = new Thread(run);
......@@ -77,17 +69,11 @@ public class JadxUpdate {
if (list == null) {
return null;
}
for (Iterator<Release> it = list.iterator(); it.hasNext(); ) {
Release release = it.next();
if (release.getName().equalsIgnoreCase(version)
|| release.isPreRelease()) {
it.remove();
}
}
list.removeIf(release -> release.getName().equalsIgnoreCase(version) || release.isPreRelease());
if (list.isEmpty()) {
return null;
}
Collections.sort(list, RELEASE_COMPARATOR);
list.sort(RELEASE_COMPARATOR);
Release latest = list.get(list.size() - 1);
if (VersionComparator.checkAndCompare(version, latest.getName()) >= 0) {
return null;
......@@ -101,7 +87,7 @@ public class JadxUpdate {
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestMethod("GET");
if (con.getResponseCode() == 200) {
Reader reader = new InputStreamReader(con.getInputStream(), "UTF-8");
Reader reader = new InputStreamReader(con.getInputStream(), StandardCharsets.UTF_8);
return GSON.fromJson(reader, type);
}
return null;
......
......@@ -21,8 +21,8 @@ public class CertificateManager {
private static final Logger LOG = LoggerFactory.getLogger(CertificateManager.class);
private static final String CERTIFICATE_TYPE_NAME = "X.509";
private final Certificate cert;
private X509Certificate x509cert;
private Certificate cert;
public static String decode(InputStream in) {
StringBuilder strBuild = new StringBuilder();
......
......@@ -9,7 +9,7 @@ import jadx.api.JavaMethod;
import jadx.api.JavaNode;
public class CodeLinesInfo {
private NavigableMap<Integer, JavaNode> map = new TreeMap<>();
private final NavigableMap<Integer, JavaNode> map = new TreeMap<>();
public CodeLinesInfo(JavaClass cls) {
addClass(cls);
......
......@@ -2,7 +2,6 @@ package jadx.gui.utils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
......@@ -47,11 +46,11 @@ public class CodeUsageInfo {
private void addUsage(JNode jNode, JavaClass javaClass,
CodeLinesInfo linesInfo, CodePosition codePosition, List<StringRef> lines) {
UsageInfo usageInfo = usageMap.computeIfAbsent(jNode, key -> new UsageInfo());
int line = codePosition.getLine();
JavaNode javaNodeByLine = linesInfo.getJavaNodeByLine(line);
StringRef codeLine = lines.get(line - 1);
JNode node = nodeCache.makeFrom(javaNodeByLine == null ? javaClass : javaNodeByLine);
UsageInfo usageInfo = usageMap.computeIfAbsent(jNode, key -> new UsageInfo());
int line = codePosition.getLine();
JavaNode javaNodeByLine = linesInfo.getJavaNodeByLine(line);
StringRef codeLine = lines.get(line - 1);
JNode node = nodeCache.makeFrom(javaNodeByLine == null ? javaClass : javaNodeByLine);
CodeNode codeNode = new CodeNode(node, line, codeLine);
usageInfo.addUsage(codeNode);
}
......
......@@ -5,7 +5,7 @@ import java.util.List;
public class JumpManager {
private List<JumpPosition> list = new ArrayList<>();
private final List<JumpPosition> list = new ArrayList<>();
private int currentPos = 0;
public void addPosition(JumpPosition pos) {
......
......@@ -3,7 +3,7 @@ package jadx.gui.utils;
import java.util.Locale;
public class LangLocale {
private Locale locale;
private final Locale locale;
public LangLocale(Locale locale) {
this.locale = locale;
......
......@@ -16,7 +16,7 @@ public class Link extends JLabel implements MouseListener {
private static final Logger LOG = LoggerFactory.getLogger(Link.class);
private String url;
private final String url;
public Link(String text, String url) {
super(text);
......
......@@ -4,24 +4,29 @@ import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.util.Vector;
import org.jetbrains.annotations.NotNull;
import jadx.core.utils.exceptions.JadxRuntimeException;
public class NLS {
private static Vector<LangLocale> i18nLocales = new Vector<>();
private static final Vector<LangLocale> i18nLocales = new Vector<>();
private static Map<LangLocale, ResourceBundle> i18nMessagesMap = new HashMap<>();
private static final Map<LangLocale, ResourceBundle> i18nMessagesMap = new HashMap<>();
private static final ResourceBundle fallbackMessagesMap;
private static final LangLocale localLocale;
// Use these two fields to avoid invoking Map.get() method twice.
private static ResourceBundle localizedMessagesMap;
private static ResourceBundle fallbackMessagesMap;
private static LangLocale currentLocale;
private static LangLocale localLocale;
static {
localLocale = new LangLocale(Locale.getDefault());
......@@ -45,10 +50,13 @@ public class NLS {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
String resName = String.format("i18n/Messages_%s.properties", locale.get());
URL bundleUrl = classLoader.getResource(resName);
if (bundleUrl == null) {
throw new JadxRuntimeException("Locale resource not found: " + resName);
}
try (Reader reader = new InputStreamReader(bundleUrl.openStream(), StandardCharsets.UTF_8)) {
bundle = new PropertyResourceBundle(reader);
} catch (IOException e) {
throw new RuntimeException("Failed to load " + resName, e);
throw new JadxRuntimeException("Failed to load " + resName, e);
}
i18nMessagesMap.put(locale, bundle);
}
......@@ -66,7 +74,8 @@ public class NLS {
if (bundle != null) {
try {
return bundle.getString(key);
} catch (MissingResourceException e) {
} catch (MissingResourceException ignored) {
// use fallback string
}
}
return fallbackMessagesMap.getString(key); // definitely exists
......
......@@ -30,7 +30,7 @@ public class Utils {
* The minimum about of memory in bytes we are trying to keep free, otherwise the application may run out of heap
* which ends up in a Java garbage collector running "amok" (CPU utilization 100% for each core and the UI is
* not responsive).
*
* <p>
* We can calculate and store this value here as the maximum heap is fixed for each JVM instance
* and can't be changed at runtime.
*/
......@@ -123,8 +123,7 @@ public class Utils {
public static long calculateMinFreeMemory() {
Runtime runtime = Runtime.getRuntime();
long minFree = (long) (runtime.maxMemory() * 0.2);
minFree = Math.min(minFree, 512 * 1048576);
return minFree;
return Math.min(minFree, 512 * 1024L * 1024L);
}
public static boolean isFreeMemoryAvailable() {
......@@ -151,7 +150,7 @@ public class Utils {
}
private static String format(long mem) {
return Long.toString((long) (mem / 1024. / 1024.)) + "MB";
return (long) (mem / (double) (1024L * 1024L)) + "MB";
}
/**
......
......@@ -47,7 +47,7 @@ tabs.closeAll=Close All
nav.back=Back
nav.forward=Forward
message.indexingClassesSkipped=<html>Jadx is running low on memory. Therefore %d classes were not indexed.<br>If you want all classes to be indexed restart Jadx with increased maximum heap size.</html>
message.indexingClassesSkipped=<html>Jadx is running low on memory. Therefore %d classes were not indexed.<br>If you want all classes to be indexed restart Jadx with increased maximum heap size.</html>
heapUsage.text=JADX memory usage: %.2f GB of %.2f GB
......@@ -152,4 +152,4 @@ apkSignature.signatureFailed=Invalid APK signature v%d found
apkSignature.errors=Errors
apkSignature.warnings=Warnings
apkSignature.exception=APK verification failed
apkSignature.unprotectedEntry=Files that are not protected by signature. Unauthorized modifications to this JAR entry will not be detected.
\ No newline at end of file
apkSignature.unprotectedEntry=Files that are not protected by signature. Unauthorized modifications to this JAR entry will not be detected.
package jadx.gui.tests
import jadx.gui.utils.search.StringRef
import spock.lang.Specification
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment