[or-cvs] r11621: prepared merging of multiple networks via RMI (in puppetor/trunk/src/de/uniba/wiai/lspi/puppetor: . groovy impl rmi)

kloesing at seul.org kloesing at seul.org
Tue Sep 25 01:23:53 UTC 2007


Author: kloesing
Date: 2007-09-24 21:23:53 -0400 (Mon, 24 Sep 2007)
New Revision: 11621

Added:
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/LogListener.java
Removed:
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/MetaNetwork.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/MetaNetworkImpl.java
Modified:
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Event.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/EventListener.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Network.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/ProxyNode.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/RmiPuppetzShell.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithDir.java
   puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithOutDir.java
Log:
prepared merging of multiple networks via RMI

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Event.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Event.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Event.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -31,6 +31,8 @@
  */
 package de.uniba.wiai.lspi.puppetor;
 
+import java.io.Serializable;
+
 /**
  * An <code>Event</code> is created for every state change of an asynchronous
  * system component, e.g. a Tor process or a client/server application running
@@ -43,7 +45,7 @@
  * 
  * @author kloesing
  */
-public interface Event {
+public interface Event extends Serializable {
 
 	/**
 	 * Returns the source of this event, which can be a Tor process or a

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/EventListener.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/EventListener.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/EventListener.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -31,13 +31,16 @@
  */
 package de.uniba.wiai.lspi.puppetor;
 
+import java.rmi.Remote;
+import java.rmi.RemoteException;
+
 /**
  * This interface must be implemented by any object in a test application that
  * shall be registered as event listener.
  * 
  * @author kloesing
  */
-public interface EventListener {
+public interface EventListener extends Remote {
 
 	/**
 	 * Is invoked when an asynchronous event is fired by the source (or one of
@@ -45,7 +48,9 @@
 	 * 
 	 * @param event
 	 *            The event that was fired.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
 	 */
-	public void handleEvent(Event event);
+	public void handleEvent(Event event) throws RemoteException;
 
 }

Deleted: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/MetaNetwork.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/MetaNetwork.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/MetaNetwork.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2007, Patrick Geyer, Johannes Jungkunst, Karsten Loesing,
- * Stefan Schilling
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 
- *     * Neither the names of the copyright owners nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- *  
- * WARNING! This class is untested, yet! Don't rely on it!
- *
- */
-
-/**
- * @author pgeyer, jjungkunst, sschilling
- */
-package de.uniba.wiai.lspi.puppetor;
-
-import java.net.MalformedURLException;
-import java.rmi.NotBoundException;
-import java.rmi.RemoteException;
-
-public interface MetaNetwork {
-
-	public abstract Network connectNetwork(String remoteHost, String bindingName)
-			throws MalformedURLException, RemoteException, NotBoundException;
-
-	public abstract void mergeNetworks(Network first, Network second);
-}
\ No newline at end of file

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Network.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Network.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/Network.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -32,12 +32,17 @@
 package de.uniba.wiai.lspi.puppetor;
 
 import java.io.File;
+import java.net.MalformedURLException;
+import java.rmi.NotBoundException;
 import java.rmi.Remote;
 import java.rmi.RemoteException;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+// TODO this does not look good! we should not depend on groovy types here!
+import de.uniba.wiai.lspi.puppetor.groovy.LogListener;
+
 /**
  * A Network instance constitutes the central object of any test run and is
  * aware of the node configuration. It creates all nodes for this configuration
@@ -684,12 +689,10 @@
 	 * <code>torrc</code> and <code>approved-routers</code> files. This
 	 * method is assumed to return very quickly. In case of a private network,
 	 * <code>configureAsPrivateNetwork</code> must be invoked in advance to
-	 * this method! This operation can only be invoked, if network status is
-	 * <code>NetworkState.CONFIGURING_NODES</code>.
+	 * this method! If network status is
+	 * <code>NetworkState.CONFIGURING_NODES</code>, it will be changed to
+	 * <code>NetworkState.CONFIGURATIONS_WRITTEN</code>.
 	 * 
-	 * @throws IllegalStateException
-	 *             Thrown if network is not in state
-	 *             <code>NetworkState.CONFIGURING_NODES</code>.
 	 * @throws TorProcessException
 	 *             Thrown if an I/O problem occurs while writing to the nodes'
 	 *             working directories.
@@ -754,4 +757,53 @@
 	public abstract void addApprovedRouters(Set<String> approvedRoutersStrings)
 			throws RemoteException, TorProcessException;
 
+	/**
+	 * TODO Unconfirmed!
+	 * 
+	 * Enables to bind a network to the groovy shell.
+	 * 
+	 * @param remoteHost
+	 *            The IpAddress where the RMI registry is running.
+	 * @param bindingName
+	 *            The name whereby the stub is bound.
+	 * @return Network Stub
+	 * @throws MalformedURLException
+	 *             Thrown to indicate that a malformed URL has occurred. Either
+	 *             no legal protocol could be found in a specification string or
+	 *             the string could not be parsed.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 * @throws NotBoundException
+	 *             A NotBoundException is thrown if an attempt is made to lookup
+	 *             or unbind in the registry a name that has no associated
+	 *             binding.
+	 */
+	public abstract Network connectNetwork(String remoteHost, String bindingName)
+			throws MalformedURLException, RemoteException, NotBoundException;
+
+	/**
+	 * TODO Unconfirmed!
+	 * 
+	 * Merges two separate networks.
+	 * 
+	 * @param remoteNetwork
+	 *            The stub of the network to merge.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 */
+	public abstract void mergeNetworks(Network remoteNetwork)
+			throws RemoteException;
+
+	/**
+	 * TODO Unconfirmed!
+	 * 
+	 * Register a listener at the network to notify about new networks.
+	 * 
+	 * @param listener
+	 *            The listener to register (groovy shell).
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 */
+	public abstract void addLogListener(LogListener listener)
+			throws RemoteException;
 }

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/ProxyNode.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/ProxyNode.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/ProxyNode.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -136,9 +136,6 @@
 	 *             Thrown if the given configurationString is either
 	 *             <code>null</code>, a zero-length string, or does not
 	 *             consist of configuration key and value.
-	 * @throws IllegalStateException
-	 *             Thrown if not invoked in state
-	 *             <code>NodeState.CONFIGURING</code>.
 	 * @throws RemoteException
 	 *             Thrown if an error occurs when accessed remotely.
 	 */
@@ -156,9 +153,6 @@
 	 *             the contained strings is either <code>null</code>, a
 	 *             zero-length string, or does not consist of configuration key
 	 *             and value.
-	 * @throws IllegalStateException
-	 *             Thrown if not invoked in state
-	 *             <code>NodeState.CONFIGURING</code>.
 	 * @throws RemoteException
 	 *             Thrown if an error occurs when accessed remotely.
 	 */
@@ -300,11 +294,9 @@
 	/**
 	 * Writes the configuration of this node to the <code>torrc</code> file in
 	 * its working directory and changes the state to
-	 * <code>NodeState.CONFIGURATION_WRITTEN</code>.
+	 * <code>NodeState.CONFIGURATION_WRITTEN</code>, if it was in state
+	 * <code>NodeState.CONFIGURING</code> before.
 	 * 
-	 * @throws IllegalStateException
-	 *             Thrown if not invoked in state
-	 *             <code>NodeState.CONFIGURING</code>.
 	 * @throws TorProcessException
 	 *             Thrown if the configuration file <code>torrc</code> cannot
 	 *             be written to disk.

Added: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/LogListener.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/LogListener.java	                        (rev 0)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/LogListener.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, Patrick Geyer, Johannes Jungkunst, Karsten Loesing,
+ * Stefan Schilling
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * 
+ *     * Neither the names of the copyright owners nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ *  
+ * WARNING! This class is untested, yet! Don't rely on it!
+ *
+ */
+package de.uniba.wiai.lspi.puppetor.groovy;
+
+import de.uniba.wiai.lspi.puppetor.EventListener;
+
+/**
+ * TODO Unconfirmed
+ * 
+ * The interface realizes the observer pattern to notify the groovy shell about
+ * new networks.
+ * 
+ * @author pgeyer, jjungkunst, sschilling
+ */
+public interface LogListener {
+
+	/**
+	 * Creates a new tab in groovy shell.
+	 * 
+	 * @param tabName
+	 *            The name of the new tab.
+	 */
+	public abstract EventListener addLogTab(String tabName);
+
+	public abstract void printToConsoleTab(String stringToPrint);
+
+}

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/RmiPuppetzShell.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/RmiPuppetzShell.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/groovy/RmiPuppetzShell.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -45,43 +45,172 @@
 import groovy.lang.GroovyShell;
 
 import java.awt.BorderLayout;
-import java.awt.Color;
 import java.awt.Dimension;
-import java.awt.Font;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.net.MalformedURLException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
+import java.rmi.RemoteException;
+import java.rmi.server.UnicastRemoteObject;
+import java.util.HashMap;
 import javax.swing.JButton;
 import javax.swing.JFrame;
 import javax.swing.JPanel;
+import javax.swing.JScrollPane;
 import javax.swing.JSplitPane;
+import javax.swing.JTabbedPane;
 import javax.swing.JTextArea;
-import de.uniba.wiai.lspi.puppetor.MetaNetwork;
-import de.uniba.wiai.lspi.puppetor.impl.MetaNetworkImpl;
+import de.uniba.wiai.lspi.puppetor.Event;
+import de.uniba.wiai.lspi.puppetor.EventListener;
+import de.uniba.wiai.lspi.puppetor.Network;
 
 @SuppressWarnings("serial")
-public class RmiPuppetzShell extends JFrame {
+/**
+ * A <code>RmiPuppetzShell</code> represents a command shell to PuppeTor. By
+ * the use of a groovy interpreter, the different nodes of a Tor network can be
+ * manipulated.
+ * 
+ * @author pgeyer, jjungkunst, sschilling
+ */
+public class RmiPuppetzShell extends JFrame implements LogListener {
 
-	private GroovyShell shell; // @jve:decl-index=0:
+	/**
+	 * The shell that evaluates the groovy commands.
+	 */
+	private GroovyShell shell;
 
+	/**
+	 * The ContentPane to which all other graphical components are added.
+	 */
 	private JPanel jContentPane = null;
 
-	private JTextArea jTextArea = null;
+	/**
+	 * The text area to which the groovy commands are entered
+	 */
+	private JTextArea inputJTextArea = null;
 
-	private JButton jButton = null;
+	/**
+	 * The OK button
+	 */
+	private JButton okJButton = null;
 
-	private MetaNetwork metaNetwork = null; // @jve:decl-index=0:
+	/**
+	 * The sothern panel for the buttons
+	 */
+	private JPanel buttonJPanel = null;
 
-	private JPanel jPanel = null;
+	/**
+	 * The Console where local evants can be printed to.
+	 */
+	private JTextArea consoleJTextArea = null;
 
-	private JButton jButton1 = null;
+	/**
+	 * Splitpane to devide the main window into a input field for groovy
+	 * commands and an output area for the different networks.
+	 */
+	private JSplitPane jSplitPane = null;
 
-	private JTextArea jTextArea1 = null;
+	/**
+	 * The String representation to which the MetaNetwork will be bound in the
+	 * groovy environment.
+	 */
+	private String bindingName = "metaNetwork";
 
-	private JSplitPane jSplitPane = null;
+	/**
+	 * The tabbedpane that provides tabs for the different networks and the
+	 * console
+	 */
+	private JTabbedPane jTabbedPane = null;
 
 	/**
-	 * This method initializes this
+	 * Scrollpane for the input jTextArea for the goovy commands
 	 */
+	private JScrollPane inputJScrollPane = null;
+
+	/**
+	 * Scrollpane for the output jTextArea.
+	 */
+	private JScrollPane ConsoleJScrollPane = null;
+
+	/**
+	 * A hash map to store the EventListeners with the coresponding network name
+	 */
+	private HashMap<String, EventListener> eventListeners = new HashMap<String, EventListener>();
+
+	/**
+	 * Main method to start the Gui.
+	 * 
+	 * @param args
+	 */
+	public static void main(String args[]) {
+
+		new RmiPuppetzShell();
+	}
+
+	/**
+	 * Initializes the Gui and registers it as a listener to the netaNetwork
+	 */
+	public RmiPuppetzShell() {
+		initialize();
+
+		// binds network on the shell
+		try {
+			shell.setVariable("shell", this);
+			consoleJTextArea.append("Network bound to: " + "shell" + "\n");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * Lookup the already running metaNetwork.
+	 * 
+	 * @param remoteHost
+	 *            The IpAddress where the RMI registry is running.
+	 * @param bindingName
+	 *            The name whereby the stub is bound.
+	 * @throws NotBoundException
+	 * @throws RemoteException
+	 * @throws MalformedURLException
+	 * @throws MalformedURLException
+	 *             Thrown to indicate that a malformed URL has occurred. Either
+	 *             no legal protocol could be found in a specification string or
+	 *             the string could not be parsed.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 * @throws NotBoundException
+	 *             A NotBoundException is thrown if an attempt is made to lookup
+	 *             or unbind in the registry a name that has no associated
+	 *             binding.
+	 */
+	public void connectNetwork(String remoteHost, String bindingName)
+			throws MalformedURLException, RemoteException, NotBoundException {
+
+		// network lookup
+		Network network = (Network) Naming.lookup("rmi://" + remoteHost + "/"
+				+ bindingName);
+
+		// adds the listener to the network
+		try {
+			network.addLogListener(this);
+		} catch (RemoteException e) {
+			e.printStackTrace();
+		}
+
+		// binds network on the shell
+		try {
+			shell.setVariable(bindingName, network);
+			consoleJTextArea.append("Network bound to: " + bindingName + "\n");
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+	}
+
+	/**
+	 * This method initializes the window. The metaNetwork is bound to
+	 * <code>bindingName<code>.
+	 */
 	private void initialize() {
 		this.setSize(new Dimension(531, 256));
 		this.setPreferredSize(new Dimension(100, 150));
@@ -90,13 +219,6 @@
 		this.setVisible(true);
 		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
 		shell = new GroovyShell();
-		metaNetwork = new MetaNetworkImpl();
-		try {
-			shell.setVariable("network", metaNetwork);
-			/* A problem occurred on this link */
-		} catch (Exception e) {
-			e.printStackTrace();
-		}
 	}
 
 	/**
@@ -115,103 +237,101 @@
 	}
 
 	/**
-	 * This method initializes jTextArea
+	 * This method initializes inputJScrollPane
 	 * 
 	 * @return javax.swing.JTextArea
 	 */
-	private JTextArea getJTextArea() {
-		if (jTextArea == null) {
-			jTextArea = new JTextArea();
-			jTextArea.setColumns(1);
-			jTextArea.setPreferredSize(new Dimension(350, 150));
-			jTextArea.setBackground(Color.white);
-			jTextArea.setRows(1);
+	private JScrollPane getInputJScrollPane() {
+		if (inputJScrollPane == null) {
+			inputJScrollPane = new JScrollPane();
+			inputJScrollPane.getViewport().add(getInputJTextArea());
 		}
-		return jTextArea;
+		return inputJScrollPane;
 	}
 
 	/**
-	 * This method initializes jButton
+	 * This method initializes inputJTextArea
 	 * 
-	 * @return javax.swing.JButton
+	 * @return javax.swing.JTextArea
 	 */
-	private JButton getJButton() {
-		if (jButton == null) {
-			jButton = new JButton();
-			jButton.setText("OK");
-			jButton.addMouseListener(new java.awt.event.MouseAdapter() {
-				public void mouseReleased(java.awt.event.MouseEvent e) {
-					try {
-						shell.evaluate(jTextArea.getText());
-					} catch (Exception e1) {
-						jTextArea1.append("Unkorrekte eingabe" + "\n");
-						e1.printStackTrace();
-					}
-
-				}
-			});
+	private JTextArea getInputJTextArea() {
+		if (inputJTextArea == null) {
+			inputJTextArea = new JTextArea();
+			inputJTextArea.setEditable(true);
 		}
-		return jButton;
+		return inputJTextArea;
 	}
 
-	public void lala(String string) {
-		System.out.println(string);
+	/**
+	 * This method initializes ConsoleJScrollPane
+	 * 
+	 * @return javax.swing.JScrollPane
+	 */
+	private JScrollPane getConsoleJScrollPane() {
+		if (ConsoleJScrollPane == null) {
+			ConsoleJScrollPane = new JScrollPane();
+			ConsoleJScrollPane.getViewport().add(getConsoleJTextArea());
+		}
+		return ConsoleJScrollPane;
 	}
 
 	/**
-	 * This method initializes jPanel
+	 * This method initializes consoleJTextArea
 	 * 
-	 * @return javax.swing.JPanel
+	 * @return javax.swing.JTextArea
 	 */
-	private JPanel getJPanel() {
-		if (jPanel == null) {
-			GridBagConstraints gridBagConstraints = new GridBagConstraints();
-			gridBagConstraints.gridx = 1;
-			gridBagConstraints.gridy = 0;
-			jPanel = new JPanel();
-			jPanel.setLayout(new GridBagLayout());
-			jPanel.setPreferredSize(new Dimension(100, 30));
-			GridBagConstraints gridBagConstraints1 = new GridBagConstraints();
-			gridBagConstraints1.gridx = 0;
-			gridBagConstraints1.gridy = 0;
-			jPanel.add(getJButton1(), gridBagConstraints);
-			jPanel.add(getJButton(), gridBagConstraints1);
-
+	private JTextArea getConsoleJTextArea() {
+		if (consoleJTextArea == null) {
+			consoleJTextArea = new JTextArea();
+			consoleJTextArea.setEditable(false);
+			consoleJTextArea.setName("Console");
 		}
-		return jPanel;
+		return consoleJTextArea;
 	}
 
 	/**
-	 * This method initializes jButton1
+	 * This method initializes okJButton.
 	 * 
+	 * It also creates and adds an EventListener that evaluates the content of
+	 * the inputJTextArea in groovy shell.
+	 * 
 	 * @return javax.swing.JButton
 	 */
-	private JButton getJButton1() {
-		if (jButton1 == null) {
-			jButton1 = new JButton();
-			jButton1.setText("Startup");
-			jButton1.setFont(new Font("Dialog", Font.BOLD, 12));
-			jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
+	private JButton getJButton() {
+		if (okJButton == null) {
+			okJButton = new JButton();
+			okJButton.setText("OK");
+			okJButton.addMouseListener(new java.awt.event.MouseAdapter() {
 				public void mouseReleased(java.awt.event.MouseEvent e) {
-					shell.evaluate("network.startupNetwork();");
+					try {
+						shell.evaluate(inputJTextArea.getText());
+					} catch (Exception e1) {
+						consoleJTextArea.append("Unkorrekte eingabe" + "\n");
+						e1.printStackTrace();
+					}
+
 				}
 			});
 		}
-		return jButton1;
+		return okJButton;
 	}
 
 	/**
-	 * This method initializes jTextArea1
+	 * This method initializes buttonJPanel
 	 * 
-	 * @return javax.swing.JTextArea
+	 * @return javax.swing.JPanel
 	 */
-	private JTextArea getJTextArea1() {
-		if (jTextArea1 == null) {
-			jTextArea1 = new JTextArea();
-			jTextArea1.setEditable(false);
-			jTextArea1.setBackground(Color.lightGray);
+	private JPanel getJPanel() {
+		if (buttonJPanel == null) {
+			GridBagConstraints gridBagConstraints = new GridBagConstraints();
+			gridBagConstraints.gridx = 0;
+			gridBagConstraints.gridy = 0;
+			buttonJPanel = new JPanel();
+			buttonJPanel.setLayout(new GridBagLayout());
+			buttonJPanel.setPreferredSize(new Dimension(100, 30));
+			buttonJPanel.add(getJButton(), gridBagConstraints);
 		}
-		return jTextArea1;
+		return buttonJPanel;
 	}
 
 	/**
@@ -222,18 +342,64 @@
 	private JSplitPane getJSplitPane() {
 		if (jSplitPane == null) {
 			jSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
-					getJTextArea(), getJTextArea1());
+					getInputJScrollPane(), getJTabbedPane());
 			jSplitPane.setContinuousLayout(true);
 		}
 		return jSplitPane;
 	}
 
-	public static void main(String args[]) {
-		new RmiPuppetzShell();
+	/**
+	 * This method initializes jTabbedPane
+	 * 
+	 * @return javax.swing.JTabbedPane
+	 */
+	private JTabbedPane getJTabbedPane() {
+		if (jTabbedPane == null) {
+			jTabbedPane = new JTabbedPane();
+			jTabbedPane.add("Console", getConsoleJScrollPane());
+		}
+		return this.jTabbedPane;
 	}
 
-	public RmiPuppetzShell() {
-		initialize();
+	/**
+	 * Implements the <code>LogListener<code> interface.
+	 * 
+	 *  A tab is created in the lower area of the Gui that is supposed to print 
+	 *  the output of an <code>EventManager<code> of a Network. To do this an 
+	 *  <code>EventListener<code> is created and its stub is returned.
+	 *  
+	 *  @return the stub of the event Listener added to the output tab of a 
+	 *  registered network
+	 */
+	public EventListener addLogTab(String tabName) {
+		// Creating ScrollPane & TextArea
+		JScrollPane jScrollPane = new JScrollPane();
+		final JTextArea jTextArea = new JTextArea();
+		// Adding TextArea to ScrollPane's Viewport
+		jScrollPane.getViewport().add(jTextArea);
+		// add ScrollPane to TabbedPane
+		jTabbedPane.add(tabName, jScrollPane);
+		// Creating EventListener
+		EventListener el = new EventListener() {
+
+			public void handleEvent(Event event) {
+
+				jTextArea.append(event.getMessage() + "\n");
+			}
+
+		};
+		this.eventListeners.put(tabName, el);
+		// creating an EventListener stub
+		EventListener elStub = null;
+		try {
+			elStub = (EventListener) UnicastRemoteObject.exportObject(el, 0);
+		} catch (RemoteException e) {
+			e.printStackTrace();
+		}
+		return elStub;
 	}
 
-} // @jve:decl-index=0:visual-constraint="10,10"
+	public void printToConsoleTab(String stringToPrint) {
+		this.consoleJTextArea.append(stringToPrint + "\n");
+	}
+}

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/EventManagerImpl.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -468,7 +468,14 @@
 				this.logger.log(Level.FINE, "Informing event listener "
 						+ eventHandler + " about recently observed event "
 						+ event + " from source " + source + "!");
-				eventHandler.handleEvent(event);
+				try {
+					eventHandler.handleEvent(event);
+				} catch (RemoteException e) {
+					this.logger.log(Level.WARNING,
+							"Cannot inform remote event listener about "
+									+ "event! Removing event listener!", e);
+					this.eventHandlers.remove(eventHandler);
+				}
 			}
 		}
 
@@ -483,7 +490,14 @@
 			this.logger.log(Level.FINE, "Informing event listener "
 					+ eventHandler + " about recently observed event " + event
 					+ " from source " + source + "!");
-			eventHandler.handleEvent(event);
+			try {
+				eventHandler.handleEvent(event);
+			} catch (RemoteException e) {
+				this.logger.log(Level.WARNING,
+						"Cannot inform remote event listener about "
+								+ "event! Removing event listener!", e);
+				this.eventHandlers.remove(eventHandler);
+			}
 		}
 
 		// log exiting

Deleted: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/MetaNetworkImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/MetaNetworkImpl.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/MetaNetworkImpl.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2007, Patrick Geyer, Johannes Jungkunst, Karsten Loesing,
- * Stefan Schilling
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * 
- *     * Neither the names of the copyright owners nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- *  
- * WARNING! This class is untested, yet! Don't rely on it!
- *
- */
-
-package de.uniba.wiai.lspi.puppetor.impl;
-
-import java.net.MalformedURLException;
-import java.rmi.Naming;
-import java.rmi.NotBoundException;
-import java.rmi.RemoteException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
-
-import de.uniba.wiai.lspi.puppetor.DirectoryNode;
-import de.uniba.wiai.lspi.puppetor.MetaNetwork;
-import de.uniba.wiai.lspi.puppetor.Network;
-import de.uniba.wiai.lspi.puppetor.RouterNode;
-import de.uniba.wiai.lspi.puppetor.TorProcessException;
-
-/**
- * @author pgeyer, jjungkunst, sschilling
- */
-public class MetaNetworkImpl implements MetaNetwork {
-
-	private HashMap<String, Network> allNetworks = new HashMap<String, Network>();
-
-	public Network connectNetwork(String remoteHost, String bindingName)
-			throws MalformedURLException, RemoteException, NotBoundException {
-
-		Network network = (Network) Naming.lookup("rmi://" + remoteHost + "/"
-				+ bindingName);
-		allNetworks.put(bindingName, network);
-		return network;
-	}
-
-	public void mergeNetworks(Network first, Network second) {
-		try {
-			HashMap<String, DirectoryNode> temp = (HashMap<String, DirectoryNode>) first
-					.getAllDirectoryNodes();
-			if (first.getAllDirectoryNodes().size() > 0) {
-				if (second.getAllDirectoryNodes().size() > 0) {
-					configureAsWithDir(first, second);
-				} else {
-					configureAsWithoutDir(first, second);
-				}
-			} else {
-				configureAsWithoutDir(second, first);
-			}
-		} catch (RemoteException e) {
-			e.printStackTrace();
-		}
-	}
-
-	private void configureAsWithoutDir(Network first, Network second) {
-		try {
-
-			exchangeDirectories(first, second);
-			startRouters(second);
-			hupRouters(second);
-			exchangeFingerprints(second, first);
-			hupDirectories(first);
-
-		} catch (RemoteException e) {
-			e.printStackTrace();
-		} catch (TorProcessException e) {
-			e.printStackTrace();
-		}
-	}
-
-	private void configureAsWithDir(Network first, Network second) {
-		try {
-
-			exchangeDirectories(first, second);
-			exchangeDirectories(second, first);
-			exchangeFingerprints(first, second);
-			exchangeFingerprints(second, first);
-
-			hupDirectories(first);
-			hupDirectories(second);
-			hupRouters(first);
-			hupRouters(second);
-
-		} catch (RemoteException e) {
-			e.printStackTrace();
-		} catch (TorProcessException e) {
-			e.printStackTrace();
-		}
-	}
-
-	private void exchangeDirectories(Network first, Network second)
-			throws RemoteException, TorProcessException {
-		HashMap<String, DirectoryNode> directories = (HashMap<String, DirectoryNode>) first
-				.getAllDirectoryNodes();
-		List<String> dirServerStrings = new ArrayList<String>();
-		for (DirectoryNode directory : directories.values()) {
-			dirServerStrings.add(directory.determineDirServerString());
-		}
-		second.addDirectoryStrings(dirServerStrings);
-	}
-
-	private void exchangeFingerprints(Network first, Network second)
-			throws RemoteException, TorProcessException {
-		HashMap<String, RouterNode> routers = (HashMap<String, RouterNode>) first
-				.getAllRouterNodes();
-		Set<String> approvedRoutersStrings = new TreeSet<String>();
-		for (RouterNode router : routers.values()) {
-			approvedRoutersStrings.add(router.getNodeName() + " "
-					+ router.getFingerprint());
-		}
-		second.addApprovedRouters(approvedRoutersStrings);
-	}
-
-	private void startRouters(Network network) throws RemoteException,
-			TorProcessException {
-		HashMap<String, RouterNode> routers = (HashMap<String, RouterNode>) network
-				.getAllRouterNodes();
-		for (RouterNode router : routers.values()) {
-			router.startNode(5000);
-		}
-	}
-
-	private void hupDirectories(Network network) throws RemoteException,
-			TorProcessException {
-		HashMap<String, DirectoryNode> directories = (HashMap<String, DirectoryNode>) network
-				.getAllDirectoryNodes();
-		for (DirectoryNode directory : directories.values()) {
-			directory.hup();
-		}
-	}
-
-	private void hupRouters(Network network) throws RemoteException,
-			TorProcessException {
-		HashMap<String, RouterNode> routers = (HashMap<String, RouterNode>) network
-				.getAllRouterNodes();
-		for (RouterNode router : routers.values()) {
-			router.hup();
-		}
-	}
-}

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/NetworkImpl.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -32,13 +32,19 @@
 package de.uniba.wiai.lspi.puppetor.impl;
 
 import java.io.File;
+import java.net.MalformedURLException;
+import java.rmi.Naming;
+import java.rmi.NotBoundException;
 import java.rmi.RemoteException;
 import java.rmi.server.UnicastRemoteObject;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -55,6 +61,7 @@
 import de.uniba.wiai.lspi.puppetor.RouterNode;
 import de.uniba.wiai.lspi.puppetor.ServerApplication;
 import de.uniba.wiai.lspi.puppetor.TorProcessException;
+import de.uniba.wiai.lspi.puppetor.groovy.LogListener;
 
 /**
  * Implementation of <code>Network</code>.
@@ -1007,23 +1014,15 @@
 		// log entering
 		this.logger.entering(this.getClass().getName(), "writeConfigurations");
 
-		// check state
-		if (this.networkState != NetworkState.CONFIGURING_NODES) {
-			IllegalStateException e = new IllegalStateException();
-			this.logger.throwing(this.getClass().getName(),
-					"writeConfigurations", e);
-			throw e;
-		}
-
 		// write configurations for all nodes
 		for (ProxyNode node : this.nodes.values()) {
-			if (node.getNodeState() == NodeState.CONFIGURING) {
-				node.writeConfiguration();
-			}
+			node.writeConfiguration();
 		}
 
-		// change state
-		this.networkState = NetworkState.CONFIGURATIONS_WRITTEN;
+		// change state if necessary
+		if (this.networkState == NetworkState.CONFIGURING_NODES) {
+			this.networkState = NetworkState.CONFIGURATIONS_WRITTEN;
+		}
 
 		// log exiting
 		this.logger.exiting(this.getClass().getName(), "writeConfigurations");
@@ -1066,4 +1065,281 @@
 		// log exiting
 		this.logger.exiting(this.getClass().getName(), "addDirectoryStrings");
 	}
+
+	/* ***** TODO The following code is still unconfirmed!! ***** */
+
+	/**
+	 * Collection of all registered listeners.
+	 */
+	private List<LogListener> listeners = new LinkedList<LogListener>();
+
+	/**
+	 * Collection of all connected networks.
+	 */
+	private HashMap<String, Network> allNetworks = new HashMap<String, Network>();
+
+	public void addLogListener(LogListener listener) {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "addLogListener");
+
+		// adds the listener to the local collection
+		this.listeners.add(listener);
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "addLogListener");
+	}
+
+	public Network connectNetwork(String remoteHost, String bindingName)
+			throws MalformedURLException, RemoteException, NotBoundException {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "connectNetwork");
+
+		// network lookup
+		Network network = (Network) Naming.lookup("rmi://" + remoteHost + "/"
+				+ bindingName);
+
+		// add the network to the allNetworks collection
+		allNetworks.put(bindingName, network);
+
+		// nodify the grooy shell about the new network and register
+		// eventlistener
+		// only if at least one listener is available
+		if (listeners.size() != 0) {
+			notifyListener(network.getEventManager(), bindingName);
+		}
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "connectNetwork");
+		return network;
+	}
+
+	public void mergeNetworks(Network remoteNetwork) throws RemoteException {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "mergeNetworks");
+		try {
+			// lookup to recognize which network is without directories
+			if (this.getAllDirectoryNodes().size() > 0) {
+				if (remoteNetwork.getAllDirectoryNodes().size() > 0) {
+					configureAsWithDir(this, remoteNetwork);
+					// log exiting
+					logger.exiting(this.getClass().getName(), "mergeNetworks");
+				} else {
+					configureAsWithoutDir(this, remoteNetwork);
+					// log exiting
+					logger.exiting(this.getClass().getName(), "mergeNetworks");
+				}
+			} else {
+				configureAsWithoutDir(remoteNetwork, this);
+				// log exiting
+				logger.exiting(this.getClass().getName(), "mergeNetworks");
+			}
+		} catch (RemoteException e) {
+			logger.log(Level.SEVERE,
+					"Caught a remote exception while merging networks!");
+		}
+	}
+
+	private void configureAsWithoutDir(Network first, Network second) {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "configureAsWithoutDir");
+
+		try {
+			// adds the directory strings to the network without
+			exchangeDirectories(first, second);
+
+			// writes configuration to the network
+			second.writeConfigurations();
+
+			// starts the router in the without network
+			startRouters(second);
+
+			// hups the router in the without network
+			hupRouters(second);
+			// adds the new router fingerprints to the directories
+			exchangeFingerprints(second, first);
+
+			// hups the directories
+			hupDirectories(first);
+
+			// log exiting
+			logger.exiting(this.getClass().getName(), "configureAsWithoutDir");
+
+		} catch (RemoteException e) {
+			logger.log(Level.SEVERE,
+					"Caught a remote exception while configureAsWithoutDir!");
+		} catch (TorProcessException e) {
+			logger
+					.log(Level.SEVERE,
+							"Caught a tor process exception while configureAsWithoutDir!");
+		}
+	}
+
+	private void configureAsWithDir(Network first, Network second) {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "configureAsWithDir");
+
+		try {
+			// adds the directory strings to the other network
+			exchangeDirectories(first, second);
+			exchangeDirectories(second, first);
+
+			// adds the new router fingerprints to the directories
+			exchangeFingerprints(first, second);
+			exchangeFingerprints(second, first);
+
+			// writes configuration to files
+			first.writeConfigurations();
+			second.writeConfigurations();
+
+			// hups the directories
+			hupDirectories(first);
+			hupDirectories(second);
+
+			// hups the routers
+			hupRouters(first);
+			hupRouters(second);
+
+			// log exiting
+			logger.exiting(this.getClass().getName(), "configureAsWithDir");
+
+		} catch (RemoteException e) {
+			logger.log(Level.SEVERE,
+					"Caught a remote exception while configureAsWithDir!");
+		} catch (TorProcessException e) {
+			logger.log(Level.SEVERE,
+					"Caught a tor process exception while configureAsWithDir!");
+		}
+	}
+
+	private void exchangeDirectories(Network first, Network second)
+			throws RemoteException, TorProcessException {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "exchangeDirectories");
+
+		// collects all directories from network
+		HashMap<String, DirectoryNode> directories = (HashMap<String, DirectoryNode>) first
+				.getAllDirectoryNodes();
+		List<String> dirServerStrings = new ArrayList<String>();
+
+		// adds the directory strings to the collection
+		for (DirectoryNode directory : directories.values()) {
+			dirServerStrings.add(directory.determineDirServerString());
+		}
+
+		// adds the directory strings to the routers
+		second.addDirectoryStrings(dirServerStrings);
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "exchangeDirectories");
+	}
+
+	private void exchangeFingerprints(Network first, Network second)
+			throws RemoteException, TorProcessException {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "exchangeFingerprints");
+
+		// collects all routers from network
+		HashMap<String, RouterNode> routers = (HashMap<String, RouterNode>) first
+				.getAllRouterNodes();
+		Set<String> approvedRoutersStrings = new TreeSet<String>();
+
+		// adds the fingerprint strings to the collection
+		for (ProxyNode router : routers.values()) {
+			if (router instanceof RouterNode) {
+				RouterNode localRouter = (RouterNode) router;
+				approvedRoutersStrings.add(localRouter.getNodeName() + " "
+						+ localRouter.getFingerprint());
+			}
+		}
+
+		// adds the fingerprint strings to the directories
+		second.addApprovedRouters(approvedRoutersStrings);
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "exchangeFingerprints");
+	}
+
+	private void startRouters(Network network) throws RemoteException,
+			TorProcessException {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "startRouters");
+
+		// collects all routers from network
+		HashMap<String, RouterNode> routers = (HashMap<String, RouterNode>) network
+				.getAllRouterNodes();
+
+		// starts all router
+		for (RouterNode router : routers.values()) {
+			router.startNode(5000);
+		}
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "startRouters");
+	}
+
+	private void hupDirectories(Network network) throws RemoteException,
+			TorProcessException {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "hupDirectories");
+
+		// collects all directories from network
+		HashMap<String, DirectoryNode> directories = (HashMap<String, DirectoryNode>) network
+				.getAllDirectoryNodes();
+
+		// hups all directories
+		for (DirectoryNode directory : directories.values()) {
+			directory.hup();
+		}
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "hupDirectories");
+	}
+
+	private void hupRouters(Network network) throws RemoteException,
+			TorProcessException {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "hupDirectories");
+
+		// collects all routers from network
+		HashMap<String, RouterNode> routers = (HashMap<String, RouterNode>) network
+				.getAllRouterNodes();
+
+		// hups all router
+		for (RouterNode router : routers.values()) {
+			router.hup();
+		}
+
+		// log exiting
+		logger.exiting(this.getClass().getName(), "hupRouters");
+	}
+
+	private void notifyListener(EventManager manager, String tabName) {
+
+		// log entering
+		logger.entering(this.getClass().getName(), "notifyListener");
+
+		for (LogListener listener : listeners) {
+			EventListener tabListener = listener.addLogTab(tabName);
+			try {
+				// adds listener to eventmanager
+				manager.addEventListener(tabListener);
+
+				// log exiting
+				logger.exiting(this.getClass().getName(), "notifyListener");
+			} catch (RemoteException e) {
+				logger.log(Level.SEVERE,
+						"Caught a remote exception while notifyListener!");
+			}
+		}
+	}
 }

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/ProxyNodeImpl.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -246,14 +246,6 @@
 		this.logger.entering(this.getClass().getName(), "addConfiguration",
 				configurationString);
 
