All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.jxta.impl.shell.bin.Shell.Shell Maven / Gradle / Ivy

Go to download

The JXTA Shell is a sample application that demonstrates key concepts of JXTA JXSE. The JXTA Shell enables users to interact with the JXTA platform through a command-line interpreter. Much like the UNIX® shell, the JXTA Shell is useful for accessing and managing core platform objects (peers, groups, pipes), debugging communications problems, checking the status of peers and/or peer groups, and communicating with other JXTA services and applications. As in UNIX®, the JXTA shell allows users to "pipe" shell commands together connecting commands "on-the-fly." Pipes in Project JXTA are useful for collecting information at one peer and perhaps processing the command at another.

The newest version!
/*
 *  Copyright (c) 2001 Sun Microsystems, Inc.  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *  2. 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.
 *
 *  3. The end-user documentation included with the redistribution,
 *  if any, must include the following acknowledgment:
 *  "This product includes software developed by the
 *  Sun Microsystems, Inc. for Project JXTA."
 *  Alternately, this acknowledgment may appear in the software itself,
 *  if and wherever such third-party acknowledgments normally appear.
 *
 *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must
 *  not be used to endorse or promote products derived from this
 *  software without prior written permission. For written
 *  permission, please contact Project JXTA at http://www.jxta.org.
 *
 *  5. Products derived from this software may not be called "JXTA",
 *  nor may "JXTA" appear in their name, without prior written
 *  permission of Sun.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 SUN MICROSYSTEMS OR
 *  ITS 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.
 *  ====================================================================
 *
 *  This software consists of voluntary contributions made by many
 *  individuals on behalf of Project JXTA.  For more
 *  information on Project JXTA, please see
 *  .
 *
 *  This license is based on the BSD license adopted by the Apache Foundation.
 *
 *  $Id: Shell.java,v 1.86 2007/02/09 23:12:45 hamada Exp $
 */
package net.jxta.impl.shell.bin.Shell;

import net.jxta.document.AdvertisementFactory;
import net.jxta.id.IDFactory;
import net.jxta.impl.shell.*;
import net.jxta.impl.shell.bin.history.HistoryQueue;
import net.jxta.impl.shell.bin.join.join.PeerGroupShellObject;
import net.jxta.peergroup.PeerGroup;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.OutputPipe;
import net.jxta.pipe.PipeService;
import net.jxta.protocol.PipeAdvertisement;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import net.jxta.logging.Logging;
import net.jxta.platform.Module;

/**
 * This class implements a JXTA Shell
 */
public class Shell extends ShellApp implements Runnable {

    /**
     * Logger
     */
    private static final transient java.util.logging.Logger LOG = java.util.logging.Logger.getLogger(Shell.class.getName());

    /**
     * Description of the Field
     */
    public final static String HISTORY_ENV_NAME = "History";

    /**
     * Description of the Field
     */
    public final static String JXTA_SHELL_EMBEDDED_KEY = "JXTA_SHELL_EMBEDDED";

    /**
     * Description of the Field
     */
    public final static String PARENT_SHELL_ENV_NAME = "parentShell";

    /**
     * Description of the Field
     */
    public final static String CMD_PROMPT = "JXTA>";

    /**
     *  Tracks how many shell instances we have created.
     */
    private static AtomicInteger shellInstance = new AtomicInteger(0);

    /**
     *  Unique instance number for this shell instance.
     */
    private final int thisInstance;

    private ShellConsole cons = null;

    private boolean execShell = true;

    private boolean gotMyOwnFrame = false;

    /**
     * If true then this shell is a sub-shell of a another shell.
     */
    private boolean gotParent = false;

    /**
     * The shell environment of our parent shell.
     */
    private ShellEnv parentEnv = null;

    private String pipecmd = null;

    private BufferedReader scriptReader = null;

    /**
     * Child Shells will install a env var in their parent for their instance
     */
    private String parentEnvEnvName = null;

    private Thread thread = null;

    /**
     * Default constructor (don't delete)
     */
    public Shell() {
        thisInstance = shellInstance.incrementAndGet();
    }

    /**
     * Create a new shell with the specified console
     */
    public Shell(ShellConsole console) {
        this();

        cons = console;
    }


