command.java

来自「OSGI这是一个中间件,与UPNP齐名,是用于移植到嵌入式平台之上」· Java 代码 · 共 295 行

JAVA
295
字号
/* * 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) {                    bc.ungetService(commandGroupRef);                }                if (out instanceof Pipe) {                    try {                        out.close();                    } catch (IOException ignore) {                    }                }                return null;            }        });        bc.removeServiceListener(this);    }    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);    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?