package abstrasy.libraries.os;
import abstrasy.Bivalence;
import abstrasy.Node;
import abstrasy.SELF;
import abstrasy.externals.AExtCachable;
import abstrasy.externals.AExtClonable;
import abstrasy.externals.AExtTools;
import abstrasy.interpreter.InterpreterException;
import abstrasy.interpreter.ORef;
import abstrasy.interpreter.StdErrors;
import abstrasy.libraries.io.External_File;
import abstrasy.privates.Private_Execute;
import java.io.File;
/**
* Abstrasy Interpreter
*
* Copyright : Copyright (c) 2006-2012, Luc Bruninx.
*
* Concédée sous licence EUPL, version 1.1 uniquement (la «Licence»).
*
* Vous ne pouvez utiliser la présente oeuvre que conformément à la Licence.
* Vous pouvez obtenir une copie de la Licence à l’adresse suivante:
*
* http://www.osor.eu/eupl
*
* Sauf obligation légale ou contractuelle écrite, le logiciel distribué sous
* la Licence est distribué "en l’état", SANS GARANTIES OU CONDITIONS QUELLES
* QU’ELLES SOIENT, expresses ou implicites.
*
* Consultez la Licence pour les autorisations et les restrictions
* linguistiques spécifiques relevant de la Licence.
*
*
* @author Luc Bruninx
* @version 1.0
*/
public class External_ShellProcess extends AExtTools implements AExtClonable,
AExtCachable {
boolean inUse = false;
private Private_Execute proc = null;
private File pwd = null;
private String command = "";
private Node stdout = null;
private Node stderr = null;
private Node stdin = null;
private int exitCode = -1;
public External_ShellProcess() {
}
private Node create_File_adp(External_File efile) throws Exception {
return Node.createExternal(efile);
}
public Node external_mutator_exec(Node startAt) throws Exception {
if (inUse)
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "ShellProcess is already runing"));
startAt.isGoodArgsLength(true, 2);
SELF.require_SELF_mutable();
command = startAt.getSubNode(1, Node.TYPE_STRING).getString();
inUse=true;
exitCode=-1;
proc = new Private_Execute();
proc.setCommand(command);
proc.setPWD(pwd);
proc.popen();
External_File eofile = new External_File();
eofile.setInputStream(proc.getStdOut());
stdout=create_File_adp(eofile);
External_File eefile = new External_File();
eefile.setInputStream(proc.getStdErr());
stderr=create_File_adp(eefile);
External_File eifile = new External_File();
eifile.setOutputStream(proc.getStdIn());
stdin=create_File_adp(eifile);
return null;
}
public Node external_get_command(Node startAt) throws Exception {
if (!inUse) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "ShellProcess is not runing"));
}
startAt.isGoodArgsLength(true, 1);
return new Node(command);
}
public Node external_get_stdout(Node startAt) throws Exception {
if (!inUse) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "ShellProcess is not runing"));
}
startAt.isGoodArgsLength(true, 1);
return stdout;
}
public Node external_get_stderr(Node startAt) throws Exception {
if (!inUse) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "ShellProcess is not runing"));
}
startAt.isGoodArgsLength(true, 1);
return stderr;
}
public Node external_get_stdin(Node startAt) throws Exception {
if (!inUse) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "ShellProcess is not runing"));
}
startAt.isGoodArgsLength(true, 1);
return stdin;
}
public Node external_get_exitCode(Node startAt) throws Exception {
if (inUse) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "ShellProcess is runing"));
}
startAt.isGoodArgsLength(true, 1);
return new Node(exitCode);
}
public Node external_wait_for_end(Node startAt) throws Exception {
if (!inUse) {
return null;
}
startAt.isGoodArgsLength(true, 1);
if(proc!=null){
proc.waitProcess();
exitCode=proc.getExitCode();
}
proc=null;
((External_File) stdout.getExternalInstanceOf(External_File.class)).internal_close();
((External_File) stderr.getExternalInstanceOf(External_File.class)).internal_close();
((External_File) stdin.getExternalInstanceOf(External_File.class)).internal_close();
stdout=null;
stdin=null;
stderr=null;
inUse=false;
return null;
}
public Node external_mutator_set_pwd(Node startAt) throws Exception {
if (inUse) {
throw new InterpreterException(StdErrors.extend(StdErrors.Already_used, "ShellProcess is runing"));
}
startAt.isGoodArgsLength(true, 2);
SELF.require_SELF_mutable();
File d=new File(startAt.getSubNode(1, Node.TYPE_STRING).getString());
if(!d.exists()){
throw new InterpreterException(StdErrors.extend(StdErrors.Invalid_parameter,"directory does not exist"));
}
if(!d.isDirectory()){
throw new InterpreterException(StdErrors.extend(StdErrors.Invalid_parameter,"pwd must be a directory"));
}
pwd=d;
return null;
}
public Node external_get_pwd(Node startAt) throws Exception {
startAt.isGoodArgsLength(true, 1);
return pwd==null ? Node.createNothing() : new Node(pwd.getAbsolutePath());
}
public String toString() {
return command;
}
@Override
public Object clone_my_self(Bivalence bival) {
return null;
}
/*
* ----------------------------------------------------------------------------
*
* Optimisation par cache d'instanciantion (mars 2012) rev 1.0-6321.0
*
* ----------------------------------------------------------------------------
*/
private static ORef _optim_symbols_cache_ = new ORef();
@Override
public Object getSymbolsCache() {
return _optim_symbols_cache_.getRef();
}
@Override
public void setSymbolsCache(Object cache) {
_optim_symbols_cache_.setRef(cache);
}
}