    /**
     * Create a new shell with embedded functionality.
     *
     * @param embedded
     */
    public Shell(boolean embedded) {
        this();

        System.setProperty(JXTA_SHELL_EMBEDDED_KEY, Boolean.toString(embedded));
    }

    /**
     * Main processing method for the Shell object
     */
    public void run() {
        try {
            if (null != pipecmd) {
                startApp(new String[0]);
            } else {
                runShell();
            }
        } catch (Throwable all) {
            System.out.flush();
            System.err.println("Uncaught Throwable in thread :" + Thread.currentThread().getName());
            all.printStackTrace(System.err);
        }
    }

    /**
     * {@inheritDoc}
     */
    public int startApp(String[] argv) {

        GetOpt options = new GetOpt(argv, "xsf:e:");

        while (true) {
            int option;
            try {
                option = options.getNextOption();
            } catch (IllegalArgumentException badopt) {
                consoleMessage("Illegal argument :" + badopt);
                return syntaxError();
            }

            if (-1 == option) {
                break;
            }

            switch (option) {
                case'f':
                    String scriptfile = options.getOptionArg();
                    if (!initScriptFile(scriptfile)) {
                        consoleMessage("Cannot access " + scriptfile);
                        return ShellApp.appMiscError;
                    }
                    break;

                case'e':
                    execScript(options.getOptionArg());
                    return Shell.appNoError;

                case's':
                    gotMyOwnFrame = true;
                    break;

                case'x':
                    execShell = false;
                    break;

                default:
                    return syntaxError();
            }
        }

        ShellEnv env = getEnv();

        if (null == env) {
            // There is no Parent Shell

            gotMyOwnFrame = true;
            env = new ShellEnv();

            ShellObject stdgrpobj = new PeerGroupShellObject("Default Group", getGroup());
            env.add("stdgroup", stdgrpobj);

            PeerGroup child = null;
            PeerGroup current = getGroup();
            while (true) {
                PeerGroup next = current.getParentGroup();
                if (next == null) {
                    break;
                }
                child = current;
                current = next;
            }

            // Unless one of our ancestor groups does not support getParent and thus we
            // know nothing, we can always find the platform.
            if (current != null) {
                ShellObject worldgrpobj;
                if (current.getPeerGroupID().equals(getGroup().getPeerGroupID())) {
                    worldgrpobj = stdgrpobj;
                } else {
                    worldgrpobj = new PeerGroupShellObject("World Peer Group", current);
                }

                env.add("worldgroup", worldgrpobj);
            }

            // Unless our initial group is the platform, our before-last ancestor is
            // the netpg.
            if (child != null) {
                ShellObject rootgrpobj;
                if (child.getPeerGroupID().equals(getGroup().getPeerGroupID())) {
                    rootgrpobj = stdgrpobj;
                } else {
                    rootgrpobj = new PeerGroupShellObject("Root Peer Group", child);
                }

                env.add("rootgroup", rootgrpobj);
            }
        } else {
            // This is a child Shell.

            gotParent = true;

            // Recover the parent env, and duplicate it
            parentEnv = env;

            env = new ShellEnv(parentEnv);

            parentEnvEnvName = parentEnv.createName();

            // Store this Shell into the parent's environment
            parentEnv.add(parentEnvEnvName, new ShellObject("Child Shell " + Integer.toString(thisInstance), this));

            // and store our parent into our environment
            ShellObject parentShell = (ShellObject) parentEnv.get("shell");
            if (parentShell != null) {
                env.add(PARENT_SHELL_ENV_NAME, parentShell);
            }
        }

        setEnv(env);

        // Store this Shell into the environment

        /*
        * Hardwiring the shell environment variable here allows us to retrieve
        * it from exit (or wherever), when we need to get the current instance
        * of the shell.
        */
        env.add("shell", new ShellObject("Shell " + Integer.toString(thisInstance), this));

        if (gotMyOwnFrame) {
            if (null == cons) {
                cons = ShellConsole.newConsole(this, "JXTA Shell - (" + getGroup().getPeerName() + ")");
            }

            env.add("console", new ShellObject("console", cons));

            cons.setStatusGroup(getGroup());

            // Create the default InputPipe
            ShellInputPipe defaultInputPipe = new ShellInputPipe(getGroup(), cons);

            env.add("stdin", new ShellObject("Default InputPipe", defaultInputPipe));

            env.add("consin", new ShellObject("Default Console InputPipe", defaultInputPipe));

            setInputPipe(defaultInputPipe);
            setInputConsPipe(defaultInputPipe);

            // Create the default OutputPipe
            ShellOutputPipe defaultOutputPipe = new ShellOutputPipe(getGroup(), cons);

            env.add("stdout", new ShellObject("Default OutputPipe", defaultOutputPipe));

            env.add("consout", new ShellObject("Default Console OutputPipe", defaultOutputPipe));

            setOutputPipe(defaultOutputPipe);
            setOutputConsPipe(defaultOutputPipe);

            // start the shell on its own thread.
            thread = new Thread(getGroup().getHomeThreadGroup(), this, "JXTA Shell " + thisInstance);
            thread.start();

            if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {
                LOG.info("Shell started.");
            }
            // HACK 20070814 bondolo This test is required because the Shell uses a return value (-1) not supported by StdPeerGroup.
            if(null == argv) {
                return Module.START_OK;
            } else {
                return ShellApp.appSpawned;
            }
        } else {
            ShellObject console = env.get("console");

            cons = (ShellConsole) console.getObject();

            if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {
                LOG.info("Shell starting.");
            }

            // a child shell just runs until exit.
            if (null != pipecmd) {
                processCmd(pipecmd);
            } else {
                runShell();
            }

            return ShellApp.appNoError;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public synchronized void stopApp() {
        // Only stop once.
        if(stopped) {
            return;
        }
        
        super.stopApp();

        // Remove itself from the parent ShellEnv (GC)
        if (parentEnv != null) {
            parentEnv.remove(parentEnvEnvName);
        }

        // Destroy ourself
        if (gotMyOwnFrame) {
            cons.setStatusGroup(null);
            cons.destroy();
            cons = null;
        }

        // Interrupt our parsing thread.
        if (thread != null) {
            thread.interrupt();
        }

        if (Logging.SHOW_INFO && LOG.isLoggable(Level.INFO)) {
            LOG.info("Shell stopped.");
        }

        if (isRootShell()) {
            PeerGroup pg = getGroup();

            getEnv().clear();

            // Until we fix all non-daemon threads in non-jxta code...
            if (!isEmbedded()) {
                pg.stopApp();

//                System.exit(0);
            }
        }
    }

    /**
     * {@inheritDoc}
     * 

*

Use the value of stdgroup environment variable. */ @Override public PeerGroup getGroup() { ShellEnv env = getEnv(); ShellObject stdgroup = null; if (null != env) { stdgroup = env.get("stdgroup"); } return (null != stdgroup) ? (PeerGroup) stdgroup.getObject() : super.getGroup(); } /** * if true then this is a root shell. A root shell is the shell which owns * the console. * * @return if true then this shell owns the console. */ public boolean isRootShell() { return !gotParent; } /** * Description of the Method * * @return error result code. */ private int syntaxError() { consoleMessage("Usage: Shell [-f filename] [-e cmds] [-s] [-x]"); return ShellApp.appParamError; } /** * {@inheritDoc} */ @Override public String getDescription() { return "JXTA Shell command interpreter"; } /** * {@inheritDoc} */ @Override public void help() { println("NAME"); println(" Shell - " + getDescription()); println(" "); println("SYNOPSIS"); println(" "); println(" Shell [Shell [-f filename] [-e cmds] [-s] [-x]"); println(" "); println("DESCRIPTION"); println(" "); info(); println(" "); println("Every Shell command is of the form ;..;. The ';'"); println("is used as command separator. Multiple commands can be entered"); println("in one line. Pipelines can be created by combining the pipe stdout"); println("of a command into the pipe stdin of another command using the"); println("pipe '|' operator. For example the following command:"); println(" "); println(" JXTA> cat env1 | more"); println(" "); println("Pipes the output of the command 'cat' into the stdin of the command "); println("'more'. An arbitrary number of commands can be pipelined together with "); println("th '|' pipe operator."); println(" "); println("The '=' operator can be used to assign the value of a command "); println("output to an environment variable. For example :"); println(" "); println(" JXTA> myadv = newpipe -n mypipe"); println(" "); println(" This command creates a new pipe advertisement and stores it in the"); println(" 'myadv' environment variable."); println(" "); println("COMMANDS"); println(" "); println(" The Shell provides the following built-in commands: "); println(" "); println(" clear Clear the shell's screen"); println(" "); println(" The additional commands available may be discovered by : "); println(" "); println(" man "); println(" "); println("OPTIONS"); println(" "); println(" [-f ] Execute the script file"); println(" [-e ] Execute the commands"); println(" [-s] Fork a new Shell console in a new window"); println(" [-x] Skip execution of .jshrc"); println(" "); println("EXAMPLE"); println(" "); println(" JXTA> Shell -f /home/tra/batch"); println(" "); println("This command executes the commands stored in the Shell script"); println("file '/home/tra/myfile' in the current Shell environment."); println(" "); println("ENVIRONMENT"); println(" "); println("The Java implementation of 'Shell' uses two Java system"); println("properties to configure the use of GUI:"); println(" SHELLNOWINDOW - if 'true' then no window is created."); println(" SHELLFONTSIZE - Size in points for the font used in GUI window."); println(" "); println("The following environment variables are defined by default:"); println(" "); println(" consin = Default Console InputPipe"); println(" consout = Default Console OutputPipe"); println(" stdout = Default OutputPipe"); println(" stdin = Default InputPipe"); println(" shell = This Shell object"); println(" stdgroup = Default peer group"); println(" rootgroup = Default Infrastructure group"); println(" worldgroup = World PeerGroup"); println(" echo = (if defined) Echo all commands before executing them"); println(" parentShell = (if defined) For child Shells this is the parent Shell"); println(" "); println("FILES"); println(" "); println(" $CWD/.jshrc"); println(" "); println(" A default startup script that is executed when the Shell "); println(" is invoked."); println(" "); println("SEE ALSO"); println(" exit env "); } /** * Description of the Method */ private void info() { println(" "); println("The JXTA Shell provides an interactive environment to the JXTA " + "platform. The Shell provides basic commands to discover peers and " + "peergroups, to join and resign from peergroups, to create pipes " + "between peers, and to send pipe messages. "); println(" "); println("The Shell provides environment variables that permit binding " + "symbolic names to JXTA platform objects. Environment variables " + "allow Shell commands to exchange data. The command 'env' " + "displays all defined environment variables in the current Shell " + "session."); println(" "); println("The Shell creates a JXTA InputPipe (stdin) for reading input from " + "the keyboard, and a JXTA OutputPipe (stdout) to display information " + "on the Shell console. All commands executed by the Shell have their " + "initial 'stdin' and 'stdout' set up to the Shell's stdin and stdout pipes. " + "The Shell also creates the environment variable 'stdgroup' that " + "contains the current JXTA PeerGroup in which the Shell and commands " + "are executed."); println(" "); println("The 'man' command is available to list the commands available. " + "Type 'man ' to get help about a particular command. " + "To exit the Shell, use the 'exit' command. "); } /** * Description of the Method * * @param script */ private void execScript(String script) { try { processMultipleCmd(script); } catch (Exception ez1) { printStackTrace("Failed with ", ez1); } } /** * Returns the ShellConsole object associated with this shell. It may be * null, if this shell does not run in its own window * * @return ShellConsole object associated with this shell */ public ShellConsole getConsole() { return cons; } /** * Returns the HistoryQueue that holds the cmds in a history list If the * queue does not exist, it is created. * * @return HistoryQueue object used to retrieve commands */ private HistoryQueue getHistoryQueue() { ShellEnv env = getEnv(); ShellObject obj = env.get(HISTORY_ENV_NAME); HistoryQueue queue = null; if (obj != null) { if (HistoryQueue.class.isAssignableFrom(obj.getObjectClass())) { queue = (HistoryQueue) obj.getObject(); } } else { String exclude[] = {cons.getCursorDownName(), cons.getCursorUpName()}; queue = new HistoryQueue(exclude); env.add(HISTORY_ENV_NAME, new ShellObject("History", queue)); } return queue; } /** * Prepare to run a command on a pipe. * * @param cmd The command to be executed. */ private void initPipe(String cmd) { String myName = "JXTA Shell - " + thisInstance + " : [" + cmd + "]"; pipecmd = cmd; thread = new Thread(getGroup().getHomeThreadGroup(), this, myName); thread.start(); } /** * Description of the Method * * @param fn * @return {@code true} if the script file was found otherwise false {@code false}. */ private boolean initScriptFile(String fn) { try { scriptReader = new BufferedReader(new FileReader(fn)); return true; } catch (Exception e) { printStackTrace("Failed with ", e); return false; } } /** * Description of the Method */ private void startupFile() { File startupFile = new File(".jshrc"); if (!startupFile.exists()) { return; } BufferedReader scriptReader = null; try { scriptReader = new BufferedReader(new FileReader(startupFile)); // nothing to do String cmd = scriptReader.readLine(); while (cmd != null) { processMultipleCmd(cmd); cmd = scriptReader.readLine(); } } catch (Exception e) { if (LOG.isLoggable(java.util.logging.Level.WARNING)) { LOG.log(Level.WARNING, "Failure with .jshrc ", e); } } finally { try { if (null != scriptReader) { scriptReader.close(); } } catch (IOException ignored) { //ignored } } } /** * Process the a single command * * @param cmd the command string. */ private void processCmd(String cmd) { if (LOG.isLoggable(java.util.logging.Level.INFO)) { LOG.info("BEGINING OF COMMAND : " + cmd); } // get the args as a list of tokens List args = new ArrayList(Arrays.asList(tokenizeLine(cmd))); if (args.size() < 1) { return; } // Get the returnvar, if any. String returnvar = null; if (args.size() >= 2) { if ("=".equals(args.get(1))) { returnvar = args.remove(0); args.remove(0); } } String app = args.remove(0); // echo the command if the echo enviroment variable is defined if (getEnv().contains("echo")) { consoleMessage("Executing command : " + cmd); } // "clear" is an internal command; just handle it here, nothing to load. if (app.equals("clear")) { cons.clear(); return; } else if (app.equals(cons.getCursorUpName())) { HistoryQueue queue = getHistoryQueue(); if (queue != null) { cons.setCommandLine(queue.getNextCommand()); } return; } else if (app.equals(cons.getCursorDownName())) { HistoryQueue queue = getHistoryQueue(); if (queue != null) { cons.setCommandLine(queue.getPreviousCommand()); } return; } else if (app.startsWith("!")) { try { int number = Integer.valueOf(app.substring(1)); HistoryQueue queue = getHistoryQueue(); if (queue != null) { queue.removeLastCommand(); cons.setCommandLine(queue.getCommand(number)); return; } } catch (Exception iox) { // was not a history command, let the remainder of // the method handle the command /* * If there are no commands starting with * '!', then why not catch the exception, * tell the user that there is nothing like this * in the history, and return a null? */ } } ShellApp appl = loadApp(returnvar, app, getEnv()); if (null != appl) { exec(appl, args.toArray(new String[args.size()])); } else { consoleMessage("Could not load command '" + app + "'"); } } /** * Process the (";" )* commands *

*

FIXME 20010611 [email protected] does not handle quoting in any form. * * @param cmd the command string. */ private void processMultipleCmd(String cmd) { HistoryQueue queue = getHistoryQueue(); if (queue != null) { queue.addCommand(cmd); } StringTokenizer tokens = new StringTokenizer(cmd, ";"); while (tokens.hasMoreElements()) { processPipeCmd(tokens.nextToken()); } } /** * Process the ("|" )* commands *

*

FIXME 20010611 [email protected] does not handle quoting in any form. * * @param cmd the command string. */ private void processPipeCmd(String cmd) { List cmds = new ArrayList(); StringTokenizer tokens = new StringTokenizer(cmd, "|"); while (tokens.hasMoreElements()) { cmds.add(tokens.nextToken()); } // at the beginning start with stdin and stdout PeerGroup current = (PeerGroup) getEnv().get("stdgroup").getObject(); InputPipe stdin = (InputPipe) getEnv().get("stdin").getObject(); OutputPipe stdout = (OutputPipe) getEnv().get("stdout").getObject(); // these are for building the pipeline InputPipe pipein = null; OutputPipe pipeout = null; InputPipe lastin = stdin; Thread willDependOn = null; // The first and last command in the pipe needs to be treated separatly PipeService pipes = current.getPipeService(); for (int i = 0; i < cmds.size() - 1; i++) { /* * create Shell cmd pipe to link the two */ PipeAdvertisement padv; try { padv = (PipeAdvertisement) AdvertisementFactory.newAdvertisement( PipeAdvertisement.getAdvertisementType()); padv.setPipeID(IDFactory.newPipeID(current.getPeerGroupID())); padv.setType(PipeService.UnicastType); pipein = pipes.createInputPipe(padv); pipeout = pipes.createOutputPipe(padv, Collections.singleton(current.getPeerID()), 0); } catch (IOException ex) { printStackTrace("Could not construct pipes for piped command.", ex); } /* * create the environment by cloning the parent. */ ShellEnv pipeenv = new ShellEnv(getEnv()); pipeenv.add("stdout", new ShellObject("Default OutputPipe", pipeout)); pipeenv.add("stdin", new ShellObject("Default InputPipe", lastin)); /* * create a new Shell process to run this pipe command */ Shell pipeShell = (Shell) loadApp(null, "Shell", pipeenv); pipeShell.setJoinedThread(willDependOn); pipeShell.initPipe(cmds.get(i)); willDependOn = pipeShell.thread; /* * update last in pipe for the next command */ lastin = pipein; } /* * Set the pipeline for the last command and let it go/ * only stdin needs redirection since stdout is the right one */ getEnv().add("stdout", new ShellObject("Default OutputPipe", stdout)); ShellObject oldin = (ShellObject) getEnv().get("stdin"); getEnv().add("stdin", new ShellObject("Default InputPipe", lastin)); setJoinedThread(willDependOn); processCmd(cmds.get(cmds.size() - 1)); setJoinedThread(null); // restore the original stdin getEnv().add("stdin", oldin); } /** * This method implements the default input stream (keyboard). */ private void runShell() { if (execShell || (scriptReader == null)) { consprintln("============================================="); consprintln("=======<[ Welcome to the JXTA Shell ]>======="); consprintln("============================================="); info(); } // check if there is a .jshrc file if (execShell) { startupFile(); } while (!stopped) { String cmd; try { if (scriptReader != null) { cmd = scriptReader.readLine(); } else { cons.setPrompt(CMD_PROMPT); cmd = waitForInput(); } } catch (IOException e) { System.err.println("Shell is reconnecting to console"); // This shell has lost its standard InputPipe. Try // to reconnect to the special keyboard InputPipe. setInputPipe(getInputConsPipe()); continue; } if (cmd == null) { if (!stopped) { exec(null, "exit", new String[0], getEnv()); } break; } processMultipleCmd(cmd); } } /** * Return true if this is an embedded shell. IE used by an application that * wouldn't like it if System.exit were called. * * @return The embedded value * @author Kevin A. Burton */ public static boolean isEmbedded() { String value = System.getProperty(JXTA_SHELL_EMBEDDED_KEY, "false"); return Boolean.valueOf(value); } /** * converts a command line string into a series of tokens. */ public String[] tokenizeLine(String line) { List tokens = new ArrayList(); StringBuilder currentToken = new StringBuilder(); int current = 0; int quote = -1; boolean escape = false; while (current < line.length()) { final char currentChar = line.charAt(current); if (escape) { currentToken.append(currentChar); escape = false; } else if (-1 != quote) { if (currentChar == quote) { quote = -1; } else { currentToken.append(currentChar); } } else { switch (currentChar) { case' ': case'\t': if (currentToken.length() > 0) { tokens.add(currentToken.toString()); currentToken.setLength(0); } break; case'=': case'|': case';': if (currentToken.length() > 0) { tokens.add(currentToken.toString()); currentToken.setLength(0); } tokens.add(Character.toString(currentChar)); break; case'"': case'\'': quote = currentChar; break; case'\\': escape = true; break; default: currentToken.append(currentChar); break; } } current++; } if (currentToken.length() > 0) { tokens.add(currentToken.toString()); currentToken.setLength(0); } return tokens.toArray(new String[tokens.size()]); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy