Explorar el Código

Fixes importing of Java files from external sources via Jars

Andreas T. Meyer-Berg hace 5 años
padre
commit
4581feba92

+ 99 - 37
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ImportController.java

@@ -2,15 +2,11 @@ package de.tu_darmstadt.tk.SmartHomeNetworkSim.control;
 
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
-import java.nio.channels.FileChannel;
-import java.nio.file.CopyOption;
 import java.nio.file.Files;
 import java.util.LinkedList;
 
@@ -299,7 +295,7 @@ public class ImportController {
 	/**
 	 * Imports the given .java File, compiles it and returns the 
 	 * 
-	 * @param javaFile
+	 * @param javaFilenew File(path)
 	 * @return Class which was compiled
 	 * @throws ClassNotFoundException on invalid package declaration or invalid file name
 	 * @throws MalformedURLException if the URL was malformed
@@ -318,31 +314,15 @@ public class ImportController {
 	public static Class<?> importJavaClass(File javaFile,String path)
 			throws ClassNotFoundException, MalformedURLException {
 		//System.out.println("File Name: "+javaFile.getPath());
-		/**
-		 * Compiler, to compile the File
-		 */
-		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
-		compiler.run(null, null, null, javaFile.getPath());
-
-		/**
-		 * ClassLoader to load the compiled class
-		 */
-		URLClassLoader classLoader = URLClassLoader/* src/ */
-				.newInstance(new URL[] { new File(path).toURI().toURL() });
-
 		/**
 		 * Package name
 		 */
 		String packageName = getJavaPackageName(javaFile);
-		if (packageName != null) {
-			// If packageName is not empty, and dot is required:
-			// "packagePath.ClassName"
-			if (!packageName.isEmpty())
-				packageName += ".";
-		} else {
+		if (packageName == null) {
 			// if package null - try default package
 			packageName = "";
 		}
+		
 		/**
 		 * Name of the Class. File name "ClassName.java"
 		 */
@@ -350,9 +330,74 @@ public class ImportController {
 				javaFile.getName().lastIndexOf('.'));
 		
 		/**
-		 * Check if compiled class file exists in the projects class path - if not, copy it into the project 
+		 * Compiler, to compile the File
+		 */
+		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
+		compiler.run(null, null, null, javaFile.getPath());
+		
+		/**
+		 * Get Root File of the imported Protocol (if in package)
 		 */
+		File root = javaFile.getParentFile();
+		//de.tu_darmstadt.tk.SmartHomeNetworkSim.control
+		if(!packageName.isEmpty()){
+			System.out.println("Checking package name: "+packageName);
+			String[] packageFolders = packageName.split("\\.");
+			if(packageFolders.length<2){
+				if(root.getName().compareTo(packageName)!=0){
+					System.out.println("Parent Folder of class was unexpected: "+root.getName()+" instead of "+packageName);
+					return null;
+				}
+				root = root.getParentFile();
+			}else{
+				for(int i = packageFolders.length-1;i>=0;i--){
+					if(root.getName().compareTo(packageFolders[i])!=0){
+						System.out.println("Parent Folder at level "+i+ " of class was unexpected: "+root.getName()+" instead of "+packageFolders[i]);
+						return null;
+					}
+					root = root.getParentFile();					
+				}
+			}
+			System.out.println("Package structure valid");
+			for(int i = 0; i<packageFolders.length; i++)
+				System.out.println(packageFolders[i]);
+			System.out.println("Root: "+root.getPath());
+		}
+		/**
+		 * ClassLoader to load the compiled class
+		 */
+		//URLClassLoader classLoader = URLClassLoader/* src/ */
+		//		.newInstance(new URL[] { new File(path).toURI().toURL() });
+		URLClassLoader classLoader = URLClassLoader/* src/ */
+				.newInstance(new URL[] { root.toURI().toURL() });
+
+		
+		// If packageName is not empty, and dot is required:
+		// "packagePath.ClassName"
+		if (!packageName.isEmpty())
+			packageName += ".";
+		
+		Class<?> cls = null;
+		try{
+			cls = Class.forName(packageName + className, true, classLoader);
+		}catch(Exception e){
+			try{
+				cls = classLoader.loadClass(packageName + className);
+			}catch(Exception e2){
+				e2.printStackTrace();
+			}
+		}
+		if(cls != null){
+			System.out.println("Preload succes");
+			return cls;
+		}
+		
+		/**
+		 * Check if compiled class file exists in the projects class path - if not, copy it into the project 
+		 *
 		File destination = new File("bin/main/"+packageName.replace('.', '/')+(packageName.isEmpty()?"":"/")+className+".class");
+		/*
+		
 		if(destination!=null&&destination.getParent()!=null&&!destination.getParentFile().exists())destination.getParentFile().mkdirs();
 		
 		File source = new File(javaFile.getParent()+"/"+className+".class");
@@ -361,14 +406,29 @@ public class ImportController {
 		System.out.println("To:   " + destination.getAbsolutePath());
 		try {
 			Files.copy(source.toPath(), destination.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
-			try {
-				Thread.sleep(1000);
-			} catch (InterruptedException e) {
-				System.out.println("Sleep Failed");
-				e.printStackTrace();
+			System.out.println("File moved ?");
+			/**
+			 * Wait until file was fully moved
+			 *//*
+			int i = 0;
+			int maxTrys = 50;
+			long lastSpace = -1;
+			while(i < maxTrys && (!destination.exists() || destination.length()!= lastSpace)){
+				System.out.print("i: "+i);
+				if(destination.exists()){
+					lastSpace = destination.length();
+					System.out.print("  Space: "+lastSpace);
+				}
+				System.out.println("");
+				i++;
+				try {
+					Thread.sleep(100);
+				} catch (InterruptedException e) {
+					System.out.println("Sleep failed");
+				}
 			}
 		} catch (IOException e1) {
-			System.out.println("Copying File failed while Importing Class");
+			System.out.println("Moving File failed while Importing Class");
 			e1.printStackTrace();
 		}
 		/*
@@ -390,19 +450,20 @@ public class ImportController {
 	    	sourceChannel.close();
 	    	destChannel.close();
 	    	}catch(Exception e){}
-	    }*/
+	    }*
 		//System.out.println(destination.getCanonicalPath()+" exists: "+destination.exists());
 
 		/**
 		 * Loaded Class
-		 */
-		Class<?> cls;
+		 *//*
+		System.out.println("Destination exists?: " + destination.exists());
+		//Class<?> cls;
 		try{
 			cls = Class.forName(packageName + className, true, classLoader);
 		}catch(Exception e){
 			cls = classLoader.loadClass(packageName + className);
-		}
-		source.delete();
+		}*/
+		//source.delete();
 		return cls;
 	}
 	
