📄 shell.java
字号:
/* * USE - UML based specification environment * Copyright (C) 1999-2004 Mark Richters, University of Bremen * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* $ProjectHeader: use 2-3-0-release.1 Mon, 12 Sep 2005 20:18:33 +0200 green $ */package org.tzi.use.main.shell;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.FileNotFoundException;import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.io.PrintWriter;import java.io.Reader;import java.io.StringReader;import java.net.InetAddress;import java.net.ServerSocket;import java.net.Socket;import java.text.NumberFormat;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.NoSuchElementException;import java.util.Set;import java.util.StringTokenizer;import java.util.TreeSet;import org.tzi.use.config.Options;import org.tzi.use.gen.model.GFlaggedInvariant;import org.tzi.use.gen.tool.GNoResultException;import org.tzi.use.gui.views.ExprEvalBrowser;import org.tzi.use.main.DaVinciProcess;import org.tzi.use.main.MonitorAspectGenerator;import org.tzi.use.main.Session;import org.tzi.use.parser.USECompiler;import org.tzi.use.uml.mm.MAssociation;import org.tzi.use.uml.mm.MClass;import org.tzi.use.uml.mm.MClassInvariant;import org.tzi.use.uml.mm.MMInstanceGenerator;import org.tzi.use.uml.mm.MMPrintVisitor;import org.tzi.use.uml.mm.MMVisitor;import org.tzi.use.uml.mm.MModel;import org.tzi.use.uml.mm.MOperation;import org.tzi.use.uml.mm.ModelFactory;import org.tzi.use.uml.ocl.expr.Evaluator;import org.tzi.use.uml.ocl.expr.Expression;import org.tzi.use.uml.ocl.expr.MultiplicityViolationException;import org.tzi.use.uml.ocl.value.Value;import org.tzi.use.uml.ocl.value.VarBindings;import org.tzi.use.uml.sys.MCmd;import org.tzi.use.uml.sys.MOperationCall;import org.tzi.use.uml.sys.MSystem;import org.tzi.use.uml.sys.MSystemException;import org.tzi.use.uml.sys.MSystemState;import org.tzi.use.util.Log;import org.tzi.use.util.NullWriter;import org.tzi.use.util.Report;import org.tzi.use.util.StringUtil;import org.tzi.use.util.USEWriter;import org.tzi.use.util.input.LineInput;import org.tzi.use.util.input.Readline;import org.tzi.use.util.input.ReadlineTestReadlineDecorator;import org.tzi.use.util.input.SocketReadline;class NoSystemException extends Exception {}/** * A shell for reading and executing user commands. * * @version $ProjectVersion: 2-3-0-release.1 $ * @author Mark Richters */public final class Shell implements Runnable { public static final String PROMPT = "use> "; public static final String CONTINUE_PROMPT = "> "; /** * Run program until true. Set by exit command. */ private volatile boolean fFinished = false; /** * If true read multiple lines into a single command before processing. */ private boolean fMultiLineMode = false; /** * The session contains the system most commands act on. */ private Session fSession; /** * The daVinci communication interface. */ private DaVinciProcess fDaVinci; /** * Result of last check command. */ private boolean fLastCheckResult = false; /** * Single-step commands. */ private boolean fStepMode = false; private ReadlineStack fReadlineStack = null; /** * Actual readline that is used. */ private Readline fReadline = null; private static Shell fShell = null; /** * Constructs a new shell. */ private Shell(Session session) { fReadlineStack = new ReadlineStack(); // no need to listen on session changes since every command // explicitly retrieves the current system fSession = session; fDaVinci = new DaVinciProcess(Options.DAVINCI_PATH); } public static Shell getInstance(Session session) { if (fShell == null) { fShell = new Shell(session); } return fShell; } /** * Returns the result of the last check command. */ public boolean lastCheckResult() { return fLastCheckResult; } /** * Main loop for accepting input and processing it. */ public void run() { setupReadline(); if (Options.cmdFilename != null) { cmdOpen(Options.cmdFilename); } else { Log.verbose("Enter `help' for a list of available commands."); } while (!fFinished) { Thread.yield(); Log.resetOutputFlag(); String line = ""; // get current readline (may be e.g. console or file) //fReadline = (Readline) fReadlineStack.peek(); fReadline = fReadlineStack.getCurrentReadline(); try { if (fMultiLineMode) { while (true) { // use special prompt to emphasize multi-line input String oneLine = fReadline.readline(CONTINUE_PROMPT); // end of input or a single dot terminates the input // loop if (oneLine == null || oneLine.equals(".")) break; line += oneLine + Options.LINE_SEPARATOR; } fMultiLineMode = false; } else { line = fReadline.readline(PROMPT); } } catch (IOException ex) { Log.error("Cannot read line: " + ex.getMessage()); } if (line != null) { processLineSafely(line); } else { fFinished = fReadlineStack.popCurrentReadline(); if (fFinished && Options.quiet) processLineSafely("check"); } } cmdExit(); } /** * Initializes readline. */ private void setupReadline() { String GNUReadlineNotAvailable; if (Options.suppressWarningsAboutMissingReadlineLibrary) GNUReadlineNotAvailable = null; else GNUReadlineNotAvailable = "Apparently, the GNU readline library is not availabe on your system." + Options.LINE_SEPARATOR + "The program will continue using a simple readline implementation." + Options.LINE_SEPARATOR + "You can turn off this warning message by using the switch -nr"; //Readline rl = null; if (!Options.quiet) { fReadline = LineInput.getUserInputReadline(GNUReadlineNotAvailable); fReadline.usingHistory(); // Read command history from previous sessions try { fReadline.readHistory(Options.USE_HISTORY_PATH); } catch (IOException ex) { // Fail silently if history file does not exist } fReadlineStack.push(fReadline); } } /** * Analyses a line of input and calls the method implementing a command. */ private void processLineSafely(String line) { try { // protocol the input line if (fReadline.doProtocol()) { // add prompt to line, because it is not included USEWriter.getInstance().protocol(PROMPT + line); } processLine(line); } catch (NoSystemException ex) { Log.error("No System available. Please load a model before executing this command."); } catch (Exception ex) { System.err.println(); String nl = Options.LINE_SEPARATOR; System.err .println("INTERNAL ERROR: An unexpected exception occured. This happened most probably" + nl + "due to an error in the program. The program will try to continue, but may" + nl + "not be able to recover from the error. Please send a bug report to mr@tzi.org" + nl + "with a description of your last input and include the following output:"); System.err.println("Program version: " + Options.RELEASE_VERSION); System.err.println("Project version: " + Options.PROJECT_VERSION); System.err.print("Stack trace: "); ex.printStackTrace(); } } /** * Method is called out of the GUI to exit the command line. <br> * * (This way the command line exits after hitting return once after closing * the window. It is not the preferd solution, but so far nothing better was * found) */ public void exit() { try { processLine("exit"); } catch (NoSystemException ex) { Log.error("No System available. Please load a model before executing this command."); } } /** * Analyses a line of input and calls the method implementing a command. */ private void processLine(String line) throws NoSystemException { line = line.trim(); if (line == null || line.length() == 0 || line.startsWith("//") || line.startsWith("--")) return; if (fStepMode) { Log.println("[step mode: `return' continues, " + "`escape' followed by `return' exits step mode.]"); try { int c = System.in.read(); if (c == 0x1b) fStepMode = false; } catch (IOException ex) { //TODO: should this be silently ignored? [throw new Error(ex)?] } } if (line.startsWith("help") || line.endsWith("--help")) cmdHelp(line); else if (line.equals("q") || line.equals("quit") || line.equals("exit")) cmdExit(); else if (line.startsWith("??")) cmdQuery(line.substring(2).trim(), true); else if (line.startsWith("?")) cmdQuery(line.substring(1).trim(), false); else if (line.startsWith(":")) cmdDeriveStaticType(line.substring(1).trim()); else if (line.startsWith("!")) cmdExec(line.substring(1).trim()); else if (line.equals("\\")) cmdMultiLine(); else if (line.equals("check") || line.startsWith("check ")) cmdCheck(line); else if (line.equals("genvcg")) cmdGenVCG(null); else if (line.startsWith("genvcg ")) cmdGenVCG(line.substring(7)); else if (line.equals("genmm")) cmdGenMM(null); else if (line.startsWith("genmm ")) cmdGenMM(line.substring(6)); else if (line.equals("genmonitor")) cmdGenMonitor(); else if (line.equals("graph")) cmdGraph(); else if (line.startsWith("info ")) cmdInfo(line.substring(5)); else if (line.equals("net")) cmdNet(); else if (line.startsWith("open ")) cmdOpen(line.substring(5));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -