FavoritesConfig generalized into NamedListConfig.

OpenersConfig introduced.
GUI for editing openers added.

git-svn-id: https://ipscan.svn.sourceforge.net/svnroot/ipscan/ipscan@17 375186e5-ef17-0410-b0b6-91563547dcda
This commit is contained in:
angryziber 2006-08-17 19:41:50 +00:00
parent 3e83fd5693
commit 315697c72d
28 changed files with 877 additions and 287 deletions

View File

@ -19,6 +19,7 @@ menu.commands.copy=&Copy IP Ctrl+C
menu.commands.copyDetails=Co&py details
menu.commands.show=Show
menu.commands.open=Open
menu.commands.open.edit=Edit openers...
menu.favorites=Fa&vorites
menu.favorites.add=Add current... Ctrl+D
menu.favorites.edit=Manage favorites...
@ -57,14 +58,20 @@ title.saveSelection=Export Selected Results
title.gettingStarted=Getting Started
title.favorite.add=Add a favorite
title.favorite.edit=Edit favorites
title.openers.edit=Edit Openers
title.find=Find
text.ip=IP
text.threads=Threads:
text.favorite.add=Enter the name of the new favorite
text.favorite.edit=Below you can rearrange or delete favorites
text.openers.edit=Below you can edit or add new openers
text.find=Enter the text to search for
text.find.notFound=Nothing was found.
text.find.restart=Would you like to start from the beginning?
text.openers.name=Opener name (menu item):
text.openers.string=Execution string:
text.openers.directory=Working directory:
text.openers.isCommandLine=Command-line program
text.about=%NAME\n\nVersion %VERSION\n%COPYLEFT\n\n<a>%WEBSITE</a>\n<a>%MAILTO</a>\n\nThis is an Open Source Software released under the GPL.
text.gettingStarted=Dummy
text.gettingStarted1=Angry IP Scanner is an IP address scanner tool.\n\nIt is used for scanning IP addresses for finding alive hosts, gathering any kind of needed information about each host.
@ -80,10 +87,17 @@ button.ipUp.img=images/buttons/ipup.gif
button.up=&Up
button.down=&Down
button.delete=De&lete
button.save=&Save
button.insert=&Insert
list.unknown.img=images/list/unknown.gif
list.dead.img=images/list/dead.gif
list.alive.img=images/list/alive.gif
list.addinfo.img=images/list/addinfo.gif
opener.web=Web Browser
opener.ftp=FTP
opener.telnet=Telnet
opener.ssh=SSH
opener.netbios=Windows Shares
feeder.range=IP Range
feeder.range.startIP=IP Range:
feeder.range.endIP=to
@ -136,6 +150,10 @@ exception.ExporterException.failed=Exporting failed
exception.ExporterException.exporter.unknown=Unknown file type, please specify correct extension in the file name.
exception.ExporterException.xml.noAppend=Appending to XML files is not supported.
exception.ExporterException.fetcher.notFound=Not enough data in the scanning results to export to this file type.
exception.UserErrorException.openURL.failed=Unable to launch your default browser, sorry.\nURL:
exception.UserErrorException.opener.failed=Unable to launch an external process, sorry.\nCommand-line:
exception.UserErrorException.opener.unknownFetcher=The referenced fetcher cannot be resolved in the current scanning result:
exception.UserErrorException.opener.nullFetcherValue=The replacement value of the fetcher is empty in the scanning results:
exception.UserErrorException.commands.noSelection=No IP address selected
exception.UserErrorException.commands.noResults=No scanning results available yet, please perform a scan first
exception.UserErrorException.favorite.alreadyExists=A favorite with the same name already exists, please try a different one

View File

