Package henplus.commands

Source Code of henplus.commands.PluginCommand

/*
* This is free software, licensed under the Gnu Public License (GPL) get a copy from <http://www.gnu.org/licenses/gpl.html> $Id:
* PluginCommand.java,v 1.8 2005-11-27 16:20:28 hzeller Exp $ author: Henner Zeller <H.Zeller@acm.org>
*/
package henplus.commands;

import henplus.AbstractCommand;
import henplus.Command;
import henplus.CommandDispatcher;
import henplus.HenPlus;
import henplus.SQLSession;
import henplus.io.ConfigurationContainer;
import henplus.view.Column;
import henplus.view.ColumnMetaData;
import henplus.view.TableRenderer;
import henplus.view.util.SortedMatchIterator;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.StringTokenizer;
import java.util.TreeMap;

/**
* A Command that handles Plugins.
*/
public final class PluginCommand extends AbstractCommand {

    private static final String PLUGINS_FILENAME = "plugins";
    private static final ColumnMetaData[] DRV_META;
    static {
        DRV_META = new ColumnMetaData[2];
        DRV_META[0] = new ColumnMetaData("plugin class");
        DRV_META[1] = new ColumnMetaData("commands");
    }

    private final SortedMap<String,Command>/* <ClassName-String,Command-Class> */_plugins;
    private final HenPlus _henplus;
    private final ConfigurationContainer _config;

    /**
     * returns the command-strings this command can handle.
     */
    @Override
    public String[] getCommandList() {
        return new String[] { "list-plugins", "plug-in", "plug-out" };
    }

    public PluginCommand(final HenPlus henplus) {
        _henplus = henplus;
        _plugins = new TreeMap<String, Command>();
        _config = henplus.createConfigurationContainer(PLUGINS_FILENAME);
    }

