Package org.knopflerfish.bundle.console

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

/*
* 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.io.Writer;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;

import org.knopflerfish.service.console.CommandGroup;
import org.knopflerfish.service.console.Session;
import org.osgi.framework.BundleContext;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;

/**
* Class for command parseing and execution.
*
* @author Jan Stein
* @version $Revision: 1.1.1.1 $
*/
public class Command implements ServiceListener, Runnable {

    final static String COMMAND_GROUP = org.knopflerfish.service.console.CommandGroup.class
            .getName();

    static SessionCommandGroup sessionCommandGroup;

    final BundleContext bc;

    String[] args;

    Reader in;

    Writer out;

    Alias aliases;

    String groupName;

    Session session;

    ServiceReference commandGroupRef;

    Thread thread = null;

    int status = -1;

    public boolean isPiped = false;

    public boolean isBackground = false;

    public Command(BundleContext bc, String group, Alias aliases,
            final StreamTokenizer cmd, Reader in, PrintWriter out,
            Session session) throws IOException {
        this.bc = bc;
        this.in = in;
        this.out = out;
        this.aliases = aliases;
        this.session = session;
        if (sessionCommandGroup == null) {
            sessionCommandGroup = new SessionCommandGroup(bc);
        }
        groupName = group;
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction() {
                public Object run() throws IOException {
                    parseCommand(cmd);
                    return null;
                }
            });
        } catch (PrivilegedActionException e) {
            throw (IOException) e.getException();
        }
    }

    void parseCommand(StreamTokenizer in) throws IOException {
        if (in.nextToken() != StreamTokenizer.TT_WORD) {
            throw new IOException("Unexpected token: " + in.ttype);
        }
        String word;
        String[] aliasBuf = null;
        int aliasPos;
        if (aliases != null
                && (aliasBuf = (String[]) aliases.get(in.sval)) != null) {
            word = aliasBuf[0];
            aliasPos = 1;
        } else {
            word = in.sval;
            aliasPos = 0;
        }
        if ("".equals(groupName) || word.startsWith("/")) {
            if (word.startsWith("/"))
                word = word.substring(1);
            commandGroupRef = matchCommandGroup(bc, word);
            word = null;
        } else {
            if (SessionCommandGroup.NAME.equals(groupName)) {
                commandGroupRef = null;
            } else {
                ServiceReference[] refs = null;
                try {
                    refs = bc.getServiceReferences(COMMAND_GROUP, "(groupName="
                            + groupName + ")");
                } catch (InvalidSyntaxException ignore) {
                }
                if (refs == null) {
                    throw new IOException("No such command group: " + groupName);
                }
                commandGroupRef = refs[0];
            }
        }
        ArrayList vargs = new ArrayList();
        boolean done = false;
        while (!done) {
            if (word != null) {
                vargs.add(word);
                word = null;
            } else if (aliasPos > 0) {
                if (aliasPos < aliasBuf.length) {
                    word = aliasBuf[aliasPos++];
                } else {
                    aliasPos = 0;
                }
            } else {
                switch (in.nextToken()) {
                case '|':
                    out = new Pipe();
                    isPiped = true;
                    done = true;
                    break;
                case '&':
                    isBackground = true;
                case ';':
                    done = true;
                    break;
                case '<':
                    if (in.nextToken() != StreamTokenizer.TT_WORD) {
                        throw new IOException("Empty input redirect");
                    }
                    // Set input to file
                    break;
                case '>':
                    if (in.nextToken() != StreamTokenizer.TT_WORD) {
                        throw new IOException("Empty output redirect");
                    }
                    // Set output to file
                    break;
                case StreamTokenizer.TT_EOL:
                case StreamTokenizer.TT_EOF:
                    in.pushBack();
                    done = true;
                    break;
                case '"':
                case '\'':
                case StreamTokenizer.TT_WORD:
                    word = in.sval;
                    break;
                default:
                    throw new IOException("Unknown token: " + in.ttype);
                }
            }
        }
        args = (String[]) vargs.toArray(new String[vargs.size()]);
    }

    public void runThreaded() {
        String gname = commandGroupRef != null ? (String) commandGroupRef
                .getProperty("groupName") : SessionCommandGroup.NAME;

        thread = new Thread(this, "Console cmd: " + gname
                + (args.length == 0 ? "" : "/" + args[0]));

        thread.start();

    }
   
    public synchronized void run() {
        bc.addServiceListener(this);
        AccessController.doPrivileged(new PrivilegedAction() {
            public Object run() {
                CommandGroup cg;
                if (commandGroupRef != null) {
                    cg = (CommandGroup) bc.getService(commandGroupRef);
                    if (cg == null) {
                        status = -2;
                        return null;
                    }
                } else {
                    cg = sessionCommandGroup;
                }
                if (out instanceof PrintWriter) {
                    status = cg.execute(args, in, (PrintWriter) out, session);
                } else {
                    status = cg.execute(args, in, new PrintWriter(out), session);
                }
                if (commandGroupRef != null) {
                    try {
                        bc.ungetService(commandGroupRef);
                    } catch (IllegalStateException ignore) {
                        // Can happen if the command has invalidated our bc (e.g. update)
                        // TODO: Warn about this? The input can be screwed up.
                    }
                }
                if (out instanceof Pipe) {
                    try {
                        out.close();
                    } catch (IOException ignore) {
                    }
                }
                return null;
            }
        });
        try {
            bc.removeServiceListener(this);
        } catch (IllegalStateException ignore) {
            // Can happen if the command has invalidated our bc (e.g. update)
        }
    }

    public void serviceChanged(ServiceEvent e) {
        if (e.getServiceReference() == commandGroupRef) {
            synchronized (this) {
                // Wait for run command
            }
        }
    }

    static ServiceReference matchCommandGroup(BundleContext bc, String word)
            throws IOException {
        ServiceReference res = null;
        ServiceReference[] refs = null;
        try {
            refs = bc.getServiceReferences(COMMAND_GROUP, "(groupName=" + word
                    + "*)");
        } catch (InvalidSyntaxException ignore) {
        }
        if (refs != null) {
            if (refs.length == 1) {
                res = refs[0];
            } else if (refs.length > 1) {
                for (int i = 0; i < refs.length; i++) {
                    if (word.equals(refs[i].getProperty("groupName"))) {
                        res = refs[i];
                        break;
                    }
                }
            }
        }
        if (SessionCommandGroup.NAME.startsWith(word)) {
            if (refs == null || SessionCommandGroup.NAME.equals(word)) {
                return null;
            }
        } else if (res != null) {
            return res;
        } else if (refs == null) {
            throw new IOException("No such command group: " + word);
        }
        throw new IOException("Several command groups starting with: " + word);
    }

}
TOP

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

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.