Package org.knopflerfish.bundle.console

Source Code of org.knopflerfish.bundle.console.SessionImpl

/*
* Copyright (c) 2003, KNOPFLERFISH project
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above copyright
*   notice, this list of conditions and the following disclaimer.
*
* - 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.
*
* - Neither the name of the KNOPFLERFISH project 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 COPYRIGHT HOLDERS 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
* COPYRIGHT OWNER 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.
*/

package org.knopflerfish.bundle.console;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.StreamTokenizer;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import org.knopflerfish.service.console.Session;
import org.knopflerfish.service.console.SessionListener;
import org.osgi.framework.BundleContext;

/**
* Implementation of the service interface ConsoleService.
*
* @see org.knopflerfish.service.console.ConsoleService
* @author Jan Stein
*/
public class SessionImpl extends Thread implements Session {

    final static String ALIAS_SAVE = "aliases";

    final BundleContext bc;

    private Dictionary properties = new Hashtable();

    Vector listeners = new Vector();

    Vector cmdline = new Vector();

    String currentGroup = "";

    String prompt = "%> ";

    String name = "UNKNOWN";

    boolean closed = false;

    boolean stopped = false;

    StreamTokenizer cmd;

    Reader in;

    PrintWriter out;

    Alias aliases;

    ReadThread readT;

    public SessionImpl(BundleContext bcontext, String name, Reader in,
            PrintWriter out, Alias aliases) {
        super(name);
        this.bc = bcontext;
        this.out = out;
        this.readT = new ReadThread(in, this);
        this.in = readT.getReader();
        this.cmd = setupTokenizer(this.in);

        if (aliases != null) {
            this.aliases = aliases;
        } else {
            this.aliases = new Alias();
            this.aliases.setDefault();
        }

        Activator.sessions.add(this);
        /*
         * AccessController.doPrivileged( new PrivilegedAction() { public Object
         * run() { File as = bc.getDataFile(ALIAS_SAVE); if (as.exists()) { try {
         * aliases.restore(new FileReader(as)); return null; } catch
         * (IOException e) { // NYI! log failure } } aliases.setDefault();
         * return null; } });
         */
    }

    // Called when the console bundle is stopped.
    void bundleStopped()
    {
        Activator.sessions.remove(this);
        stopped = true;
        this.interrupt();
    }


    //
    // Session implementation
    //

    /**
     * Abort current command in session
     *
     */
    public void abortCommand() {
        if (closed) {
            throw new IllegalStateException("Session is closed");
        }
        synchronized (cmdline) {
            for (Enumeration e = cmdline.elements(); e.hasMoreElements();) {
                Command c = (Command) e.nextElement();
                if (c.thread != null) {
                    c.thread.interrupt();
                }
            }
        }
    }

    /**
     * Get escape character.
     *
     * @return Current escape character
     */
    public char getEscapeChar() {
        if (closed) {
            throw new IllegalStateException("Session is closed");
        }
        return readT.escapeChar;
    }

    /**
     * Set escape character.
     *
     * @param ch
     *            New escape character
     */
    public void setEscapeChar(char ch) {
        if (closed) {
            throw new IllegalStateException("Session is closed");
        }
        readT.escapeChar = ch;
    }

    /**
     * Get interrupt string.
     *
     * @return Current interrupt string
     */
    public String getInterruptString() {
        if (closed) {
            throw new IllegalStateException("Session is closed");
        }
        return readT.interruptString;
    }

    /**
     * Set interrupt string.
     *
     * @param str
     *            New interrupt string
     */
    public void setInterruptString(String str) {
        if (closed) {
            throw new IllegalStateException("Session is closed");
        }
        readT.interruptString = str;
    }

    /**
     * Close session
     *
     */
    public void close() {
        if (closed) {
            return;
        }
        readT.close();
        abortCommand();
        closed = true;
        try {
            readT.join(2000);
        } catch (InterruptedException ignore) {
        }
        if (readT.isAlive()) {
            // TBD log error, readT.stop();
        }
        for (Enumeration e = listeners.elements(); e.hasMoreElements();) {
            SessionListener l = (SessionListener) e.nextElement();
            l.sessionEnd(this);
        }
    }

