org.projectodd.wunderboss.ruby.RubyHelper Maven / Gradle / Ivy
/*
* Copyright 2014-2016 Red Hat, Inc, and individual contributors.
*
* 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.projectodd.wunderboss.ruby;
import org.jcodings.specific.USASCIIEncoding;
import org.jruby.Ruby;
import org.jruby.RubyHash;
import org.jruby.RubyModule;
import org.jruby.RubyString;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ByteList;
import org.projectodd.wunderboss.WunderBoss;
import org.slf4j.Logger;
import java.util.Map;
import java.util.Map.Entry;
/**
* Ruby reflection helper utilities.
*
* @author Bob McWhirter
*/
public class RubyHelper {
/**
* Set a property on a Ruby object, if possible.
*
*
* If the target responds to {@code name=}, the property will be set.
* Otherwise, not.
*
*
* @param ruby
* The Ruby interpreter.
* @param target
* The target object.
* @param name
* The basic name of the property.
* @param value
* The value to attempt to set.
* @return {@code true} if successful, otherwise {@code false}
*/
public static boolean setIfPossible(final Ruby ruby, final Object target, final String name, final Object value) {
boolean success = false;
if (defined( ruby, target, name + "=" )) {
JavaEmbedUtils.invokeMethod( ruby, target, name + "=", new Object[] { value }, void.class );
success = true;
}
return success;
}
public static Object getIfPossible(final Ruby ruby, final Object target, final String name) {
Object result = null;
if (defined( ruby, target, name )) {
result = JavaEmbedUtils.invokeMethod( ruby, target, name, new Object[] {}, Object.class );
}
return result;
}
public static Object call(final Ruby ruby, final Object target, final String name, final Object[] parameters) {
return JavaEmbedUtils.invokeMethod( ruby, target, name, parameters, Object.class );
}
public static Object callIfPossible(final Ruby ruby, final Object target, final String name, final Object[] parameters) {
Object result = null;
if (defined( ruby, target, name )) {
result = JavaEmbedUtils.invokeMethod( ruby, target, name, parameters, Object.class );
}
return result;
}
public static boolean defined(final Ruby ruby, final Object target, final String name) {
return (Boolean) JavaEmbedUtils.invokeMethod( ruby, target, "respond_to?", new Object[] { name }, Boolean.class );
}
public static RubyModule getClass(final Ruby ruby, final String className) {
return ruby.getClassFromPath(className);
}
public static Object invokeClassMethod(Ruby ruby, String className, String name, Object[] parameters) {
return call(ruby, getClass(ruby, className), name, parameters);
}
public static void require(Ruby ruby, String requirement) {
try {
evalScriptlet( ruby, "require %q(" + requirement + ")" );
} catch (Throwable t) {
log.error("Unable to require file: " + requirement, t );
}
}
public static boolean requireIfAvailable(Ruby ruby, String requirement) {
return requireIfAvailable( ruby, requirement, true );
}
/**
* Calls "require 'requirement'" in the Ruby provided.
* @return boolean If successful, returns true, otherwise false.
*/
public static boolean requireIfAvailable(Ruby ruby, String requirement, boolean logErrors) {
boolean success = false;
try {
StringBuilder script = new StringBuilder();
script.append("require %q(");
script.append(requirement);
script.append(")\n");
evalScriptlet( ruby, script.toString(), false );
success = true;
} catch (Throwable t) {
success = false;
if (logErrors) {
log.debug( "Error encountered. Unable to require file: " + requirement, t );
}
}
return success;
}
public static void requireUnlessDefined(Ruby ruby, String requirement, String constant) {
try {
evalScriptlet( ruby, "require %q(" + requirement + ") unless defined?(" + constant + ")" );
} catch (Throwable t) {
log.error("Unable to require file: " + requirement, t);
}
}
// ------------------------------------------------------------------------
public static IRubyObject evalScriptlet(final Ruby ruby, final String script) {
return evalScriptlet( ruby, script, true );
}
public static IRubyObject evalScriptlet(final Ruby ruby, final String script, final boolean logErrors) {
try {
return ruby.evalScriptlet( script );
} catch (Exception e) {
if (logErrors)
log.error("Error during evaluation: " + script, e);
throw e;
}
}
public static IRubyObject executeScript(final Ruby ruby, final String script, final String location) {
try {
return ruby.executeScript( script, location );
} catch (Exception e) {
log.error("Error during execution: " + script, e);
throw e;
}
}
// ------------------------------------------------------------------------
public static IRubyObject instantiate(Ruby ruby, String className) {
return instantiate( ruby, className, new Object[] {} );
}
public static IRubyObject instantiate(final Ruby ruby, final String className, final Object[] parameters) {
IRubyObject result = null;
RubyModule rubyClass = ruby.getClassFromPath( className );
if (rubyClass != null) {
try {
result = (IRubyObject) JavaEmbedUtils.invokeMethod( ruby, rubyClass, "new", parameters, IRubyObject.class );
} catch (Exception e) {
log.error("Unable to instantiate: " + className, e);
throw e;
}
}
return result;
}
@SuppressWarnings("rawtypes")
public static RubyHash convertJavaMapToRubyHash(Ruby runtime, Map map) {
RubyHash rubyHash = RubyHash.newHash( runtime );
for (Object object : map.entrySet()) {
Entry entry = (Entry) object;
rubyHash.put( entry.getKey(), entry.getValue() );
}
return rubyHash;
}
public static final RubyString toUsAsciiRubyString(final Ruby runtime, final String string) {
byte[] bytes = new byte[string.length()];
for (int i = 0; i < bytes.length; i++) {
bytes[i] = (byte) string.charAt(i);
}
return toUsAsciiRubyString(runtime, bytes);
}
public static final RubyString toUsAsciiRubyString(final Ruby runtime, final byte[] bytes) {
return RubyString.newString(runtime, new ByteList(bytes, USASCIIEncoding.INSTANCE, false));
}
public static final RubyString toUnicodeRubyString(final Ruby runtime, final String string) {
return RubyString.newUnicodeString(runtime, string);
}
private static final Logger log = WunderBoss.logger(RubyHelper.class);
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy