| /******************************************************************************* |
| * Copyright (c) 2020 Hannes Wellmann and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * Hannes Wellmann - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.debug.tests.console; |
| |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Optional; |
| import java.util.concurrent.CompletableFuture; |
| import java.util.stream.Collectors; |
| import java.util.stream.Stream; |
| |
| /** |
| * A mockup ProcessHandle which works in conjunction with {@link MockProcess}. |
| */ |
| public class MockProcessHandle implements ProcessHandle { |
| |
| private final MockProcess process; |
| private final Collection<ProcessHandle> children; |
| private final CompletableFuture<ProcessHandle> onExit = new CompletableFuture<>(); |
| |
| /** |
| * Create new mockup process handle for a process without children. |
| * |
| * @param process the process of this handle |
| */ |
| public MockProcessHandle(MockProcess process) { |
| this(process, Collections.emptyList()); |
| } |
| |
| /** |
| * Create new mockup process handle for a process with the given children. |
| * |
| * @param process the process of this handle |
| * @param children the child-processes of the given process |
| */ |
| public MockProcessHandle(MockProcess process, Collection<Process> children) { |
| this.process = process; |
| this.children = children.stream().map(Process::toHandle).collect(Collectors.toUnmodifiableList()); |
| } |
| |
| @Override |
| public Stream<ProcessHandle> children() { |
| return this.children.stream(); |
| } |
| |
| @Override |
| public Stream<ProcessHandle> descendants() { |
| return Stream.concat(children(), children().flatMap(ProcessHandle::descendants)); |
| } |
| |
| @Override |
| public CompletableFuture<ProcessHandle> onExit() { |
| return onExit; // onExit must be completed by process |
| } |
| |
| @Override |
| public boolean supportsNormalTermination() { |
| return true; |
| } |
| |
| @Override |
| public boolean destroy() { |
| process.destroy(); |
| return true; |
| } |
| |
| @Override |
| public boolean destroyForcibly() { |
| return destroy(); |
| } |
| |
| @Override |
| public boolean isAlive() { |
| return process.isAlive(); |
| } |
| |
| @Override |
| public int compareTo(ProcessHandle other) { |
| return Long.compare(pid(), ((MockProcessHandle) other).pid()); |
| } |
| |
| /** |
| * Notify this handle that this mock-process has terminated. If this is not |
| * called handles of descendant processes do not know about the termination |
| * (and for descendants only the handle is queried, not the process itself). |
| */ |
| void setTerminated() { |
| onExit.complete(this); |
| } |
| |
| // not yet implemented methods |
| |
| @Override |
| public long pid() { |
| throw new UnsupportedOperationException("Not yet implemented"); |
| } |
| |
| @Override |
| public Optional<ProcessHandle> parent() { |
| throw new UnsupportedOperationException("Not yet implemented"); |
| } |
| |
| @Override |
| public Info info() { |
| throw new UnsupportedOperationException("Not yet implemented"); |
| } |
| } |