@ -16,6 +16,7 @@ import org.eclipse.swt.widgets.Shell;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.gui.MainWindow;
import net.azib.ipscan.gui.UserErrorException;
/**
* The main executable class.
@ -80,9 +81,14 @@ public class Main {
String localizedMessage;
try {
// try to load localized message
String exceptionClassName = getClassShortName(e.getClass());
String originalMessage = e.getMessage();
localizedMessage = Labels.getInstance().getString("exception." + exceptionClassName + (originalMessage != null ? "." + originalMessage : ""));
if (e instanceof UserErrorException) {
localizedMessage = e.getMessage();
}
else {
String exceptionClassName = getClassShortName(e.getClass());
String originalMessage = e.getMessage();
localizedMessage = Labels.getInstance().getString("exception." + exceptionClassName + (originalMessage != null ? "." + originalMessage : ""));
}
// add cause summary, if it exists
if (e.getCause() != null) {
localizedMessage += "\n\n" + e.getCause().toString();

View File

@ -18,7 +18,9 @@ public final class Config {
/** easily accessible global configuration */
private static GlobalConfig globalConfig;
/** favorites are stored here */
private static FavoritesConfig favoritesConfig;
private static NamedListConfig favoritesConfig;
/** openers are stored here */
private static OpenersConfig openersConfig;
/** various dimensions are stored here */
private static DimensionsConfig dimensionsConfig;
@ -32,12 +34,14 @@ public final class Config {
preferences = Preferences.userRoot().node("ipscan");
globalConfig = new GlobalConfig();
favoritesConfig = new FavoritesConfig();
openersConfig = new OpenersConfig();
dimensionsConfig = new DimensionsConfig();
}
public static void store() {
globalConfig.store();
favoritesConfig.store();
openersConfig.store();
dimensionsConfig.store();
}
@ -55,10 +59,20 @@ public final class Config {
/**
* @return Favorites config (quick access);
*/
public static FavoritesConfig getFavoritesConfig() {
public static NamedListConfig getFavoritesConfig() {
return favoritesConfig;
}
/**
* @return Openers config (quick access);
*/
public static OpenersConfig getOpenersConfig() {
return openersConfig;
}
/**
* @return Dimensions config (quick access);
*/
public static DimensionsConfig getDimensionsConfig() {
return dimensionsConfig;
}

View File

@ -1,108 +0,0 @@
/**
*
*/
package net.azib.ipscan.config;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.prefs.Preferences;
/**
* FavoritesConfig
*
* @author anton
*/
public class FavoritesConfig {
private Preferences preferences = Config.getPreferences();
private Map favorites = new LinkedHashMap();
// package local constructor
FavoritesConfig() {
load();
}
/**
* This constructor is for tests
* @param preferences
*/
FavoritesConfig(Preferences preferences) {
this.preferences = preferences;
load();
}
/**
* Loads preferences
*/
void load() {
if (preferences == null) {
return;
}
String[] favoritePrefs = preferences.get("favorites", "").split("###");
for (int i = 0; i < favoritePrefs.length; i += 2) {
if (favoritePrefs[i].length() > 0) {
favorites.put(favoritePrefs[i], favoritePrefs[i+1]);
}
}
}
/**
* Stores the currently available favorites
*/
public void store() {
StringBuffer sb = new StringBuffer(32);
for (Iterator i = favorites.entrySet().iterator(); i.hasNext();) {
Map.Entry e = (Map.Entry) i.next();
sb.append(e.getKey()).append("###").append(e.getValue()).append("###");
}
if (sb.length() > 3) {
sb.delete(sb.length() - 3, sb.length());
}
preferences.put("favorites", sb.toString());
}
/**
* @param name favorite name
* @param feederInfo feederInfo to restore feeder state
*/
public void add(String name, String feederInfo) {
favorites.put(name, feederInfo);
}
/**
* @param name favorite name
* @return feederInfo string
*/
public String get(String name) {
return (String) favorites.get(name);
}
/**
* @return an Iterator for iterating names of available favorites
*/
public Iterator iterateNames() {
return favorites.keySet().iterator();
}
public int size() {
return favorites.size();
}
/**
* Updates favorites, retaining only those that are passed in the array.
* The order of elements will be the same as in the array.
*
* @param names
*/
public void update(String[] names) {
// rebuild the map (to recreate the new order of elements)
Map newFavorites = new LinkedHashMap();
for (int i = 0; i < names.length; i++) {
newFavorites.put(names[i], favorites.get(names[i]));
}
favorites = newFavorites;
}
}

View File

@ -0,0 +1,113 @@
/**
*
*/
package net.azib.ipscan.config;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.prefs.Preferences;
/**
* This is a generic named list config.
* Can be used for storing favorites, openers, and other
* user-defined configuration.
*
* @author anton
*/
public class NamedListConfig {
private String preferenceName;
private Preferences preferences = Config.getPreferences();
private Map namedList = new LinkedHashMap();
// package local constructor
NamedListConfig(String preferenceName) {
this.preferenceName = preferenceName;
load();
}
/**
* This constructor is for tests
* @param preferences
*/
NamedListConfig(Preferences preferences, String preferenceName) {
this.preferenceName = preferenceName;
this.preferences = preferences;
load();
}
/**
* Loads preferences
*/
public void load() {
if (preferences == null) {
return;
}
String[] namedListPrefs = preferences.get(preferenceName, "").split("###");
for (int i = 0; i < namedListPrefs.length; i += 2) {
if (namedListPrefs[i].length() > 0) {
namedList.put(namedListPrefs[i], namedListPrefs[i+1]);
}
}
}
/**
* Stores the currently available named list
*/
public void store() {
StringBuffer sb = new StringBuffer(32);
for (Iterator i = namedList.entrySet().iterator(); i.hasNext();) {
Map.Entry e = (Map.Entry) i.next();
sb.append(e.getKey()).append("###").append(e.getValue()).append("###");
}
if (sb.length() > 3) {
sb.delete(sb.length() - 3, sb.length());
}
preferences.put(preferenceName, sb.toString());
}
/**
* @param name displayed to the user
* @param value to store according to the name
*/
public void add(String name, String value) {
namedList.put(name, value);
}
/**
* @param name favorite name
* @return stored value
*/
public String get(String name) {
return (String) namedList.get(name);
}
/**
* @return an Iterator for iterating names of available favorites
*/
public Iterator iterateNames() {
return namedList.keySet().iterator();
}
public int size() {
return namedList.size();
}
/**
* Updates the list, retaining only items that are passed in the array.
* The order of elements will be the same as in the array.
*
* @param names
*/
public void update(String[] names) {
// rebuild the map (to recreate the new order of elements)
Map newList = new LinkedHashMap();
for (int i = 0; i < names.length; i++) {
newList.put(names[i], namedList.get(names[i]));
}
namedList = newList;
}
}

View File

@ -0,0 +1,31 @@
/**
*
*/
package net.azib.ipscan.config;
/**
* OpenersConfig
*
* @author anton
*/
public class OpenersConfig extends NamedListConfig {
public OpenersConfig() {
super("openers");
if (size() == 0) {
Labels labels = Labels.getInstance();
// add default openers
add(labels.getString("opener.web"), "http://${fetcher.ip}/");
add(labels.getString("opener.netbios"), "\\\\${fetcher.ip}");
add(labels.getString("opener.ftp"), "ftp://${fetcher.ip}/");
add(labels.getString("opener.telnet"), "telnet ${fetcher.ip}");
add(labels.getString("opener.ssh"), "ssh ${fetcher.ip}");
}
}
}

View File

@ -33,7 +33,14 @@ public class ScanningResultList {
scanningResults.set(index, result);
}
public synchronized String getIPDetails(int index) {
/**
* Returns all results for a particular IP address as a String.
* This is used in showing the IP Details dialog box.
*
* @param index
* @return
*/
public synchronized String getResultsAsString(int index) {
// TODO: what if a String is retrieved???
ScanningResult scanningResult = (ScanningResult) scanningResults.get(index);
StringBuffer details = new StringBuffer(1024);
@ -63,7 +70,7 @@ public class ScanningResultList {
/**
* @return an Iterator of scanning results
*/
public Iterator iterator() {
public synchronized Iterator iterator() {
return scanningResults.iterator();
}
@ -71,6 +78,10 @@ public class ScanningResultList {
return scanningResults.get(tableIndex) instanceof ScanningResult;
}
/**
* @param tableIndex
* @return a results of a single IP adress, corresponding to an index
*/
public synchronized ScanningResult getResult(int tableIndex) {
// TODO: error handling
return (ScanningResult) scanningResults.get(tableIndex);

View File

@ -54,4 +54,19 @@ public class FetcherRegistry {
return fetchers;
}
/**
* Searches for selected fetcher with the given label
* @param label
* @return the index, if found, or -1
*/
public int getSelectedFetcherIndex(String label) {
// TODO: this probably needs to be changed to reflect selected fetchers and be more effective
for (int i = 0; i < fetchers.size(); i++) {
if (label.equals(((Fetcher)fetchers.get(i)).getLabel())) {
return i;
}
}
return -1;
}
}

View File

@ -23,24 +23,12 @@ import org.eclipse.swt.widgets.Text;
*
* @author anton
*/
public class AboutWindow {
private Shell shell; // @jve:decl-index=0:visual-constraint="10,10"
public class AboutWindow extends AbstractModalDialog {
public AboutWindow() {
createShell();
}
public void open() {
shell.open();
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.dispose();
}
/**
* This method initializes shell
*/

View File

@ -0,0 +1,28 @@
/**
*
*/
package net.azib.ipscan.gui;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
/**
* This is the base of a modal dialog window
*
* @author anton
*/
public abstract class AbstractModalDialog {
protected Shell shell = null;
public void open() {
shell.open();
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.dispose();
}
}

View File

@ -19,26 +19,15 @@ import org.eclipse.swt.widgets.Text;
*
* @author anton
*/
public class DetailsWindow {
public class DetailsWindow extends AbstractModalDialog {
private ResultTable resultTable;
private Shell shell;
public DetailsWindow(ResultTable resultTable) {
this.resultTable = resultTable;
createShell(resultTable.getShell());
}
public void open() {
shell.open();
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.dispose();
}
/**
* This method initializes shell
*/

View File

@ -6,8 +6,8 @@ package net.azib.ipscan.gui;
import java.util.Iterator;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.FavoritesConfig;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.config.NamedListConfig;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
@ -25,25 +25,14 @@ import org.eclipse.swt.widgets.Shell;
*
* @author anton
*/
public class EditFavoritesDialog {
public class EditFavoritesDialog extends AbstractModalDialog {
private Shell shell = null;
private List favoritesList;
public EditFavoritesDialog() {
createShell();
}
public void open() {
shell.open();
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.dispose();
}
/**
* This method initializes shell
*/
@ -105,7 +94,7 @@ public class EditFavoritesDialog {
}
private void saveFavorites() {
FavoritesConfig favoritesConfig = Config.getFavoritesConfig();
NamedListConfig favoritesConfig = Config.getFavoritesConfig();
favoritesConfig.update(favoritesList.getItems());
favoritesConfig.store();
}

View File

@ -0,0 +1,248 @@
/**
*
*/
package net.azib.ipscan.gui;
import java.util.Iterator;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.config.OpenersConfig;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
/**
* EditOpenersDialog
*
* @author anton
*/
public class EditOpenersDialog extends AbstractModalDialog {
private List openersList;
private Group editGroup;
private Text openerNameText;
private Text openerStringText;
private Text openerDirText;
private SaveButtonListener saveButtonListener;
public EditOpenersDialog() {
createShell();
}
/**
* This method initializes shell
*/
private void createShell() {
Display currentDisplay = Display.getCurrent();
Shell parent = currentDisplay != null ? currentDisplay.getActiveShell() : null;
shell = new Shell(parent, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
shell.setText(Labels.getInstance().getString("title.openers.edit"));
shell.setSize(new Point(405, 295));
shell.setLayout(null);
Label messageLabel = new Label(shell, SWT.NONE);
messageLabel.setText(Labels.getInstance().getString("text.openers.edit"));
messageLabel.setBounds(new Rectangle(10, 10, 282, 14));
openersList = new List(shell, SWT.BORDER | SWT.MULTI | SWT.V_SCROLL);
openersList.setBounds(new Rectangle(10, 30, 135, 200));
for (Iterator i = Config.getOpenersConfig().iterateNames(); i.hasNext();) {
String name = (String) i.next();
openersList.add(name);
}
openersList.addListener(SWT.Selection, new ItemSelectListener());
Button upButton = new Button(shell, SWT.NONE);
upButton.setText(Labels.getInstance().getString("button.up"));
upButton.setBounds(new Rectangle(150, 30, 40, 25));
upButton.addListener(SWT.Selection, new UpButtonListener());
Button downButton = new Button(shell, SWT.NONE);
downButton.setText(Labels.getInstance().getString("button.down"));
downButton.setBounds(new Rectangle(150, 60, 40, 25));
downButton.addListener(SWT.Selection, new DownButtonListener());
Button insertButton = new Button(shell, SWT.NONE);
insertButton.setText(Labels.getInstance().getString("button.insert"));
insertButton.setBounds(new Rectangle(150, 105, 40, 25));
insertButton.addListener(SWT.Selection, new InsertButtonListener());
Button deleteButton = new Button(shell, SWT.NONE);
deleteButton.setText(Labels.getInstance().getString("button.delete"));
deleteButton.setBounds(new Rectangle(150, 135, 40, 25));
deleteButton.addListener(SWT.Selection, new DeleteButtonListener());
Button saveButton = new Button(shell, SWT.NONE);
saveButton.setText(Labels.getInstance().getString("button.save"));
saveButton.setBounds(new Rectangle(150, 165, 40, 25));
saveButtonListener = new SaveButtonListener();
saveButton.addListener(SWT.Selection, saveButtonListener);
Button okButton = new Button(shell, SWT.NONE);
okButton.setText(Labels.getInstance().getString("button.OK"));
okButton.setBounds(new Rectangle(180, 240, 75, 22));
shell.setDefaultButton(okButton);
Button cancelButton = new Button(shell, SWT.NONE);
cancelButton.setText(Labels.getInstance().getString("button.cancel"));
cancelButton.setBounds(new Rectangle(265, 240, 75, 22));
editGroup = new Group(shell, SWT.NONE);
editGroup.setBounds(205, 30, 185, 200);
RowLayout rowLayout = new RowLayout(SWT.VERTICAL);
rowLayout.fill = true;
rowLayout.justify = true;
rowLayout.marginTop = 13;
editGroup.setLayout(rowLayout);
Label openerNameLabel = new Label(editGroup, SWT.NONE);
openerNameLabel.setText(Labels.getInstance().getString("text.openers.name"));
openerNameLabel.setSize(SWT.DEFAULT, 18);
openerNameText = new Text(editGroup, SWT.BORDER);
openerNameText.setSize(SWT.DEFAULT, 22);
Label openerStringLabel = new Label(editGroup, SWT.NONE);
openerStringLabel.setText(Labels.getInstance().getString("text.openers.string"));
openerStringLabel.setSize(SWT.DEFAULT, 18);
openerStringText = new Text(editGroup, SWT.BORDER);
openerStringText.setSize(SWT.DEFAULT, 22);
Label openerDirLabel = new Label(editGroup, SWT.NONE);
openerDirLabel.setText(Labels.getInstance().getString("text.openers.directory"));
openerDirLabel.setSize(SWT.DEFAULT, 18);
openerDirText = new Text(editGroup, SWT.BORDER);
openerDirText.setSize(SWT.DEFAULT, 22);
Button isCommanLineCheckbox = new Button(editGroup, SWT.CHECK);
isCommanLineCheckbox.setText(Labels.getInstance().getString("text.openers.isCommandLine"));
isCommanLineCheckbox.setSize(SWT.DEFAULT, 18);
editGroup.layout();
okButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
saveOpeners();
shell.close();
}
});
cancelButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
Config.getOpenersConfig().load();
shell.close();
}
});
}
private void saveOpeners() {
// save any possible changes in the text boxes
saveButtonListener.handleEvent(null);
// now save everything else
OpenersConfig openersConfig = Config.getOpenersConfig();
openersConfig.update(openersList.getItems());
openersConfig.store();
}
private class UpButtonListener implements Listener {
public void handleEvent(Event event) {
if (openersList.isSelected(0)) {
// do not move anything if the first item is selected
return;
}
int[] selectedItems = openersList.getSelectionIndices();
for (int i = 0; i < selectedItems.length; i++) {
// here, index is always > 0
int index = selectedItems[i];
openersList.deselect(index);
String oldItem = openersList.getItem(index - 1);
openersList.setItem(index - 1, openersList.getItem(index));
openersList.setItem(index, oldItem);
openersList.select(index - 1);
}
openersList.setTopIndex(selectedItems[0] - 2);
}
}
private class DownButtonListener implements Listener {
public void handleEvent(Event event) {
if (openersList.isSelected(openersList.getItemCount() - 1)) {
// do not move anything if the last items is selected
return;
}
int[] selectedItems = openersList.getSelectionIndices();
for (int i = selectedItems.length - 1; i >= 0; i--) {
// here, index is always < getItemCount()
int index = selectedItems[i];
openersList.deselect(index);
String oldItem = openersList.getItem(index + 1);
openersList.setItem(index + 1, openersList.getItem(index));
openersList.setItem(index, oldItem);
openersList.select(index + 1);
}
openersList.setTopIndex(selectedItems[0]);
}
}
private class DeleteButtonListener implements Listener {
public void handleEvent(Event event) {
openersList.remove(openersList.getSelectionIndices());
}
}
private class SaveButtonListener implements Listener {
public void handleEvent(Event event) {
String openerName = openerNameText.getText();
String openerValue = openerStringText.getText();
Config.getOpenersConfig().add(openerName, openerValue);
openersList.setItem(openersList.getSelectionIndex(), openerName);
}
}
private class InsertButtonListener implements Listener {
public void handleEvent(Event event) {
int selectionIndex = openersList.getSelectionIndex();
if (selectionIndex < 0) {
selectionIndex = openersList.getItemCount();
}
openersList.add("", selectionIndex);
openersList.setSelection(selectionIndex);
}
}
private class ItemSelectListener implements Listener {
public void handleEvent(Event event) {
int selectionIndex = openersList.getSelectionIndex();
String openerName = openersList.getItem(selectionIndex);
editGroup.setText(openerName);
String openerValue = Config.getOpenersConfig().get(openerName);
openerNameText.setText(openerName);
openerStringText.setText(openerValue);
// TODO: load other stuff too
}
}
}

View File

@ -20,9 +20,8 @@ import org.eclipse.swt.widgets.Text;
*
* @author anton
*/
public class GettingStartedWindow {
public class GettingStartedWindow extends AbstractModalDialog {
private Shell shell; // @jve:decl-index=0:visual-constraint="10,10"
private int activePage = 1;
private Text gettingStartedText;
private Button closeButton;
@ -32,16 +31,6 @@ public class GettingStartedWindow {
createShell();
}
public void open() {
shell.open();
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.dispose();
}
/**
* This method initializes shell
*/

View File

@ -19,9 +19,8 @@ import org.eclipse.swt.widgets.Button;
*
* @author anton
*/
public class InputDialog {
public class InputDialog extends AbstractModalDialog {
private Shell shell = null; // @jve:decl-index=0:visual-constraint="10,10"
private Label messageLabel = null;
private Text text = null;
private Button okButton = null;
@ -73,7 +72,7 @@ public class InputDialog {
});
}
public void setText(String text) {
private void setText(String text) {
this.text.setText(text);
this.text.setSelection(0, -1);
}
@ -83,14 +82,9 @@ public class InputDialog {
*
* @return the entered text or null in case of cancel.
*/
public String open() {
shell.open();
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.dispose();
public String open(String text) {
setText(text);
super.open();
return message;
}

View File

@ -31,6 +31,7 @@ public class MainMenu {
private Menu resultsContextMenu;
private Menu favoritesMenu;
private Menu columnsMenu;
private Menu openersMenu;
public MainMenu(MainWindow mainWindow) {
@ -45,6 +46,19 @@ public class MainMenu {
// generate the menu from the definition
generateMenu(shell, menuDefinition, mainMenu);
openersMenu = new Menu(shell, SWT.DROP_DOWN);
MenuItem openersMenuItem = new MenuItem(mainMenu.getItem(2).getMenu(), SWT.CASCADE);
openersMenuItem.setText(Labels.getInstance().getString("menu.commands.open"));
openersMenuItem.setMenu(openersMenu);
CommandsActions.ShowOpenersMenu showOpenersMenuListener = new CommandsActions.ShowOpenersMenu(mainWindow, openersMenu);
openersMenu.addListener(SWT.Show, showOpenersMenuListener);
MenuItem menuItem = new MenuItem(openersMenu, SWT.PUSH);
menuItem.setText(Labels.getInstance().getString("menu.commands.open.edit"));
menuItem.addListener(SWT.Selection, new CommandsActions.EditOpeners());
menuItem = new MenuItem(openersMenu, SWT.SEPARATOR);
// run the listener to populate the menu initially and initialize accelerators
showOpenersMenuListener.handleEvent(null);
// retrieve results context menu, that is the same as "commands" menu
// note: the index of 2 is hardcoded and may theoretically change
// TODO: probably something better should be done here
@ -94,7 +108,6 @@ public class MainMenu {
new Object[] {"menu.commands.copyDetails", null, null},
null,
new Object[] {"menu.commands.show", null, null},
new Object[] {"menu.commands.open", null, null},
}
},
new Object[] {"menu.favorites",

View File

@ -29,9 +29,8 @@ import org.eclipse.swt.layout.RowLayout;
*
* @author anton
*/
public class OptionsWindow {
public class OptionsWindow extends AbstractModalDialog {
private Shell shell = null; // @jve:decl-index=0:visual-constraint="10,10"
private TabFolder tabFolder;
private Composite scanningTab;
private Composite displayTab;
@ -54,16 +53,6 @@ public class OptionsWindow {
loadOptions();
}
public void open() {
shell.open();
Display display = Display.getCurrent();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
shell.dispose();
}
/**
* This method initializes shell
*/

View File

@ -144,7 +144,7 @@ public class ResultTable extends Table {
*/
public String getIPDetails() {
int selectedIndex = getSelectionIndex();
return scanningResults.getIPDetails(selectedIndex);
return scanningResults.getResultsAsString(selectedIndex);
}
/**

View File

@ -3,6 +3,8 @@
*/
package net.azib.ipscan.gui;
import net.azib.ipscan.config.Labels;
/**
* Exception for throwing in case of user errors.
* These generally result in showing an error message.
@ -14,12 +16,16 @@ public class UserErrorException extends RuntimeException {
private static final long serialVersionUID = 123283472834982L;
public UserErrorException(String label) {
super(label);
super(Labels.getInstance().getString("exception.UserErrorException." + label));
}
public UserErrorException(String label, Throwable cause) {
super(label);
this(label);
initCause(cause);
}
public UserErrorException(String label, String rawInfo) {
super(Labels.getInstance().getString("exception.UserErrorException." + label) + rawInfo);
}
}

View File

@ -0,0 +1,51 @@
/**
*
*/
package net.azib.ipscan.gui.actions;
import java.lang.reflect.Method;
import net.azib.ipscan.gui.UserErrorException;
/**
* BrowserLauncher
*
* @author anton
*/
public class BrowserLauncher {
/**
* Opens an URL in the default browser.
* Supports Linux/Unix, MacOS, and Windows
* @param url
*/
public static void openURL(String url) {
String osName = System.getProperty("os.name");
try {
if (osName.startsWith("Windows")) {
Runtime.getRuntime().exec("rundll32 url.dll,FileProtocolHandler " + url);
}
else
if (osName.startsWith("Mac OS")) {
Class fileMgr = Class.forName("com.apple.eio.FileManager");
Method openURL = fileMgr.getDeclaredMethod("openURL", new Class[] { String.class });
openURL.invoke(null, new Object[] { url });
}
else { // assume Linux or other Unix
// TODO: what if browser is already running as another user, not root?
String[] browsers = { "htmlview", "firefox", "opera", "konqueror", "epiphany", "mozilla", "netscape" };
String browser = null;
for (int count = 0; count < browsers.length && browser == null; count++)
if (Runtime.getRuntime().exec(new String[] { "which", browsers[count] }).waitFor() == 0)
browser = browsers[count];
if (browser == null)
throw new Exception("Could not find web browser");
Runtime.getRuntime().exec(new String[] { browser, url });
}
}
catch (Exception e) {
throw new UserErrorException("openURL.failed", url);
}
}
}

View File

@ -3,16 +3,28 @@
*/
package net.azib.ipscan.gui.actions;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.fetchers.FetcherRegistry;
import net.azib.ipscan.gui.DetailsWindow;
import net.azib.ipscan.gui.EditOpenersDialog;
import net.azib.ipscan.gui.MainWindow;
import net.azib.ipscan.gui.ResultTable;
import net.azib.ipscan.gui.UserErrorException;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
/**
* Commands and Context menu Actions.
* All these operate on the items, selected in the results list.
* TODO: check for selection everywhere
*
* @author anton
*/
@ -44,4 +56,113 @@ public class CommandsActions {
throw new UserErrorException("commands.noSelection");
}
}
public static class ShowOpenersMenu implements Listener {
private Menu openersMenu;
private Listener openersSelectListener;
public ShowOpenersMenu(MainWindow mainWindow, Menu openersMenu) {
this.openersMenu = openersMenu;
this.openersSelectListener = new SelectOpener(mainWindow);
}
public void handleEvent(Event event) {
MenuItem[] menuItems = openersMenu.getItems();
for (int i = 2; i < menuItems.length; i++) {
menuItems[i].dispose();
}
// update menu items
int index = 0;
for (Iterator i = Config.getOpenersConfig().iterateNames(); i.hasNext();) {
MenuItem menuItem = new MenuItem(openersMenu, SWT.CASCADE);
String name = (String)i.next();
index++;
if (index <= 9) {
name += "\tCtrl+" + index;
menuItem.setAccelerator(SWT.CONTROL | ('0' + index));
}
menuItem.setText(name);
menuItem.setData(new Integer(index));
menuItem.addListener(SWT.Selection, openersSelectListener);
}
}
}
public static class EditOpeners implements Listener {
public void handleEvent(Event event) {
new EditOpenersDialog().open();
}
}
public static class SelectOpener implements Listener {
private MainWindow mainWindow;
public SelectOpener(MainWindow mainWindow) {
this.mainWindow = mainWindow;
}
public void handleEvent(Event event) {
MenuItem menuItem = (MenuItem) event.widget;
String name = menuItem.getText();
int indexOf = name.lastIndexOf('\t');
if (indexOf >= 0) {
name = name.substring(0, indexOf);
}
String openerString = Config.getOpenersConfig().get(name);
int selectedItem = mainWindow.getResultTable().getSelectionIndex();
if (selectedItem < 0) {
throw new UserErrorException("commands.noSelection");
}
openerString = prepareOpenerStringForItem(openerString, selectedItem);
new OpenerLauncher().launch(openerString);
}
/**
* Replaces references to scanned values in an opener string.
* Refefernces look like ${fetcher_label}
* @param openerString
* @return opener string with values replaced
*/
String prepareOpenerStringForItem(String openerString, int selectedItem) {
Pattern paramsPattern = Pattern.compile("\\$\\{(.+?)\\}");
Matcher matcher = paramsPattern.matcher(openerString);
StringBuffer sb = new StringBuffer(64);
while (matcher.find()) {
// resolve the required fetcher
String fetcherName = matcher.group(1);
int fetcherIndex = FetcherRegistry.getInstance().getSelectedFetcherIndex(fetcherName);
if (fetcherIndex < 0) {
throw new UserErrorException("opener.unknownFetcher", fetcherName);
}
// retrieve the scanned value
String scannedValue = getScannedValue(selectedItem, fetcherIndex);
if (scannedValue == null) {
throw new UserErrorException("opener.nullFetcherValue", fetcherName);
}
matcher.appendReplacement(sb, scannedValue);
}
matcher.appendTail(sb);
return sb.toString();
}
String getScannedValue(int selectedItem, int fetcherIndex) {
return (String) mainWindow.getResultTable().getScanningResults().getResult(selectedItem).getValues().get(fetcherIndex);
}
}
}

View File

@ -6,8 +6,8 @@ package net.azib.ipscan.gui.actions;
import java.util.Iterator;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.FavoritesConfig;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.config.NamedListConfig;
import net.azib.ipscan.gui.EditFavoritesDialog;
import net.azib.ipscan.gui.InputDialog;
import net.azib.ipscan.gui.MainWindow;
@ -38,11 +38,10 @@ public class FavoritesActions {
InputDialog inputDialog = new InputDialog(
Labels.getInstance().getString("title.favorite.add"),
Labels.getInstance().getString("text.favorite.add"));
inputDialog.setText(feederInfo);
String favoriteName = inputDialog.open();
String favoriteName = inputDialog.open(feederInfo);
if (favoriteName != null) {
FavoritesConfig favoritesConfig = Config.getFavoritesConfig();
NamedListConfig favoritesConfig = Config.getFavoritesConfig();
if (favoritesConfig.get(favoriteName) != null) {
throw new UserErrorException("favorite.alreadyExists");
}
@ -90,7 +89,7 @@ public class FavoritesActions {
public void handleEvent(Event event) {
// populate favorites in the menu
FavoritesConfig favoritesConfig = Config.getFavoritesConfig();
NamedListConfig favoritesConfig = Config.getFavoritesConfig();
// note: 3 is the number of items in the menu when no favorites exist
// dispose old favorites

View File

@ -73,8 +73,7 @@ public class GotoActions {
public void handleEvent(Event event) {
InputDialog dialog = new InputDialog(Labels.getInstance().getString("title.find"), Labels.getInstance().getString("text.find"));
dialog.setText(lastText);
String text = dialog.open();
String text = dialog.open(lastText);
if (text == null) {
return;
}

View File

@ -9,7 +9,6 @@ import net.azib.ipscan.gui.GettingStartedWindow;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.MessageBox;
/**
* HelpActions
@ -31,10 +30,8 @@ public class HelpActions {
}
public static class Website implements Listener {
public void handleEvent(Event event) {
MessageBox messageBox = new MessageBox(event.display.getActiveShell());
messageBox.setMessage(Version.WEBSITE);
messageBox.open();
public void handleEvent(Event event) {
BrowserLauncher.openURL(Version.WEBSITE);
}
}

View File

@ -0,0 +1,35 @@
/**
*
*/
package net.azib.ipscan.gui.actions;
import java.io.IOException;
import net.azib.ipscan.gui.UserErrorException;
/**
* OpenerLauncher
*
* @author anton
*/
public class OpenerLauncher {
public void launch(String openerString) {
// check for URLs
if (openerString.startsWith("http:") || openerString.startsWith("https:") || openerString.startsWith("ftp:") || openerString.startsWith("mailto:")) {
BrowserLauncher.openURL(openerString);
}
else {
// run a process here
try {
// TODO: we probably need to support shell patterns, etc
Runtime.getRuntime().exec(openerString);
}
catch (IOException e) {
throw new UserErrorException("opener.failed", openerString);
}
}
}
}

View File

@ -1,81 +0,0 @@
/**
*
*/
package net.azib.ipscan.config;
import java.util.Iterator;
import java.util.prefs.Preferences;
import junit.framework.TestCase;
/**
* FavoritesConfigTest
*
* @author anton
*/
public class FavoritesConfigTest extends TestCase {
private Preferences preferences;
private FavoritesConfig config;
protected void setUp() throws Exception {
preferences = Preferences.userRoot().node("ipscan-test");
config = new FavoritesConfig(preferences);
}
protected void tearDown() throws Exception {
preferences.removeNode();
}
public void testAdd() {
config.add("Mega favorite", "aaa:xxx");
assertEquals("aaa:xxx", config.get("Mega favorite"));
assertEquals(1, config.size());
}
public void testLoad() throws Exception {
preferences.put("favorites", "aa###aaa###bb###bbb###cc###ccc");
FavoritesConfig favorites = new FavoritesConfig(preferences);
assertEquals("aaa", favorites.get("aa"));
assertEquals("bbb", favorites.get("bb"));
assertEquals("ccc", favorites.get("cc"));
assertEquals(3, favorites.size());
}
public void testOrder() throws Exception {
preferences.put("favorites", "aa###aaa###bb###bbb###cc###ccc");
FavoritesConfig favorites = new FavoritesConfig(preferences);
Iterator favoriteNames = favorites.iterateNames();
assertEquals("aa", favoriteNames.next());
assertEquals("bb", favoriteNames.next());
assertEquals("cc", favoriteNames.next());
assertFalse(favoriteNames.hasNext());
}
public void testStore() throws Exception {
FavoritesConfig favorites = new FavoritesConfig(preferences);
favorites.add("x", "y");
favorites.add("Buga muga x,1,2,3,4,5", "opopo op : , . l ; - # | @@");
favorites.add("127.0.0.1", "192.168.2.25");
favorites.store();
assertEquals("x###y###Buga muga x,1,2,3,4,5###opopo op : , . l ; - # | @@###127.0.0.1###192.168.2.25", preferences.get("favorites", ""));
}
public void testUpdate() {
config.add("z", "zzz");
config.add("y", "yyy");
config.add("x", "xxx");
config.update(new String[] {"x", "z"});
Iterator i = config.iterateNames();
assertEquals("xxx", config.get((String)i.next()));
assertEquals("zzz", config.get((String)i.next()));
assertFalse(i.hasNext());
}
}

View File

@ -0,0 +1,82 @@
/**
*
*/
package net.azib.ipscan.config;
import java.util.Iterator;
import java.util.prefs.Preferences;
import junit.framework.TestCase;
/**
* NamedListConfigTest
*
* @author anton
*/
public class NamedListConfigTest extends TestCase {
private static final String PREFERENCE_NAME = "blah";
private Preferences preferences;
private NamedListConfig config;
protected void setUp() throws Exception {
preferences = Preferences.userRoot().node("ipscan-test");
config = new NamedListConfig(preferences, PREFERENCE_NAME);
}
protected void tearDown() throws Exception {
preferences.removeNode();
}
public void testAdd() {
config.add("Mega favorite", "aaa:xxx");
assertEquals("aaa:xxx", config.get("Mega favorite"));
assertEquals(1, config.size());
}
public void testLoad() throws Exception {
preferences.put(PREFERENCE_NAME, "aa###aaa###bb###bbb###cc###ccc");
NamedListConfig config = new NamedListConfig(preferences, PREFERENCE_NAME);
assertEquals("aaa", config.get("aa"));
assertEquals("bbb", config.get("bb"));
assertEquals("ccc", config.get("cc"));
assertEquals(3, config.size());
}
public void testOrder() throws Exception {
preferences.put(PREFERENCE_NAME, "aa###aaa###bb###bbb###cc###ccc");
NamedListConfig config = new NamedListConfig(preferences, PREFERENCE_NAME);
Iterator namesIterator = config.iterateNames();
assertEquals("aa", namesIterator.next());
assertEquals("bb", namesIterator.next());
assertEquals("cc", namesIterator.next());
assertFalse(namesIterator.hasNext());
}
public void testStore() throws Exception {
NamedListConfig config = new NamedListConfig(preferences, PREFERENCE_NAME);
config.add("x", "y");
config.add("Buga muga x,1,2,3,4,5", "opopo op : , . l ; - # | @@");
config.add("127.0.0.1", "192.168.2.25");
config.store();
assertEquals("x###y###Buga muga x,1,2,3,4,5###opopo op : , . l ; - # | @@###127.0.0.1###192.168.2.25", preferences.get(PREFERENCE_NAME, ""));
}
public void testUpdate() {
config.add("z", "zzz");
config.add("y", "yyy");
config.add("x", "xxx");
config.update(new String[] {"x", "z"});
Iterator i = config.iterateNames();
assertEquals("xxx", config.get((String)i.next()));
assertEquals("zzz", config.get((String)i.next()));
assertFalse(i.hasNext());
}
}

View File

@ -0,0 +1,54 @@
/**
*
*/
package net.azib.ipscan.gui.actions;
import net.azib.ipscan.config.Config;
import net.azib.ipscan.config.Labels;
import net.azib.ipscan.gui.UserErrorException;
import net.azib.ipscan.gui.actions.CommandsActions.SelectOpener;
import junit.framework.TestCase;
/**
* CommandsActionsTest
*
* @author anton
*/
public class CommandsActionsTest extends TestCase {
public void testReplaceValues() {
Config.initialize();
CommandsActions.SelectOpener so = new SelectOpener(null) {
String getScannedValue(int selectedItem, int fetcherIndex) {
switch (fetcherIndex) {
case 0:
return "127.0.0.1";
case 1:
return "PING";
default:
return null;
}
}
};
assertEquals("\\\\127.0.0.1", so.prepareOpenerStringForItem("\\\\${fetcher.ip}", 0));
assertEquals("PING$$$127.0.0.1xxx${}", so.prepareOpenerStringForItem("${fetcher.ping}$$$${fetcher.ip}xxx${}", 0));
assertEquals("http://127.0.0.1:80/www", so.prepareOpenerStringForItem("http://${fetcher.ip}:80/www", 0));
try {
so.prepareOpenerStringForItem("${noSuchFetcher}", 0);
fail();
}
catch (UserErrorException e) {
assertEquals(Labels.getInstance().getString("exception.UserErrorException.opener.unknownFetcher") + "noSuchFetcher", e.getMessage());
}
try {
so.prepareOpenerStringForItem("${fetcher.ping.ttl}", 0);
fail();
}
catch (UserErrorException e) {
assertEquals(Labels.getInstance().getString("exception.UserErrorException.opener.nullFetcherValue") + "fetcher.ping.ttl", e.getMessage());
}
}
}