All Downloads are FREE. Search and download functionalities are using the official Maven repository.

rexsl-maven-plugin-0.2.7.src.main.java.com.rexsl.maven.utils.EmbeddedContainer Maven / Gradle / Ivy

There is a newer version: 0.13.3
Show newest version
/**
 * Copyright (c) 2011, ReXSL.com
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met: 1) Redistributions of source code must retain the above
 * copyright notice, this list of conditions and the following
 * disclaimer. 2) Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following
 * disclaimer in the documentation and/or other materials provided
 * with the distribution. 3) Neither the name of the ReXSL.com nor
 * the names of its contributors may be used to endorse or promote
 * products derived from this software without specific prior written
 * permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.rexsl.maven.utils;

import com.rexsl.maven.Environment;
import com.ymock.util.Logger;
import java.io.File;
import java.security.Permission;
import java.security.Policy;
import java.security.ProtectionDomain;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.servlet.DispatcherType;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.webapp.WebAppContext;

/**
 * Start/stop grizzly container.
 *
 * @author Yegor Bugayenko ([email protected])
 * @version $Id: EmbeddedContainer.java 495 2011-12-18 09:54:56Z guard $
 * @checkstyle ClassDataAbstractionCoupling (3 lines)
 */
public final class EmbeddedContainer {

    /**
     * The server just started.
     */
    private final transient Server server;

    /**
     * Private ctor.
     * @param srv The server just started
     */
    private EmbeddedContainer(final Server srv) {
        this.server = srv;
    }

    /**
     * Create and start Grizzly container.
     * @param env The environment
     * @return The container
     */
    @SuppressWarnings("PMD.AvoidCatchingGenericException")
    public static EmbeddedContainer start(final Environment env) {
        if (!env.webdir().exists()) {
            throw new IllegalArgumentException(
                String.format(
                    // @checkstyle LineLength (1 line)
                    "Directory %s is absent, maybe you forgot to 'package' the project?",
                    env.webdir()
                )
            );
        }
        final Server server = new Server(env.port());
        final WebAppContext ctx = new WebAppContext();
        // it is required because of classloading conflict between
        // Maven classloader and Jetty WebApp classloader
        // @see http://docs.codehaus.org/display/JETTY/Classloading
        ctx.setParentLoaderPriority(false);
        if (env.useRuntimeFiltering()) {
            ctx.addFilter(
                RuntimeFilter.class,
                "/*",
                EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR)
            );
        }
        for (ConcurrentMap.Entry entry
            : EmbeddedContainer.params(env).entrySet()) {
            ctx.setInitParameter(entry.getKey(), entry.getValue());
        }
        ctx.setWar(env.webdir().getPath());
        ctx.addEventListener(new RuntimeListener());
        server.setHandler(ctx);
        Policy.setPolicy(new EmbeddedContainer.FreePolicy());
        ctx.setExtraClasspath(EmbeddedContainer.testClasspath(env));
        try {
            server.start();
        // @checkstyle IllegalCatch (1 line)
        } catch (Exception ex) {
            throw new IllegalArgumentException("Failed to start Jetty", ex);
        }
        EmbeddedContainer.setup(env);
        return new EmbeddedContainer(server);
    }

    /**
     * Stop this container.
     */
    @SuppressWarnings("PMD.AvoidCatchingGenericException")
    public void stop() {
        try {
            this.server.stop();
        // @checkstyle IllegalCatch (1 line)
        } catch (Exception ex) {
            throw new IllegalArgumentException("Failed to stop Jetty", ex);
        }
    }

    /**
     * Build set of params for embedded container.
     * @param env Environment
     * @return The params
     */
    private static ConcurrentMap params(final Environment env) {
        final List folders = new ArrayList();
        folders.add(new File(env.basedir(), "src/main/webapp").getPath());
        folders.add(new File(env.basedir(), "src/test/rexsl").getPath());
        final ConcurrentMap params =
            new ConcurrentHashMap();
        params.put(
            "com.rexsl.maven.utils.BASEDIR",
            env.basedir().getAbsolutePath()
        );
        params.put(
            "com.rexsl.maven.utils.WEBDIR",
            env.basedir().getAbsolutePath()
        );
        params.put(
            "com.rexsl.maven.utils.PORT",
            env.port().toString()
        );
        params.put(
            "com.rexsl.maven.utils.RUNTIME_FOLDERS",
            StringUtils.join(folders, ";")
        );
        params.put(
            // this parameter is used by com.rexsl.core.XslResolver
            "com.rexsl.core.XSD_FOLDER",
            new File(env.basedir(), "src/test/rexsl/xsd").getPath()
        );
        return params;
    }

    /**
     * Run setup Groovy scripts.
     * @param env The environment
     */
    private static void setup(final Environment env) {
        final File dir = new File(env.basedir(), "src/test/rexsl/setup");
        if (dir.exists()) {
            final GroovyExecutor exec = new GroovyExecutor(
                env,
                new BindingBuilder(env).build()
            );
            final String[] exts = new String[] {"groovy"};
            for (File script : FileUtils.listFiles(dir, exts, true)) {
                Logger.info(EmbeddedContainer.class, "Running '%s'...", script);
                try {
                    exec.execute(script);
                } catch (com.rexsl.maven.utils.GroovyException ex) {
                    throw new IllegalStateException(ex);
                }
            }
        } else {
            Logger.info(
                EmbeddedContainer.class,
                "%s directory is absent, no setup scripts to run",
                dir
            );
        }
    }

    /**
     * Build and return test classpath, for WebAppContext.
     * @param env The environment
     * @return Extra classpath to be used in tests
     * @see #start(Environment)
     */
    private static String testClasspath(final Environment env) {
        final List urls = new ArrayList();
        for (File path : env.classpath(true)) {
            if (path.isDirectory()) {
                urls.add(String.format("%s/", path.getAbsolutePath()));
            } else {
                urls.add(path.getAbsolutePath());
            }
        }
        Logger.debug(
            EmbeddedContainer.class,
            "#testClasspath(%s): %[list]s",
            env.getClass().getName(),
            urls
        );
        return StringUtils.join(urls, ",");
    }

    /**
     * Custom security policy that allows access to classloader.
     */
    private static final class FreePolicy extends Policy {
        /**
         * {@inheritDoc}
         */
        @Override
        public boolean implies(final ProtectionDomain domain,
            final Permission perm) {
            return "getClassLoader".equals(perm.getName());
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy