//----------------------------------------------------------------------------
// COMPONENT NAME: LPEX Editor
//
// © Copyright IBM Corporation 2006
// All Rights Reserved.
//
// DESCRIPTION:
// ExecCommand - sample user-defined command (exec)
//----------------------------------------------------------------------------
package com.ibm.lpex.samples;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import com.ibm.lpex.core.LpexCommand;
import com.ibm.lpex.core.LpexStringTokenizer;
import com.ibm.lpex.core.LpexView;
/**
* Sample command <b>exec</b> - execute the specified file, visible selected
* text, or current line as editor commands. This command is similar to the
* <b>execCommand</b> editor action, but extends it to allow the execution of
* several editor commands. Comment lines, starting with <code>"//"</code>,
* are ignored.
*
* <p>Here is the ExecCommand
* <a href="doc-files/ExecCommand.java.html">source code</a>.</p>
*
* <p>To run this sample:
* <ul>
* <li>Define this user command via an editor preference page, where available,
* or from the editor command line:
* <pre>set commandClass.exec com.ibm.lpex.samples.ExecCommand</pre></li>
* <li>Run it from the editor command line:
* <pre>exec [<i>fileName</i>]</pre></li>
* </ul></p>
*
* @see com.ibm.lpex.samples All the samples
*/
public class ExecCommand implements LpexCommand
{
boolean _inExec;
/**
* Runs this command.
* Executes the specified file, selected text, or current line as editor commands.
*
* @param lpexView the document view in which the command was issued
* @param fileName optional name of a file to use
*/
public boolean doCommand(LpexView lpexView, String fileName)
{
if ("?".equals(fileName.trim())) // command help
{
lpexView.doCommand("set messageText Syntax: exec [<file name>]");
return true;
}
// prevent recursive calls
if (_inExec)
{
if (lpexView != null)
{
lpexView.doCommand("set messageText Command \"exec\" already in progress, canceled.");
}
return true;
}
/**/ _inExec = true;
fileName = LpexStringTokenizer.trimQuotes(fileName.trim());
if (fileName.length() != 0)
{
exec(lpexView, fileName);
}
else
{
exec(lpexView);
}
/**/ _inExec = false;
return true;
}
/**
* Executes as editor commands the lines in the specified text file.
*/
private void exec(LpexView lpexView, String fileName)
{
BufferedReader br = null;
try
{
br = new BufferedReader(new FileReader(fileName));
for (String line; (line = br.readLine()) != null;)
{
execOneLine(lpexView, line);
}
}
catch (IOException e)
{
if (lpexView != null)
{
lpexView.doCommand("set messageText Cannot read file \"" + fileName + "\".");
}
}
finally
{
if (br != null)
{
try
{
br.close();
}
catch(Exception e) {} // ignore exceptions on close
}
}
}
/**
* Executes as editor commands any visible selection, or else the current element.
*/
private void exec(LpexView lpexView)
{
if (lpexView != null)
{
String commands = lpexView.query("block.text");
if (commands == null)
{
commands = lpexView.query("text");
}
if (commands != null)
{
String[] lines = commands.split("\\r\\n|\\r|\\n");
for (int i = 0; i < lines.length; i++)
{
execOneLine(lpexView, lines[i]);
}
}
}
}
/**
* Executes the editor command in the given line of text.
* It the text starts with a comment "//", it is ignored.
* @return true the line is correct (empty / comment / valid editor command)
*/
private boolean execOneLine(LpexView lpexView, String text)
{
int i = 0;
// skip leading whitespace
while (i < text.length() && (text.charAt(i) == ' ' || text.charAt(i) == '\t')) { i++; }
// ignore comment "//" lines
if (text.startsWith("//", i))
{
return true;
}
if (i != 0)
{
text = text.substring(i);
}
// if there is anything in the line, run it
return (text.length() == 0)? true :
(lpexView != null)? lpexView.doCommand(text) :
LpexView.doGlobalCommand(text);
}
}