@@ -464,12 +525,13 @@ public class ImportController {
 	}
 	
 	public static void main(String[] args) {
-		testFileCompilation("src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java", "src/");
+		//testFileCompilation("src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java", "src/");
 		testFileCompilation("testCompilation/project1/MQTT_protocolProject1.java", "/bin/main/");
 		testFileCompilation("testCompilation/packageTest/MQTT_protocolPackageTest.java", "/bin/main/");
-		testFileCompilation("src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java", "src/");
+		//testFileCompilation("src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/core/protocols/MQTT_protocol.java", "src/");
 		testFileCompilation("testCompilation/project1/MQTT_protocolProject1.java", "src/");
 		testFileCompilation("testCompilation/packageTest/MQTT_protocolPackageTest.java", "../");
+		testFileCompilation("testCompilation/packageTest/deepPackage/reallyDeepPackage/MQTT_protocolDeepPackageTest.java", "../");
 	}
 	
 	private static void testFileCompilation(String pathToFile, String classPath){

+ 422 - 0
testCompilation/packageTest/MQTT_protocolPackageTest.java

@@ -0,0 +1,422 @@
+package packageTest;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.MQTT_packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.util.Pair;
+
+/**
+ * Implementation of the MQTT Protocol to generate packets for the simulation
+ * 
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class MQTT_protocolPackageTest implements Protocol {
+
+	/**
+	 * Broker which collects and distributes messages
+	 */
+	private Port broker;
+
+	/**
+	 * Publishers like sensors, which publish data
+	 */
+	private LinkedList<Port> pubs;
+
+	/**
+	 * Subscriber which subscribe to different Topics
+	 */
+	private LinkedList<Port> subs;
+	
+	/**
+	 * Topics subscribed by each Port
+	 */
+	private HashMap<Port,LinkedList<String>> subbedTopics = new HashMap<Port,LinkedList<String>>();
+
+	/**
+	 * Devices that are Publisher and Subscriber and therefore send and receive
+	 * messages
+	 */
+	private LinkedList<Port> pubSubs;
+
+	/**
+	 * Packets which are currently being generated or were generated after the
+	 * last generatePackets Call
+	 */
+	private LinkedList<Packet> currentPackets = new LinkedList<Packet>();
+	
+	private LinkedList<Pair<Port,Port>> deletedConnectionLinks = new LinkedList<Pair<Port,Port>>();
+	private SmartDevice deletedBroker = new SmartDevice("DeletedBroker");
+	private Port deletedBrokerPort = new Port(deletedBroker,(short)-1);
+	
+	/**
+	 * Topics of the MQTT Broker
+	 */
+	private LinkedList<String> topics = new LinkedList<String>();
+
+	/**
+	 * Creates a new MQTT Protocol
+	 */
+	public MQTT_protocolPackageTest() {
+		this.broker = null;
+	    initialize();
+	    
+	}
+	
+	/**
+	 * Creates a new MQTT Protocol
+	 * 
+	 * @param broker broker of the protocol
+	 */
+	public MQTT_protocolPackageTest(Port broker) {
+		this.broker = broker;
+		initialize();
+		
+	}
+	
+	/**
+	 * Initializes the different fields
+	 */
+	private void initialize() {
+		topics.add("/home/temperatureHot");
+	    topics.add("/home/doorOpen");
+	    topics.add("/home/lightOn");
+	    subs = new LinkedList<Port>();
+	    pubs = new LinkedList<Port>();
+	    pubSubs = new LinkedList<Port>();
+	}
+	
+	@Override
+	public Collection<Packet> generateNextPakets(Port port, long timestep, boolean packetLost) {
+		/**
+		 * Packets which will be generated
+		 */
+		LinkedList<Packet> returnPackets = new LinkedList<Packet>();
+		//Update all Timestamps of previous created Packets
+		for(Packet p: currentPackets){
+			p.setTimestamp(p.getTimestamp()+timestep);
+		}
+		//Add these packets to the return
+		returnPackets.addAll(currentPackets);
+		//remove packets from the old list
+		currentPackets.clear();
+		//Clear deleted connections
+		deletedConnectionLinks.clear();
+		//Return termination packets
+		if(port==null)return returnPackets;
+		
+		/**
+		 * Update the lastTime the port was triggered
+		 */
+		port.setLastTrigger(timestep);
+		/**
+		 * if port null, skip this step
+		 */
+		if(broker==null)return returnPackets;
+		
+		/**
+		 * Generate new Packets regarding to their class
+		 */
+		if(port==broker){
+			//Broker should not send new packages, without new messages
+			//But could perform some Ping request to random participants
+			Collection<Port> devices = getDevices();
+			devices.remove(port);
+			Port dest = null;
+			java.util.Iterator<Port> it = devices.iterator();
+			for(int i=0; i<(Math.random()*devices.size())&&it.hasNext();i++){
+				dest = it.next();
+			}
+			if(dest != null){
+				returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, port, dest));
+				if(dest.getStatus()!=Port.CLOSED)
+					returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, dest, port));
+			}
+		}else if(subs.contains(port)||pubSubs.contains(port)){
+			
+			//Subs can either subscribe to topics or unsubscribe
+			/**
+			 * Topics, the SmartDevice is subscribed to
+			 */
+			LinkedList<String> tops= subbedTopics.get(port);
+			
+			/**
+			 * Topic which should be subscribed or unsubscribed
+			 */
+			String newTopic;
+			//Subscribe if no subscriptions so far or not subscribed to all, with a probability of70%
+			if(tops.size()==0||(tops.size()!=subbedTopics.size()&&Math.random()<0.7)){
+				//Forced Subscribe
+				newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
+					tops.add(newTopic);
+				}
+			}
+			else if(tops.size()==subbedTopics.size()){
+				//Forced Unsubscribe
+				newTopic = tops.get((int) Math.floor(Math.random()*tops.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBACK, timestep, broker, port));
+					tops.remove(newTopic);
+				}
+			}
+			
+			if(pubSubs.contains(port)&&Math.random()<0.3){
+				//When also Pub, publish sometimes 
+				newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "Topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
+				}
+			}
+		}
+		if(pubs.contains(port)||pubSubs.contains(port)&&Math.random()<0.3){
+			String newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+			/**
+			 * Message to be published (Should be further specialized by a Sensor Device) 
+			 */
+			String msg = "Topic:"+newTopic+":"+(Math.random()<0.5?"true":"false");
+			returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, port, broker, msg));
+			//Response
+			timestep+=broker.getResponseTime();
+			returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep, broker, port));
+			
+			//Publish to Subscribers
+			//Should be be improved to just notify Subs that are subscribed to the topic
+			if(broker.getStatus()!=Port.CLOSED){
+				for(Port p:subs){
+					if(!subbedTopics.get(p).contains(newTopic))continue;//Skip unsubbed ports
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+					
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
+				}
+				for(Port p:pubSubs){
+					if(!subbedTopics.get(p).contains(newTopic))continue;//skip unsubbed ports
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
+				}
+			}
+		}
+		if(Math.random() < 0.05 && port != broker){
+			returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, port, broker));
+			if(port.getStatus()!=Port.CLOSED)
+				returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, broker, port));
+		}
+		return returnPackets;
+	}
+
+	@Override
+	public int getNumberOfRoles() {
+		return 4;
+	}
+
+	@Override
+	public String[] getRoles() {
+		// PublisherSubscriber is Publisher as well as Subscriber
+		return new String[] { "Broker", "PublisherSubscriber", "Publisher", "Subscriber" };
+	}
+
+	@Override
+	public Collection<Port> getDevicesWithRole(int role) {
+		switch (role) {
+		case 0:
+			return new LinkedList<Port>(Arrays.asList(broker));
+		case 1:
+			return pubSubs;
+		case 2:
+			return pubs;
+		case 3:
+			return subs;
+
+		default:
+			return null;
+		}
+	}
+
+	@Override
+	public boolean addDeviceOfRole(Port device, int role) {
+		/*
+		 * First device has to be the Broker 
+		 */
+		if (broker==null) {
+			if (role == 0) {
+				broker = device;
+				updateBrokerOnDeletedConnections(null);
+				return true;
+			} else {
+				return false;
+			}
+		}
+		switch (role) {
+		case 0:
+			//Just one broker allowed.
+			return false;
+		case 1:
+			pubSubs.add(device);
+			subbedTopics.putIfAbsent(device, new LinkedList<String>());
+			break;
+		case 2:
+			pubs.add(device);
+			break;
+		case 3:
+			subs.add(device);
+			subbedTopics.putIfAbsent(device, new LinkedList<String>());
+			break;
+		default:
+			// invalid role
+			return false;
+		}
+		// Create packets for the connecting Client
+		currentPackets.add(new MQTT_packet(MQTT_packet.CONNECT, currentPackets.size()/2, device, broker));
+		currentPackets.add(new MQTT_packet(MQTT_packet.CONNACK, currentPackets.size()/2+1, broker, device));
+		return true;
+	}
+
+	@Override
+	public void removeDevice(Port device) {
+		/**
+		 * true if the device was removed
+		 */
+		boolean removedDevice=false;
+		if (broker == device){
+			broker = null;
+			deletedConnectionLinks.add(new Pair<Port, Port>(new Port(device.getOwner(), (short)-1), deletedBrokerPort));
+			updateBrokerOnDeletedConnections(device);
+		}
+		removedDevice|=pubSubs.remove(device);
+		removedDevice|=subs.remove(device);
+		removedDevice|=pubs.remove(device);
+		//Remove Port from topics and clear its list
+		LinkedList<String> oldTopics = subbedTopics.remove(device);
+		if(oldTopics!=null)oldTopics.clear();
+		if(removedDevice){
+			if(broker == null){
+				deletedConnectionLinks.add(new Pair<Port, Port>(deletedBrokerPort,device));
+			}else{
+				deletedConnectionLinks.add(new Pair<Port, Port>(broker, device));
+				//If not the broker and device was removed -> disconnect
+				currentPackets.add(new MQTT_packet(MQTT_packet.DISCONNECT, currentPackets.size()/2, device, broker));
+			}
+		}
+	}
+	
+	public void addTopic(String topic){
+		topics.add(topic);
+	}
+
+	@Override
+	public String getName() {
+		return "MQTT";
+	}
+	
+	@Override
+	public int getRoleOfDevice(Port device){
+		if(device == null)
+			return -1;
+		if(device == broker)
+			return 0;
+		if(pubSubs.contains(device))
+			return 1;
+		if(pubs.contains(device))
+			return 2;
+		if(subs.contains(device))
+			return 3;
+		return -1;
+	}
+	
+	@Override
+	public Collection<Port> getDevices(){
+		LinkedList<Port> returnDevices = new LinkedList<Port>();
+		if(broker!=null)
+			returnDevices.add(broker);
+		returnDevices.addAll(pubSubs);
+		returnDevices.addAll(pubs);
+		returnDevices.addAll(subs);
+		return returnDevices;
+	}
+	
+	@Override
+	public byte getTopologyType() {
+		return STAR;
+	}
+	
+	@Override
+	public Collection<Pair<Port,Port>> getTopology(){
+		LinkedList<Pair<Port,Port>> topology = new LinkedList<Pair<Port,Port>>();
+		Port center = broker;
+		calcDeletedBrokerPosition();
+		if(broker==null)
+			center = new Port(deletedBroker, (short)-1);
+		for(Port p: pubSubs)
+			topology.add(new Pair<Port, Port>(center, p));
+		for(Port p: pubs)
+			topology.add(new Pair<Port, Port>(center, p));
+		for(Port p: subs)
+			topology.add(new Pair<Port, Port>(center, p));
+		return topology;
+	}
+
+	@Override
+	public Collection<Pair<Port, Port>> getDeletedTopology() {
+		calcDeletedBrokerPosition();
+		return deletedConnectionLinks;
+	}
+	
+	/**
+	 * Calculate and update the position of the deleted Broker
+	 */
+	private void calcDeletedBrokerPosition(){
+		if(broker == null){
+			int x = 0, y = 0, noP = 0;
+			for(Port p: getDevices()){
+				if(p!=null && p.getOwner()!=null){
+					x += p.getOwner().getX();
+					y += p.getOwner().getY();
+					noP++;
+				}
+			}
+			if(noP==0)
+				return;
+			deletedBroker.setX(((int)(x*1.0)/noP));
+			deletedBroker.setY(((int)(y*1.0)/noP));
+		}
+	}
+	
+	/**
+	 * Update the broker port on the deleted Connections
+	 * 
+	 * @param device old broker
+	 */
+	private void updateBrokerOnDeletedConnections(Port device){
+		for(Pair<Port, Port> p: deletedConnectionLinks){
+			if(broker == null){
+				if(p.getLeft() == device)
+					p.setLeft(deletedBrokerPort);
+				if(p.getRight() == device)
+					p.setRight(deletedBrokerPort);
+			}else{
+				if(p.getLeft() == deletedBrokerPort)
+					p.setLeft(broker);
+				if(p.getRight() == deletedBrokerPort)
+					p.setRight(broker);
+				
+			}
+		}
+	}
+
+}

+ 422 - 0
testCompilation/packageTest/deepPackage/reallyDeepPackage/MQTT_protocolDeepPackageTest.java

@@ -0,0 +1,422 @@
+package packageTest.deepPackage.reallyDeepPackage;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.MQTT_packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.util.Pair;
+
+/**
+ * Implementation of the MQTT Protocol to generate packets for the simulation
+ * 
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class MQTT_protocolDeepPackageTest implements Protocol {
+
+	/**
+	 * Broker which collects and distributes messages
+	 */
+	private Port broker;
+
+	/**
+	 * Publishers like sensors, which publish data
+	 */
+	private LinkedList<Port> pubs;
+
+	/**
+	 * Subscriber which subscribe to different Topics
+	 */
+	private LinkedList<Port> subs;
+	
+	/**
+	 * Topics subscribed by each Port
+	 */
+	private HashMap<Port,LinkedList<String>> subbedTopics = new HashMap<Port,LinkedList<String>>();
+
+	/**
+	 * Devices that are Publisher and Subscriber and therefore send and receive
+	 * messages
+	 */
+	private LinkedList<Port> pubSubs;
+
+	/**
+	 * Packets which are currently being generated or were generated after the
+	 * last generatePackets Call
+	 */
+	private LinkedList<Packet> currentPackets = new LinkedList<Packet>();
+	
+	private LinkedList<Pair<Port,Port>> deletedConnectionLinks = new LinkedList<Pair<Port,Port>>();
+	private SmartDevice deletedBroker = new SmartDevice("DeletedBroker");
+	private Port deletedBrokerPort = new Port(deletedBroker,(short)-1);
+	
+	/**
+	 * Topics of the MQTT Broker
+	 */
+	private LinkedList<String> topics = new LinkedList<String>();
+
+	/**
+	 * Creates a new MQTT Protocol
+	 */
+	public MQTT_protocolDeepPackageTest() {
+		this.broker = null;
+	    initialize();
+	    
+	}
+	
+	/**
+	 * Creates a new MQTT Protocol
+	 * 
+	 * @param broker broker of the protocol
+	 */
+	public MQTT_protocolDeepPackageTest(Port broker) {
+		this.broker = broker;
+		initialize();
+		
+	}
+	
+	/**
+	 * Initializes the different fields
+	 */
+	private void initialize() {
+		topics.add("/home/temperatureHot");
+	    topics.add("/home/doorOpen");
+	    topics.add("/home/lightOn");
+	    subs = new LinkedList<Port>();
+	    pubs = new LinkedList<Port>();
+	    pubSubs = new LinkedList<Port>();
+	}
+	
+	@Override
+	public Collection<Packet> generateNextPakets(Port port, long timestep, boolean packetLost) {
+		/**
+		 * Packets which will be generated
+		 */
+		LinkedList<Packet> returnPackets = new LinkedList<Packet>();
+		//Update all Timestamps of previous created Packets
+		for(Packet p: currentPackets){
+			p.setTimestamp(p.getTimestamp()+timestep);
+		}
+		//Add these packets to the return
+		returnPackets.addAll(currentPackets);
+		//remove packets from the old list
+		currentPackets.clear();
+		//Clear deleted connections
+		deletedConnectionLinks.clear();
+		//Return termination packets
+		if(port==null)return returnPackets;
+		
+		/**
+		 * Update the lastTime the port was triggered
+		 */
+		port.setLastTrigger(timestep);
+		/**
+		 * if port null, skip this step
+		 */
+		if(broker==null)return returnPackets;
+		
+		/**
+		 * Generate new Packets regarding to their class
+		 */
+		if(port==broker){
+			//Broker should not send new packages, without new messages
+			//But could perform some Ping request to random participants
+			Collection<Port> devices = getDevices();
+			devices.remove(port);
+			Port dest = null;
+			java.util.Iterator<Port> it = devices.iterator();
+			for(int i=0; i<(Math.random()*devices.size())&&it.hasNext();i++){
+				dest = it.next();
+			}
+			if(dest != null){
+				returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, port, dest));
+				if(dest.getStatus()!=Port.CLOSED)
+					returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, dest, port));
+			}
+		}else if(subs.contains(port)||pubSubs.contains(port)){
+			
+			//Subs can either subscribe to topics or unsubscribe
+			/**
+			 * Topics, the SmartDevice is subscribed to
+			 */
+			LinkedList<String> tops= subbedTopics.get(port);
+			
+			/**
+			 * Topic which should be subscribed or unsubscribed
+			 */
+			String newTopic;
+			//Subscribe if no subscriptions so far or not subscribed to all, with a probability of70%
+			if(tops.size()==0||(tops.size()!=subbedTopics.size()&&Math.random()<0.7)){
+				//Forced Subscribe
+				newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
+					tops.add(newTopic);
+				}
+			}
+			else if(tops.size()==subbedTopics.size()){
+				//Forced Unsubscribe
+				newTopic = tops.get((int) Math.floor(Math.random()*tops.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBACK, timestep, broker, port));
+					tops.remove(newTopic);
+				}
+			}
+			
+			if(pubSubs.contains(port)&&Math.random()<0.3){
+				//When also Pub, publish sometimes 
+				newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "Topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
+				}
+			}
+		}
+		if(pubs.contains(port)||pubSubs.contains(port)&&Math.random()<0.3){
+			String newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+			/**
+			 * Message to be published (Should be further specialized by a Sensor Device) 
+			 */
+			String msg = "Topic:"+newTopic+":"+(Math.random()<0.5?"true":"false");
+			returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, port, broker, msg));
+			//Response
+			timestep+=broker.getResponseTime();
+			returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep, broker, port));
+			
+			//Publish to Subscribers
+			//Should be be improved to just notify Subs that are subscribed to the topic
+			if(broker.getStatus()!=Port.CLOSED){
+				for(Port p:subs){
+					if(!subbedTopics.get(p).contains(newTopic))continue;//Skip unsubbed ports
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+					
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
+				}
+				for(Port p:pubSubs){
+					if(!subbedTopics.get(p).contains(newTopic))continue;//skip unsubbed ports
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
+				}
+			}
+		}
+		if(Math.random() < 0.05 && port != broker){
+			returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, port, broker));
+			if(port.getStatus()!=Port.CLOSED)
+				returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, broker, port));
+		}
+		return returnPackets;
+	}
+
+	@Override
+	public int getNumberOfRoles() {
+		return 4;
+	}
+
+	@Override
+	public String[] getRoles() {
+		// PublisherSubscriber is Publisher as well as Subscriber
+		return new String[] { "Broker", "PublisherSubscriber", "Publisher", "Subscriber" };
+	}
+
+	@Override
+	public Collection<Port> getDevicesWithRole(int role) {
+		switch (role) {
+		case 0:
+			return new LinkedList<Port>(Arrays.asList(broker));
+		case 1:
+			return pubSubs;
+		case 2:
+			return pubs;
+		case 3:
+			return subs;
+
+		default:
+			return null;
+		}
+	}
+
+	@Override
+	public boolean addDeviceOfRole(Port device, int role) {
+		/*
+		 * First device has to be the Broker 
+		 */
+		if (broker==null) {
+			if (role == 0) {
+				broker = device;
+				updateBrokerOnDeletedConnections(null);
+				return true;
+			} else {
+				return false;
+			}
+		}
+		switch (role) {
+		case 0:
+			//Just one broker allowed.
+			return false;
+		case 1:
+			pubSubs.add(device);
+			subbedTopics.putIfAbsent(device, new LinkedList<String>());
+			break;
+		case 2:
+			pubs.add(device);
+			break;
+		case 3:
+			subs.add(device);
+			subbedTopics.putIfAbsent(device, new LinkedList<String>());
+			break;
+		default:
+			// invalid role
+			return false;
+		}
+		// Create packets for the connecting Client
+		currentPackets.add(new MQTT_packet(MQTT_packet.CONNECT, currentPackets.size()/2, device, broker));
+		currentPackets.add(new MQTT_packet(MQTT_packet.CONNACK, currentPackets.size()/2+1, broker, device));
+		return true;
+	}
+
+	@Override
+	public void removeDevice(Port device) {
+		/**
+		 * true if the device was removed
+		 */
+		boolean removedDevice=false;
+		if (broker == device){
+			broker = null;
+			deletedConnectionLinks.add(new Pair<Port, Port>(new Port(device.getOwner(), (short)-1), deletedBrokerPort));
+			updateBrokerOnDeletedConnections(device);
+		}
+		removedDevice|=pubSubs.remove(device);
+		removedDevice|=subs.remove(device);
+		removedDevice|=pubs.remove(device);
+		//Remove Port from topics and clear its list
+		LinkedList<String> oldTopics = subbedTopics.remove(device);
+		if(oldTopics!=null)oldTopics.clear();
+		if(removedDevice){
+			if(broker == null){
+				deletedConnectionLinks.add(new Pair<Port, Port>(deletedBrokerPort,device));
+			}else{
+				deletedConnectionLinks.add(new Pair<Port, Port>(broker, device));
+				//If not the broker and device was removed -> disconnect
+				currentPackets.add(new MQTT_packet(MQTT_packet.DISCONNECT, currentPackets.size()/2, device, broker));
+			}
+		}
+	}
+	
+	public void addTopic(String topic){
+		topics.add(topic);
+	}
+
+	@Override
+	public String getName() {
+		return "MQTT";
+	}
+	
+	@Override
+	public int getRoleOfDevice(Port device){
+		if(device == null)
+			return -1;
+		if(device == broker)
+			return 0;
+		if(pubSubs.contains(device))
+			return 1;
+		if(pubs.contains(device))
+			return 2;
+		if(subs.contains(device))
+			return 3;
+		return -1;
+	}
+	
+	@Override
+	public Collection<Port> getDevices(){
+		LinkedList<Port> returnDevices = new LinkedList<Port>();
+		if(broker!=null)
+			returnDevices.add(broker);
+		returnDevices.addAll(pubSubs);
+		returnDevices.addAll(pubs);
+		returnDevices.addAll(subs);
+		return returnDevices;
+	}
+	
+	@Override
+	public byte getTopologyType() {
+		return STAR;
+	}
+	
+	@Override
+	public Collection<Pair<Port,Port>> getTopology(){
+		LinkedList<Pair<Port,Port>> topology = new LinkedList<Pair<Port,Port>>();
+		Port center = broker;
+		calcDeletedBrokerPosition();
+		if(broker==null)
+			center = new Port(deletedBroker, (short)-1);
+		for(Port p: pubSubs)
+			topology.add(new Pair<Port, Port>(center, p));
+		for(Port p: pubs)
+			topology.add(new Pair<Port, Port>(center, p));
+		for(Port p: subs)
+			topology.add(new Pair<Port, Port>(center, p));
+		return topology;
+	}
+
+	@Override
+	public Collection<Pair<Port, Port>> getDeletedTopology() {
+		calcDeletedBrokerPosition();
+		return deletedConnectionLinks;
+	}
+	
+	/**
+	 * Calculate and update the position of the deleted Broker
+	 */
+	private void calcDeletedBrokerPosition(){
+		if(broker == null){
+			int x = 0, y = 0, noP = 0;
+			for(Port p: getDevices()){
+				if(p!=null && p.getOwner()!=null){
+					x += p.getOwner().getX();
+					y += p.getOwner().getY();
+					noP++;
+				}
+			}
+			if(noP==0)
+				return;
+			deletedBroker.setX(((int)(x*1.0)/noP));
+			deletedBroker.setY(((int)(y*1.0)/noP));
+		}
+	}
+	
+	/**
+	 * Update the broker port on the deleted Connections
+	 * 
+	 * @param device old broker
+	 */
+	private void updateBrokerOnDeletedConnections(Port device){
+		for(Pair<Port, Port> p: deletedConnectionLinks){
+			if(broker == null){
+				if(p.getLeft() == device)
+					p.setLeft(deletedBrokerPort);
+				if(p.getRight() == device)
+					p.setRight(deletedBrokerPort);
+			}else{
+				if(p.getLeft() == deletedBrokerPort)
+					p.setLeft(broker);
+				if(p.getRight() == deletedBrokerPort)
+					p.setRight(broker);
+				
+			}
+		}
+	}
+
+}

