Package org.jboss.arquillian.container.appengine.embedded.hack

Source Code of org.jboss.arquillian.container.appengine.embedded.hack.DevAppServerFactoryHack

package org.jboss.arquillian.container.appengine.embedded.hack;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.security.Permission;
import java.util.HashMap;
import java.util.Map;
import java.util.PropertyPermission;

import com.google.appengine.tools.development.AppContext;
import com.google.appengine.tools.development.DevAppServer;
import com.google.appengine.tools.development.DevAppServerClassLoaderExposed;
import com.google.appengine.tools.development.DevAppServerFactory;

/**
* DevAppServerFactory
*
* @author Google GAE team
*/
public class DevAppServerFactoryHack {
    private static final Class[] DEV_APPSERVER_CTOR_ARG_TYPES = {File.class, File.class, File.class, File.class, String.class, Integer.TYPE, Boolean.TYPE, Map.class};

    public static DevAppServer createDevAppServer(File appLocation, String bindAddress, int bindHttpPort) {
        return createDevAppServer(new Object[]{appLocation, null, null, null, bindAddress, bindHttpPort, true, new HashMap()});
    }

    private static DevAppServer createDevAppServer(Object[] ctorArgs) {
        ClassLoader loader = DevAppServerClassLoaderExposed.newClassLoader(DevAppServerFactory.class.getClassLoader());

        DevAppServer devAppServer;
        try {
            Class<?> devAppServerClass = Class.forName("com.google.appengine.tools.development.DevAppServerImpl", true, loader);
            Constructor<?> cons = devAppServerClass.getConstructor(DEV_APPSERVER_CTOR_ARG_TYPES);
            cons.setAccessible(true);
            devAppServer = (DevAppServer) cons.newInstance(ctorArgs);
        } catch (Exception e) {
            Throwable t = e;
            if (e instanceof InvocationTargetException) {
                t = e.getCause();
            }
            throw new RuntimeException("Unable to create a DevAppServer", t);
        }
        System.setSecurityManager(new CustomSecurityManager(devAppServer));
        return devAppServer;
    }

    private static class CustomSecurityManager extends SecurityManager {
        private static final RuntimePermission PERMISSION_MODIFY_THREAD_GROUP = new RuntimePermission("modifyThreadGroup");

        private static final RuntimePermission PERMISSION_MODIFY_THREAD = new RuntimePermission("modifyThread");

        private static final String KEYCHAIN_JNILIB = "/libkeychain.jnilib";

        private static final Object PERMISSION_LOCK = new Object();

        private final DevAppServer devAppServer;

        public CustomSecurityManager(DevAppServer devAppServer) {
            this.devAppServer = devAppServer;
        }

        private synchronized boolean appHasPermission(Permission perm) {
            synchronized (PERMISSION_LOCK) {
                AppContext context = this.devAppServer.getAppContext();
                if ((context.getUserPermissions().implies(perm)) || (context.getApplicationPermissions().implies(perm))) {
                    return true;
                }
            }
            return ("read".equals(perm.getActions())) && (perm.getName().endsWith(KEYCHAIN_JNILIB));
        }

        public void checkPermission(Permission perm) {
            if (perm instanceof PropertyPermission) {
                return;
            }

            if (isDevAppServerThread()) {
                if (appHasPermission(perm)) {
                    return;
                }
                super.checkPermission(perm);
            }
        }

        public void checkPermission(Permission perm, Object context) {
            if (isDevAppServerThread()) {
                if (appHasPermission(perm)) {
                    return;
                }
                super.checkPermission(perm, context);
            }
        }

        public void checkAccess(ThreadGroup g) {
            if (g == null) {
                throw new NullPointerException("thread group can't be null");
            }
            checkPermission(PERMISSION_MODIFY_THREAD_GROUP);
        }

        public void checkAccess(Thread t) {
            if (t == null) {
                throw new NullPointerException("thread can't be null");
            }
            checkPermission(PERMISSION_MODIFY_THREAD);
        }

        public boolean isDevAppServerThread() {
            return Boolean.getBoolean("devappserver-thread-" + Thread.currentThread().getName());
        }
    }
}
TOP

Related Classes of org.jboss.arquillian.container.appengine.embedded.hack.DevAppServerFactoryHack

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.