Package org.terasology.engine.module

Source Code of org.terasology.engine.module.ModuleManager

/*
* Copyright 2014 MovingBlocks
*
* Licensed 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.terasology.engine.module;

import com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.terasology.engine.TerasologyConstants;
import org.terasology.engine.paths.PathManager;
import org.terasology.module.ClasspathModule;
import org.terasology.module.Module;
import org.terasology.module.ModuleEnvironment;
import org.terasology.module.ModuleLoader;
import org.terasology.module.ModuleMetadata;
import org.terasology.module.ModuleMetadataReader;
import org.terasology.module.ModulePathScanner;
import org.terasology.module.ModuleRegistry;
import org.terasology.module.TableModuleRegistry;
import org.terasology.module.sandbox.APIScanner;
import org.terasology.module.sandbox.BytecodeInjector;
import org.terasology.module.sandbox.ModuleSecurityManager;
import org.terasology.module.sandbox.ModuleSecurityPolicy;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.ReflectPermission;
import java.net.URISyntaxException;
import java.security.Policy;
import java.util.Collections;
import java.util.Set;

/**
* @author Immortius
*/
public class ModuleManager {

    public static final String SERVER_SIDE_ONLY_EXT = "serverSideOnly";
    public static final String IS_GAMEPLAY_EXT = "isGameplay";
    public static final String DEFAULT_WORLD_GENERATOR_EXT = "defaultWorldGenerator";

    private ModuleSecurityManager moduleSecurityManager;

    private ModuleRegistry registry;
    private ModuleEnvironment environment;
    private ModuleMetadataReader metadataReader;

    public ModuleManager() {
        metadataReader = new ModuleMetadataReader();
        metadataReader.registerExtension(SERVER_SIDE_ONLY_EXT, Boolean.TYPE);
        metadataReader.registerExtension(IS_GAMEPLAY_EXT, Boolean.TYPE);
        metadataReader.registerExtension(DEFAULT_WORLD_GENERATOR_EXT, String.class);
        Module engineModule;
        try (Reader reader = new InputStreamReader(getClass().getResourceAsStream("/engine-module.txt"))) {
            ModuleMetadata metadata = metadataReader.read(reader);
            engineModule = ClasspathModule.create(metadata, getClass(), Module.class);
        } catch (IOException e) {
            throw new RuntimeException("Failed to read engine metadata", e);
        } catch (URISyntaxException e) {
            throw new RuntimeException("Failed to convert engine library location to path", e);
        }

        registry = new TableModuleRegistry();
        registry.add(engineModule);
        ModulePathScanner scanner = new ModulePathScanner(new ModuleLoader(metadataReader));
        scanner.getModuleLoader().setModuleInfoPath(TerasologyConstants.MODULE_INFO_FILENAME);
        scanner.scan(registry, PathManager.getInstance().getModulePaths());

        setupSandbox();
        loadEnvironment(Sets.newHashSet(engineModule), true);
    }

    private void setupSandbox() {
        moduleSecurityManager = new ModuleSecurityManager();
        // TODO: This one org.terasology entry is a hack and needs a proper fix
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("org.terasology.world.biomes");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.lang");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.lang.ref");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.math");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.util");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.util.concurrent");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.util.concurrent.atomic");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.util.concurrent.locks");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.util.regex");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.awt");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.awt.geom");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("java.awt.image");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.google.common.annotations");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.google.common.cache");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.google.common.collect");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.google.common.base");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.google.common.math");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.google.common.primitives");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.google.common.util.concurrent");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.decorator");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.function");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.iterator");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.iterator.hash");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.list");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.list.array");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.list.linked");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.map");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.map.hash");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.map.custom_hash");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.procedure");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.procedure.array");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.queue");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.set");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.set.hash");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.stack");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.stack.array");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("gnu.trove.strategy");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("javax.vecmath");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.yourkit.runtime");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("com.bulletphysics.linearmath");
        moduleSecurityManager.getBasePermissionSet().addAPIPackage("sun.reflect");
        moduleSecurityManager.getBasePermissionSet().addAPIClass(com.esotericsoftware.reflectasm.MethodAccess.class);
        moduleSecurityManager.getBasePermissionSet().addAPIClass(IOException.class);
        moduleSecurityManager.getBasePermissionSet().addAPIClass(InvocationTargetException.class);
        moduleSecurityManager.getBasePermissionSet().addAPIClass(LoggerFactory.class);
        moduleSecurityManager.getBasePermissionSet().addAPIClass(Logger.class);

        APIScanner apiScanner = new APIScanner(moduleSecurityManager);
        for (Module module : registry) {
            if (module.isOnClasspath()) {
                apiScanner.scan(module);
            }
        }

        moduleSecurityManager.getBasePermissionSet().grantPermission("com.google.gson", ReflectPermission.class);
        moduleSecurityManager.getBasePermissionSet().grantPermission("com.google.gson.internal", ReflectPermission.class);

        moduleSecurityManager.getBasePermissionSet().addAPIClass(java.nio.ByteBuffer.class);
        moduleSecurityManager.getBasePermissionSet().addAPIClass(java.nio.IntBuffer.class);

        Policy.setPolicy(new ModuleSecurityPolicy());
        System.setSecurityManager(moduleSecurityManager);
    }

    public ModuleRegistry getRegistry() {
        return registry;
    }

    public ModuleEnvironment getEnvironment() {
        return environment;
    }

    public ModuleEnvironment loadEnvironment(Set<Module> modules, boolean asPrimary) {
        Set<Module> finalModules = Sets.newLinkedHashSet(modules);
        for (Module module : registry) {
            if (module.isOnClasspath()) {
                finalModules.add(module);
            }
        }
        ModuleEnvironment newEnvironment = new ModuleEnvironment(finalModules, moduleSecurityManager, Collections.<BytecodeInjector>emptyList());
        if (asPrimary) {
            if (environment != null) {
                environment.close();
            }
            environment = newEnvironment;
        }
        return newEnvironment;
    }

    public ModuleMetadataReader getModuleMetadataReader() {
        return metadataReader;
    }

    public boolean isGameplayModule(Module module) {
        Boolean isGameplay = module.getMetadata().getExtension(IS_GAMEPLAY_EXT, Boolean.class);
        return isGameplay != null && isGameplay;
    }
}
TOP

Related Classes of org.terasology.engine.module.ModuleManager

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.