diff --git a/resources/Labels.txt b/resources/Labels.txt
index a73b4a55..b2ab8c0e 100755
--- a/resources/Labels.txt
+++ b/resources/Labels.txt
@@ -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%WEBSITE\n%MAILTO\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
diff --git a/src/net/azib/ipscan/Main.java b/src/net/azib/ipscan/Main.java
index bffb51e2..fec06e19 100755
--- a/src/net/azib/ipscan/Main.java
+++ b/src/net/azib/ipscan/Main.java
@@ -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();
diff --git a/src/net/azib/ipscan/config/Config.java b/src/net/azib/ipscan/config/Config.java
index 3eea7265..f88732af 100755
--- a/src/net/azib/ipscan/config/Config.java
+++ b/src/net/azib/ipscan/config/Config.java
@@ -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;
}
diff --git a/src/net/azib/ipscan/config/FavoritesConfig.java b/src/net/azib/ipscan/config/FavoritesConfig.java
deleted file mode 100755
index 02d0c268..00000000
--- a/src/net/azib/ipscan/config/FavoritesConfig.java
+++ /dev/null
@@ -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;
- }
-
-}
diff --git a/src/net/azib/ipscan/config/NamedListConfig.java b/src/net/azib/ipscan/config/NamedListConfig.java
new file mode 100755
index 00000000..12ff4403
--- /dev/null
+++ b/src/net/azib/ipscan/config/NamedListConfig.java
@@ -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;
+ }
+
+}
diff --git a/src/net/azib/ipscan/config/OpenersConfig.java b/src/net/azib/ipscan/config/OpenersConfig.java
new file mode 100755
index 00000000..904785fe
--- /dev/null
+++ b/src/net/azib/ipscan/config/OpenersConfig.java
@@ -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}");
+ }
+ }
+
+
+
+
+
+}
diff --git a/src/net/azib/ipscan/core/ScanningResultList.java b/src/net/azib/ipscan/core/ScanningResultList.java
index 017009e0..e3d7e355 100755
--- a/src/net/azib/ipscan/core/ScanningResultList.java
+++ b/src/net/azib/ipscan/core/ScanningResultList.java
@@ -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);
diff --git a/src/net/azib/ipscan/fetchers/FetcherRegistry.java b/src/net/azib/ipscan/fetchers/FetcherRegistry.java
index 28d34ff0..fe1bed87 100755
--- a/src/net/azib/ipscan/fetchers/FetcherRegistry.java
+++ b/src/net/azib/ipscan/fetchers/FetcherRegistry.java
@@ -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;
+ }
+
}
diff --git a/src/net/azib/ipscan/gui/AboutWindow.java b/src/net/azib/ipscan/gui/AboutWindow.java
index b7d1a9d2..6ed98ff6 100755
--- a/src/net/azib/ipscan/gui/AboutWindow.java
+++ b/src/net/azib/ipscan/gui/AboutWindow.java
@@ -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
*/
diff --git a/src/net/azib/ipscan/gui/AbstractModalDialog.java b/src/net/azib/ipscan/gui/AbstractModalDialog.java
new file mode 100755
index 00000000..09d4414c
--- /dev/null
+++ b/src/net/azib/ipscan/gui/AbstractModalDialog.java
@@ -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();
+ }
+
+}
diff --git a/src/net/azib/ipscan/gui/DetailsWindow.java b/src/net/azib/ipscan/gui/DetailsWindow.java
index 441a844e..c16ee821 100755
--- a/src/net/azib/ipscan/gui/DetailsWindow.java
+++ b/src/net/azib/ipscan/gui/DetailsWindow.java
@@ -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
*/
diff --git a/src/net/azib/ipscan/gui/EditFavoritesDialog.java b/src/net/azib/ipscan/gui/EditFavoritesDialog.java
index a2a75374..f857faa0 100755
--- a/src/net/azib/ipscan/gui/EditFavoritesDialog.java
+++ b/src/net/azib/ipscan/gui/EditFavoritesDialog.java
@@ -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();
}
diff --git a/src/net/azib/ipscan/gui/EditOpenersDialog.java b/src/net/azib/ipscan/gui/EditOpenersDialog.java
new file mode 100755
index 00000000..148987be
--- /dev/null
+++ b/src/net/azib/ipscan/gui/EditOpenersDialog.java
@@ -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
+ }
+ }
+
+}
diff --git a/src/net/azib/ipscan/gui/GettingStartedWindow.java b/src/net/azib/ipscan/gui/GettingStartedWindow.java
index 6039b03f..64ef6d5c 100755
--- a/src/net/azib/ipscan/gui/GettingStartedWindow.java
+++ b/src/net/azib/ipscan/gui/GettingStartedWindow.java
@@ -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
*/
diff --git a/src/net/azib/ipscan/gui/InputDialog.java b/src/net/azib/ipscan/gui/InputDialog.java
index f0f8cf6a..7ff1e1f3 100755
--- a/src/net/azib/ipscan/gui/InputDialog.java
+++ b/src/net/azib/ipscan/gui/InputDialog.java
@@ -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;
}
diff --git a/src/net/azib/ipscan/gui/MainMenu.java b/src/net/azib/ipscan/gui/MainMenu.java
index a27ca8f3..586307c7 100755
--- a/src/net/azib/ipscan/gui/MainMenu.java
+++ b/src/net/azib/ipscan/gui/MainMenu.java
@@ -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",
diff --git a/src/net/azib/ipscan/gui/OptionsWindow.java b/src/net/azib/ipscan/gui/OptionsWindow.java
index 3c6657d4..d15f74b9 100755
--- a/src/net/azib/ipscan/gui/OptionsWindow.java
+++ b/src/net/azib/ipscan/gui/OptionsWindow.java
@@ -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
*/
diff --git a/src/net/azib/ipscan/gui/ResultTable.java b/src/net/azib/ipscan/gui/ResultTable.java
index b8ebf0b9..393590cd 100755
--- a/src/net/azib/ipscan/gui/ResultTable.java
+++ b/src/net/azib/ipscan/gui/ResultTable.java
@@ -144,7 +144,7 @@ public class ResultTable extends Table {
*/
public String getIPDetails() {
int selectedIndex = getSelectionIndex();
- return scanningResults.getIPDetails(selectedIndex);
+ return scanningResults.getResultsAsString(selectedIndex);
}
/**
diff --git a/src/net/azib/ipscan/gui/UserErrorException.java b/src/net/azib/ipscan/gui/UserErrorException.java
index 8a7af0a6..a5eb4cad 100755
--- a/src/net/azib/ipscan/gui/UserErrorException.java
+++ b/src/net/azib/ipscan/gui/UserErrorException.java
@@ -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);
+ }
}
diff --git a/src/net/azib/ipscan/gui/actions/BrowserLauncher.java b/src/net/azib/ipscan/gui/actions/BrowserLauncher.java
new file mode 100755
index 00000000..8b61f788
--- /dev/null
+++ b/src/net/azib/ipscan/gui/actions/BrowserLauncher.java
@@ -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);
+ }
+ }
+}
diff --git a/src/net/azib/ipscan/gui/actions/CommandsActions.java b/src/net/azib/ipscan/gui/actions/CommandsActions.java
index 71c3b46a..71d77736 100755
--- a/src/net/azib/ipscan/gui/actions/CommandsActions.java
+++ b/src/net/azib/ipscan/gui/actions/CommandsActions.java
@@ -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);
+ }
+
+ }
+
}
diff --git a/src/net/azib/ipscan/gui/actions/FavoritesActions.java b/src/net/azib/ipscan/gui/actions/FavoritesActions.java
index b45999c2..112d29e6 100755
--- a/src/net/azib/ipscan/gui/actions/FavoritesActions.java
+++ b/src/net/azib/ipscan/gui/actions/FavoritesActions.java
@@ -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
diff --git a/src/net/azib/ipscan/gui/actions/GotoActions.java b/src/net/azib/ipscan/gui/actions/GotoActions.java
index a7aeb25b..a42834e4 100755
--- a/src/net/azib/ipscan/gui/actions/GotoActions.java
+++ b/src/net/azib/ipscan/gui/actions/GotoActions.java
@@ -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;
}
diff --git a/src/net/azib/ipscan/gui/actions/HelpActions.java b/src/net/azib/ipscan/gui/actions/HelpActions.java
index e7267a52..421b09dd 100755
--- a/src/net/azib/ipscan/gui/actions/HelpActions.java
+++ b/src/net/azib/ipscan/gui/actions/HelpActions.java
@@ -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);
}
}
diff --git a/src/net/azib/ipscan/gui/actions/OpenerLauncher.java b/src/net/azib/ipscan/gui/actions/OpenerLauncher.java
new file mode 100755
index 00000000..2269319c
--- /dev/null
+++ b/src/net/azib/ipscan/gui/actions/OpenerLauncher.java
@@ -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);
+ }
+ }
+
+ }
+
+}
diff --git a/test/net/azib/ipscan/config/FavoritesConfigTest.java b/test/net/azib/ipscan/config/FavoritesConfigTest.java
deleted file mode 100755
index 525785a6..00000000
--- a/test/net/azib/ipscan/config/FavoritesConfigTest.java
+++ /dev/null
@@ -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());
- }
-
-}
diff --git a/test/net/azib/ipscan/config/NamedListConfigTest.java b/test/net/azib/ipscan/config/NamedListConfigTest.java
new file mode 100755
index 00000000..17d2ac1e
--- /dev/null
+++ b/test/net/azib/ipscan/config/NamedListConfigTest.java
@@ -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());
+ }
+
+}
diff --git a/test/net/azib/ipscan/gui/actions/CommandsActionsTest.java b/test/net/azib/ipscan/gui/actions/CommandsActionsTest.java
new file mode 100755
index 00000000..32295e24
--- /dev/null
+++ b/test/net/azib/ipscan/gui/actions/CommandsActionsTest.java
@@ -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());
+ }
+ }
+}