From: <cr...@us...> - 2008-08-24 05:36:32
|
Revision: 4488 http://jnode.svn.sourceforge.net/jnode/?rev=4488&view=rev Author: crawley Date: 2008-08-24 05:36:29 +0000 (Sun, 24 Aug 2008) Log Message: ----------- Change Emu to use the 'alias' and 'syntax' extension points in selected plugin descriptors, rather than relying on hard wired aliases (and no syntax). Modified Paths: -------------- trunk/distr/src/emu/org/jnode/emu/EditEmu.java trunk/distr/src/emu/org/jnode/emu/Emu.java trunk/distr/src/emu/org/jnode/emu/ShellEmu.java trunk/shell/src/shell/org/jnode/shell/syntax/DefaultSyntaxManager.java trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxManager.java trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java Added Paths: ----------- trunk/distr/src/emu/org/jnode/emu/EmuException.java Modified: trunk/distr/src/emu/org/jnode/emu/EditEmu.java =================================================================== --- trunk/distr/src/emu/org/jnode/emu/EditEmu.java 2008-08-23 21:51:35 UTC (rev 4487) +++ trunk/distr/src/emu/org/jnode/emu/EditEmu.java 2008-08-24 05:36:29 UTC (rev 4488) @@ -11,14 +11,13 @@ */ public class EditEmu extends Emu { public static void main(String[] argv) throws Exception { - initEnv(); - - - if (argv.length == 0) { - System.out.println("No file specified"); + if (argv.length == 0 || argv[0].startsWith("-")) { + System.err.println("Usage: editEmu <file> [<jnode-home>]"); return; } + initEnv(argv.length > 1 ? new File(argv[1]) : null); + SwingTextScreenConsoleManager cm = new SwingTextScreenConsoleManager(); final TextScreenConsole console = cm.createConsole( null, Modified: trunk/distr/src/emu/org/jnode/emu/Emu.java =================================================================== --- trunk/distr/src/emu/org/jnode/emu/Emu.java 2008-08-23 21:51:35 UTC (rev 4487) +++ trunk/distr/src/emu/org/jnode/emu/Emu.java 2008-08-24 05:36:29 UTC (rev 4488) @@ -1,16 +1,29 @@ package org.jnode.emu; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.naming.NameAlreadyBoundException; import javax.naming.NameNotFoundException; import javax.naming.NamingException; + +import org.apache.log4j.Priority; import org.jnode.naming.InitialNaming; import org.jnode.naming.NameSpace; +import org.jnode.nanoxml.XMLElement; +import org.jnode.plugin.ConfigurationElement; import org.jnode.shell.ShellManager; +import org.jnode.shell.syntax.PluginSyntaxSpecAdapter; +import org.jnode.shell.syntax.SyntaxBundle; import org.jnode.shell.syntax.SyntaxManager; import org.jnode.shell.syntax.DefaultSyntaxManager; +import org.jnode.shell.syntax.SyntaxSpecAdapter; +import org.jnode.shell.syntax.SyntaxSpecLoader; +import org.jnode.shell.syntax.XMLSyntaxSpecAdapter; import org.jnode.shell.alias.AliasManager; import org.jnode.shell.alias.def.DefaultAliasManager; import org.jnode.shell.def.DefaultShellManager; @@ -19,10 +32,33 @@ /** * @author Levente S\u00e1ntha + * @author Stephen Crawley */ -public class Emu { - protected static void initEnv() throws NamingException { +public abstract class Emu { + private static final String[] ALL_PROJECTS = new String[] { + "core", "distr", "fs", "gui", "net", "shell", "sound", "textui" + }; + + private static final String[] PLUGIN_NAMES = new String[] { + "org.jnode.shell.command", + "org.jnode.shell.command.driver.console", + "org.jnode.apps.editor", + "org.jnode.apps.edit", + "org.jnode.apps.console", + }; + + /** + * Initialize a minimal subset of JNode services to allow us to run JNode commands. + * + * @param root the notional JNode sandbox root directory or <code>null</code>. + * @throws EmuException + */ + protected static void initEnv(File root) throws EmuException { if (true) { + if (root == null) { + root = new File("").getAbsoluteFile(); + System.err.println("Assuming that the JNode root is '" + root + "'"); + } InitialNaming.setNameSpace(new NameSpace() { private Map<Class<?>, Object> space = new HashMap<Class<?>, Object>(); @@ -45,20 +81,145 @@ return space.keySet(); } }); + + try { InitialNaming.bind(DeviceManager.NAME, DeviceManager.INSTANCE); - AliasManager alias_mgr = new DefaultAliasManager(new DummyExtensionPoint()).createAliasManager(); - alias_mgr.add("console", "org.jnode.shell.command.driver.console.ConsoleCommand"); - alias_mgr.add("help", "org.jnode.shell.command.HelpCommand"); - alias_mgr.add("alias", "org.jnode.shell.command.AliasCommand"); - alias_mgr.add("exit", "org.jnode.shell.command.ExitCommand"); - alias_mgr.add("edit", "org.jnode.apps.edit.EditCommand"); - alias_mgr.add("leed", "org.jnode.apps.editor.LeedCommand"); - alias_mgr.add("sconsole", "org.jnode.apps.console.SwingConsole"); + AliasManager aliasMgr = + new DefaultAliasManager(new DummyExtensionPoint()).createAliasManager(); + SyntaxManager syntaxMgr = + new DefaultSyntaxManager(new DummyExtensionPoint()).createSyntaxManager(); + for (String pluginName : PLUGIN_NAMES) { + configurePluginCommands(root, pluginName, aliasMgr, syntaxMgr); + } System.setProperty("jnode.invoker", "default"); - InitialNaming.bind(AliasManager.NAME, alias_mgr); + InitialNaming.bind(AliasManager.NAME, aliasMgr); InitialNaming.bind(ShellManager.NAME, new DefaultShellManager()); - InitialNaming.bind(SyntaxManager.NAME, new DefaultSyntaxManager(new DummyExtensionPoint())); + InitialNaming.bind(SyntaxManager.NAME, syntaxMgr); InitialNaming.bind(Help.NAME, new DefaultHelp()); + } catch (NamingException ex) { + throw new EmuException("Problem setting up InitialNaming bindings", ex); + } } } + + /** + * Configure any command classes specified by a given plugin's descriptor + * @param root the root directory for the JNode sandbox. + * @param pluginName the plugin to be processed + * @param aliasMgr the alias manager to be populated + * @param syntaxMgr the syntax manager to be populated + * @throws EmuException + */ + private static void configurePluginCommands(File root, String pluginName, AliasManager aliasMgr, + SyntaxManager syntaxMgr) throws EmuException { + XMLElement pluginDescriptor = loadPluginDescriptor(root, pluginName); + extractAliases(pluginDescriptor, aliasMgr); + extractSyntaxBundles(pluginDescriptor, syntaxMgr); + } + + /** + * Populate the supplied syntax manager with syntax entries from a plugin descriptor. + * @param pluginDescriptor the plugin descriptor's root XML element + * @param syntaxMgr the syntax manager to be populated. + * @throws EmuException + */ + private static void extractSyntaxBundles(XMLElement pluginDescriptor, SyntaxManager syntaxMgr) + throws EmuException { + XMLElement syntaxesDescriptor = findExtension(pluginDescriptor, SyntaxManager.SYNTAXES_EP_NAME); + if (syntaxesDescriptor == null) { + return; + } + SyntaxSpecLoader loader = new SyntaxSpecLoader(); + for (XMLElement syntaxDescriptor : syntaxesDescriptor.getChildren()) { + if (!syntaxDescriptor.getName().equals("syntax")) { + continue; + } + SyntaxSpecAdapter adaptedElement = new XMLSyntaxSpecAdapter(syntaxDescriptor); + try { + SyntaxBundle bundle = loader.loadSyntax(adaptedElement); + if (bundle != null) { + syntaxMgr.add(bundle); + } + } catch (Exception ex) { + throw new EmuException("problem in syntax", ex); + } + } + } + + /** + * Populate the supplied alias manager with aliases from a plugin descriptor. + * @param pluginDescriptor the plugin descriptor's root XML element + * @param aliasMgr the alias manager to be populated. + * @throws EmuException + */ + private static void extractAliases(XMLElement pluginDescriptor, AliasManager aliasMgr) { + XMLElement aliasesDescriptor = findExtension(pluginDescriptor, AliasManager.ALIASES_EP_NAME); + if (aliasesDescriptor == null) { + return; + } + for (XMLElement aliasDescriptor : aliasesDescriptor.getChildren()) { + if (aliasDescriptor.getName().equals("alias")) { + String alias = aliasDescriptor.getStringAttribute("name"); + String className = aliasDescriptor.getStringAttribute("class"); + aliasMgr.add(alias, className); + } + } + } + + /** + * Locate the descriptor for a given extension point. + * @param pluginDescriptor the plugin descriptor + * @param epName the extension point's name + * @return + */ + private static XMLElement findExtension(XMLElement pluginDescriptor, String epName) { + for (XMLElement child : pluginDescriptor.getChildren()) { + if (child.getName().equals("extension") && + epName.equals(child.getStringAttribute("point"))) { + return child; + } + } + return null; + } + + /** + * Locate and load a plugin descriptor. We search the "descriptors" directory of + * each of the projects listed in ALL_PROJECTS + * @param root the notional root directory for the user's JNode sandbox. + * @param pluginName the name of the plugin we're trying to locate + * @return the loaded plugin descriptor or <code>null</code> + * @throws EmuException + */ + private static XMLElement loadPluginDescriptor(File root, String pluginName) + throws EmuException { + File file = null; + for (String projectName : ALL_PROJECTS) { + file = new File(new File(new File(root, projectName), "descriptors"), pluginName + ".xml"); + if (file.exists()) { + break; + } + } + if (!file.exists()) { + throw new EmuException("Cannot find plugin descriptor file for '" + + pluginName + "': " + file.getAbsolutePath()); + } + BufferedReader br = null; + try { + XMLElement elem = new XMLElement(); + br = new BufferedReader(new FileReader(file)); + elem.parseFromReader(br); + if (!elem.getName().equals("plugin")) { + throw new EmuException("File does not contain a 'plugin' descriptor: " + file); + } + return elem; + } catch (IOException ex) { + throw new EmuException("Problem reading / parsing plugin descriptor file " + file, ex); + } finally { + try { + br.close(); + } catch (IOException ex) { + // ignore + } + } + } } Added: trunk/distr/src/emu/org/jnode/emu/EmuException.java =================================================================== --- trunk/distr/src/emu/org/jnode/emu/EmuException.java (rev 0) +++ trunk/distr/src/emu/org/jnode/emu/EmuException.java 2008-08-24 05:36:29 UTC (rev 4488) @@ -0,0 +1,12 @@ +package org.jnode.emu; + +public class EmuException extends Exception { + + public EmuException(String message) { + super(message); + } + + public EmuException(String message, Throwable cause) { + super(message, cause); + } +} Modified: trunk/distr/src/emu/org/jnode/emu/ShellEmu.java =================================================================== --- trunk/distr/src/emu/org/jnode/emu/ShellEmu.java 2008-08-23 21:51:35 UTC (rev 4487) +++ trunk/distr/src/emu/org/jnode/emu/ShellEmu.java 2008-08-24 05:36:29 UTC (rev 4488) @@ -1,5 +1,7 @@ package org.jnode.emu; +import java.io.File; + import org.jnode.driver.console.ConsoleManager; import org.jnode.driver.console.swing.SwingTextScreenConsoleManager; import org.jnode.shell.CommandShell; @@ -10,7 +12,11 @@ public class ShellEmu extends Emu { public static void main(String[] argv) throws Exception { - initEnv(); + if (argv.length > 0 && argv[0].startsWith("-")) { + System.err.println("Usage: shellemu [<jnode-home>]"); + return; + } + initEnv(argv.length > 0 ? new File(argv[0]) : null); SwingTextScreenConsoleManager cm = new SwingTextScreenConsoleManager(); new Thread(new CommandShell(cm.createConsole( "Console 1", Modified: trunk/shell/src/shell/org/jnode/shell/syntax/DefaultSyntaxManager.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/syntax/DefaultSyntaxManager.java 2008-08-23 21:51:35 UTC (rev 4487) +++ trunk/shell/src/shell/org/jnode/shell/syntax/DefaultSyntaxManager.java 2008-08-24 05:36:29 UTC (rev 4488) @@ -115,17 +115,12 @@ System.out.println("Refreshing syntax list"); if (syntaxEP != null) { syntaxes.clear(); - final Extension[] extensions = syntaxEP.getExtensions(); - for (int i = 0; i < extensions.length; i++) { - final Extension ext = extensions[i]; - final ConfigurationElement[] elements = - ext.getConfigurationElements(); + for (Extension ext : syntaxEP.getExtensions()) { SyntaxSpecLoader loader = new SyntaxSpecLoader(); - - for (int j = 0; j < elements.length; j++) { - SyntaxSpecAdapter element = new PluginSyntaxSpecAdapter(elements[j]); + for (ConfigurationElement element : ext.getConfigurationElements()) { + SyntaxSpecAdapter adaptedElement = new PluginSyntaxSpecAdapter(element); try { - SyntaxBundle bundle = loader.loadSyntax(element); + SyntaxBundle bundle = loader.loadSyntax(adaptedElement); if (bundle != null) { syntaxes.put(bundle.getAlias(), bundle); } Modified: trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxManager.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxManager.java 2008-08-23 21:51:35 UTC (rev 4487) +++ trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxManager.java 2008-08-24 05:36:29 UTC (rev 4488) @@ -36,7 +36,7 @@ */ public static final Class<SyntaxManager> NAME = SyntaxManager.class; - public static final String ALIASES_EP_NAME = "org.jnode.shell.syntaxes"; + public static final String SYNTAXES_EP_NAME = "org.jnode.shell.syntaxes"; /** * Add a syntax bundle Modified: trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java =================================================================== --- trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java 2008-08-23 21:51:35 UTC (rev 4487) +++ trunk/shell/src/shell/org/jnode/shell/syntax/SyntaxSpecLoader.java 2008-08-24 05:36:29 UTC (rev 4488) @@ -120,14 +120,14 @@ return new RepeatSyntax(label, childSyntax, minCount, maxCount, description); } else if (kind.equals("sequence")) { int nos = syntaxElement.getNosChildren(); - Syntax[] seq = new OptionSyntax[nos]; + Syntax[] seq = new Syntax[nos]; for (int i = 0; i < nos; i++) { seq[i] = doLoad(syntaxElement.getChild(i)); } return new SequenceSyntax(label, description, seq); } else if (kind.equals("optional")) { int nos = syntaxElement.getNosChildren(); - Syntax[] seq = new OptionSyntax[nos]; + Syntax[] seq = new Syntax[nos]; for (int i = 0; i < nos; i++) { seq[i] = doLoad(syntaxElement.getChild(i)); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |