Package com.commongroundpublishing.rubylet.jruby

Source Code of com.commongroundpublishing.rubylet.jruby.RubyConfig

package com.commongroundpublishing.rubylet.jruby;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;

import org.jruby.CompatVersion;
import org.jruby.RubyInstanceConfig.CompileMode;
import org.jruby.embed.LocalContextScope;

import com.commongroundpublishing.rubylet.Factory;
import com.commongroundpublishing.rubylet.config.ChainedConfig;
import com.commongroundpublishing.rubylet.config.FilterConfigConfig;
import com.commongroundpublishing.rubylet.config.IConfig;
import com.commongroundpublishing.rubylet.config.ServletConfigConfig;
import com.commongroundpublishing.rubylet.config.ServletContextConfig;

public class RubyConfig {
   
    public static String urlPath(String url) {
        try {
            return new URL(url).getPath();
        } catch (MalformedURLException e) {
            return null;
        }
    }
   
    /**
     * Get the path the the WEB-INF folder by assuming
     * "rubylet_helper.rb" can be found on the
     * classpath as a resource inside a JAR file (i.e.
     * rubylet-ee.jar).
     *
     * @return
     */
    public static String getWebInfPath() {
        final String resource = "rubylet_helper.rb";
        final URL url =
                Factory.class.getClassLoader().getResource(resource);

        // TODO: this works for Jetty.  What about others?
        if (url.getProtocol().equals("jar")) {
            final String p = url.getPath();
            final String search = "/WEB-INF/";
            final int i;
            if ((i = p.indexOf(search)) > 0) {
               return urlPath(p.substring(0, i + search.lastIndexOf("/")));
            }
        }
       
        return null;
    }
   
    private final IConfig config;
   
    public RubyConfig(ServletConfig config) {
        this(new ChainedConfig(new ServletConfigConfig(config),
                               new ServletContextConfig(config.getServletContext())));
    }
   
    public RubyConfig(FilterConfig config) {
        this(new ChainedConfig(new FilterConfigConfig(config),
                               new ServletContextConfig(config.getServletContext())));
    }
   
    public RubyConfig(ServletContext context) {
        this(new ServletContextConfig(context));
    }
   
    public RubyConfig(IConfig config) {
        this.config = config;
    }
   
    public ServletContext getServletContext() {
        return config.getServletContext();
    }

    /**
     *
     *
     * @param name
     * @param defaultValue
     * @return
     */
    public final String get(String name, String defaultValue) {
        final String value = config.get(name);
        if (value != null) {
            return value;
        } else {
            return defaultValue;
        }
    }

    /**
     * Get the closest required parameter or throw an exception if it is not set.
     *
     * @param param
     * @return
     */
    public final String getRequired(String name) {
        final String value = config.get(name);
        if (value == null) {
            throw new IllegalStateException("Missing required value for '" + name + "'");
        }
        return value;
    }

    public final <E extends Enum<E>> E getEnum(String param, E defaultValue) {
        final String name = config.get(param);
        if (name != null) {
            @SuppressWarnings("unchecked")
            Class<E> klass = (Class<E>) defaultValue.getClass();
            return (E) Enum.valueOf(klass, name);
        } else {
            return defaultValue;
        }
    }

    /**
     * Iterate through all init parameters.  For each parameter whose name
     * starts with {@code prefix}, store the corresponding value in a hash
     * using a key derived from the name with the prefix stripped.
     *
     * @param prefix
     * @return
     */
    public final Map<String, String> getAllAsMap(String prefix) {
        final HashMap<String, String> map = new HashMap<String, String>();
       
        final Enumeration<String> names = config.getNames();
        while (names.hasMoreElements()) {
            final String name = names.nextElement();
            if (name.startsWith(prefix)) {
                final String key = name.substring(prefix.length());
                map.put(key, config.get(name));
            }
        }
       
        return Collections.unmodifiableMap(map);
    }
   
    /**
     * @return JRuby home or null
     */
    public final String getJrubyHome() {
        return get("rubylet.jrubyHome", null);
    }
   
