| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.openide.execution; |
| |
| import java.security.AllPermission; |
| import java.security.CodeSource; |
| import java.security.PermissionCollection; |
| import java.security.Permissions; |
| import org.openide.util.Lookup; |
| import org.openide.util.RequestProcessor; |
| import org.openide.util.lookup.Lookups; |
| import org.openide.windows.InputOutput; |
| |
| /** |
| * Engine providing the environment necessary to run long-lived processes. |
| * May perform tasks such as setting up thread groups, etc. |
| * Modules should not implement this class. |
| * <p> |
| * <b>Note for implementors</b>: it is highly advised that the value {@code Lookup#getDefault} is saved, |
| * and established in the forked thread before the executed {@link Runnable} is called. This is |
| * done by OpenIDE libraries If the ExecutionEngine implementation uses {@link RequestProcessor} for |
| * planning the tasks. |
| * |
| * @author Jaroslav Tulach, Ales Novak |
| */ |
| public abstract class ExecutionEngine extends Object { |
| |
| /** |
| * Run some task in the execution engine. |
| * @param name a name of the new process |
| * @param run a runnable to execute |
| * @param io an I/O handle to automatically redirect system I/O streams in the dynamic scope of the task to, |
| * or InputOutput.NULL if no such redirection is required |
| * @return an executor task that can control the execution |
| */ |
| public abstract ExecutorTask execute(String name, Runnable run, InputOutput io); |
| |
| /** |
| * Users that want to link their classes with NetBeans module classes should do this through |
| * internal execution. The {@link NbClassLoader} used in internal execution will assume that calling |
| * this method and giving the permission collection to the class being defined will |
| * trigger automatic redirection of system output, input, and error streams into the given I/O tab. |
| * Implementations of the engine should bind the tab and returned permissions. |
| * Since the permission collection is on the stack when calling methods on {@link System#out} etc., |
| * it is possible to find the appropriate tab for redirection. |
| * @param cs code source to construct the permission collection for |
| * @param io an I/O tab |
| * @return a permission collection |
| */ |
| protected abstract PermissionCollection createPermissions(CodeSource cs, InputOutput io); |
| |
| /** Method that allows implementor of the execution engine to provide |
| * class path to all libraries that one could find useful for development |
| * in the system. |
| * |
| * @return class path to libraries |
| * @deprecated There are generally no excuses to be using this method as part of a normal module; |
| * its exact meaning is vague, and probably not what you want. |
| */ |
| protected abstract NbClassPath createLibraryPath (); |
| |
| /** |
| * Obtains default instance of the execution engine. |
| * If default {@link Lookup} contains an instance of {@link ExecutionEngine}, |
| * that is used. Otherwise, a trivial basic implementation is returned with |
| * the following behavior: |
| * <ul> |
| * <li>{@link #execute} just runs the runnable immediately and pretends to be done. |
| * <li>{@link #createPermissions} just uses {@link AllPermission}. No I/O redirection |
| * or {@link System#exit} trapping is done. |
| * <li>{@link #createLibraryPath} produces an empty path. |
| * </ul> |
| * This basic implementation is helpful in unit tests and perhaps in standalone usage |
| * of other libraries. |
| * @return some execution engine implementation (never null) |
| * @since 2.16 |
| */ |
| public static ExecutionEngine getDefault() { |
| ExecutionEngine ee = (ExecutionEngine) Lookup.getDefault().lookup(ExecutionEngine.class); |
| if (ee == null) { |
| ee = new Trivial(); |
| } |
| return ee; |
| } |
| |
| /** |
| * Dummy fallback implementation, useful for unit tests. |
| */ |
| static final class Trivial extends ExecutionEngine { |
| |
| public Trivial() {} |
| |
| protected NbClassPath createLibraryPath() { |
| return new NbClassPath(new String[0]); |
| } |
| |
| protected PermissionCollection createPermissions(CodeSource cs, InputOutput io) { |
| PermissionCollection allPerms = new Permissions(); |
| allPerms.add(new AllPermission()); |
| allPerms.setReadOnly(); |
| return allPerms; |
| } |
| |
| public ExecutorTask execute(String name, Runnable run, InputOutput io) { |
| return new ET(run, name, io); |
| } |
| |
| private static final class ET extends ExecutorTask { |
| private final Lookup originalLookup; |
| private RequestProcessor.Task task; |
| private int resultValue; |
| private final String name; |
| private final InputOutput io; |
| |
| public ET(Runnable run, String name, InputOutput io) { |
| super(run); |
| this.originalLookup = Lookup.getDefault(); |
| this.resultValue = resultValue; |
| this.name = name; |
| this.io = io; |
| task = RequestProcessor.getDefault().post(this); |
| } |
| |
| public void stop() { |
| task.cancel(); |
| } |
| |
| public int result() { |
| waitFinished(); |
| return resultValue; |
| } |
| |
| public InputOutput getInputOutput() { |
| return io; |
| } |
| |
| public void run() { |
| Lookups.executeWith(originalLookup, () -> { |
| try { |
| super.run(); |
| } catch (RuntimeException x) { |
| x.printStackTrace(); |
| resultValue = 1; |
| } |
| }); |
| } |
| |
| } |
| |
| } |
| |
| } |