/*
* Copyright 2015 Red Hat, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*
*
* Copyright (c) 2015 The original author or authors
* ------------------------------------------------------
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* and Apache License v2.0 which accompanies this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* The Apache License v2.0 is available at
* http://www.opensource.org/licenses/apache2.0.php
*
* You may elect to redistribute this code under either of these licenses.
*
*/
package io.vertx.ext.shell.system.impl;
import io.vertx.core.Handler;
import io.vertx.core.Promise;
import io.vertx.ext.shell.session.Session;
import io.vertx.ext.shell.system.Process;
import io.vertx.ext.shell.term.Tty;
import io.vertx.ext.shell.system.Job;
import io.vertx.ext.shell.system.ExecStatus;
Author: Julien Viet
/**
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
*/
public class JobImpl implements Job {
final int id;
final JobControllerImpl controller;
final Process process;
final String line;
private volatile ExecStatus actualStatus; // Used internally for testing only
volatile long lastStopped; // When the job was last stopped
volatile Tty tty;
volatile Session session;
volatile Handler<ExecStatus> statusUpdateHandler;
final Promise<Void> terminatePromise;
JobImpl(int id, JobControllerImpl controller, Process process, String line) {
this.id = id;
this.controller = controller;
this.process = process;
this.line = line;
this.terminatePromise = Promise.promise();
process.terminatedHandler(exitCode -> {
if (controller.foregroundJob == this) {
controller.foregroundJob = null;
if (controller.foregroundUpdatedHandler != null) {
controller.foregroundUpdatedHandler.handle(null);
}
}
controller.removeJob(JobImpl.this.id);
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(ExecStatus.TERMINATED);
}
terminatePromise.complete();
});
}
@Override
public Job setSession(Session session) {
this.session = session;
return this;
}
public ExecStatus actualStatus() {
return actualStatus;
}
@Override
public Job statusUpdateHandler(Handler<ExecStatus> handler) {
statusUpdateHandler = handler;
return this;
}
@Override
public boolean interrupt() {
return process.interrupt();
}
@Override
public Job resume(boolean foreground) {
if (controller.foregroundJob != null) {
throw new IllegalStateException();
}
try {
process.resume(foreground, v -> {
actualStatus = ExecStatus.RUNNING;
});
} catch (IllegalStateException ignore) {
}
if (foreground) {
controller.foregroundJob = this;
if (controller.foregroundUpdatedHandler != null) {
controller.foregroundUpdatedHandler.handle(this);
}
}
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
return this;
}
@Override
public Job suspend() {
try {
process.suspend(v -> {
actualStatus = ExecStatus.STOPPED;
});
} catch (IllegalStateException ignore) {
return this;
}
if (controller.foregroundJob == this) {
controller.foregroundJob = null;
if (controller.foregroundUpdatedHandler != null) {
controller.foregroundUpdatedHandler.handle(null);
}
}
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
return this;
}
@Override
public void terminate() {
try {
process.terminate();
} catch (IllegalStateException ignore) {
// Process already terminated, likely by itself
}
}
@Override
public Process process() {
return process;
}
public long lastStopped() {
return lastStopped;
}
public ExecStatus status() {
return process.status();
}
public String line() {
return line;
}
@Override
public Job toBackground() {
if (controller.foregroundJob == this) {
controller.foregroundJob = null;
process.toBackground();
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
}
return this;
}
@Override
public Job toForeground() {
if (controller.foregroundJob != null) {
throw new IllegalStateException();
}
controller.foregroundJob = this;
if (controller.foregroundUpdatedHandler != null) {
controller.foregroundUpdatedHandler.handle(this);
}
process.toForeground();
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(process.status());
}
return this;
}
@Override
public int id() {
return id;
}
@Override
public Job setTty(Tty tty) {
this.tty = tty;
return this;
}
@Override
public Job run() {
controller.foregroundJob = this;
if (controller.foregroundUpdatedHandler != null) {
controller.foregroundUpdatedHandler.handle(this);
}
actualStatus = ExecStatus.RUNNING;
if (statusUpdateHandler != null) {
statusUpdateHandler.handle(ExecStatus.RUNNING);
}
process.setTty(tty);
process.setSession(session);
process.run();
return this;
}
}