package php.runtime.ext.core.classes; import php.runtime.Memory; import php.runtime.common.HintType; import php.runtime.env.Environment; import php.runtime.ext.core.classes.stream.FileObject; import php.runtime.ext.core.classes.stream.MiscStream; import php.runtime.lang.BaseObject; import php.runtime.lang.ForeachIterator; import php.runtime.memory.ArrayMemory; import php.runtime.memory.LongMemory; import php.runtime.memory.ObjectMemory; import php.runtime.reflection.ClassEntity; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import static php.runtime.annotation.Reflection.*; @Name("php\\lang\\Process") public class WrapProcess extends BaseObject { protected Process process; protected ProcessBuilder processBuilder; public WrapProcess(Environment env, Process process) { super(env); this.process = process; } public WrapProcess(Environment env, ClassEntity clazz) { super(env, clazz); } @Signature({ @Arg(value = "commands", type = HintType.ARRAY), @Arg(value = "directory", optional = @Optional("NULL")), @Arg(value = "environment", type = HintType.ARRAY, optional = @Optional("NULL")) }) public Memory __construct(Environment env, Memory... args) { if (args[0].isNull()) processBuilder = new ProcessBuilder(); else processBuilder = new ProcessBuilder(args[0].toValue(ArrayMemory.class).toStringArray()); if (!args[1].isNull()) { processBuilder.directory(FileObject.valueOf(args[1])); } if (!args[2].isNull()) { ForeachIterator iterator = args[2].getNewIterator(env); while (iterator.next()) { processBuilder.environment().put(iterator.getKey().toString(), iterator.getValue().toString()); } } return Memory.NULL; } protected Process getProcess() { if (process == null) throw new IllegalStateException("Process is not started, use the start() method to initialize it"); return process; } @Signature public Memory start(Environment env, Memory... args) throws IOException { if (processBuilder == null) throw new IllegalStateException("Process is final and it cannot start new ones"); Process process1 = processBuilder.start(); WrapProcess wrapProcess = new WrapProcess(env, process1); wrapProcess.processBuilder = processBuilder; return new ObjectMemory(wrapProcess); } @Signature public Memory startAndWait(Environment env, Memory... args) throws IOException, InterruptedException { Memory r = start(env, args); r.toObject(WrapProcess.class).process.waitFor(); return r; } @Signature public Memory getExitValue(Environment env, Memory... args) { try { return LongMemory.valueOf(getProcess().exitValue()); } catch (IllegalThreadStateException e) { return Memory.NULL; } } @Signature public Memory getInput(Environment env, Memory... args) { return new ObjectMemory(new MiscStream(env, getProcess().getInputStream())); } @Signature public Memory getOutput(Environment env, Memory... args) { return new ObjectMemory(new MiscStream(env, getProcess().getOutputStream())); } @Signature public Memory getError(Environment env, Memory... args) { return new ObjectMemory(new MiscStream(env, getProcess().getErrorStream())); } @Signature(@Arg(value = "force", optional = @Optional("false"))) public void destroy(Environment env, Memory... args) throws Throwable { if (args[0].toBoolean()) { Process process = getProcess(); Method destroyForcibly = process.getClass().getMethod("destroyForcibly"); try { destroyForcibly.invoke(process); } catch (InvocationTargetException e) { throw e.getTargetException(); } } else { getProcess().destroy(); } } }