    /**
     * initial load of plugins.
     */
    public void load() {
        _config.read(new ConfigurationContainer.ReadAction() {

            @Override
            public void readConfiguration(final InputStream inStream) throws Exception {
                if (inStream == null) {
                    return;
                }
                final BufferedReader in = new BufferedReader(new InputStreamReader(inStream, "UTF-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    line = line.trim();
                    if (line.length() == 0) {
                        continue;
                    }
                    Command plugin = null;
                    try {
                        plugin = loadPlugin(line);
                    } catch (final Exception e) {
                        HenPlus.msg().println("couldn't load plugin '" + line + "' " + e.getMessage());
                    }
                    _plugins.put(line, plugin);
                }
                in.close();
            }
        });
    }

    @Override
    public boolean requiresValidSession(final String cmd) {
        return false;
    }

    /**
     * load a plugin and register it at HenPlus.
     */
    private Command loadPlugin(final String className) throws ClassNotFoundException, ClassCastException, InstantiationException,
            IllegalAccessException {
        Command plugin = null;
        final Class<?> pluginClass = Class.forName(className);
        plugin = (Command) pluginClass.newInstance();
        _henplus.getDispatcher().register(plugin);
        return plugin;
    }

    /**
     * execute the command given.
     */
    @Override
    public int execute(final SQLSession currentSession, final String cmd, final String param) {
        final StringTokenizer st = new StringTokenizer(param);
        final int argc = st.countTokens();

        if ("list-plugins".equals(cmd)) {
            if (argc != 0) {
                return SYNTAX_ERROR;
            }
            HenPlus.msg().println("loaded plugins are marked with '*'");
            DRV_META[0].resetWidth();
            DRV_META[1].resetWidth();
            final TableRenderer table = new TableRenderer(DRV_META, HenPlus.out());
            for (Entry<String,Command> entry : _plugins.entrySet()) {
                final Column[] row = new Column[2];
                final Command c = entry.getValue();
                final String clsName = entry.getKey();
                row[0] = new Column((c != null ? "* " : "  ") + clsName);
                if (c != null) {
                    final StringBuilder cmds = new StringBuilder();
                    final String[] cmdList = c.getCommandList();
                    for (int i = 0; i < cmdList.length; ++i) {
                        cmds.append(cmdList[i]).append("\n");
                    }
                    row[1] = new Column(cmds.toString().trim());
                } else {
                    row[1] = new Column(null);
                }
                table.addRow(row);
            }
            table.closeTable();
            return SUCCESS;
        } else if ("plug-in".equals(cmd)) {
            if (argc != 1) {
                return SYNTAX_ERROR;
            }
            final String pluginClass = (String) st.nextElement();
            if (_plugins.containsKey(pluginClass)) {
                HenPlus.msg().println("plugin '" + pluginClass + "' already loaded");
                return EXEC_FAILED;
            }
            Command plugin = null;
            try {
                plugin = loadPlugin(pluginClass);
            } catch (final Exception e) {
                HenPlus.msg().println("couldn't load plugin: " + e.getMessage());
                return EXEC_FAILED;
            }
            if (plugin != null) {
                _plugins.put(pluginClass, plugin);
                final String[] cmds = plugin.getCommandList();
                HenPlus.out().print("adding commands: ");
                for (int i = 0; i < cmds.length; ++i) {
                    if (i != 0) {
                        HenPlus.out().print(", ");
                    }
                    HenPlus.out().print(cmds[i]);
                }
                HenPlus.out().println();
            }
        } else if ("plug-out".equals(cmd)) {
            if (argc != 1) {
                return SYNTAX_ERROR;
            }
            final String pluginClass = (String) st.nextElement();
            if (!_plugins.containsKey(pluginClass)) {
                HenPlus.msg().println("unknown plugin '" + pluginClass + "'");
                return EXEC_FAILED;
            } else {
                final Command c = _plugins.remove(pluginClass);
                _henplus.getDispatcher().unregister(c);
            }
        }
        return SUCCESS;
    }

    @Override
    public Iterator<String> complete(final CommandDispatcher disp, final String partialCommand, final String lastWord) {
        final StringTokenizer st = new StringTokenizer(partialCommand);
        final String cmd = (String) st.nextElement();
        final int argc = st.countTokens();
        // list-plugins gets no names.
        if ("list-plugins".equals(cmd)) {
            return null;
        }
        // do not complete beyond first word.
        if (argc > ("".equals(lastWord) ? 0 : 1)) {
            return null;
        }
        return new SortedMatchIterator(lastWord, _plugins);
    }

    @Override
    public void shutdown() {
        _config.write(new ConfigurationContainer.WriteAction() {

            @Override
            public void writeConfiguration(final OutputStream outStream) throws Exception {
                final PrintWriter out = new PrintWriter(new OutputStreamWriter(outStream, "UTF-8"));
                for (String s : _plugins.keySet()) {
                    out.println(s);
                }
                out.close();
            }
        });
    }

    /**
     * return a descriptive string.
     */
    @Override
    public String getShortDescription() {
        return "handle Plugins";
    }

    @Override
    public String getSynopsis(final String cmd) {
        if ("list-plugins".equals(cmd)) {
            return cmd;
        }
        return cmd + " <plugin-class>";
    }

    @Override
    public String getLongDescription(final String cmd) {
        String dsc = null;
        if ("plug-in".equals(cmd)) {
            dsc = "\tLoad plugin. This command takes as argument the name of\n"
                    + "\tthe  class  that  implements  the  plugin, that is then\n"
                    + "\tloaded from your classpath. The plugin then behaves like\n"
                    + "\tany other built-in command (including help and completion).\n\n"
                    + "\tWriting a  plugin is  simple: Just  write a  class that\n"
                    + "\timplements the well documented henplus.Command interface.\n"
                    + "\tYou can just simply derive from henplus.AbstractCommand\n"
                    + "\tthat already implements the default behaviour. An example\n"
                    + "\tof a plugin is the henplus.SamplePlugin that does nothing\n" + "\tbut shows how it works; try it:\n\n"
                    + "\tplug-in henplus.SamplePlugin\n\n" + "\tOn exit of HenPlus, all names of the plugin-classes are\n"
                    + "\tstored, so that  they are automatically  loaded on next\n" + "\tstartup.";
        } else if ("plug-out".equals(cmd)) {
            dsc = "\tUnload plugin. Unload a previously loaded plugin. This\n"
                    + "\tcommand provides completion for the class name.\n";
        } else if ("list-plugins".equals(cmd)) {
            dsc = "\tList the plugins loaded. The plugins, that are actually\n"
                    + "\tloaded have a little star (*) in the first column. If it\n"
                    + "\tis not loaded, then you have to extend your CLASSPATH to\n" + "\taccess the plugins class.";
        }
        return dsc;
    }
}

/*
* Local variables: c-basic-offset: 4 compile-command:
* "ant -emacs -find build.xml" End:
*/ 
TOP

Related Classes of henplus.commands.PluginCommand

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.