Package ch.cmbntr.modulizer.modules

Source Code of ch.cmbntr.modulizer.modules.ModulizerModulesUtil$MainRunner

package ch.cmbntr.modulizer.modules;

import static ch.cmbntr.modulizer.bootstrap.util.SystemPropertyHelper.restoreProps;
import static ch.cmbntr.modulizer.bootstrap.util.SystemPropertyHelper.snapshotProps;

import java.io.File;
import java.io.IOException;
import java.lang.Thread.UncaughtExceptionHandler;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

import org.jboss.modules.LocalModuleLoader;
import org.jboss.modules.Main;
import org.jboss.modules.Module;
import org.jboss.modules.ModuleIdentifier;

import ch.cmbntr.modulizer.bootstrap.util.ModulizerLog.ExceptionLogger;
import ch.cmbntr.modulizer.bootstrap.util.Resources;
import ch.cmbntr.modulizer.bootstrap.util.Resources.Pool;

public class ModulizerModulesUtil {

  private static final Class<?>[] LAUNCH_SIGNATURE = { File.class, String.class, String[].class };

  private ModulizerModulesUtil() {
    super();
  }

  public static List<Module> loadModules(final Iterable<String> moduleIdentifiers, final File... repoRoots) {
    final Pool pool = Resources.getPoolHandle();
    final ExecutorService exec = pool.aquireExec();
    final Properties origProps = snapshotProps();
    try {
      final LocalModuleLoader loader = new LocalModuleLoader(repoRoots);
      final List<Future<Module>> asyncModules = new LinkedList<Future<Module>>();
      for (final String moduleIdentifier : moduleIdentifiers) {
        asyncModules.add(exec.submit(new Callable<Module>() {
          @Override
          public Module call() throws Exception {
            return loader.loadModule(ModuleIdentifier.fromString(moduleIdentifier));
          }
        }));
      }

      final List<Module> modules = new ArrayList<Module>(asyncModules.size());
      for (final Future<Module> m : asyncModules) {
        modules.add(Resources.get(m, "failed to load module"));
      }
      return modules;
    } finally {
      restoreProps(origProps);
      pool.releaseExec(exec);
    }
  }

  public static CountDownLatch invokeModulesMain(final File modulesRepo, final String mainModule, final String... args) {
    return invokeModulesMain(mainModule, modulesRepo, mainModule, args);
  }

  public static CountDownLatch invokeModulesMain(final String appName, final File modulesRepo, final String mainModule,
      final String... args) {
    final String threadName = String.format("main[%s]", appName);
    return invokeModulesMain(threadName, ExceptionLogger.create(), modulesRepo, mainModule, args);
  }

  private static CountDownLatch invokeModulesMain(final String threadName,
      final UncaughtExceptionHandler exceptionHandler, final File modulesRepo, final String mainModule,
      final String... args) {
    final CountDownLatch running = new CountDownLatch(1);
    final CountDownLatch done = new CountDownLatch(1);
    startAndAwaitRunning(createThread(threadName, running, done, exceptionHandler, modulesRepo, mainModule, args),
        running);
    return done;
  }

  private static Thread createThread(final String threadName, final CountDownLatch running, final CountDownLatch done,
      final UncaughtExceptionHandler exceptionHandler, final File modulesRepo, final String mainModule,
      final String... args) {
    final Thread t = Resources.newThread(threadName, MainRunner.create(running, done, modulesRepo, mainModule, args));
    if (exceptionHandler != null) {
      t.setUncaughtExceptionHandler(exceptionHandler);
    }
    return t;
  }

  private static void startAndAwaitRunning(final Thread t, final CountDownLatch running) {
    t.start();
    try {
      running.await();
    } catch (final InterruptedException e) {
      Thread.currentThread().interrupt();
    }
  }

  public static void invokeModulesMainAndWait(final File modulesRepo, final String mainModule, final String... args) {
    try {
      Main.main(assembleRunArguments(modulesRepo, mainModule, args));
    } catch (final Throwable e) {
      if (e instanceof RuntimeException) {
        throw (RuntimeException) e;
      }
      throw new RuntimeException(e);
    }
  }

  private static String[] assembleRunArguments(final File modulesRepo, final String mainModule, final String... args)
      throws IOException {
    final String repoPath = modulesRepo.getCanonicalFile().getAbsolutePath();
    final String[] basicArgs = { "-modulepath", repoPath, mainModule };
    if (args != null) {
      final int argsCount = args.length;
      if (args.length > 0) {
        final int basicCount = basicArgs.length;
        final String[] fullArgs = new String[basicCount + argsCount];
        System.arraycopy(basicArgs, 0, fullArgs, 0, basicCount);
        System.arraycopy(args, 0, fullArgs, basicCount, argsCount);
        return fullArgs;
      }
    }
    return basicArgs;
  }

  public static Method getLaunchMethod(final ClassLoader loader, final boolean wait) throws NoSuchMethodException,
      SecurityException, ClassNotFoundException {
    final Class<?> mmu = loader.loadClass(ModulizerModulesUtil.class.getName());
    return mmu.getMethod(wait ? "invokeModulesMainAndWait" : "invokeModulesMain", LAUNCH_SIGNATURE);
  }

  public static void main(final String[] args) throws InterruptedException {
    if (args == null || args.length < 2) {
      System.err.format("Usage: java %s repoPath mainModule [args...]", ModulizerModulesUtil.class.getName());
      System.exit(1);
    } else {

      final File repoPath = new File(args[0]);
      final String mainModule = args[1];
      String[] moduleArgs = null;
      if (args.length > 2) {
        moduleArgs = new String[args.length - 2];
        System.arraycopy(args, 0, moduleArgs, 0, moduleArgs.length);
      }
      final CountDownLatch done = invokeModulesMain(mainModule, repoPath, mainModule, moduleArgs);
      done.await();
      System.exit(0);
    }
  }

  private static final class MainRunner implements Runnable {

    private final CountDownLatch running;
    private final CountDownLatch done;
    private final File modulesRepo;
    private final String mainModule;
    private final String[] args;

    private MainRunner(final CountDownLatch running, final CountDownLatch done, final File modulesRepo,
        final String mainModule, final String... args) {
      this.running = running;
      this.done = done;
      this.modulesRepo = modulesRepo;
      this.mainModule = mainModule;
      this.args = args;
    }

    private static Runnable create(final CountDownLatch running, final CountDownLatch done, final File modulesRepo,
        final String mainModule, final String... args) {
      return new MainRunner(running, done, modulesRepo, mainModule, args);
    }

    @Override
    public void run() {
      try {
        this.running.countDown();
        invokeModulesMainAndWait(this.modulesRepo, this.mainModule, this.args);
      } finally {
        this.done.countDown();
      }
    }
  }

}
TOP

Related Classes of ch.cmbntr.modulizer.modules.ModulizerModulesUtil$MainRunner

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.