Explorar el Código

Implements the runtime compiler and java packageName detection

Andreas T. Meyer-Berg hace 5 años
padre
commit
9d334ff391

+ 143 - 35
src/main/java/de/tu_darmstadt/tk/SmartHomeNetworkSim/control/ImportController.java

@@ -1,6 +1,10 @@
 package de.tu_darmstadt.tk.SmartHomeNetworkSim.control;
 
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.LinkedList;
@@ -12,96 +16,200 @@ import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Model;
 import de.tu_darmstadt.tk.SmartHomeNetworkSim.core.Protocol;
 
 /**
- * Controller which manages Imported Classes of the 
+ * Controller which manages Imported Classes of the
  *
  * @author Andreas T. Meyer-Berg
  */
 public class ImportController {
 	Model model;
 	Controller controller;
-	
+
 	/**
 	 * Creates a new ImportController
-	 * @param model model to be edited
-	 * @param controller parent controller
+	 * 
+	 * @param model
+	 *            model to be edited
+	 * @param controller
+	 *            parent controller
 	 */
 	public ImportController(Model model, Controller controller) {
 		this.model = model;
 		this.controller = controller;
 	}
-	
+
 	/**
 	 * Returns the available Protocols of the model
 	 * 
 	 * @return available protocols
 	 */
-	public LinkedList<Class<? extends Protocol>> getProtocols(){
+	public LinkedList<Class<? extends Protocol>> getProtocols() {
 		return model.getProtocols();
 	}
-	
+
 	/**
 	 * Adds new Protocol to the model
-	 * @param protocol protocol to be added
+	 * 
+	 * @param protocol
+	 *            protocol to be added
 	 * @return true if it was added
 	 */
-	public boolean addProtocol(Class<? extends Protocol> protocol){
-		if(isValidProtocol(protocol))
+	public boolean addProtocol(Class<? extends Protocol> protocol) {
+		if (isValidProtocol(protocol))
 			model.addProtocol(protocol);
-		else 
+		else
 			return false;
 		return true;
-		
+
 	}
-	
+
 	/**
 	 * Removes protocol from the model
-	 * @param protocol protocol to be removed
+	 * 
+	 * @param protocol
+	 *            protocol to be removed
 	 */
-	public void removeProtocol(Class<? extends Protocol> protocol){
+	public void removeProtocol(Class<? extends Protocol> protocol) {
 		model.removeProtocol(protocol);
 	}
-	
+
 	/**
 	 * Returns true if it is a Valid Protocol, false if not
 	 * 
-	 * @param protocol protocol to be checked
+	 * @param protocol
+	 *            protocol to be checked
 	 * @return true if it is a valid protocol
 	 */
-	public boolean isValidProtocol(Class<? extends Protocol> protocol){
+	public boolean isValidProtocol(Class<? extends Protocol> protocol) {
 		try {
+			/**
+			 * Protocol to be tested
+			 */
 			Protocol p = protocol.newInstance();
-			//Empty constructor required, to create new instance
-			if(p == null)
+			// Empty constructor required, to create new instance
+			if (p == null)
 				throw new Exception("Protocol required an empty constructor");
 			// Name shall not be null or empty string
-			if(p.getName() == null || p.getName()=="")
-				throw new Exception("Protocol name shall not be null or empty string.");
-			if(p.getRoles()==null||p.getRoles().length==0)
+			if (p.getName() == null || p.getName() == "")
+				throw new Exception(
+						"Protocol name shall not be null or empty string.");
+			if (p.getRoles() == null || p.getRoles().length == 0)
 				throw new Exception("Roles shall not be null or empty");
 			// Number of roles have to match
-			if(p.getNumberOfRoles()!=p.getRoles().length) 
-				throw new Exception("getNumberOfRoles() does not match getRoles().length");
+			if (p.getNumberOfRoles() != p.getRoles().length)
+				throw new Exception(
+						"getNumberOfRoles() does not match getRoles().length");
 		} catch (Exception e) {
 			return false;
 		}
 		return true;
 	}
 	
-	public Class importJavaClass(File javaFile){
-		// Compile
+	/**
+	 * Imports the given .java File, compiles it and returns the 
+	 * 
+	 * @param javaFile
+	 * @return Class which was compiled
+	 * @throws ClassNotFoundException on invalid package declaration or invalid file name
+	 * @throws MalformedURLException if the URL was malformed
+	 */
+	@SuppressWarnings("rawtypes")
+	public static Class importJavaClass(File javaFile)
+			throws ClassNotFoundException, MalformedURLException {
+		/**
+		 * Compiler, to compile the File
+		 */
 		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
 		compiler.run(null, null, null, javaFile.getPath());
 
-		// Load compiled class. - not working
-		try{
-		URLClassLoader classLoader = URLClassLoader.newInstance(new URL[] { new File("src/").toURI().toURL() });
-		String className = javaFile.getName().substring(javaFile.getName().lastIndexOf('.'));
-		Class<?> cls = Class.forName(className, true, classLoader); // Should load the class
+		/**
+		 * ClassLoader to load the compiled class
+		 */
+		URLClassLoader classLoader = URLClassLoader
+				.newInstance(new URL[] { new File("src/").toURI().toURL() });
+
+		/**
+		 * Package name
+		 */
+		String packageName = getJavaPackageName(javaFile);
+		if (packageName != null) {
+			System.out.println("Package: " + packageName);
+			// If packageName is not empty, and dot is required:
+			// "packagePath.ClassName"
+			if (!packageName.isEmpty())
+				packageName += ".";
+		} else {
+			// if package null - try default package
+			packageName = "";
+		}
+		/**
+		 * Name of the Class. File name "ClassName.java"
+		 */
+		String className = javaFile.getName().substring(0,
+				javaFile.getName().lastIndexOf('.'));
 		
+		/**
+		 * Loaded Class
+		 */
+		Class<?> cls = Class
+				.forName(packageName + className, true, classLoader);
+
 		return cls;
-		}catch(Exception e){
-			
+	}
+
+	/**
+	 * Returns the package path of a given Java File. Returns null if the
+	 * exception occurred and returns an empty string if no package declaration
+	 * was found. Package declaration should be in a single line.
+	 * 
+	 * @param javaFile
+	 *            File to be searched for the package path
+	 * @return PackagePath of the JavaFile, EmptyString, if no declaration was
+	 *         found, null on errors
+	 */
+	public static String getJavaPackageName(File javaFile) {
+		/**
+		 * Package name
+		 */
+		String packageName = "";
+		/**
+		 * Reader to read the java File
+		 */
+		BufferedReader reader = null;
+		try {
+			reader = new BufferedReader(new FileReader(javaFile.getPath()));
+			/**
+			 * Current Line which is investigated
+			 */
+			String currentLine = reader.readLine();
+
+			// Search each line until a valid package is found
+			while (currentLine != null) {
+				currentLine = currentLine.trim();
+				if (!currentLine.isEmpty()) {
+					if (currentLine.length() >= 7 && currentLine.startsWith("package")) {
+						packageName = currentLine.substring(8, currentLine.length() - 1);
+					}
+				}
+				if (packageName.isEmpty()) {
+					currentLine = reader.readLine();
+				} else {
+					currentLine = null;
+				}
+			}
+		} catch (Exception e) {
+			try {
+				reader.close();
+			} catch (IOException e1) {
+			}
+			return null;
+		} finally {
+			try {
+				reader.close();
+			} catch (IOException e) {
+			}
 		}
-		return null;
+		// Remove whitespace in cases like "import   test.package  ;"
+		packageName = packageName.trim();
+		return packageName;
 	}
 }