/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2010, Red Hat Middleware LLC, and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.modules;

import java.io.File;
import java.lang.reflect.InvocationTargetException;

public final class Main {

    private Main() {
    }

    public static String getJarName() {
        return "UNSET";
    }

    public static String getVersionString() {
        return "TRUNK SNAPSHOT";
    }

    private static void usage() {
        System.out.println("Usage: java [-jvmoptions...] -jar " + getJarName() + ".jar [-options...] <module-spec> [args...]\n");
        System.out.println("where options include:");
        System.out.println("    -help         Display this message");
        System.out.println("    -modulepath <search path of directories>");
        System.out.println("    -mp <search path of directories>");
        System.out.println("                  A list of directories, separated by '" + File.pathSeparator + "', where modules may be located");
        System.out.println("                  If not specified, the value of the \"module.path\" system property is used");
        System.out.println("    -version      Print version and exit\n");
        System.out.println("and module-spec is a valid module specification string");
    }

    public static void main(String[] args) throws Throwable {
        final int argsLen = args.length;
        String[] moduleArgs = null;
        String modulePath = null;
        ModuleIdentifier moduleIdentifier = null;
        for (int i = 0, argsLength = argsLen; i < argsLength; i++) {
            final String arg = args[i];
            try {
                if (arg.charAt(0) == '-') {
                    // it's an option
                    if ("-version".equals(arg)) {
                        System.out.println("Module loader " + getVersionString());
                        return;
                    } else if ("-help".equals(arg)) {
                        usage();
                        return;
                    } else if ("-modulepath".equals(arg) || "-mp".equals(arg)) {
                        if (modulePath != null) {
                            System.err.println("Module path may only be specified once");
                            System.exit(1);
                        }
                        modulePath = args[++i];
                        System.setProperty("module.path", modulePath);
                    } else {
                        System.err.printf("Invalid option '%s'\n", arg);
                        usage();
                        System.exit(1);
                    }
                } else {
                    // it's the module specification
                    moduleIdentifier = ModuleIdentifier.fromString(arg);
                    int cnt = argsLen - i - 1;
                    moduleArgs = new String[cnt];
                    System.arraycopy(args, i + 1, moduleArgs, 0, cnt);
                    break;
                }
            } catch (IndexOutOfBoundsException e) {
                System.err.printf("Argument expected for option %s\n", arg);
                usage();
                System.exit(1);
            }
        }
        // run the module
        if (moduleIdentifier == null) {
            System.err.println("No module specified");
            usage();
            System.exit(1);
        }
        final ModuleLoader loader = InitialModuleLoader.INSTANCE;
        final Module module;
        try {
            module = loader.loadModule(moduleIdentifier);
        } catch (ModuleNotFoundException e) {
            e.printStackTrace(System.err);
            System.exit(1);
            return;
        }
        try {
            module.run(moduleArgs);
        } catch (InvocationTargetException e) {
            throw e.getCause();
        }
        return;
    }
}
@@ -1126,16 +1126,132 @@
 ception;
+%0Aimport java.security.AccessController;%0Aimport java.security.PrivilegedAction;%0A%0Aimport java.util.logging.LogManager;
 %0A%0Apublic
@@ -2152,24 +2152,181 @@
  is used%22);%0A
+        System.out.println(%22    -logmodule %3Cmodule-name%3E%22);%0A        System.out.println(%22                  The module to use to load the system logmanager%22);%0A
         Syst
@@ -2695,32 +2695,92 @@
 ntifier = null;%0A
+        ModuleIdentifier logManagerModuleIdentifier = null;%0A
         for (int
@@ -3666,16 +3666,168 @@
 ePath);%0A
+                    %7D else if (%22-logmodule%22.equals(arg)) %7B%0A                        logManagerModuleIdentifier = ModuleIdentifier.fromString(args%5B++i%5D);%0A
         
@@ -4835,16 +4835,399 @@
 STANCE;%0A
+        if (logManagerModuleIdentifier != null) %7B%0A            final ModuleClassLoader classLoader = ModuleClassLoader.forModule(logManagerModuleIdentifier);%0A            final ClassLoader old = setContextClassLoader(classLoader);%0A            try %7B%0A                LogManager.getLogManager();%0A            %7D finally %7B%0A                setContextClassLoader(old);%0A            %7D%0A        %7D%0A
         
@@ -5598,32 +5598,32 @@
 se();%0A        %7D%0A
-
         return;%0A
@@ -5627,10 +5627,762 @@
 n;%0A    %7D
+%0A%0A    private static ClassLoader setContextClassLoader(final ClassLoader classLoader) %7B%0A        final SecurityManager sm = System.getSecurityManager();%0A        if (sm != null) %7B%0A            return AccessController.doPrivileged(new PrivilegedAction%3CClassLoader%3E() %7B%0A                public ClassLoader run() %7B%0A                    return doSetContextClassLoader(classLoader);%0A                %7D%0A            %7D);%0A        %7D%0A        return doSetContextClassLoader(classLoader);%0A    %7D%0A%0A    private static ClassLoader doSetContextClassLoader(final ClassLoader classLoader) %7B%0A        try %7B%0A            return Thread.currentThread().getContextClassLoader();%0A        %7D finally %7B%0A            Thread.currentThread().setContextClassLoader(classLoader);%0A        %7D%0A    %7D
 %0A%7D

Add logmanager module feature