From 56eb4b894540384799ae8fe903b404b3e2e8a18d Mon Sep 17 00:00:00 2001 From: deathmarine Date: Tue, 16 May 2017 11:42:57 -0400 Subject: [PATCH] #79 Allow FindAll Dialog to search and display nonbinary files. --- src/us/deathmarine/luyten/FindAllBox.java | 105 ++++++++++++++++++---- src/us/deathmarine/luyten/FindBox.java | 29 +++--- 2 files changed, 106 insertions(+), 28 deletions(-) diff --git a/src/us/deathmarine/luyten/FindAllBox.java b/src/us/deathmarine/luyten/FindAllBox.java index 0dc8f56..25276c0 100644 --- a/src/us/deathmarine/luyten/FindAllBox.java +++ b/src/us/deathmarine/luyten/FindAllBox.java @@ -19,12 +19,16 @@ import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.io.BufferedReader; import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; import java.io.StringWriter; import java.util.Collections; import java.util.Enumeration; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.regex.Pattern; import javax.swing.*; import javax.swing.GroupLayout.Alignment; @@ -36,7 +40,12 @@ public class FindAllBox extends JDialog { private JButton findButton; private JTextField textField; + private JCheckBox mcase; + private JCheckBox regex; + private JCheckBox wholew; + private JList list; private JProgressBar progressBar; + private JLabel statusLabel = new JLabel(""); private DefaultListModel classesList = new DefaultListModel(); @@ -54,9 +63,13 @@ public FindAllBox(final MainWindow mainWindow) { findButton = new JButton("Find"); findButton.addActionListener(new FindButton()); + mcase = new JCheckBox("Match Case"); + regex = new JCheckBox("Regex"); + wholew = new JCheckBox("Whole Words"); + this.getRootPane().setDefaultButton(findButton); - JList list = new JList(classesList); + list = new JList(classesList); list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); list.setLayoutOrientation(JList.VERTICAL_WRAP); list.setVisibleRowCount(-1); @@ -68,18 +81,36 @@ public void mouseClicked(MouseEvent evt) { int index = list.locationToIndex(evt.getPoint()); String entryName = (String) list.getModel().getElementAt(index); String[] array = entryName.split("/"); - String internalName = StringUtilities.removeRight(entryName, ".class"); - TypeReference type = Model.metadataSystem.lookupType(internalName); - try { - mainWindow.getModel().extractClassToTextPane(type, array[array.length - 1], entryName, null); - } catch (Exception e) { - Luyten.showExceptionDialog("Exception!", e); + if (entryName.toLowerCase().endsWith(".class")) { + String internalName = StringUtilities.removeRight(entryName, ".class"); + TypeReference type = Model.metadataSystem.lookupType(internalName); + try { + mainWindow.getModel().extractClassToTextPane(type, array[array.length - 1], entryName, + null); + } catch (Exception e) { + Luyten.showExceptionDialog("Exception!", e); + } + + } else { + try { + JarFile jfile = new JarFile(MainWindow.model.getOpenedFile()); + mainWindow.getModel().extractSimpleFileEntryToTextPane( + jfile.getInputStream(jfile.getEntry(entryName)), array[array.length - 1], + entryName); + jfile.close(); + } catch (IOException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } } } } }); - JScrollPane listScroller = new JScrollPane(list); + list.setLayoutOrientation(JList.VERTICAL); + JScrollPane listScroller = new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); final Dimension center = new Dimension((int) (screenSize.width * 0.35), 500); @@ -95,11 +126,17 @@ public void mouseClicked(MouseEvent evt) { layout.setHorizontalGroup( layout.createSequentialGroup().addComponent(label) - .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(statusLabel) - .addComponent(textField) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(Alignment.LEADING) - .addComponent(listScroller).addComponent(progressBar)))) + .addGroup( + layout.createParallelGroup(Alignment.LEADING).addComponent(statusLabel) + .addComponent(textField) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.LEADING) + .addComponent(mcase)) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(wholew)) + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(regex))) + .addGroup(layout.createSequentialGroup() + .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(listScroller) + .addComponent(progressBar)))) .addGroup(layout.createParallelGroup(Alignment.LEADING).addComponent(findButton)) ); @@ -108,6 +145,8 @@ public void mouseClicked(MouseEvent evt) { layout.setVerticalGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(label).addComponent(textField) .addComponent(findButton)) + .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(mcase).addComponent(wholew) + .addComponent(regex)) .addGroup(layout.createParallelGroup(Alignment.LEADING) .addGroup(layout.createSequentialGroup() .addGroup(layout.createParallelGroup(Alignment.BASELINE).addComponent(listScroller)))) @@ -149,6 +188,7 @@ public void run() { JarEntry entry = ent.nextElement(); String name = entry.getName(); setStatus(name); + System.out.println(entry.getName()); if (filter && name.contains("$")) continue; if (entry.getName().endsWith(".class")) { @@ -169,11 +209,30 @@ public void run() { decompilationOptions.getSettings().isUnicodeOutputEnabled()); settings.getLanguage().decompileType(resolvedType, plainTextOutput, decompilationOptions); - String decompiledSource = stringwriter.toString().toLowerCase(); - if (decompiledSource.contains(textField.getText().toLowerCase())) { + if (search(stringwriter.toString())) addClassName(entry.getName()); + } + } else { + + StringBuilder sb = new StringBuilder(); + long nonprintableCharactersCount = 0; + try (InputStreamReader inputStreamReader = new InputStreamReader( + jfile.getInputStream(entry)); + BufferedReader reader = new BufferedReader(inputStreamReader);) { + String line; + while ((line = reader.readLine()) != null) { + sb.append(line).append("\n"); + + for (byte nextByte : line.getBytes()) { + if (nextByte <= 0) { + nonprintableCharactersCount++; + } + } + } } + if (nonprintableCharactersCount < 5 && search(sb.toString())) + addClassName(entry.getName()); } } setSearching(false); @@ -195,6 +254,22 @@ public void run() { } + private boolean search(String bulk) { + String a = textField.getText(); + String b = bulk; + if (regex.isSelected()) + return Pattern.matches(a, b); + if (wholew.isSelected()) + a = " " + a + " "; + if (!mcase.isSelected()) { + a = a.toLowerCase(); + b = b.toLowerCase(); + } + if (b.contains(a)) + return true; + return false; + } + private void setHideOnEscapeButton() { Action escapeAction = new AbstractAction() { private static final long serialVersionUID = 6846566740472934801L; diff --git a/src/us/deathmarine/luyten/FindBox.java b/src/us/deathmarine/luyten/FindBox.java index bec690d..d43dc8f 100644 --- a/src/us/deathmarine/luyten/FindBox.java +++ b/src/us/deathmarine/luyten/FindBox.java @@ -63,15 +63,15 @@ public FindBox(final MainWindow mainWindow) { wholew = new JCheckBox("Whole Words"); reverse = new JCheckBox("Search Backwards"); wrap = new JCheckBox("Wrap"); - + findButton = new JButton("Find"); findButton.addActionListener(new FindButton()); this.getRootPane().setDefaultButton(findButton); - + KeyStroke funcF3 = KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0, false); this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(funcF3, "FindNext"); this.getRootPane().getActionMap().put("FindNext", new FindExploreAction(true)); - + KeyStroke sfuncF3 = KeyStroke.getKeyStroke(KeyEvent.VK_F3, InputEvent.SHIFT_DOWN_MASK, false); this.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(sfuncF3, "FindPrevious"); this.getRootPane().getActionMap().put("FindPrevious", new FindExploreAction(false)); @@ -144,10 +144,10 @@ public void actionPerformed(ActionEvent event) { context.setWholeWord(wholew.isSelected()); if (!SearchEngine.find(pane, context).wasFound()) { - if(wrap.isSelected()){ + if (wrap.isSelected()) { pane.setSelectionStart(0); pane.setSelectionEnd(0); - }else{ + } else { mainWindow.getLabel().setText("Search Complete"); } } @@ -187,19 +187,22 @@ public void windowDeactivated(WindowEvent e) { } }); } - - public void fireExploreAction(boolean direction){ + + public void fireExploreAction(boolean direction) { new FindExploreAction(direction).actionPerformed(null); } - class FindExploreAction extends AbstractAction{ + + class FindExploreAction extends AbstractAction { /** * */ private static final long serialVersionUID = -4391670062679240573L; boolean direction; - public FindExploreAction(boolean forward){ + + public FindExploreAction(boolean forward) { direction = forward; } + @Override public void actionPerformed(ActionEvent e) { if (textField.getText().length() == 0) @@ -215,15 +218,15 @@ public void actionPerformed(ActionEvent e) { context.setWholeWord(wholew.isSelected()); if (!SearchEngine.find(pane, context).wasFound()) { - if(wrap.isSelected()){ + if (wrap.isSelected()) { pane.setSelectionStart(0); pane.setSelectionEnd(0); - }else{ + } else { mainWindow.getLabel().setText("Search Complete"); } } - + } - + } }