[Mulgara-svn] r456 - branches/nw-interface/src/jar/itql/java/org/mulgara/itql
pag at mulgara.org
pag at mulgara.org
Wed Sep 26 04:51:34 UTC 2007
Author: pag
Date: 2007-09-25 23:51:33 -0500 (Tue, 25 Sep 2007)
New Revision: 456
Modified:
branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlAutoInterpreter.java
branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSession.java
branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSessionUI.java
Log:
Major round of debugging on the new TqlSession front end. Found some incorrect code paths I made in the port, but also discovered some bad and unused code in the original ItqlSessions. Pipe reading is particularly egregious.
Modified: branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlAutoInterpreter.java
===================================================================
--- branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlAutoInterpreter.java 2007-09-26 04:49:58 UTC (rev 455)
+++ branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlAutoInterpreter.java 2007-09-26 04:51:33 UTC (rev 456)
@@ -19,6 +19,7 @@
import org.mulgara.connection.Connection;
import org.mulgara.connection.ConnectionException;
import org.mulgara.connection.ConnectionFactory;
+import org.mulgara.connection.DummyConnection;
import org.mulgara.parser.Interpreter;
import org.mulgara.query.Answer;
import org.mulgara.query.QueryException;
@@ -37,6 +38,8 @@
public class TqlAutoInterpreter {
/** The logger. */
private final static Logger logger = Logger.getLogger(TqlAutoInterpreter.class.getName());
+
+ private static Connection localStateConnection = new DummyConnection();
/** The parser and AST builder for commands. */
private Interpreter interpreter = new TqlInterpreter();
@@ -88,8 +91,8 @@
// execute the operation
try {
// set up a connection, if required
- Connection conn = cmd.isLocalOperation() ? null : establishConnection(cmd.getServerURI());
- cmd.execute(conn);
+ Connection conn = establishConnection(cmd.getServerURI());
+ handleResult(cmd.execute(conn), cmd);
updateOnConnectionState(conn);
lastMessage = cmd.getResultMessage();
} catch (Exception e) {
@@ -97,8 +100,8 @@
lastMessage = "Error: " + e.getMessage();
}
- // test if the command wants the user to quit
- return cmd.isLocalOperation() && ((LocalCommand)cmd).isQuitCommand();
+ // test if the command wants the user to quit - return false if it does
+ return !(cmd.isLocalOperation() && ((LocalCommand)cmd).isQuitCommand());
}
@@ -153,6 +156,19 @@
/**
+ * Process the result from a command.
+ * @param result The result to handle.
+ * @param cmd The command that gave the result. Used for type checking.
+ */
+ private void handleResult(Object result, Command cmd) {
+ if (result != null) {
+ if (cmd.isAnswerable()) lastAnswer = (Answer)result;
+ else logger.debug("Result: " + result);
+ }
+ }
+
+
+ /**
* Returns a connection to the server with the given URI.
* @param serverUri The URI for the server to get a connection to.
* @return A connection to the server, cached if available.
@@ -160,8 +176,7 @@
* @throws QueryException There is a transaction underway, but the new connection cannot turn off autocommit.
*/
private Connection establishConnection(URI serverUri) throws ConnectionException, QueryException {
- if (serverUri == null) throw new IllegalArgumentException("Server URI may not be null.");
- Connection connection = connectionFactory.newConnection(serverUri);
+ Connection connection = (serverUri == null) ? localStateConnection : connectionFactory.newConnection(serverUri);
// If in a transaction, turn off autocommit
if (inTransaction && connection.getAutoCommit()) {
connection.setAutoCommit(false);
Modified: branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSession.java
===================================================================
--- branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSession.java 2007-09-26 04:49:58 UTC (rev 455)
+++ branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSession.java 2007-09-26 04:51:33 UTC (rev 456)
@@ -129,28 +129,37 @@
// command line options as we can override the defaults
tqlSession.executeLoadingScript(tqlSession.getPreLoadingScriptURL());
- tqlSession.executeScript(tqlSession.getScript());
-
if (log.isDebugEnabled()) log.debug("Executed pre-loading script");
// if we can, execute this session using std in and std out
if (startSession) tqlSession.runInterface();
- else tqlSession.executeLoadingScript(tqlSession.getPostLoadingScriptURL());
+ else {
+ // otherwise, run the scripts we were given
+ tqlSession.executeScript(tqlSession.getScript());
+ tqlSession.executeLoadingScript(tqlSession.getPostLoadingScriptURL());
+ tqlSession.close();
+ }
} catch (ItqlOptionParser.UnknownOptionException uoe) {
- log.warn("Invalid command line option specified: " + uoe.getOptionName());
- System.err.println("Invalid option: " + uoe.getOptionName());
- tqlSession.printUsage(System.out);
+ errorTermination(tqlSession, "Invalid command line option: " + uoe.getOptionName());
} catch (ItqlOptionParser.IllegalOptionValueException iove) {
- String optionMsg = "-" + iove.getOption().shortForm() + ", --" +
- iove.getOption().longForm() + " = " + iove.getValue();
- log.warn("Invalid command line option value specified: " + optionMsg);
- System.err.println("Invalid option value: " + optionMsg);
- tqlSession.printUsage(System.out);
+ String optionMsg = "-" + iove.getOption().shortForm() + ", --" + iove.getOption().longForm() + " = " + iove.getValue();
+ errorTermination(tqlSession, "Invalid command line option value specified: " + optionMsg);
}
- tqlSession.close();
}
+
+ /**
+ * Convenience method to log errors and terminate the program.
+ * @param session The current session to close.
+ * @param message The error message to log.
+ */
+ private static void errorTermination(TqlSession session, String message) {
+ log.warn(message);
+ System.err.println(message);
+ session.printUsage(System.out);
+ session.close();
+ }
/**
* Constructor. Creates a new TQL session.
@@ -217,6 +226,15 @@
}
}
+ /**
+ * Executes a script given by URL name. {@see executeScript} for implementation.
+ * @param script The string for the script URL.
+ * @throws MalformedURLException The given script name cannot be represented as a URL.
+ */
+ private void executeScript(String script) throws MalformedURLException {
+ if (script == null) return;
+ executeScript(new URL(script));
+ }
/**
* Executes a script. This is done separately to {@link org.mulgara.query.operation.ExecuteScript}
@@ -279,7 +297,7 @@
mainWindow.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
mainWindow.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
- gui = new TqlSessionUI(this);
+ gui = new TqlSessionUI(this, System.in, System.out);
mainWindow.getContentPane().add(gui);
if (log.isInfoEnabled()) log.info("Starting TQL interpreter");
@@ -308,11 +326,10 @@
/**
* Returns the location of the script to run.
- * @return the location of the script to run.
- * @throws MalformedURLException The script location is not a valid URL.
+ * @return A string with the location of the script to run.
*/
- private URL getScript() throws MalformedURLException {
- return new URL(scriptLocation);
+ private String getScript() throws MalformedURLException {
+ return scriptLocation;
}
@@ -464,7 +481,8 @@
}
// If there is a script to run, then return false, else true for no script
- return null == parser.getOptionValue(ItqlOptionParser.SCRIPT);
+ scriptLocation = (String)parser.getOptionValue(ItqlOptionParser.SCRIPT);
+ return null == scriptLocation;
}
} catch (MalformedURLException e) {
log.warn("Invalid URL on command line - " + e.getMessage());
Modified: branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSessionUI.java
===================================================================
--- branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSessionUI.java 2007-09-26 04:49:58 UTC (rev 455)
+++ branches/nw-interface/src/jar/itql/java/org/mulgara/itql/TqlSessionUI.java 2007-09-26 04:51:33 UTC (rev 456)
@@ -44,11 +44,15 @@
*
* @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
*/
-import java.io.*;
import java.util.*;
+import java.util.List;
import java.awt.*;
import java.awt.event.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
import javax.swing.*;
import javax.swing.text.*;
@@ -61,81 +65,48 @@
public class TqlSessionUI extends JScrollPane implements Runnable,
KeyListener, java.awt.event.MouseListener, ActionListener {
- /**
- * The logging category to log to
- */
+ /** The logging category to log to */
private final static Logger log = Logger.getLogger(TqlSessionUI.class);
+
+ private static final String NEWLINE = System.getProperty("line.separator");
+
+ /** The bold font used for output */
+ private final Font boldFont = new Font("Monospaced", Font.BOLD, 12);
+
+ /** The iTQL session to send queries and used to send results. */
+ private TqlSession tqlSession;
- /**
- * Inputstream to take user input.
- */
- private InputStream in;
-
- /**
- * Outputstream to display user output.
- */
- private PrintStream out;
-
- /**
- * Used to pipe input.
- */
+ /** Used to pipe input. */
private InputStream inPipe;
- /**
- * Used to pipe output.
- */
- private OutputStream outPipe;
+ /** The list of history items. */
+ private ArrayList<String> history = new ArrayList<String>();
- /**
- * The iTQL session to send queries and used to send results.
- */
- private TqlSession tqlSession;
-
- /**
- * The list of history items.
- */
- private ArrayList history = new ArrayList();
-
- /**
- * Current index into the history.
- */
+ /** Current index into the history. */
private int historyIndex = 0;
- /**
- * Current cursor position.
- */
+ /** Current cursor position. */
private int cursorPosition = 0;
- /**
- * The UI widget for displaying all text.
- */
+ /** The UI widget for displaying all text. */
private JTextPane text;
- /**
- * The default styled document.
- */
+ /** The default styled document. */
private DefaultStyledDocument doc;
- /**
- * Popup menu for Windows users.
- */
+ /** Popup menu for Windows users. */
private JPopupMenu popupMenu = new JPopupMenu();
- /**
- * Whether we are running a command still.
- */
+ /** Whether we are running a command still. */
private volatile boolean runningCommand = false;
/**
* Create a new UI representation.
- *
* @param newItqlSession the itql session to call when we receive commands and
- * when we want to display them.
+ * when we want to display them.
*/
- public TqlSessionUI(TqlSession newTqlSession) {
-
+ public TqlSessionUI(TqlSession newTqlSession, InputStream inStream, OutputStream outStream) {
super();
-
tqlSession = newTqlSession;
doc = new DefaultStyledDocument();
text = new PasteablePane(doc);
@@ -157,25 +128,8 @@
copyItem.addActionListener(this);
pasteItem.addActionListener(this);
- outPipe = new PipedOutputStream();
- try {
+ inPipe = inStream;
- in = new PipedInputStream((PipedOutputStream) outPipe);
- } catch (IOException e) {
-
- log.error("Error creating input stream", e);
- }
-
- PipedOutputStream pout = new PipedOutputStream();
- out = new PrintStream(pout);
- try {
-
- inPipe = new PipedInputStream(pout);
- } catch (IOException e) {
-
- log.error("Error creating input pipe", e);
- }
-
// Start the inpipe watcher
new Thread(this).start();
requestFocus();
@@ -456,7 +410,7 @@
// Put the command at the end of the array.
history.add(command);
- command = command + System.getProperty("line.separator");
+ command = command + NEWLINE;
// If the array gets too large remove the last entry.
if (history.size() > 30) {
@@ -552,8 +506,7 @@
* @param message the message to display.
*/
public void println(String message) {
-
- print(message + System.getProperty("line.separator"));
+ print(message + NEWLINE);
text.repaint();
}
@@ -561,23 +514,17 @@
* Prints empty line.
*/
public void println() {
-
- print(System.getProperty("line.separator"));
+ print(NEWLINE);
text.repaint();
}
/**
- * Prints a message to the UI.
- *
+ * Prints a message to the UI. Sends a little "closure" to the UI thread.
* @param message the message to display.
*/
public void print(final String message) {
-
invokeAndWait(new Runnable() {
-
public void run() {
-
-
append(message);
cursorPosition = textLength();
text.setCaretPosition(cursorPosition);
@@ -585,43 +532,37 @@
});
}
+
/**
* Print out an error message to the UI.
- *
* @param errorMessage the error message to display.
*/
public void error(String errorMessage) {
-
print(errorMessage, Color.red);
}
+
/**
* Print out the message with the given color using the current font.
- *
* @param message the message to display.
* @param color the color to use.
*/
public void print(String message, Color color) {
-
print(message, null, color);
}
+
/**
- * Print out the message with the given font and colour. Uses invoke and
- * wait.
- *
+ * Print out the message with the given font and colour.
+ * Uses invoke and wait to send a "closure" to the UI thread.
* @param message the message to display.
* @param font the font to use.
* @param color the color to use.
*/
public void print(final String message, final Font font, final Color color) {
-
invokeAndWait(new Runnable() {
-
public void run() {
-
try {
-
AttributeSet oldStyle = text.getCharacterAttributes();
setStyle(font, color);
append(message);
@@ -629,36 +570,37 @@
text.setCaretPosition(cursorPosition);
text.setCharacterAttributes(oldStyle, true);
} catch (Exception e) {
-
log.error("Error when printing: " + message, e);
}
}
});
}
+
/**
+ * Print out the message followed by a newline with the given font and colour.
+ * @param message the message to display.
+ * @param font the font to use.
+ * @param color the color to use.
+ */
+ public void println(final String message, final Font font, final Color color) {
+ print(message + NEWLINE, font, color);
+ text.repaint();
+ }
+
+
+ /**
* Sets the new style of a font and color to the text.
- *
* @param font the new font.
* @param color the new color.
* @return the attributes of the given font and color.
*/
private AttributeSet setStyle(Font font, Color color) {
-
MutableAttributeSet attr = new SimpleAttributeSet();
StyleConstants.setForeground(attr, color);
-
// Don't set if null
if (font != null) {
-
- if (font.isBold()) {
-
- StyleConstants.setBold(attr, true);
- } else {
-
- StyleConstants.setBold(attr, false);
- }
-
+ StyleConstants.setBold(attr, font.isBold());
StyleConstants.setFontFamily(attr, font.getFamily());
StyleConstants.setFontSize(attr, font.getSize());
}
@@ -666,57 +608,51 @@
return text.getCharacterAttributes();
}
+
/**
* Append the given string to the existing string.
- *
* @param newString the string to append to.
*/
private void append(String newString) {
-
int length = textLength();
text.select(length, length);
text.replaceSelection(newString);
}
+
/**
- * Thread that runs while waiting for input.
+ * Thread that reads the inPipe, and prints the output.
*/
public void run() {
-
try {
-
byte[] buffer = new byte[255];
int read;
- while ((read = inPipe.read(buffer)) != -1) {
-
- print(new String(buffer, 0, read));
- }
+ log.info("Starting input reader");
+ while ((read = inPipe.read(buffer)) != -1) print(new String(buffer, 0, read));
} catch (IOException e) {
-
log.error("Error reading input", e);
}
+ log.warn("End of input");
}
+
/**
- * If not in the event thread run via SwingUtilities.invokeAndWait()
+ * If not in the event thread run via SwingUtilities.invokeAndWait().
+ * @param runnable The operation that a client wants the UI to perform. Like a "closure".
*/
private void invokeAndWait(Runnable runnable) {
-
if (!SwingUtilities.isEventDispatchThread()) {
-
try {
-
SwingUtilities.invokeAndWait(runnable);
} catch (Exception e) {
-
log.error("Error while executing invoke and wait", e);
}
} else {
-
runnable.run();
}
}
+
/**
* Extension to JTextPane to put all pastes at the end of the command line.
*/
@@ -731,145 +667,113 @@
}
}
+ /** Class to listen for mouse press events. */
class MouseListener implements AWTEventListener {
-
public void eventDispatched(AWTEvent event) {
-
- MouseEvent me = (MouseEvent) event;
- if (me.getButton() == MouseEvent.BUTTON2) {
-
- me.consume();
- }
+ MouseEvent me = (MouseEvent)event;
+ if (me.getButton() == MouseEvent.BUTTON2) me.consume();
}
}
+
/**
* Executes the command in a separate thread and display the results.
*/
class ExecutionThread extends Thread {
- /**
- * The command to execute.
- */
+ /** The command to execute. */
private String command;
/**
* Create a new execution thread.
- *
* @param threadName the name of the thread.
* @param newCommand the iTQL command to execute.
*/
public ExecutionThread(String threadName, String newCommand) {
-
super(threadName);
command = newCommand;
}
+
/**
* Run the command and display answer results.
*/
public void run() {
-
tqlSession.executeCommand(command);
println();
- java.util.List answers = tqlSession.getLastAnswers();
- java.util.List messages = tqlSession.getLastMessages();
+ List<Answer> answers = tqlSession.getLastAnswers();
+ List<String> messages = tqlSession.getLastMessages();
- int answerIndex = 0;
- String lastMessage;
-
- while (answerIndex < answers.size()) {
-
- lastMessage = (String) messages.get(answerIndex);
-
- try {
-
- // Assume the same number of answers and messages
- Answer answer = (Answer) answers.get(answerIndex);
-
- // If there's more than one answer print a heading.
- if (answers.size() > 1) {
-
- println();
- // If there's more than one answer add an extra line before the
- // heading.
- print("Executing Query " + (answerIndex+1),
- new Font("Monospaced", Font.BOLD, 12), Color.BLACK);
- println();
- }
-
- // print the results
- if (answer != null) {
-
- boolean hasAnswers = true;
-
- answer.beforeFirst();
- long rowCount = 0;
-
- if (answer.isUnconstrained()) {
- println("[ true ]");
- rowCount = 1;
- } else {
- if (!answer.next()) {
- print("No results returned.",
- new Font("Monospaced", Font.BOLD, 12), Color.BLACK);
- hasAnswers = false;
+ if (answers.isEmpty()) {
+ for (String message: messages) println(message, boldFont, Color.BLACK);
+ } else {
+ int answerIndex = 0;
+ while (answerIndex < answers.size()) {
+ String lastMessage = (String)messages.get(answerIndex);
+ try {
+ // Assume the same number of answers and messages
+ Answer answer = answers.get(answerIndex);
+
+ // If there's more than one answer print a heading.
+ if (answers.size() > 1) {
+ println();
+ // If there's more than one answer add an extra line before the heading.
+ println("Executing Query " + (answerIndex+1), boldFont, Color.BLACK);
+ }
+
+ // print the results
+ if (answer != null) {
+ boolean hasAnswers = true;
+
+ long rowCount = 0;
+ answer.beforeFirst();
+ if (answer.isUnconstrained()) {
+ println("[ true ]");
+ rowCount = 1;
} else {
- do {
- rowCount++;
- print("[ ");
- for (int index = 0; index < answer.getNumberOfVariables();
- index++) {
- Object object = answer.getObject(index);
-
- assert(object instanceof Answer) ||
- (object instanceof Node ) ||
- (object == null);
-
- print(String.valueOf(object));
- if (index < (answer.getNumberOfVariables() - 1)) {
- print(", ");
+ if (!answer.next()) {
+ print("No results returned.", boldFont, Color.BLACK);
+ hasAnswers = false;
+ } else {
+ do {
+ rowCount++;
+ print("[ ");
+ for (int index = 0; index < answer.getNumberOfVariables(); index++) {
+ Object object = answer.getObject(index);
+ assert(object instanceof Answer) ||
+ (object instanceof Node ) ||
+ (object == null);
+ print(String.valueOf(object));
+ if (index < (answer.getNumberOfVariables() - 1)) print(", ");
}
- }
- println(" ]");
+ println(" ]");
+ } while (answer.next());
}
- while (answer.next());
}
+ if (hasAnswers) println(rowCount + " rows returned.", boldFont, Color.BLACK);
+ answer.close();
}
- if (hasAnswers) {
- print(rowCount + " rows returned.",
- new Font("Monospaced", Font.BOLD, 12), Color.BLACK);
- }
-
- answer.close();
+ } catch (Exception te) {
+ // Failed to iterate over or retrieve the answer.
+ log.fatal("Failed to retrieve or iterate over answer", te);
+ error("Failed to get answer");
}
- } catch (Exception te) {
-
- // Failed to iterate over or retrieve the answer.
- log.fatal("Failed to retrieve or iterate over answer", te);
- error("Failed to get answer");
+
+ if ((lastMessage != null) && (lastMessage != "")) print(lastMessage, boldFont, Color.BLACK);
+
+ // If there's more than one answer add a new line.
+ if (answers.size() > 1) println();
+
+ // Increment index
+ answerIndex++;
}
-
- if ((lastMessage != null) && (lastMessage != "")) {
-
- print(lastMessage, new Font("Monospaced", Font.BOLD, 12),
- Color.BLACK);
- }
-
- // If there's more than one answer add a new line.
- if (answers.size() > 1) {
-
- println();
- }
-
- // Increment index
- answerIndex++;
}
// Signal that the command has finished and display prompt
runningCommand = false;
printPrompt();
}
- };
+ }
+
}
More information about the Mulgara-svn
mailing list