-		// check state
-		if (this.nodeState != NodeState.CONFIGURING) {
-			IllegalStateException e = new IllegalStateException();
-			this.logger.throwing(this.getClass().getName(), "addConfiguration",
-					e);
-			throw e;
-		}
-
 		// check parameter
 		if (configurationString == null || configurationString.length() < 1
 				|| !configurationString.contains(" ")) {
@@ -276,14 +268,6 @@
 		this.logger.entering(this.getClass().getName(), "addConfigurations",
 				configurationStrings);
 
-		// check state
-		if (this.nodeState != NodeState.CONFIGURING) {
-			IllegalStateException e = new IllegalStateException();
-			this.logger.throwing(this.getClass().getName(),
-					"addConfigurations", e);
-			throw e;
-		}
-
 		// check parameter
 		if (configurationStrings == null) {
 			IllegalArgumentException e = new IllegalArgumentException();
@@ -889,19 +873,13 @@
 		// log entering
 		this.logger.entering(this.getClass().getName(), "writeConfiguration");
 
-		// check state
-		if (this.nodeState != NodeState.CONFIGURING) {
-			IllegalStateException e = new IllegalStateException();
-			this.logger.throwing(this.getClass().getName(),
-					"writeConfiguration", e);
-			throw e;
-		}
-
 		// write config file
 		this.writeConfigurationFile(this.configFile, this.configuration);
 
-		// change state
-		this.nodeState = NodeState.CONFIGURATION_WRITTEN;
+		// change state, if necessary
+		if (this.nodeState == NodeState.CONFIGURING) {
+			this.nodeState = NodeState.CONFIGURATION_WRITTEN;
+		}
 
 		// log exiting
 		this.logger.exiting(this.getClass().getName(), "writeConfiguration");

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/impl/RouterNodeImpl.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -148,7 +148,11 @@
 		if (orPort < 0 || orPort > 65535 || dirPort < 0 || dirPort > 65535
 				|| serverIpAddress == null
 				|| !validIpAddressPattern.matcher(serverIpAddress).matches()) {
-			IllegalArgumentException e = new IllegalArgumentException();
+			IllegalArgumentException e = new IllegalArgumentException(
+					"nodeName=" + nodeName + ", controlPort=" + controlPort
+							+ ", socksPort=" + socksPort + ", orPort="
+							+ this.orPort + ", dirPort=" + this.dirPort
+							+ ", serverIpAddress='" + serverIpAddress + "'");
 			this.logger
 					.throwing(this.getClass().getName(), "RouterNodeImpl", e);
 			throw e;

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithDir.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithDir.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithDir.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -53,35 +53,143 @@
 import de.uniba.wiai.lspi.puppetor.TorProcessException;
 
 /**
+ * Example for a v2 test environment with modified directory server.
+ * 
  * @author pgeyer, jjungkunst, sschilling
  */
 public class MergingNetworkWithDir {
 
+	/**
+	 * Number of hours to perform this test network.
+	 */
+	private static int hours = 25;
+
+	/**
+	 * Sets up and runs the test.
+	 * 
+	 * @param args
+	 *            args[0] The IpAddress where the directory server are running.
+	 *            args[1] The IpAddress to bind the stub. args[2] The name to
+	 *            bind the stub. args[3] The hours to run this test.
+	 * @throws TorProcessException
+	 *             Thrown if there is a problem with the JVM-external Tor
+	 *             processes that we cannot handle.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 */
+	public static void main(String[] args) throws TorProcessException,
+			RemoteException {
+
+		// test if enough args are commited
+		if (args.length < 3) {
+			System.out.println("Usage: java "
+					+ MergingNetworkWithOutDir.class.getCanonicalName()
+					+ " [dirServerIpAddress] [hostAndOrPort] [bindingName]");
+			System.exit(1);
+		}
+
+		// test if hours is an int value
+		if (args.length == 4) {
+			try {
+				hours = Integer.parseInt(args[3]);
+			} catch (Exception e) {
+				System.out
+						.println("Usage: java "
+								+ MergingNetworkWithOutDir.class
+										.getCanonicalName()
+								+ " [dirServerIpAddress] [hostAndOrPort] [bindingName] [hours]");
+				System.exit(1);
+			}
+		}
+
+		if (args.length > 4) {
+			System.out
+					.println("Usage: java "
+							+ MergingNetworkWithOutDir.class.getCanonicalName()
+							+ " [dirServerIpAddress] [hostAndOrPort] [bindingName] [hours]");
+			System.exit(1);
+		}
+
+		/**
+		 * create a new MergingNetworkWithDir with dirServerIpAddress
+		 */
+		MergingNetworkWithDir mergingWith = new MergingNetworkWithDir(args[0]);
+
+		/**
+		 * set the RMISecurityManager
+		 */
+		System.setSecurityManager(new RMISecurityManager());
+
+		// bind the network to RMIRegistry
+		try {
+			Naming.rebind("//" + args[1] + "/" + args[2], mergingWith
+					.getNetwork());
+			System.out.println("Bound With, registered to: " + args[2]);
+		} catch (Exception e) {
+			e.printStackTrace();
+			System.out
+					.println("Binding Exception. Is the rmiregistry running?");
+		}
+
+		// put the Thread on hold
+		try {
+			Thread.sleep(hours * 60 * 60 * 1000);
+		} catch (InterruptedException e) {
+			// do nothing
+		}
+
+		// shutdown after hours
+		mergingWith.shutdownNetwork();
+	}
+
+	/**
+	 * Network reference
+	 */
 	private Network network = null;
 
+	/**
+	 * Set up the MergingNetworkWithDir.
+	 * 
+	 * @param dirServerIpAddress
+	 *            The IpAddress where the directory server are running.
+	 * @throws TorProcessException
+	 *             Thrown if there is a problem with the JVM-external Tor
+	 *             processes that we cannot handle.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 */
 	public MergingNetworkWithDir(String dirServerIpAddress)
 			throws TorProcessException, RemoteException {
+
+		// create a network to initialize a test case (networkName, startPort)
 		network = NetworkFactory.createNetwork("with", 8000);
 
+		// create two directory nodes with parameters (routerName,
+		// dirServerIpAddress)
 		DirectoryNode dir1 = network
 				.createDirectory("dir1", dirServerIpAddress);
 		DirectoryNode dir2 = network
 				.createDirectory("dir2", dirServerIpAddress);
+
+		// configure all nodes hidden service directories
 		dir1.replaceConfiguration("DirListenAddress " + dirServerIpAddress);
 		dir2.replaceConfiguration("DirListenAddress " + dirServerIpAddress);
 
-		RouterNode node1 = network.createRouter("node1", dirServerIpAddress);
-		RouterNode node2 = network.createRouter("node2", dirServerIpAddress);
-		RouterNode node3 = network.createRouter("node3", dirServerIpAddress);
-		RouterNode node4 = network.createRouter("node4", dirServerIpAddress);
-		RouterNode node5 = network.createRouter("node5", dirServerIpAddress);
-		RouterNode node6 = network.createRouter("node6", dirServerIpAddress);
-
 		dir1.addConfiguration("HidServDirectoryV2 1");
 		dir2.addConfiguration("HidServDirectoryV2 1");
 		dir1.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
 		dir2.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
 
+		// create three router nodes with parameters (routerName,
+		// dirServerIpAddress)
+		RouterNode node1 = network.createRouter("router1", dirServerIpAddress);
+		RouterNode node2 = network.createRouter("router2", dirServerIpAddress);
+		RouterNode node3 = network.createRouter("router3", dirServerIpAddress);
+		RouterNode node4 = network.createRouter("router4", dirServerIpAddress);
+		RouterNode node5 = network.createRouter("router5", dirServerIpAddress);
+		RouterNode node6 = network.createRouter("router6", dirServerIpAddress);
+
+		// configure all nodes hidden service directories
 		node1.addConfiguration("HidServDirectoryV2 1");
 		node2.addConfiguration("HidServDirectoryV2 1");
 		node3.addConfiguration("HidServDirectoryV2 1");
@@ -101,6 +209,7 @@
 		node5.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
 		node6.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
 
+		// re-configure routers for V2 compatibility
 		node1.addConfiguration("PublishHidServDescriptors 0");
 		node1.addConfiguration("PublishV2HidServDescriptors 1");
 		node1.addConfiguration("FetchHidServDescriptors 0");
@@ -126,6 +235,7 @@
 		node6.addConfiguration("PublishHidServDescriptors 0");
 		node6.addConfiguration("PublishV2HidServDescriptors 1");
 
+		// obtain reference to event manager to be able to respond to events
 		try {
 			EventManager manager = network.getEventManager();
 			EventListener listener = new EventListener() {
@@ -138,24 +248,34 @@
 			e.printStackTrace();
 		}
 
+		// start up network
 		startupNetwork();
 	}
 
 	public void startupNetwork() {
 
 		try {
+			// configure nodes of this network to be part of a private network
 			network.configureAsPrivateNetwork();
 			System.out.println("Network written ...");
+			// write configuration of proxy node
 			network.writeConfigurations();
 			System.out.println("Config written ...");
+
+			// start proxy node and wait until it has opened a circuit with a
+			// timeout of 5 seconds
 			if (!network.startNodes(5000)) {
 				System.out.println("Failed to start the nodes!");
 				return;
 			}
 			System.out.println("Nodes started ...");
 
-			if (!network.hupUntilUp(30, 5000)) {
-				// System.out.println("Failed to build circuits!");
+			// hup until proxy has built circuits (20 retries, 5 seconds timeout
+			// each)
+			if (!network.hupUntilUp(20, 5000)) {
+
+				// failed to build circuits
+				System.out.println("Failed to build circuits!");
 				return;
 			}
 			System.out.println("Successfully built circuits!");
@@ -166,10 +286,12 @@
 		}
 	}
 
+	// get network
 	public Network getNetwork() {
 		return this.network;
 	}
 
+	// shutdown network
 	public void shutdownNetwork() {
 		try {
 			this.network.shutdownNodes();
@@ -180,37 +302,4 @@
 		}
 		System.out.println("Nodes stopped ...");
 	}
-
-	private static int hours = 25;
-
-	public static void main(String[] args) throws TorProcessException,
-			RemoteException {
-
-		if (args.length == 2) {
-			System.out.println("Usage: java "
-					+ MergingNetworkWithOutDir.class.getCanonicalName()
-					+ " [hostAndOrPort] [bindingName]");
-			System.exit(1);
-		}
-
-		MergingNetworkWithDir mergingWith = new MergingNetworkWithDir(args[0]);
-
-		System.setSecurityManager(new RMISecurityManager());
-
-		try {
-			Naming.rebind("//" + args[1] + "/" + args[2], mergingWith
-					.getNetwork());
-			System.out.println("Bound With, registered to: " + args[2]);
-		} catch (Exception e) {
-			e.printStackTrace();
-			System.out
-					.println("Binding Exception. Is the rmiregistry running?");
-		}
-
-		try {
-			Thread.sleep(hours * 60 * 60 * 1000);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
 }
\ No newline at end of file

Modified: puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithOutDir.java
===================================================================
--- puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithOutDir.java	2007-09-25 00:24:40 UTC (rev 11620)
+++ puppetor/trunk/src/de/uniba/wiai/lspi/puppetor/rmi/MergingNetworkWithOutDir.java	2007-09-25 01:23:53 UTC (rev 11621)
@@ -39,88 +39,231 @@
 
 package de.uniba.wiai.lspi.puppetor.rmi;
 
+import java.net.MalformedURLException;
 import java.rmi.Naming;
+import java.rmi.NotBoundException;
 import java.rmi.RMISecurityManager;
 import java.rmi.RemoteException;
 
+import de.uniba.wiai.lspi.puppetor.Event;
+import de.uniba.wiai.lspi.puppetor.EventListener;
+import de.uniba.wiai.lspi.puppetor.EventManager;
 import de.uniba.wiai.lspi.puppetor.Network;
 import de.uniba.wiai.lspi.puppetor.NetworkFactory;
 import de.uniba.wiai.lspi.puppetor.RouterNode;
 import de.uniba.wiai.lspi.puppetor.TorProcessException;
-import de.uniba.wiai.lspi.puppetor.diststorage.DistributedStorage;
 
 /**
+ * Example for a v2 test environment without directory server.
+ * 
  * @author pgeyer, jjungkunst, sschilling
  */
 public class MergingNetworkWithOutDir {
 
+	/**
+	 * Number of hours to perform this test network.
+	 */
+	private static int hours = 25;
+
+	/**
+	 * Sets up and runs the test.
+	 * 
+	 * @param args
+	 *            args[0] The IpAddress where the directory server are running.
+	 *            args[1] The IpAddress to bind the stub. args[2] The name to
+	 *            bind the stub. args[3] The hours to run this test.
+	 * @throws TorProcessException
+	 *             Thrown if there is a problem with the JVM-external Tor
+	 *             processes that we cannot handle.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 */
+	public static void main(String[] args) throws TorProcessException,
+			RemoteException {
+
+		// test if enough args are passed
+		if (args.length < 3) {
+			System.out.println("Usage: java "
+					+ MergingNetworkWithOutDir.class.getCanonicalName()
+					+ " [dirServerIpAddress] [hostAndOrPort] [bindingName]");
+			System.exit(1);
+		}
+
+		// test if hours is an int value
+		if (args.length == 4) {
+			try {
+				hours = Integer.parseInt(args[3]);
+			} catch (Exception e) {
+				System.out
+						.println("Usage: java "
+								+ MergingNetworkWithOutDir.class
+										.getCanonicalName()
+								+ " [dirServerIpAddress] [hostAndOrPort] [bindingName] [hours]");
+				System.exit(1);
+			}
+		}
+
+		if (args.length > 4) {
+			System.out
+					.println("Usage: java "
+							+ MergingNetworkWithOutDir.class.getCanonicalName()
+							+ " [dirServerIpAddress] [hostAndOrPort] [bindingName] [hours]");
+			System.exit(1);
+		}
+
+		/**
+		 * create a new MergingNetworkWithDir with dirServerIpAddress
+		 */
+		MergingNetworkWithOutDir mergingWithout = new MergingNetworkWithOutDir(
+				args[0]);
+
+		/**
+		 * set the RMISecurityManager
+		 */
+		System.setSecurityManager(new RMISecurityManager());
+
+		// bind the network to RMIRegistry
+		try {
+			Naming.rebind("//" + args[1] + "/" + args[2], mergingWithout
+					.getNetwork());
+			System.out.println("Bound Without, registered to: " + args[2]);
+		} catch (Exception e) {
+			e.printStackTrace();
+			System.out
+					.println("Binding Exception. Is the rmiregistry running?");
+		}
+
+		// put the Thread on hold
+		try {
+			Thread.sleep(60000 * 60 * hours);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+
+		// shutdown after hours
+		mergingWithout.shutdownNetwork();
+	}
+
+	/**
+	 * Network reference
+	 */
 	private Network network = null;
 
+	/**
+	 * Set up the MergingNetworkWithDir.
+	 * 
+	 * @param dirServerIpAddress
+	 *            The IpAddress where the directory server are running
+	 * @throws TorProcessException
+	 *             Thrown if there is a problem with the JVM-external Tor
+	 *             processes that we cannot handle.
+	 * @throws RemoteException
+	 *             Thrown if an error occurs when accessed remotely.
+	 */
 	public MergingNetworkWithOutDir(String dirServerIpAddress)
 			throws TorProcessException, RemoteException {
+
+		// create a network to initialize a test case (networkName)
 		network = NetworkFactory.createNetwork("without");
+		// create three router nodes with parameters (routerName,
+		// dirServerIpAddress)
+		RouterNode node10 = network
+				.createRouter("router10", dirServerIpAddress);
+		RouterNode node11 = network
+				.createRouter("router11", dirServerIpAddress);
+		RouterNode node12 = network
+				.createRouter("router12", dirServerIpAddress);
+		RouterNode node13 = network
+				.createRouter("router13", dirServerIpAddress);
+		RouterNode node14 = network
+				.createRouter("router14", dirServerIpAddress);
+		RouterNode node15 = network
+				.createRouter("router15", dirServerIpAddress);
 
-		RouterNode node1 = network.createRouter("node10", dirServerIpAddress);
-		RouterNode node2 = network.createRouter("node20", dirServerIpAddress);
-		RouterNode node3 = network.createRouter("node30", dirServerIpAddress);
-		RouterNode node4 = network.createRouter("node40", dirServerIpAddress);
-		RouterNode node5 = network.createRouter("node50", dirServerIpAddress);
-		RouterNode node6 = network.createRouter("node60", dirServerIpAddress);
+		// configure all nodes hidden service directories
+		node10.addConfiguration("HidServDirectoryV2 1");
+		node11.addConfiguration("HidServDirectoryV2 1");
+		node12.addConfiguration("HidServDirectoryV2 1");
+		node13.addConfiguration("HidServDirectoryV2 1");
+		node14.addConfiguration("HidServDirectoryV2 1");
+		node15.addConfiguration("HidServDirectoryV2 1");
+		node10.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
+		node11.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
+		node12.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
+		node13.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
+		node14.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
+		node15.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
+		node10.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
+		node11.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
+		node12.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
+		node13.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
+		node14.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
+		node15.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
 
-		node1.addConfiguration("HidServDirectoryV2 1");
-		node2.addConfiguration("HidServDirectoryV2 1");
-		node3.addConfiguration("HidServDirectoryV2 1");
-		node4.addConfiguration("HidServDirectoryV2 1");
-		node5.addConfiguration("HidServDirectoryV2 1");
-		node6.addConfiguration("HidServDirectoryV2 1");
-		node1.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
-		node2.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
-		node3.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
-		node4.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
-		node5.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
-		node6.addConfiguration("ConsiderAllRoutersAsHidServDirectories 1");
-		node1.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
-		node2.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
-		node3.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
-		node4.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
-		node5.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
-		node6.addConfiguration("MinUptimeHidServDirectoryV2 0 minutes");
+		// re-configure routers for V2 compatibility
+		node10.addConfiguration("PublishHidServDescriptors 0");
+		node10.addConfiguration("PublishV2HidServDescriptors 1");
+		node10.addConfiguration("FetchHidServDescriptors 0");
+		node10.addConfiguration("FetchV2HidServDescriptors 1");
+		node11.addConfiguration("PublishHidServDescriptors 0");
+		node11.addConfiguration("PublishV2HidServDescriptors 1");
+		node11.addConfiguration("FetchHidServDescriptors 0");
+		node11.addConfiguration("FetchV2HidServDescriptors 1");
+		node12.addConfiguration("PublishHidServDescriptors 0");
+		node12.addConfiguration("PublishV2HidServDescriptors 1");
+		node12.addConfiguration("FetchHidServDescriptors 0");
+		node12.addConfiguration("FetchV2HidServDescriptors 1");
+		node13.addConfiguration("FetchHidServDescriptors 0");
+		node13.addConfiguration("FetchV2HidServDescriptors 1");
+		node14.addConfiguration("FetchHidServDescriptors 0");
+		node14.addConfiguration("FetchV2HidServDescriptors 1");
+		node15.addConfiguration("FetchHidServDescriptors 0");
+		node15.addConfiguration("FetchV2HidServDescriptors 1");
+		node13.addConfiguration("PublishHidServDescriptors 0");
+		node13.addConfiguration("PublishV2HidServDescriptors 1");
+		node14.addConfiguration("PublishHidServDescriptors 0");
+		node14.addConfiguration("PublishV2HidServDescriptors 1");
+		node15.addConfiguration("PublishHidServDescriptors 0");
+		node15.addConfiguration("PublishV2HidServDescriptors 1");
 
-		node1.addConfiguration("PublishHidServDescriptors 0");
-		node1.addConfiguration("PublishV2HidServDescriptors 1");
-		node1.addConfiguration("FetchHidServDescriptors 0");
-		node1.addConfiguration("FetchV2HidServDescriptors 1");
-		node2.addConfiguration("PublishHidServDescriptors 0");
-		node2.addConfiguration("PublishV2HidServDescriptors 1");
-		node2.addConfiguration("FetchHidServDescriptors 0");
-		node2.addConfiguration("FetchV2HidServDescriptors 1");
-		node3.addConfiguration("PublishHidServDescriptors 0");
-		node3.addConfiguration("PublishV2HidServDescriptors 1");
-		node3.addConfiguration("FetchHidServDescriptors 0");
-		node3.addConfiguration("FetchV2HidServDescriptors 1");
-		node4.addConfiguration("FetchHidServDescriptors 0");
-		node4.addConfiguration("FetchV2HidServDescriptors 1");
-		node5.addConfiguration("FetchHidServDescriptors 0");
-		node5.addConfiguration("FetchV2HidServDescriptors 1");
-		node6.addConfiguration("FetchHidServDescriptors 0");
-		node6.addConfiguration("FetchV2HidServDescriptors 1");
-		node4.addConfiguration("PublishHidServDescriptors 0");
-		node4.addConfiguration("PublishV2HidServDescriptors 1");
-		node5.addConfiguration("PublishHidServDescriptors 0");
-		node5.addConfiguration("PublishV2HidServDescriptors 1");
-		node6.addConfiguration("PublishHidServDescriptors 0");
-		node6.addConfiguration("PublishV2HidServDescriptors 1");
+		// obtain reference to event manager to be able to respond to events
+		try {
+			EventManager manager = network.getEventManager();
+			EventListener listener = new EventListener() {
+				public void handleEvent(Event event) {
+					System.out.println(event.getMessage());
+				}
+			};
+			manager.addEventListener(listener);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
 
+		// configure network
 		configureNetwork();
+
+		try {
+			// collects the dirNetwork stub
+			Network dirNetwork = network.connectNetwork("192.168.1.10", "with");
+			System.out.println("Network with connected ...");
+
+			// merge both networks
+			network.mergeNetworks(dirNetwork);
+			System.out.println("Network merged ...");
+
+		} catch (MalformedURLException e) {
+			e.printStackTrace();
+		} catch (NotBoundException e) {
+			e.printStackTrace();
+		}
 	}
 
 	public void configureNetwork() {
 
 		try {
+			// configure nodes of this network to be part of a private network
 			network.configureAsPrivateNetwork();
 			System.out.println("Network written ...");
-			network.writeConfigurations();
-			System.out.println("Config written ...");
 		} catch (TorProcessException e) {
 			e.printStackTrace();
 		} catch (Exception e) {
@@ -131,14 +274,20 @@
 	public void startupNetwork() {
 
 		try {
+			// start proxy node and wait until it has opened a circuit with a
+			// timeout of 5 seconds
 			if (!network.startNodes(5000)) {
 				System.out.println("Failed to start the nodes!");
 				return;
 			}
 			System.out.println("Nodes started ...");
 
+			// hup until proxy has built circuits (20 retries, 5 seconds timeout
+			// each)
 			if (!network.hupUntilUp(30, 5000)) {
-				// System.out.println("Failed to build circuits!");
+
+				// failed to build circuits
+				System.out.println("Failed to build circuits!");
 				return;
 			}
 			System.out.println("Successfully built circuits!");
@@ -149,10 +298,12 @@
 		}
 	}
 
+	// get network
 	public Network getNetwork() {
 		return this.network;
 	}
 
+	// shutdown network
 	public void shutdownNetwork() {
 		try {
 			this.network.shutdownNodes();
@@ -163,38 +314,4 @@
 		}
 		System.out.println("Nodes stopped ...");
 	}
-
-	private static int hours = 25;
-
-	public static void main(String[] args) throws TorProcessException,
-			RemoteException {
-
-		if (args.length == 2) {
-				System.out.println("Usage: java "
-						+ MergingNetworkWithOutDir.class.getCanonicalName()
-						+ " [hostAndOrPort] [bindingName]");
-				System.exit(1);
-		}
-
-		MergingNetworkWithOutDir without = new MergingNetworkWithOutDir(args[0]);
-
-		System.setSecurityManager(new RMISecurityManager());
-
-		try {
-			Naming.rebind("//" + args[1] + "/" + args[2], without.getNetwork());
-			System.out.println("Bound Without, registered to: " + args[2]);
-		} catch (Exception e) {
-			e.printStackTrace();
-			System.out
-					.println("Binding Exception. Is the rmiregistry running?");
-		}
-
-		try {
-			Thread.sleep(60000 * 60 * hours);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-
-		without.shutdownNetwork();
-	}
 }
\ No newline at end of file



More information about the tor-commits mailing list