Package ruby

Source Code of ruby.RubyPlugin

package ruby;

import hudson.Extension;
import hudson.ExtensionComponent;
import hudson.Plugin;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.Hudson;
import hudson.model.Items;
import hudson.util.XStream2;
import org.jenkinsci.jruby.JRubyMapper;
import org.jenkinsci.jruby.JRubyXStream;
import org.jruby.embed.LocalContextScope;
import org.jruby.embed.ScriptingContainer;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;


/**
* The primary Java interface to a plugin which is implemented in Ruby
*
* When this plugin initializes, it will instantiate a Jenkins::Plugin
* object which acts as the gateway for Ruby to interact with the java
* side.
*
* When the RubyPlugin is loaded, it will discover, load and provide
* a mechanism for extensions written in Ruby that it contains to register
* themselves.
*
* These Extensions are presented to Jenkins via the {@link RubyExtensionFinder}
*
* Each plugin has its own JRuby environment
*/
@SuppressWarnings({"UnusedDeclaration"})
@Extension
public class RubyPlugin extends Plugin implements Describable<RubyPlugin> {
  /**
   * The unique JRuby environment used by this plugin and all the objects
   * and classes that it contains.
   */
    private ScriptingContainer ruby;


  private Object plugin;
  private ArrayList<ExtensionComponent> extensions;

  public static RubyPlugin get() {
    return Hudson.getInstance().getPlugin(RubyPlugin.class);
  }

  /**
   * Kinda acts like the "agent" of this ruby plugin in the Ruby world.
   * This is the object that the internals of the ruby side talk to when
   * then want to talk back to Java.
   * @return an instance of Jenkins::Plugin
   */
    public static Object getRubyController() {
        return get().plugin;
    }

  /**
   * invokes a Ruby method on the specified object in the context of this plugin's
   * {@link ScriptingContainer}
   *
   * @param object <b>JRuby</b> object to use as invocant
   * @param methodName the method to end
   * @param args arguments to the method
   * @return the return value of the method call.
   */
  public static Object callMethod(Object object, String methodName, Object... args) {
    return RubyPlugin.get().ruby.callMethod(object, methodName, args);
  }

  /**
   * Registers an extenion with this Ruby plugin so that it will be found later on
   *
   * This method is generally called from inside Ruby, as objects that implement
   * extension points register themselves.
   * @param extension
   */
  public void addExtension(Object extension) {
    extensions.add(new ExtensionComponent(extension));
  }

  /**
   * @return the list of extensions registered with this Plugin. this is used by
   * the {@link RubyExtensionFinder} to present extension points to Jenkins
   */
  public static Collection<ExtensionComponent> getExtensions() {
    return get().extensions;
  }

  /**
   * Reads a resource relative to this plugin's Java class using a formatted string
   * @param resource the string template specifying the resource
   * @param args format arguments
   * @return the content of the resource
   */
  public static String readf(String resource, Object... args) {
    return RubyPlugin.get().read(String.format(resource, args));
  }

  /**
   * Initializes this plugin by setting up the JRuby scripting container
   * and then loading up the ruby side of the plugin by creating an
   * instance of the Ruby class Jenkins::Plugin which will serve as
   * its agent in the Ruby world.
   *
   * We also register xstream mappers for JRuby objects so that they
   * can be persisted along with other objects in Jenkins.
   */
  public RubyPlugin() {
    this.ruby = new ScriptingContainer(LocalContextScope.THREADSAFE);
    this.ruby.setClassLoader(this.getClass().getClassLoader());
    this.ruby.getLoadPaths().add(0, this.getClass().getResource("support").getPath());
    this.ruby.getLoadPaths().add(this.getClass().getResource("jenkins-plugins/lib").getPath());
    this.ruby.getLoadPaths().add(this.getClass().getResource(".").getPath());
    this.extensions = new ArrayList<ExtensionComponent>();
    this.ruby.runScriptlet("require 'rubygems'");
    this.ruby.runScriptlet("require 'bundled-gems.jar'");
    this.ruby.runScriptlet("require 'jenkins/plugins'");
    Object pluginClass = this.ruby.runScriptlet("Jenkins::Plugin");
    this.plugin = this.ruby.callMethod(pluginClass, "new", this);

        register((XStream2)Hudson.XSTREAM, ruby);
        register((XStream2)Items.XSTREAM, ruby);
  }

    private void register(XStream2 xs, ScriptingContainer ruby) {
        JRubyXStream.register(xs,ruby);
        synchronized (xs) {
            xs.setMapper(new JRubyMapper(xs.getMapperInjectionPoint()));
        }
    }

  /**
   * Read a resource relative to this plugin clas
   * @param resource the name of the resource to be read
   * @return the content of the resource
   */
    public String read(String resource) {
    InputStream stream = this.getClass().getResourceAsStream(resource);
    try {
      if (stream == null) {
        throw new RuntimeException("no such resource: " + resource);
      }
      StringBuffer buffer = new StringBuffer();
      for (int c = stream.read(); c > 0; c = stream.read()) {
        buffer.append((char)c);
      }
      return buffer.toString();
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  /**
   * Jenkins will call this method whenever the plugin is initialized
   * The plugin will in turn delegate to its instance of Jenkins::Plugin
   * which can take action on the Ruby side.
   * @throws Exception
   */
  @Override
    public void start() throws Exception {
        this.ruby.callMethod(plugin, "start");
    }

  /**
   * Jenkins will call this method whenever the plugin is shut down
   * The plugin will in turn delegate to its instance of Jenkins::Plugin
   * which can take action on the Ruby side
   * @throws Exception
   */
  @Override
  public void stop() throws Exception {
    this.ruby.callMethod(plugin, "stop");
  }


  /**
   * This is mandatory for Jenkins to find this plugin, although I'm not
   * exactly sure why.
   * @return
   */
    public DescriptorImpl getDescriptor() {
        return (DescriptorImpl)Hudson.getInstance().getDescriptorOrDie(getClass());
    }

  public static String getResourceURI(String relativePathFormat, Object... args) {
    return get().getClass().getResource(String.format(relativePathFormat, args)).getPath();
  }

  /**
   * Again, this is mandatory for Jenkins to find this plugin, although I'm not
   * exactly sure why.
   */
  @Extension
    public static final class DescriptorImpl extends Descriptor<RubyPlugin> {
        @Override
        public String getDisplayName() {
            return "Ruby Plugin";
        }
    }
}
TOP

Related Classes of ruby.RubyPlugin

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.