    /**
     * Add session event listener.
     *
     * @param l
     *            Session listener
     */
    public void addSessionListener(SessionListener l) {
        if (closed) {
            throw new IllegalStateException("Session is closed");
        }
        listeners.addElement(l);
    }

    /**
     * Remove session event listener.
     *
     * @param l
     *            Session listener
     */
    public void removeSessionListener(SessionListener l) {
        if (closed) {
            throw new IllegalStateException("Session is closed");
        }
        listeners.removeElement(l);
    }

    /**
     * Returns the property information tied to this session.
     *
     * @return Property Dictionary.
     */
    public Dictionary getProperties() {
        return properties;
    }

    //
    // Main Thread
    //

    /**
     * Run command dispatcher thread
     *
     */
    public void run() {
        readT.start();
        while (!stopped) {
            cmdline.removeAllElements();
            Command c = null;
            if (prompt != null) {
                int i = prompt.indexOf('%');
                if (i != -1) {
                    out.print(prompt.substring(0, i) + currentGroup
                            + prompt.substring(i + 1));
                } else {
                    out.print(prompt);
                }
                out.flush();
            }
            try {
                while (cmd.nextToken() != StreamTokenizer.TT_EOF
                        && cmd.ttype != StreamTokenizer.TT_EOL) {
                    cmd.pushBack();
                    if (c != null && c.isPiped) {
                        c = new Command(bc, currentGroup, aliases, cmd,
                                ((Pipe) c.out).getReader(), out, this);
                    } else {
                        c = new Command(bc, currentGroup, aliases, cmd, in,
                                out, this);
                    }
                    cmdline.addElement(c);
                }
            } catch (IOException e) {
                out.println("ERROR: " + e.getMessage());
                try {
                    while (cmd.ttype != StreamTokenizer.TT_EOF
                            && cmd.ttype != StreamTokenizer.TT_EOL) {
                        cmd.nextToken();
                    }
                } catch (IOException ignore) {
                    break;
                }
                cmdline.removeAllElements();
            }
            if (cmd.ttype == StreamTokenizer.TT_EOF) {
                break;
            }
            if (cmdline.size() > 0) {
                if (!c.isPiped) {
                    int first = 0;
                    for (int i = 0; i < cmdline.size(); i++) {
                        c = (Command) cmdline.elementAt(i);
                        c.runThreaded();
                        if (c.isPiped) {
                            continue;
                        }
                        if (c.isBackground) {
                            // Need to close input for this command chain
                            Command f = (Command) cmdline.elementAt(first);
                            f.in = null;
                            first = i + 1;
                            continue;
                        }
                        try {
                            for (int j = first; j <= i; j++) {
                                c.thread.join();
                            }
                        } catch (InterruptedException e) {
                            // TODO: cleanup
                        }
                        first = i + 1;
                    }
                } else {
                    out.println("ERROR: Ends with pipe without command!");
                }
            }
        }
        close();
    }

    //
    // Private utility methods
    //

    /**
     * Setup a tokenizer with following properties:
     *
     * @param in
     *            Input reader
     * @return Configured StreamTokenizer
     */
    static StreamTokenizer setupTokenizer(Reader in) {
        StreamTokenizer st = new StreamTokenizer(in);
        st.resetSyntax();
        st.whitespaceChars(0, ' ');
        // '!' token
        st.quoteChar('"');
        st.commentChar('#');
        // '$' token
        st.wordChars('%', '%');
        // '&' token
        st.quoteChar('\'');
        st.wordChars('(', ':');
        // '<' token
        st.wordChars('=', '=');
        // '>' token
        st.wordChars('?', '{');
        // '|' token
        st.wordChars('}', 255);
        st.eolIsSignificant(true);
        return st;
    }

}
TOP

Related Classes of org.knopflerfish.bundle.console.SessionImpl

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.