/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.shell.bjorne;
import org.jnode.shell.CommandShell;
import org.jnode.shell.CommandThread;
import org.jnode.shell.ShellException;
/**
* This is the base class for parse tree nodes that represent simple
* and compound bjorne commands.
*
* @author crawley@jnode.org
*/
public abstract class CommandNode {
private RedirectionNode[] redirects;
private int nodeType;
private int flags;
/**
* Construct with its initial parse tree node type
* @param nodeType the parse tree node type
*/
public CommandNode(int nodeType) {
this.nodeType = nodeType;
}
/**
* Get the redirection parse tree nodes for this command node
* @return the redirection nodes or {@code null}
*/
public RedirectionNode[] getRedirects() {
return redirects;
}
/**
* Set the redirection parse tree nodes for this command node
* @param redirects the redirection nodes or {@code null}
*/
public void setRedirects(RedirectionNode[] redirects) {
this.redirects = redirects;
}
/**
* Get the parse tree node type
* @return the node type
*/
public int getNodeType() {
return nodeType;
}
/**
* Get the node's flags. The meaning is specific to each CommandNode subclass.
* @return the flags
*/
public int getFlags() {
return flags;
}
/**
* Set (OR) one or more flags
* @param flag
*/
public void setFlag(int flag) {
flags |= flag;
}
/**
* Update the node type.
* @param nodeType
*/
public void setNodeType(int nodeType) {
this.nodeType = nodeType;
}
/**
* Execute this command node with the given bjorne shell context
* @param context the bjorne context
* @return the return code from executing the command node
* @throws ShellException
*/
public abstract int execute(BjorneContext context) throws ShellException;
/**
* Create a CommandThread that will run this command node with the given
* bjorne shell context.
* @param shell our parent CommandShell instance
* @param context the bjorne context
* @return a CommandThread that will run the command node when
* {@link Thread#start()} is called.
* @throws ShellException
*/
public abstract CommandThread fork(CommandShell shell, BjorneContext context)
throws ShellException;
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("nodeType=").append(nodeType);
if (flags != 0) {
sb.append(",flags=0x").append(Integer.toHexString(flags));
}
if (redirects != null) {
sb.append(",redirects=");
appendArray(sb, redirects);
}
return sb.toString();
}
/**
* A helper method for toString() implementations that renders an
* array in a human readable form.
* @param sb the destination for rendering
* @param array the object array to be rendered.
*/
protected static void appendArray(StringBuilder sb, Object[] array) {
sb.append('[');
for (int i = 0; i < array.length; i++) {
if (i > 0) {
sb.append(',');
}
sb.append(array[i]);
}
sb.append(']');
}
/**
* Build a pipeline descriptor for this node.
*
* @param context the bjorne shell context supplying variables, etc
* @return the assembled descriptor or {@code null} if none is needed.
* @throws ShellException
*/
public BjornePipeline buildPipeline(BjorneContext context) throws ShellException {
// FIXME ... I think I need to implement this for all CommandNode subtypes ...
return null;
}
}