diff --git a/tools/cooja/java/se/sics/cooja/DirectoryClassLoader.java b/tools/cooja/java/se/sics/cooja/DirectoryClassLoader.java deleted file mode 100644 index f9e5bbc10..000000000 --- a/tools/cooja/java/se/sics/cooja/DirectoryClassLoader.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2006, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. 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. - * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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. - * - * $Id: DirectoryClassLoader.java,v 1.1 2006/08/21 12:12:56 fros4943 Exp $ - */ - -package se.sics.cooja; - -import java.io.*; -import org.apache.log4j.Logger; - -/** - * Loads an external file from the given directory as a Java class. - * - * @author Fredrik Osterlind - */ -public class DirectoryClassLoader extends ClassLoader { - private static Logger logger = Logger.getLogger(DirectoryClassLoader.class); - private File directory; - - /** - * Creates a new class loader reading from given directory. - * - * @param directory - * Directory - */ - public DirectoryClassLoader(File directory) { - super(); - this.directory = directory; - } - - /** - * Creates a new class loader reading from given directory, with the given - * class loader as parent class loader. - * - * @param parent - * Parent class loader - * @param directory - * Directory - */ - public DirectoryClassLoader(ClassLoader parent, File directory) { - super(parent); - this.directory = directory; - } - - public Class findClass(String name) throws ClassNotFoundException { - String fullFilePath = directory.getPath() + File.separatorChar + name - + ".class"; - - // Read external file - //logger.info("Directory class loader reading file: " + fullFilePath); - byte[] classData = loadClassData(fullFilePath); - if (classData == null) { - throw new ClassNotFoundException(); - } - - // Create class - return defineClass(name, classData, 0, classData.length); - } - - private byte[] loadClassData(String name) { - // Support for fill class names in configuration file - // TODO Quick-fix (may contain bugs) - name = name.replace('.', File.separatorChar); - name = name.replace(File.separatorChar + "class", ".class"); - - // Open file for read access - File classFile = new File(name); - InputStream inputStream = null; - if (!classFile.exists()) { - //logger.fatal("File " + classFile + " does not exist!"); - return null; - } - - try { - inputStream = new FileInputStream(classFile); - - if (inputStream == null) { - logger.fatal("File input stream is null!"); - return null; - } - } catch (FileNotFoundException e) { - logger.fatal("Could not open file (not found?)!"); - return null; - } - long fileSize = classFile.length(); - - if (fileSize > Integer.MAX_VALUE) { - logger.fatal("Class file is too large"); - return null; - } - - // Read class data - byte[] classData = new byte[(int) fileSize]; - int offset = 0; - int numRead = 0; - try { - while (offset < classData.length - && (numRead = inputStream.read(classData, offset, classData.length - - offset)) >= 0) { - offset += numRead; - } - - inputStream.close(); - } catch (IOException e) { - logger.fatal("Error when reading class file"); - return null; - } - - // Ensure all the bytes have been read in - if (offset < classData.length) { - logger.fatal("Could not read entire class file"); - return null; - } - - return classData; - } -} diff --git a/tools/cooja/java/se/sics/cooja/GUI.java b/tools/cooja/java/se/sics/cooja/GUI.java index 252f34d87..7ee8afd27 100644 --- a/tools/cooja/java/se/sics/cooja/GUI.java +++ b/tools/cooja/java/se/sics/cooja/GUI.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: GUI.java,v 1.3 2006/08/22 12:25:24 nifi Exp $ + * $Id: GUI.java,v 1.4 2006/08/22 15:28:17 fros4943 Exp $ */ package se.sics.cooja; @@ -560,24 +560,15 @@ public class GUI extends JDesktopPane { unregisterPositioners(); unregisterRadioMediums(); - // Read default configuration - platformConfig = new PlatformConfig(); - // logger.info("Loading default platform configuration: " + - // PLATFORM_DEFAULT_CONFIG_FILENAME); try { - InputStream input = - GUI.class.getResourceAsStream(PLATFORM_DEFAULT_CONFIG_FILENAME); - if (input != null) { - try { - platformConfig.appendConfig(input); - } finally { - input.close(); - } - } else { - logger.fatal("Could not find default platform config file: " - + PLATFORM_DEFAULT_CONFIG_FILENAME); - return false; - } + // Read default configuration + platformConfig = new PlatformConfig(true); + // logger.info("Loading default platform configuration: " + + // PLATFORM_DEFAULT_CONFIG_FILENAME); + } catch (FileNotFoundException e) { + logger.fatal("Could not find default platform config file: " + + PLATFORM_DEFAULT_CONFIG_FILENAME); + return false; } catch (IOException e) { logger.fatal("Error when reading default platform config file: " + PLATFORM_DEFAULT_CONFIG_FILENAME); @@ -586,20 +577,18 @@ public class GUI extends JDesktopPane { // Append user platform configurations for (File userPlatform : currentUserPlatforms) { - File userPlatformConfig = new File(userPlatform.getPath() - + File.separatorChar + PLATFORM_CONFIG_FILENAME); - // logger.info("Loading platform configuration: " + userPlatformConfig); try { // Append config to general config - platformConfig.appendConfig(userPlatformConfig); + // logger.info("Appending user platform configuration: " + userPlatform); + platformConfig.appendUserPlatform(userPlatform); } catch (FileNotFoundException e) { logger.fatal("Could not find platform config file: " - + userPlatformConfig); + + userPlatform); return false; } catch (IOException e) { logger.fatal("Error when reading platform config file: " - + userPlatformConfig); + + userPlatform); return false; } } @@ -1556,45 +1545,43 @@ public class GUI extends JDesktopPane { } private ClassLoader createClassLoader(ClassLoader parent, - Vector platformsList) { + Vector platformsList) { if (platformsList == null || platformsList.isEmpty()) { return parent; } - + // Combine class loader from all user platforms (including any // specified JAR files) ArrayList urls = new ArrayList(); for (int j = platformsList.size() - 1; j >= 0; j--) { File userPlatform = platformsList.get(j); try { - urls.add((new File(userPlatform, "java")).toURL()); - - // Read configuration to check if any JAR files should be loaded - File userPlatformConfigFile = - new File(userPlatform, PLATFORM_CONFIG_FILENAME); - PlatformConfig userPlatformConfig = new PlatformConfig(); - userPlatformConfig.appendConfig(userPlatformConfigFile); + urls.add((new File(userPlatform, "java")).toURL()); + + // Read configuration to check if any JAR files should be loaded + PlatformConfig userPlatformConfig = new PlatformConfig(false); + userPlatformConfig.appendUserPlatform(userPlatform); String[] platformJarFiles = userPlatformConfig.getStringArrayValue( GUI.class, "JARFILES"); if (platformJarFiles != null && platformJarFiles.length > 0) { - for (String jarfile : platformJarFiles) { + for (String jarfile : platformJarFiles) { File jarpath = findJarFile(userPlatform, jarfile); - if (jarpath == null) { - throw new FileNotFoundException(jarfile); - } - urls.add(jarpath.toURL()); + if (jarpath == null) { + throw new FileNotFoundException(jarfile); + } + urls.add(jarpath.toURL()); } } - + } catch (Exception e) { logger.fatal("Error when trying to read JAR-file in " + userPlatform + ": " + e); } } return new URLClassLoader((URL[]) urls.toArray(new URL[urls.size()]), - userPlatformClassLoader); + userPlatformClassLoader); } - + /** * Help method that returns the description for given object. This method * reads from the object's class annotations if existing. Otherwise it returns diff --git a/tools/cooja/java/se/sics/cooja/PlatformConfig.java b/tools/cooja/java/se/sics/cooja/PlatformConfig.java index 64cd7156d..7ec6b990e 100644 --- a/tools/cooja/java/se/sics/cooja/PlatformConfig.java +++ b/tools/cooja/java/se/sics/cooja/PlatformConfig.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: PlatformConfig.java,v 1.1 2006/08/21 12:12:56 fros4943 Exp $ + * $Id: PlatformConfig.java,v 1.2 2006/08/22 15:28:17 fros4943 Exp $ */ package se.sics.cooja; @@ -86,13 +86,124 @@ import org.apache.log4j.Logger; public class PlatformConfig { private static Logger logger = Logger.getLogger(PlatformConfig.class); - private Properties myConfig = new Properties(); + private Properties myConfig = null; + private Vector myUserPlatformHistory = null; /** - * Creates a new empty platform configuration. + * Creates new platform configuration. + * + * @param useDefault + * If true the default configuration will be loaded + * @throws FileNotFoundException + * If file was not found + * @throws IOException + * Stream read error */ - public PlatformConfig() { + public PlatformConfig(boolean useDefault) throws IOException, + FileNotFoundException { + // Create empty configuration myConfig = new Properties(); + myUserPlatformHistory = new Vector(); + + if (useDefault) { + InputStream input = GUI.class + .getResourceAsStream(GUI.PLATFORM_DEFAULT_CONFIG_FILENAME); + if (input != null) { + try { + appendConfigStream(input); + } finally { + input.close(); + } + } else { + throw new FileNotFoundException(GUI.PLATFORM_DEFAULT_CONFIG_FILENAME); + } + } + } + + /** + * Appends the given user platform's config file. Thus method also saved a + * local history of which user platforms has been loaded. + * + * @param userPlatform + * User platform + * @return True if loaded OK + * @throws FileNotFoundException + * If file was not found + * @throws IOException + * Stream read error + */ + public boolean appendUserPlatform(File userPlatform) + throws FileNotFoundException, IOException { + File userPlatformConfig = new File(userPlatform.getPath() + + File.separatorChar + GUI.PLATFORM_CONFIG_FILENAME); + myUserPlatformHistory.add(userPlatform); + return appendConfigFile(userPlatformConfig); + } + + + /** + * Returns the user platform earlier appended to this configuration that + * defined the given key. If the key is of an array format and the given array + * element is non-null, then the user platform that added this element will be + * returned instead. If no such user platform can be found null is returned + * instead. + * + * @param callingClass + * Class which value belongs to + * @param key + * Key + * @param value + * Element of array + * @return User platform + */ + public File getUserPlatformDefining(Class callingClass, String key, String arrayElement) { + + // Check that key really exists in current config + if (getStringValue(callingClass, key, null) == null) { + return null; + } + + // Check that element really exists, if any + if (arrayElement != null) { + String[] array = getStringArrayValue(callingClass, key); + boolean foundValue = false; + for (int c=0; c < array.length; c++) { + if (array[c].equals(arrayElement)) + foundValue = true; + } + if (!foundValue) { + return null; + } + } + + // Search in all user platform in reversed order + try { + PlatformConfig remadeConfig = new PlatformConfig(false); + + for (int i=myUserPlatformHistory.size()-1; i >= 0; i--) { + remadeConfig.appendUserPlatform(myUserPlatformHistory.get(i)); + + if (arrayElement != null) { + // Look for array + String[] array = remadeConfig.getStringArrayValue(callingClass, key); + for (int c=0; c < array.length; c++) { + if (array[c].equals(arrayElement)) + return myUserPlatformHistory.get(i); + } + } else { + // Look for key + if (remadeConfig.getStringValue(callingClass, key, null) != null) { + return myUserPlatformHistory.get(i); + } + } + } + + } catch (Exception e) { + logger.fatal("Exception when searching in user platform history: " + e); + return null; + } + + return null; } /** @@ -100,6 +211,9 @@ public class PlatformConfig { * If a property already exists it will be overwritten, unless the new value * begins with a '+' in which case the old value will be extended. * + * WARNING! The user platform history will not be saved if this method is + * called, instead the appendUserPlatform method should be used. + * * @param propertyFile * Property file to read * @return True if file was read ok, false otherwise @@ -108,35 +222,33 @@ public class PlatformConfig { * @throws IOException * Stream read error */ - public boolean appendConfig(File propertyFile) throws FileNotFoundException, - IOException { - return appendConfig(myConfig, propertyFile); - } - - private static boolean appendConfig(Properties currentValues, - File propertyFile) throws FileNotFoundException, IOException { - // Open file + public boolean appendConfigFile(File propertyFile) + throws FileNotFoundException, IOException { FileInputStream in = new FileInputStream(propertyFile); - return appendConfig(currentValues, in); + return appendConfigStream(myConfig, in); } /** - * Reads propertues from the given stream and appends them to the current + * Reads properties from the given stream and appends them to the current * configuration. If a property already exists it will be overwritten, unless * the new value begins with a '+' in which case the old value will be * extended. * + * WARNING! The user platform history will not be saved if this method is + * called, instead the appendUserPlatform method should be used. + * * @param configFileStream * Stream to read from * @return True if stream was read ok, false otherwise * @throws IOException * Stream read error */ - public boolean appendConfig(InputStream configFileStream) throws IOException { - return appendConfig(myConfig, configFileStream); + public boolean appendConfigStream(InputStream configFileStream) + throws IOException { + return appendConfigStream(myConfig, configFileStream); } - private static boolean appendConfig(Properties currentValues, + private static boolean appendConfigStream(Properties currentValues, InputStream configFileStream) throws IOException { // Read from stream @@ -151,7 +263,8 @@ public class PlatformConfig { String property = newProps.getProperty(key); if (property.startsWith("+ ")) { if (currentValues.getProperty(key) != null) - currentValues.setProperty(key, currentValues.getProperty(key) + " " + property.substring(1).trim()); + currentValues.setProperty(key, currentValues.getProperty(key) + " " + + property.substring(1).trim()); else currentValues.setProperty(key, property.substring(1).trim()); } else @@ -189,7 +302,8 @@ public class PlatformConfig { String val = currentValues.getProperty(callingClass.getName() + "." + id); if (val == null) { - logger.warn("Could not find key named '" + callingClass.getName() + "." + id + "'"); + logger.warn("Could not find key named '" + callingClass.getName() + "." + + id + "'"); return defaultValue; } @@ -253,6 +367,21 @@ public class PlatformConfig { return getStringValue(callingClass, id); } + /** + * Get string array value with given id. + * + * @param id + * Id of value to return + * @return Value or null if id wasn't found + */ + public String[] getStringArrayValue(String id) { + String stringVal = getStringValue(id); + if (stringVal == null) + return new String[0]; + + return getStringValue(id).split(" "); + } + /** * Get integer value with given id. * @@ -352,8 +481,13 @@ public class PlatformConfig { } public PlatformConfig clone() { - PlatformConfig clone = new PlatformConfig(); - clone.myConfig = (Properties) this.myConfig.clone(); - return clone; + try { + PlatformConfig clone = new PlatformConfig(false); + clone.myConfig = (Properties) this.myConfig.clone(); + clone.myUserPlatformHistory = (Vector) this.myUserPlatformHistory.clone(); + return clone; + } catch (Exception e) { + return null; + } } } diff --git a/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java b/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java index 667cd97e1..11ad03046 100644 --- a/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java +++ b/tools/cooja/java/se/sics/cooja/contikimote/ContikiMoteTypeDialog.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: ContikiMoteTypeDialog.java,v 1.3 2006/08/22 12:26:36 nifi Exp $ + * $Id: ContikiMoteTypeDialog.java,v 1.4 2006/08/22 15:28:18 fros4943 Exp $ */ package se.sics.cooja.contikimote; @@ -898,8 +898,19 @@ public class ContikiMoteTypeDialog extends JDialog { String[] projectSourceFiles = newMoteTypeConfig.getStringArrayValue( ContikiMoteType.class, "C_SOURCES"); for (String projectSourceFile : projectSourceFiles) { - if (!projectSourceFile.trim().equals("")) { - filesToCompile.add(new File(projectSourceFile)); + if (!projectSourceFile.equals("")) { + File file = new File(projectSourceFile); + if (file.getParent() != null) { + // Find which user platform added this file + File userPlatform = newMoteTypeConfig.getUserPlatformDefining( + ContikiMoteType.class, "C_SOURCES", projectSourceFile); + if (userPlatform != null) { + // We found a user platform - Add directory + filesToCompile.add(new File(userPlatform.getPath(), + file.getParent())); + } + } + filesToCompile.add(new File(file.getName())); } } @@ -1165,16 +1176,20 @@ public class ContikiMoteTypeDialog extends JDialog { String sourceDirs = System.getProperty("PROJECTDIRS", ""); String sourceFileNames = ""; + String ccFlags = GUI.getExternalToolsSetting("COMPILER_ARGS", ""); for (File sourceFile : sourceFiles) { if (sourceFile.isDirectory()) { // Add directory to search path sourceDirs += " " + sourceFile.getPath().replace(File.separatorChar, '/'); + ccFlags += " -I" + sourceFile.getPath().replace(File.separatorChar, '/'); } else if (sourceFile.isFile()) { // Add both file name and directory - sourceDirs += " " + - sourceFile.getParent().replace(File.separatorChar, '/'); + if (sourceFile.getParent() != null) { + sourceDirs += " " + + sourceFile.getParent().replace(File.separatorChar, '/'); + } sourceFileNames += " " + sourceFile.getName(); } else { // Add filename and hope Contiki knows where to find it... @@ -1182,12 +1197,16 @@ public class ContikiMoteTypeDialog extends JDialog { } } + logger.info("Project dirs: " + sourceDirs); + logger.info("Project sources: " + sourceFileNames); + logger.info("Compiler flags: " + ccFlags); + String[] env = new String[]{ "CONTIKI=" + contikiDir.getPath().replace(File.separatorChar, '/'), "TARGET=cooja", "TYPEID=" + identifier, "LD_ARGS_1=" + GUI.getExternalToolsSetting("LINKER_ARGS_1", ""), "LD_ARGS_2=" + GUI.getExternalToolsSetting("LINKER_ARGS_2", ""), - "EXTRA_CC_ARGS=" + GUI.getExternalToolsSetting("COMPILER_ARGS", ""), + "EXTRA_CC_ARGS=" + ccFlags, "CC=" + GUI.getExternalToolsSetting("PATH_C_COMPILER"), "LD=" + GUI.getExternalToolsSetting("PATH_LINKER"), "COMPILE_MAIN=1", "PROJECTDIRS=" + sourceDirs, @@ -2008,18 +2027,12 @@ public class ContikiMoteTypeDialog extends JDialog { // Merge with all user platform configs (if any) for (File userPlatform : moteTypeUserPlatforms) { - File userPlatformConfig = new File(userPlatform.getPath() - + File.separatorChar + GUI.PLATFORM_CONFIG_FILENAME); - if (userPlatformConfig.exists()) { - try { - newMoteTypeConfig.appendConfig(userPlatformConfig); - } catch (Exception ex) { - logger.fatal("Error when parsing user platform config: " + ex); - return; - } - } else - logger.fatal("Could not find user platform config file: " - + userPlatformConfig); + try { + newMoteTypeConfig.appendUserPlatform(userPlatform); + } catch (Exception ex) { + logger.fatal("Error when parsing user platform config: " + ex); + return; + } } // Get all mote interfaces available from config diff --git a/tools/cooja/java/se/sics/cooja/dialogs/UserPlatformsDialog.java b/tools/cooja/java/se/sics/cooja/dialogs/UserPlatformsDialog.java index f474d91b0..1e040fc27 100644 --- a/tools/cooja/java/se/sics/cooja/dialogs/UserPlatformsDialog.java +++ b/tools/cooja/java/se/sics/cooja/dialogs/UserPlatformsDialog.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: UserPlatformsDialog.java,v 1.2 2006/08/22 08:56:08 nifi Exp $ + * $Id: UserPlatformsDialog.java,v 1.3 2006/08/22 15:28:18 fros4943 Exp $ */ package se.sics.cooja.dialogs; @@ -220,22 +220,14 @@ public class UserPlatformsDialog extends JDialog { button = new JButton("View resulting config"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - // Create default configuration - PlatformConfig config = new PlatformConfig(); + PlatformConfig config; try { - InputStream input = - GUI.class.getResourceAsStream(GUI.PLATFORM_DEFAULT_CONFIG_FILENAME); - if (input != null) { - try { - config.appendConfig(input); - } finally { - input.close(); - } - } else { - logger.fatal("Could not find default platform config file1: " - + GUI.PLATFORM_DEFAULT_CONFIG_FILENAME); - return; - } + // Create default configuration + config = new PlatformConfig(true); + } catch (FileNotFoundException ex) { + logger.fatal("Could not find default platform config file: " + + GUI.PLATFORM_DEFAULT_CONFIG_FILENAME); + return; } catch (IOException ex) { logger.fatal("Error when reading default platform config file: " + GUI.PLATFORM_DEFAULT_CONFIG_FILENAME); @@ -245,10 +237,8 @@ public class UserPlatformsDialog extends JDialog { // Add the fixed platform configurations if (fixedPlatformsList != null) { for (String userPlatform : fixedPlatformsList.getItems()) { - File userPlatformConfig = new File(userPlatform + File.separatorChar - + GUI.PLATFORM_CONFIG_FILENAME); try { - config.appendConfig(userPlatformConfig); + config.appendUserPlatform(new File(userPlatform)); } catch (Exception ex) { logger.fatal("Error when merging configurations: " + ex); return; @@ -258,10 +248,8 @@ public class UserPlatformsDialog extends JDialog { // Add the user platform configurations for (String userPlatform : changablePlatformsList.getItems()) { - File userPlatformConfig = new File(userPlatform + File.separatorChar - + GUI.PLATFORM_CONFIG_FILENAME); try { - config.appendConfig(userPlatformConfig); + config.appendUserPlatform(new File(userPlatform)); } catch (Exception ex) { logger.fatal("Error when merging configurations: " + ex); return; @@ -422,7 +410,10 @@ class ConfigViewer extends JDialog { String propertyName = allPropertyNames.nextElement(); keyPane.add(new JLabel(propertyName)); - valuePane.add(new JLabel(config.getStringValue(propertyName))); + if (config.getStringValue(propertyName).equals("")) + valuePane.add(new JLabel(" ")); + else + valuePane.add(new JLabel(config.getStringValue(propertyName))); } // Add components