    /**
     * For every key starting with {@code rubylet.env.<NAME>}, make an
     * entry in a map from {@code <NAME>} to the associated value.
     *
     * <p>This map will be applied as environment variables to a new
     * runtime during boot.
     *
     * @return the configured environment map
     */
    public final Map<String, String> getEnv() {
        return getAllAsMap("rubylet.env.");
    }

    /**
     * For every key starting with {@code rubylet.gem.<NAME>}, make an
     * entry in a map from {@code <NAME>} to the associated value.
     *
     * <p>The values must be gem names followed by an optional command
     * and version requirement.  During runtime boot, the gems will
     * be required via {@code rubygems} in spite of any {@code bundler}
     * restrictions.
     *
     * @return the configured environment map
     */
    public final Map<String, String> getGems() {
        return getAllAsMap("rubylet.gem.");
    }
   
    /**
     * Get the configured runtime.
     *
     * @return the runtime name, or "default".
     */
    public final String getRuntime() {
        return get("rubylet.runtime", "default");
    }
   
    /**
     * Get the configured appRoot.  If none is configured, attempt to detect
     * the path to the WEB-INF dir of an unpacked WAR file.  The appRoot will
     * then be WEB-INF/classes, which is where Maven will put files in
     * src/main/ruby by default.
     *
     * @return the configured appRoot, WEB-INF/classes,
     * or null if unconfigured and the WEB-INF path could not be determined
     */
    public final String getAppRoot() {
        final String webInfPath = getWebInfPath();
        if (webInfPath == null) {
            return getRequired("rubylet.appRoot");
        } else {
            return get("rubylet.appRoot", webInfPath + "/classes");
        }
    }
   
    /**
     * Get a file to monitor for changes after which restarts will be triggered.
     * File must be relative to appRoot.
     *
     * @return
     */
    public final File getWatchFile() {
        return new File(getAppRoot(), get("rubylet.watchFile", "tmp/restart.txt"));
    }
   
    /**
     * @return true if bundle exec was configured.
     */
    public final boolean isBundleExec() {
        return Boolean.parseBoolean(get("rubylet.bundleExec", null));
    }
   
    /**
     * @return the configured gemfile, or "Gemfile"
     */
    public final String getBundleGemfile() {
        return get("rubylet.bundleGemfile", "Gemfile");
    }

    /**
     * @return the configured bundle "without" values, or "development:test"
     */
    public final String getBundleWithout() {
        return get("rubylet.bundleWithout", "development:test");
    }
   
    /**
     * The servletPath is (in rubylet-tasks) derived from a simple url-pattern
     * of the form '/servletPath/*'.  Complex (or multiple) url-patterns
     * cannot be automatically converted into a servletPath.
     *
     * <p>This is intended to be concatenated with the context path
     * and then used by rubylet/servlet, for example to set {@code
     * ActionController::Base.config.relative_url_root} in a Rails app.
     *
     * <p>FIXME: is this used anywhere?
     *
     * @return
     */
    public final String getServletPath() {
        return get("servletPath", null);
    }
   
    /**
     * @return the configured boot file, which should be relative to appRoot
     */
    public final String getBoot() {
        return get("rubylet.boot", null);
    }
   
    /**
     * @return the configured Ruby class to instantiate as {@link javax.servlet.Servlet}
     */
    public final String getServletClass() {
        return get("rubylet.servletClass", "Rubylet::Servlet");
    }

    /**
     * @return the configured Ruby class to instantiate as {@link javax.servlet.ServletContextListener}
     */
    public final String getListenerClass() {
        return getRequired("rubylet.listenerClass");
    }

    /**
     * @return the configured LocalContextScope, or {@code LocalContextScope.THREADSAFE}
     */
    public final LocalContextScope getScope() {
        return getEnum("rubylet.localContextScope", LocalContextScope.THREADSAFE);
    }

    public final CompileMode getCompileMode() {
        return getEnum("rubylet.compileMode", CompileMode.JIT);
    }

    public final CompatVersion getCompatVersion() {
        return getEnum("rubylet.compatVersion", CompatVersion.RUBY1_9);
    }
   
}
TOP

Related Classes of com.commongroundpublishing.rubylet.jruby.RubyConfig

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.