+ 421 - 0
testCompilation/project1/MQTT_protocolProject1.java

@@ -0,0 +1,421 @@
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Port;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.SmartDevice;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.protocols.packets.MQTT_packet;
+import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.util.Pair;
+
+/**
+ * Implementation of the MQTT Protocol to generate packets for the simulation
+ * 
+ *
+ * @author Andreas T. Meyer-Berg
+ */
+public class MQTT_protocolProject1 implements Protocol {
+
+	/**
+	 * Broker which collects and distributes messages
+	 */
+	private Port broker;
+
+	/**
+	 * Publishers like sensors, which publish data
+	 */
+	private LinkedList<Port> pubs;
+
+	/**
+	 * Subscriber which subscribe to different Topics
+	 */
+	private LinkedList<Port> subs;
+	
+	/**
+	 * Topics subscribed by each Port
+	 */
+	private HashMap<Port,LinkedList<String>> subbedTopics = new HashMap<Port,LinkedList<String>>();
+
+	/**
+	 * Devices that are Publisher and Subscriber and therefore send and receive
+	 * messages
+	 */
+	private LinkedList<Port> pubSubs;
+
+	/**
+	 * Packets which are currently being generated or were generated after the
+	 * last generatePackets Call
+	 */
+	private LinkedList<Packet> currentPackets = new LinkedList<Packet>();
+	
+	private LinkedList<Pair<Port,Port>> deletedConnectionLinks = new LinkedList<Pair<Port,Port>>();
+	private SmartDevice deletedBroker = new SmartDevice("DeletedBroker");
+	private Port deletedBrokerPort = new Port(deletedBroker,(short)-1);
+	
+	/**
+	 * Topics of the MQTT Broker
+	 */
+	private LinkedList<String> topics = new LinkedList<String>();
+
+	/**
+	 * Creates a new MQTT Protocol
+	 */
+	public MQTT_protocolProject1() {
+		this.broker = null;
+	    initialize();
+	    
+	}
+	
+	/**
+	 * Creates a new MQTT Protocol
+	 * 
+	 * @param broker broker of the protocol
+	 */
+	public MQTT_protocolProject1(Port broker) {
+		this.broker = broker;
+		initialize();
+		
+	}
+	
+	/**
+	 * Initializes the different fields
+	 */
+	private void initialize() {
+		topics.add("/home/temperatureHot");
+	    topics.add("/home/doorOpen");
+	    topics.add("/home/lightOn");
+	    subs = new LinkedList<Port>();
+	    pubs = new LinkedList<Port>();
+	    pubSubs = new LinkedList<Port>();
+	}
+	
+	@Override
+	public Collection<Packet> generateNextPakets(Port port, long timestep, boolean packetLost) {
+		/**
+		 * Packets which will be generated
+		 */
+		LinkedList<Packet> returnPackets = new LinkedList<Packet>();
+		//Update all Timestamps of previous created Packets
+		for(Packet p: currentPackets){
+			p.setTimestamp(p.getTimestamp()+timestep);
+		}
+		//Add these packets to the return
+		returnPackets.addAll(currentPackets);
+		//remove packets from the old list
+		currentPackets.clear();
+		//Clear deleted connections
+		deletedConnectionLinks.clear();
+		//Return termination packets
+		if(port==null)return returnPackets;
+		
+		/**
+		 * Update the lastTime the port was triggered
+		 */
+		port.setLastTrigger(timestep);
+		/**
+		 * if port null, skip this step
+		 */
+		if(broker==null)return returnPackets;
+		
+		/**
+		 * Generate new Packets regarding to their class
+		 */
+		if(port==broker){
+			//Broker should not send new packages, without new messages
+			//But could perform some Ping request to random participants
+			Collection<Port> devices = getDevices();
+			devices.remove(port);
+			Port dest = null;
+			java.util.Iterator<Port> it = devices.iterator();
+			for(int i=0; i<(Math.random()*devices.size())&&it.hasNext();i++){
+				dest = it.next();
+			}
+			if(dest != null){
+				returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, port, dest));
+				if(dest.getStatus()!=Port.CLOSED)
+					returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, dest, port));
+			}
+		}else if(subs.contains(port)||pubSubs.contains(port)){
+			
+			//Subs can either subscribe to topics or unsubscribe
+			/**
+			 * Topics, the SmartDevice is subscribed to
+			 */
+			LinkedList<String> tops= subbedTopics.get(port);
+			
+			/**
+			 * Topic which should be subscribed or unsubscribed
+			 */
+			String newTopic;
+			//Subscribe if no subscriptions so far or not subscribed to all, with a probability of70%
+			if(tops.size()==0||(tops.size()!=subbedTopics.size()&&Math.random()<0.7)){
+				//Forced Subscribe
+				newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
+					tops.add(newTopic);
+				}
+			}
+			else if(tops.size()==subbedTopics.size()){
+				//Forced Unsubscribe
+				newTopic = tops.get((int) Math.floor(Math.random()*tops.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBSCRIBE, timestep, port, broker, "topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.UNSUBACK, timestep, broker, port));
+					tops.remove(newTopic);
+				}
+			}
+			
+			if(pubSubs.contains(port)&&Math.random()<0.3){
+				//When also Pub, publish sometimes 
+				newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+				returnPackets.add(new MQTT_packet(MQTT_packet.SUBSCRIBE, timestep, port, broker, "Topic:"+newTopic));
+				if(broker.getStatus()!=Port.CLOSED){
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.SUBACK, timestep, broker, port));
+				}
+			}
+		}
+		if(pubs.contains(port)||pubSubs.contains(port)&&Math.random()<0.3){
+			String newTopic = topics.get((int) Math.floor(Math.random()*topics.size()));
+			/**
+			 * Message to be published (Should be further specialized by a Sensor Device) 
+			 */
+			String msg = "Topic:"+newTopic+":"+(Math.random()<0.5?"true":"false");
+			returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, port, broker, msg));
+			//Response
+			timestep+=broker.getResponseTime();
+			returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep, broker, port));
+			
+			//Publish to Subscribers
+			//Should be be improved to just notify Subs that are subscribed to the topic
+			if(broker.getStatus()!=Port.CLOSED){
+				for(Port p:subs){
+					if(!subbedTopics.get(p).contains(newTopic))continue;//Skip unsubbed ports
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+					
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
+				}
+				for(Port p:pubSubs){
+					if(!subbedTopics.get(p).contains(newTopic))continue;//skip unsubbed ports
+					timestep+=broker.getResponseTime();
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBLISH, timestep, broker, p, msg));
+					returnPackets.add(new MQTT_packet(MQTT_packet.PUBACK, timestep+p.getResponseTime(), p, broker));
+				}
+			}
+		}
+		if(Math.random() < 0.05 && port != broker){
+			returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, port, broker));
+			if(port.getStatus()!=Port.CLOSED)
+				returnPackets.add(new MQTT_packet(MQTT_packet.PINGREQ, timestep, broker, port));
+		}
+		return returnPackets;
+	}
+
+	@Override
+	public int getNumberOfRoles() {
+		return 4;
+	}
+
+	@Override
+	public String[] getRoles() {
+		// PublisherSubscriber is Publisher as well as Subscriber
+		return new String[] { "Broker", "PublisherSubscriber", "Publisher", "Subscriber" };
+	}
+
+	@Override
+	public Collection<Port> getDevicesWithRole(int role) {
+		switch (role) {
+		case 0:
+			return new LinkedList<Port>(Arrays.asList(broker));
+		case 1:
+			return pubSubs;
+		case 2:
+			return pubs;
+		case 3:
+			return subs;
+
+		default:
+			return null;
+		}
+	}
+
+	@Override
+	public boolean addDeviceOfRole(Port device, int role) {
+		/*
+		 * First device has to be the Broker 
+		 */
+		if (broker==null) {
+			if (role == 0) {
+				broker = device;
+				updateBrokerOnDeletedConnections(null);
+				return true;
+			} else {
+				return false;
+			}
+		}
+		switch (role) {
+		case 0:
+			//Just one broker allowed.
+			return false;
+		case 1:
+			pubSubs.add(device);
+			subbedTopics.putIfAbsent(device, new LinkedList<String>());
+			break;
+		case 2:
+			pubs.add(device);
+			break;
+		case 3:
+			subs.add(device);
+			subbedTopics.putIfAbsent(device, new LinkedList<String>());
+			break;
+		default:
+			// invalid role
+			return false;
+		}
+		// Create packets for the connecting Client
+		currentPackets.add(new MQTT_packet(MQTT_packet.CONNECT, currentPackets.size()/2, device, broker));
+		currentPackets.add(new MQTT_packet(MQTT_packet.CONNACK, currentPackets.size()/2+1, broker, device));
+		return true;
+	}
+
+	@Override
+	public void removeDevice(Port device) {
+		/**
+		 * true if the device was removed
+		 */
+		boolean removedDevice=false;
+		if (broker == device){
+			broker = null;
+			deletedConnectionLinks.add(new Pair<Port, Port>(new Port(device.getOwner(), (short)-1), deletedBrokerPort));
+			updateBrokerOnDeletedConnections(device);
+		}
+		removedDevice|=pubSubs.remove(device);
+		removedDevice|=subs.remove(device);
+		removedDevice|=pubs.remove(device);
+		//Remove Port from topics and clear its list
+		LinkedList<String> oldTopics = subbedTopics.remove(device);
+		if(oldTopics!=null)oldTopics.clear();
+		if(removedDevice){
+			if(broker == null){
+				deletedConnectionLinks.add(new Pair<Port, Port>(deletedBrokerPort,device));
+			}else{
+				deletedConnectionLinks.add(new Pair<Port, Port>(broker, device));
+				//If not the broker and device was removed -> disconnect
+				currentPackets.add(new MQTT_packet(MQTT_packet.DISCONNECT, currentPackets.size()/2, device, broker));
+			}
+		}
+	}
+	
+	public void addTopic(String topic){
+		topics.add(topic);
+	}
+
+	@Override
+	public String getName() {
+		return "MQTT";
+	}
+	
+	@Override
+	public int getRoleOfDevice(Port device){
+		if(device == null)
+			return -1;
+		if(device == broker)
+			return 0;
+		if(pubSubs.contains(device))
+			return 1;
+		if(pubs.contains(device))
+			return 2;
+		if(subs.contains(device))
+			return 3;
+		return -1;
+	}
+	
+	@Override
+	public Collection<Port> getDevices(){
+		LinkedList<Port> returnDevices = new LinkedList<Port>();
+		if(broker!=null)
+			returnDevices.add(broker);
+		returnDevices.addAll(pubSubs);
+		returnDevices.addAll(pubs);
+		returnDevices.addAll(subs);
+		return returnDevices;
+	}
+	
+	@Override
+	public byte getTopologyType() {
+		return STAR;
+	}
+	
+	@Override
+	public Collection<Pair<Port,Port>> getTopology(){
+		LinkedList<Pair<Port,Port>> topology = new LinkedList<Pair<Port,Port>>();
+		Port center = broker;
+		calcDeletedBrokerPosition();
+		if(broker==null)
+			center = new Port(deletedBroker, (short)-1);
+		for(Port p: pubSubs)
+			topology.add(new Pair<Port, Port>(center, p));
+		for(Port p: pubs)
+			topology.add(new Pair<Port, Port>(center, p));
+		for(Port p: subs)
+			topology.add(new Pair<Port, Port>(center, p));
+		return topology;
+	}
+
+	@Override
+	public Collection<Pair<Port, Port>> getDeletedTopology() {
+		calcDeletedBrokerPosition();
+		return deletedConnectionLinks;
+	}
+	
+	/**
+	 * Calculate and update the position of the deleted Broker
+	 */
+	private void calcDeletedBrokerPosition(){
+		if(broker == null){
+			int x = 0, y = 0, noP = 0;
+			for(Port p: getDevices()){
+				if(p!=null && p.getOwner()!=null){
+					x += p.getOwner().getX();
+					y += p.getOwner().getY();
+					noP++;
+				}
+			}
+			if(noP==0)
+				return;
+			deletedBroker.setX(((int)(x*1.0)/noP));
+			deletedBroker.setY(((int)(y*1.0)/noP));
+		}
+	}
+	
+	/**
+	 * Update the broker port on the deleted Connections
+	 * 
+	 * @param device old broker
+	 */
+	private void updateBrokerOnDeletedConnections(Port device){
+		for(Pair<Port, Port> p: deletedConnectionLinks){
+			if(broker == null){
+				if(p.getLeft() == device)
+					p.setLeft(deletedBrokerPort);
+				if(p.getRight() == device)
+					p.setRight(deletedBrokerPort);
+			}else{
+				if(p.getLeft() == deletedBrokerPort)
+					p.setLeft(broker);
+				if(p.getRight() == deletedBrokerPort)
+					p.setRight(broker);
+				
+			}
+		}
+	}
+
+}