diff --git a/tools/cooja/java/se/sics/cooja/COOJAProject.java b/tools/cooja/java/se/sics/cooja/COOJAProject.java index 5e303c5a4..685e333d5 100644 --- a/tools/cooja/java/se/sics/cooja/COOJAProject.java +++ b/tools/cooja/java/se/sics/cooja/COOJAProject.java @@ -29,21 +29,62 @@ package se.sics.cooja; import java.io.File; +import java.util.ArrayList; import java.util.Arrays; - +import java.util.Collections; import org.apache.log4j.Logger; /** * COOJA Project. * * @author Fredrik Osterlind + * @author Moritz StrĂ¼be */ public class COOJAProject { private static Logger logger = Logger.getLogger(COOJAProject.class); + + + public static File[] sarchProjects(File folder){ + return sarchProjects(folder, 3); + } + + public static File[] sarchProjects(File folder, int depth){ + if(depth == 0){ + return null; + } + depth--; + ArrayList dirs = new ArrayList(); + + if(!folder.isDirectory()){ + logger.warn("Project directorys: " + folder.getPath() + "is not a Folder" ); + return null; + } + File[] files = folder.listFiles(); + for(File subf : files){ + if(subf.getName().charAt(0) == '.') continue; + if(subf.isDirectory()){ + File[] newf = sarchProjects(subf, depth); + if(newf != null){ + Collections.addAll(dirs, newf); + } + } + if(subf.getName().equals(GUI.PROJECT_CONFIG_FILENAME)){ + try{ + dirs.add(folder); + } catch(Exception e){ + logger.error("Somthing odd happend", e); + } + } + } + return dirs.toArray(new File[0]); + + } + public File dir = null; public File configFile = null; public ProjectConfig config = null; + public COOJAProject(File dir) { try { diff --git a/tools/cooja/java/se/sics/cooja/GUI.java b/tools/cooja/java/se/sics/cooja/GUI.java index d966685b9..12c0d4bab 100644 --- a/tools/cooja/java/se/sics/cooja/GUI.java +++ b/tools/cooja/java/se/sics/cooja/GUI.java @@ -60,13 +60,16 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.StringReader; +import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.net.URL; import java.net.URLClassLoader; import java.security.AccessControlException; import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.Enumeration; import java.util.List; import java.util.Observable; @@ -244,7 +247,8 @@ public class GUI extends Observable { public static Properties currentExternalToolsSettings; private static final String externalToolsSettingNames[] = new String[] { - "PATH_CONTIKI", "PATH_COOJA_CORE_RELATIVE", + "PATH_CONTIKI", "PATH_COOJA_CORE_RELATIVE","PATH_COOJA","PATH_APPS", + "PATH_APPSEARCH", "PATH_MAKE", "PATH_SHELL", @@ -423,6 +427,20 @@ public class GUI extends Observable { currentProjects.add(new COOJAProject(projectDir)); } } + + //Scan for projects + String searchProjectDirs = getExternalToolsSetting("PATH_APPSEARCH", null); + if (searchProjectDirs != null && searchProjectDirs.length() > 0) { + String[] arr = searchProjectDirs.split(";"); + for (String d : arr) { + File searchDir = restorePortablePath(new File(d)); + File[] projects = COOJAProject.sarchProjects(searchDir, 3); + if(projects == null) continue; + for(File p : projects){ + currentProjects.add(new COOJAProject(p)); + } + } + } /* Parse current extension configuration */ try { @@ -2772,11 +2790,7 @@ public class GUI extends Observable { * New value */ public static void setExternalToolsSetting(String name, String newVal) { - if (specifiedContikiPath != null && "PATH_CONTIKI".equals(name)) { - specifiedContikiPath = newVal; - } else { - currentExternalToolsSettings.setProperty(name, newVal); - } + currentExternalToolsSettings.setProperty(name, newVal); } /** @@ -3227,14 +3241,14 @@ public class GUI extends Observable { logger.fatal("Error: " + e.getMessage(), e); System.exit(1); } - sim.setSpeedLimit(null); - sim.startSimulation(); } else { logger.fatal("No test editor controlling simulation, aborting"); System.exit(1); } } - + sim.setSpeedLimit(null); + sim.startSimulation(); + } else if (args.length > 0 && args[0].startsWith("-applet")) { String tmpWebPath=null, tmpBuildPath=null, tmpEsbFirmware=null, tmpSkyFirmware=null; @@ -4122,52 +4136,99 @@ public class GUI extends Observable { return file; } - private final static String PATH_CONTIKI_IDENTIFIER = "[CONTIKI_DIR]"; + private final static String[][] PATH_IDENTIFIER = { + {"[CONTIKI_DIR]","PATH_CONTIKI",""}, + {"[COOJA_DIR]","PATH_COOJA","/tools/cooja"}, + {"[APPS_DIR]","PATH_APPS","/tools/cooja/apps"} + }; + private File createContikiRelativePath(File file) { try { - File contikiPath = new File(GUI.getExternalToolsSetting("PATH_CONTIKI", null)); - String contikiCanonical = contikiPath.getCanonicalPath(); + int elem = PATH_IDENTIFIER.length; + File path[] = new File [elem]; + String canonicals[] = new String[elem]; + int match = -1; + int mlength = 0; + String fileCanonical = file.getCanonicalPath(); + + //No so nice, but goes along with GUI.getExternalToolsSetting + String defp = GUI.getExternalToolsSetting("PATH_CONTIKI", null); + + + for(int i = 0; i < elem; i++){ + path[i] = new File(GUI.getExternalToolsSetting(PATH_IDENTIFIER[i][1], defp + PATH_IDENTIFIER[i][2])); + canonicals[i] = path[i].getCanonicalPath(); + if (fileCanonical.startsWith(canonicals[i])){ + if(mlength < canonicals[i].length()){ + mlength = canonicals[i].length(); + match = i; + } + + } + } + + if(match == -1) return null; - String fileCanonical = file.getCanonicalPath(); - if (!fileCanonical.startsWith(contikiCanonical)) { - /* File is not in a Contiki subdirectory */ - /*logger.info("File is not in a Contiki subdirectory: " + file.getAbsolutePath());*/ - return null; - } - /* Replace Contiki's canonical path with Contiki identifier */ - String portablePath = fileCanonical.replaceFirst( - java.util.regex.Matcher.quoteReplacement(contikiCanonical), - java.util.regex.Matcher.quoteReplacement(PATH_CONTIKI_IDENTIFIER)); - File portable = new File(portablePath); + /* Replace Contiki's canonical path with Contiki identifier */ + String portablePath = fileCanonical.replaceFirst( + java.util.regex.Matcher.quoteReplacement(canonicals[match]), + java.util.regex.Matcher.quoteReplacement(PATH_IDENTIFIER[match][0])); + File portable = new File(portablePath); + + /* Verify conversion */ + File verify = restoreContikiRelativePath(portable); + if (verify == null || !verify.exists()) { + /* Error: did file even exist pre-conversion? */ + return null; + } - /* Verify conversion */ - File verify = restoreContikiRelativePath(portable); - if (verify == null || !verify.exists()) { - /* Error: did file even exist pre-conversion? */ - return null; - } - - return portable; + return portable; } catch (IOException e1) { /*logger.warn("Error when converting to Contiki relative path: " + e1.getMessage());*/ return null; } } + + private File restoreContikiRelativePath(File portable) { + int elem = PATH_IDENTIFIER.length; + File path = null; + String canonical = null; + try { - File contikiPath = new File(GUI.getExternalToolsSetting("PATH_CONTIKI", null)); - String contikiCanonical = contikiPath.getCanonicalPath(); - - String portablePath = portable.getPath(); - if (!portablePath.startsWith(PATH_CONTIKI_IDENTIFIER)) { - return null; - } - - File absolute = new File(portablePath.replace(PATH_CONTIKI_IDENTIFIER, contikiCanonical)); - return absolute; + + String portablePath = portable.getPath(); + + int i = 0; + //logger.info("PPATH: " + portablePath); + + for(; i < elem; i++){ + if (portablePath.startsWith(PATH_IDENTIFIER[i][0])) break; + + } + + + if(i == elem) return null; + //logger.info("Found: " + PATH_IDENTIFIER[i][0]); + + //No so nice, but goes along with GUI.getExternalToolsSetting + String defp = GUI.getExternalToolsSetting("PATH_CONTIKI", null); + path = new File(GUI.getExternalToolsSetting(PATH_IDENTIFIER[i][1], defp + PATH_IDENTIFIER[i][2])); + + //logger.info("Config: " + PATH_IDENTIFIER[i][1] + ", " + defp + PATH_IDENTIFIER[i][2] + " = " + path.toString()); + canonical = path.getCanonicalPath(); + + + File absolute = new File(portablePath.replace(PATH_IDENTIFIER[i][0], canonical)); + if(!absolute.exists()){ + logger.warn("Replaced " + portable + " with " + absolute.toString() + " (default: "+ defp + PATH_IDENTIFIER[i][2] +"), but could not find it. This does not have to be an error, as the file might be created later."); + } + + + return absolute; } catch (IOException e) { - return null; + return null; } } @@ -4623,3 +4684,4 @@ public class GUI extends Observable { }; } + diff --git a/tools/cooja/java/se/sics/cooja/ProjectConfig.java b/tools/cooja/java/se/sics/cooja/ProjectConfig.java index 767ba8922..85a31bf2f 100644 --- a/tools/cooja/java/se/sics/cooja/ProjectConfig.java +++ b/tools/cooja/java/se/sics/cooja/ProjectConfig.java @@ -237,7 +237,7 @@ public class ProjectConfig { public boolean appendConfigFile(File propertyFile) throws FileNotFoundException, IOException { if (!propertyFile.exists()) { - logger.warn("Trying to import non-existant project configuration"); + logger.warn("Trying to import non-existant project configuration: " + propertyFile.toString()); return true; } diff --git a/tools/cooja/java/se/sics/cooja/Simulation.java b/tools/cooja/java/se/sics/cooja/Simulation.java index 3e76cbde7..71c5bfc86 100644 --- a/tools/cooja/java/se/sics/cooja/Simulation.java +++ b/tools/cooja/java/se/sics/cooja/Simulation.java @@ -59,7 +59,8 @@ public class Simulation extends Observable implements Runnable { /*private static long EVENT_COUNTER = 0;*/ private Vector motes = new Vector(); - + private Vector motesUninit = new Vector(); + private Vector moteTypes = new Vector(); /* If true, run simulation at full speed */ @@ -819,6 +820,7 @@ public class Simulation extends Observable implements Runnable { } motes.add(mote); + motesUninit.remove(mote); currentRadioMedium.registerMote(mote, Simulation.this); /* Notify mote interfaces that node was added */ @@ -838,6 +840,9 @@ public class Simulation extends Observable implements Runnable { /* Add mote from simulation thread */ invokeSimulationThread(addMote); } + //Add to list of uninitialized motes + motesUninit.add(mote); + } /** @@ -868,6 +873,24 @@ public class Simulation extends Observable implements Runnable { return null; } + /** + * Returns uninitialised simulation mote with with given ID. + * + * @param id ID + * @return Mote or null + * @see Mote#getID() + */ + public Mote getMoteWithIDUninit(int id) { + for (Mote m: motesUninit) { + if (m.getID() == id) { + return m; + } + } + return null; + } + + + /** * Returns number of motes in this simulation. * @@ -888,6 +911,16 @@ public class Simulation extends Observable implements Runnable { return arr; } + /** + * Returns uninitialised motes + * + * @return Motes + */ + public Mote[] getMotesUninit() { + return motesUninit.toArray(new Mote[motesUninit.size()]); + } + + /** * Returns all mote types in simulation. * @@ -1071,9 +1104,6 @@ public class Simulation extends Observable implements Runnable { * @return True if simulation is runnable */ public boolean isRunnable() { - if (motes.isEmpty()) { - return false; - } return isRunning || hasPollRequests || eventQueue.peekFirst() != null; } diff --git a/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java b/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java index c70f35fa0..15719b005 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java +++ b/tools/cooja/java/se/sics/cooja/plugins/LogScriptEngine.java @@ -339,6 +339,7 @@ public class LogScriptEngine { engine.put("global", hash); engine.put("sim", simulation); engine.put("gui", simulation.getGUI()); + engine.put("msg", new String("")); scriptMote = new ScriptMote(); engine.put("node", scriptMote); diff --git a/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java b/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java index 93e5e7fb4..fd3084e7d 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java +++ b/tools/cooja/java/se/sics/cooja/plugins/ScriptRunner.java @@ -672,8 +672,6 @@ public class ScriptRunner extends VisPlugin { } catch (Exception e) { logger.fatal("Error: " + e.getMessage(), e); } - simulation.setSpeedLimit(null); - simulation.startSimulation(); } return true; }