/** * Assist with setting the parameter values on a PreparedStatement * * @param ps the PreparedStatement for which parameters should be set * @param recv * @param args an array of parameter values */ private static void prepareStatementFromArgs( PreparedStatement ps, IRubyObject recv, IRubyObject[] args) { int index = 1; try { for (IRubyObject arg : args) { // Handle multiple valued arguments, i.e. arrays + ranges if (arg instanceof RubyArray) { // Handle a RubyArray passed into a query // // NOTE: This should not call ps.setArray(i,v) as this is // designed to work with the SQL Array type, and in most cases // is not what we want. // Instead, this functionality is for breaking down a Ruby // array of ["a","b","c"] into SQL "('a','b','c')": // // So, in this case, we actually want to augment the number of // ? params in the PreparedStatement query appropriately. RubyArray array_value = arg.convertToArray(); for (int j = 0; j < array_value.getLength(); j++) { setPreparedStatementParam(ps, recv, array_value.eltInternal(j), index++); } } else if (arg instanceof RubyRange) { // Handle a RubyRange passed into a query // // NOTE: see above - need to augment the number of ? params // in the PreparedStatement: (? AND ?) RubyRange range_value = (RubyRange) arg; setPreparedStatementParam(ps, recv, range_value.first(), index++); setPreparedStatementParam(ps, recv, range_value.last(), index++); } else { // Otherwise, handle each argument setPreparedStatementParam(ps, recv, arg, index++); } } } catch (SQLException sqle) { // TODO: log sqle.printStackTrace(); // TODO: possibly move this exception string parsing somewhere else Pattern pattern = Pattern.compile( "Parameter index out of bounds. (\\d+) is not between valid values of (\\d+) and (\\d+)"); Matcher matcher = pattern.matcher(sqle.getMessage()); if (matcher.matches()) { throw recv.getRuntime() .newArgumentError( String.format( "Binding mismatch: %1$d for %2$d", Integer.parseInt(matcher.group(1)), Integer.parseInt(matcher.group(2)))); } else { throw DataObjectsUtils.newDriverError(recv.getRuntime(), errorName, sqle); } } }
@JRubyMethod(rest = true) public static IRubyObject set_types(IRubyObject recv, IRubyObject[] args) { Ruby runtime = recv.getRuntime(); RubyArray types = RubyArray.newArray(runtime, args); RubyArray type_strings = RubyArray.newArray(runtime); for (IRubyObject arg : args) { if (arg instanceof RubyClass) { type_strings.append(arg); } else if (arg instanceof RubyArray) { for (IRubyObject sub_arg : arg.convertToArray().toJavaArray()) { if (sub_arg instanceof RubyClass) { type_strings.append(sub_arg); } else { throw runtime.newArgumentError("Invalid type given"); } } } else { throw runtime.newArgumentError("Invalid type given"); } } api.setInstanceVariable(recv, "@field_types", type_strings); return types; }
/** Compatibility with Tempfile#make_tmpname(basename, n) in MRI */ @JRubyMethod(visibility = PRIVATE) public IRubyObject make_tmpname( ThreadContext context, IRubyObject basename, IRubyObject n, Block block) { Ruby runtime = context.getRuntime(); IRubyObject[] newargs = new IRubyObject[5]; IRubyObject base, suffix; if (basename instanceof RubyArray) { RubyArray array = (RubyArray) basename; int length = array.getLength(); base = length > 0 ? array.eltInternal(0) : runtime.getNil(); suffix = length > 0 ? array.eltInternal(1) : runtime.getNil(); } else { base = basename; suffix = runtime.newString(""); } newargs[0] = runtime.newString("%s.%d.%d%s"); newargs[1] = base; newargs[2] = runtime.getGlobalVariables().get("$$"); // PID newargs[3] = n; newargs[4] = suffix; return callMethod(context, "sprintf", newargs); }
protected RubyArray buildRubyArray(Class[] classes) { RubyArray result = getRuntime().newArray(classes.length); for (int i = 0; i < classes.length; i++) { result.append(JavaClass.get(getRuntime(), classes[i])); } return result; }
/** * this method uses the appropriate lookup strategy to find a file. It is used by Kernel#require. * * @mri rb_find_file * @param name the file to find, this is a path name * @return the correct file */ protected LoadServiceResource findFileInClasspath(String name) { // Look in classpath next (we do not use File as a test since UNC names will match) // Note: Jar resources must NEVER begin with an '/'. (previous code said "always begin with a // /") ClassLoader classLoader = runtime.getJRubyClassLoader(); // handle security-sensitive case if (Ruby.isSecurityRestricted() && classLoader == null) { classLoader = runtime.getInstanceConfig().getLoader(); } // absolute classpath URI, no need to iterate over loadpaths if (name.startsWith("classpath:/")) { LoadServiceResource foundResource = getClassPathResource(classLoader, name); if (foundResource != null) { return foundResource; } } else if (name.startsWith("classpath:")) { // "relative" classpath URI name = name.substring("classpath:".length()); } for (int i = 0; i < loadPath.size(); i++) { // TODO this is really inefficient, and potentially a problem everytime anyone require's // something. // we should try to make LoadPath a special array object. RubyString entryString = loadPath.eltInternal(i).convertToString(); String entry = entryString.asJavaString(); // if entry is an empty string, skip it if (entry.length() == 0) continue; // if entry starts with a slash, skip it since classloader resources never start with a / if (entry.charAt(0) == '/' || (entry.length() > 1 && entry.charAt(1) == ':')) continue; if (entry.startsWith("classpath:/")) { entry = entry.substring("classpath:/".length()); } else if (entry.startsWith("classpath:")) { entry = entry.substring("classpath:".length()); } // otherwise, try to load from classpath (Note: Jar resources always uses '/') LoadServiceResource foundResource = getClassPathResource(classLoader, entry + "/" + name); if (foundResource != null) { return foundResource; } } // if name starts with a / we're done (classloader resources won't load with an initial /) if (name.charAt(0) == '/' || (name.length() > 1 && name.charAt(1) == ':')) return null; // Try to load from classpath without prefix. "A/b.rb" will not load as // "./A/b.rb" in a jar file. LoadServiceResource foundResource = getClassPathResource(classLoader, name); if (foundResource != null) { return foundResource; } return null; }
@Override public IRubyObject op_plus(IRubyObject obj) { if (!packed()) return super.op_plus(obj); RubyArray y = obj.convertToArray(); if (y.size() == 0) return new RubyArrayOneObject(this); return super.op_plus(y); }
@Specialization public RubyArray unpack(RubyString string, RubyString format) { final org.jruby.RubyArray jrubyArray = Pack.unpack(getContext().getRuntime(), string.getBytes(), format.getBytes()); return RubyArray.specializedFromObjects( getContext().getCoreLibrary().getArrayClass(), jrubyArray.toArray()); }
@JRubyMethod( name = {"create_invoker", "createInvoker"}, required = 5) public IRubyObject createInvoker(ThreadContext context, IRubyObject[] args) { RubyArray paramTypes = (RubyArray) args[3]; NativeParam[] nativeParamTypes = new NativeParam[paramTypes.size()]; for (int i = 0; i < paramTypes.size(); ++i) { IRubyObject obj = (IRubyObject) paramTypes.entry(i); if (obj instanceof NativeParam) { nativeParamTypes[i] = (NativeParam) obj; } else if (obj instanceof RubyInteger) { nativeParamTypes[i] = NativeType.valueOf(Util.int32Value(obj)); } else { context.getRuntime().newArgumentError("Invalid parameter type"); } } try { return createInvoker( context.getRuntime(), args[0].isNil() ? null : args[0].toString(), args[1].toString(), NativeType.valueOf(Util.int32Value(args[2])), nativeParamTypes, args[4].toString()); } catch (UnsatisfiedLinkError ex) { return context.getRuntime().getNil(); } }
protected RubyArray buildRubyArray(IRubyObject[] constructors) { RubyArray result = getRuntime().newArray(constructors.length); for (int i = 0; i < constructors.length; i++) { result.append(constructors[i]); } return result; }
public void testRubyExceptionBacktraceIncludesJavaOrigin() throws Exception { String script = "require 'java'\n" + "hash = Hash.new { org.jruby.test.TestRaiseException::ThrowFromJava.new.throwIt }\n" + "begin; hash['missing']; rescue java.lang.Exception => e; $ex_trace = e.backtrace end \n" + "$ex_trace"; RubyArray trace = (RubyArray) runtime.evalScriptlet(script); String fullTrace = trace.join(runtime.getCurrentContext(), runtime.newString("\n")).toString(); // System.out.println(fullTrace); // NOTE: 'unknown' JRuby packages e.g. "org.jruby.test" should not be filtered // ... if they are that hurts stack-traces from extensions such as jruby-rack and jruby-openssl assertTrue( trace.get(0).toString(), trace .get(0) .toString() .startsWith("org.jruby.test.TestRaiseException$ThrowFromJava.throwIt")); boolean hash_default = false; for (Object element : trace) { if (element.toString().contains("org.jruby.RubyHash.default")) { if (hash_default) fail("duplicate " + element + " in : \n" + fullTrace); hash_default = true; } } assertTrue("missing org.jruby.RubyHash.default ... in : \n" + fullTrace, hash_default); }
/** * Gets a ruby array of the names of all members of this struct. * * @return a <tt>RubyArray</tt> containing the names of all members. */ @JRubyMethod(name = "members") public IRubyObject members(ThreadContext context) { RubyArray mbrs = RubyArray.newArray(context.getRuntime(), fieldNames.size()); for (IRubyObject name : fieldNames) { mbrs.append(name); } return mbrs; }
public static RubyArray safeArrayToRubyArray(ThreadContext context, SafeArray sa) { Variant[] variants = sa.toVariantArray(); RubyArray ary = RubyArray.newArray(context.getRuntime(), variants.length); for (int i = 0; i < variants.length; i++) { ary.add(jacobToRuby(context, variants[i])); } return ary; }
@JRubyMethod(backtrace = true) public IRubyObject java_method( ThreadContext context, IRubyObject rubyName, IRubyObject argTypes) { String name = rubyName.asJavaString(); RubyArray argTypesAry = argTypes.convertToArray(); Class[] argTypesClasses = (Class[]) argTypesAry.toArray(new Class[argTypesAry.size()]); return getRubyMethod(name, argTypesClasses); }
@Override public Label interpret(InterpreterContext interp) { // ENEBO: Can I assume since IR figured this is an internal array it will be RubyArray like // this? RubyArray array = (RubyArray) getArg().retrieve(interp); getResult().store(interp, array.entry(index)); return null; }
@Override public void postInvoke(IRubyObject rbValue, long[] arr, ToNativeContext context) { if (rbValue instanceof RubyArray && arr != null) { RubyArray rbArray = (RubyArray) rbValue; Ruby runtime = rbArray.getRuntime(); for (int i = 0; i < arr.length; i++) { rbArray.store(i, Util.newSigned64(runtime, arr[i])); } } }
/** * This name may be a bit misleading, since this also attempts to coerce array behavior using * to_ary. * * @param runtime The JRuby runtime * @param value The value to convert * @param coerce Whether to coerce using to_ary or just wrap with an array */ public static RubyArray convertToRubyArray(Ruby runtime, IRubyObject value, boolean coerce) { if (value == null) { return RubyArray.newEmptyArray(runtime); } if (coerce) return convertToRubyArrayWithCoerce(runtime, value); // don't attempt to coerce to array, just wrap and return return RubyArray.newArrayLight(runtime, value); }
private Object[] convertArguments(final RubyArray arguments) { final int argsSize = arguments.size(); final Object[] args = new Object[argsSize]; final Class<?>[] parameterTypes = getParameterTypes(); for (int i = 0; i < argsSize; i++) { args[i] = arguments.eltInternal(i).toJava(parameterTypes[i]); } return args; }
@JRubyMethod(name = "to_a") public static IRubyObject s_hist_to_a(IRubyObject recv) throws Exception { Ruby runtime = recv.getRuntime(); ConsoleHolder holder = getHolder(runtime); RubyArray histList = runtime.newArray(); for (Iterator i = holder.history.getHistoryList().iterator(); i.hasNext(); ) { histList.append(runtime.newString((String) i.next())); } return histList; }
@Override public long[] toNative(IRubyObject value, ToNativeContext context) { RubyArray rbArray = value.convertToArray(); long[] arr = new long[rbArray.getLength()]; if (ArrayFlags.isIn(arrayFlags)) { for (int i = 0; i < arr.length; i++) { arr[i] = Util.longValue(rbArray.entry(i)); } } return arr; }
public void init(List additionalDirectories) { loadPath = RubyArray.newArray(runtime); loadedFeatures = RubyArray.newArray(runtime); loadedFeaturesInternal = Collections.synchronizedList(loadedFeatures); // add all startup load paths to the list first for (Iterator iter = additionalDirectories.iterator(); iter.hasNext(); ) { addPath((String) iter.next()); } // add $RUBYLIB paths RubyHash env = (RubyHash) runtime.getObject().fastGetConstant("ENV"); RubyString env_rubylib = runtime.newString("RUBYLIB"); if (env.has_key_p(env_rubylib).isTrue()) { String rubylib = env.op_aref(runtime.getCurrentContext(), env_rubylib).toString(); String[] paths = rubylib.split(File.pathSeparator); for (int i = 0; i < paths.length; i++) { addPath(paths[i]); } } // wrap in try/catch for security exceptions in an applet if (!Ruby.isSecurityRestricted()) { try { String jrubyHome = runtime.getJRubyHome(); if (jrubyHome != null) { char sep = '/'; String rubyDir = jrubyHome + sep + "lib" + sep + "ruby" + sep; // If we're running in 1.9 compat mode, add Ruby 1.9 libs to path before 1.8 libs if (runtime.is1_9()) { addPath(rubyDir + "site_ruby" + sep + Constants.RUBY1_9_MAJOR_VERSION); addPath(rubyDir + "site_ruby" + sep + "shared"); addPath(rubyDir + "site_ruby" + sep + Constants.RUBY_MAJOR_VERSION); addPath(rubyDir + Constants.RUBY1_9_MAJOR_VERSION); } else { // Add 1.8 libs addPath(rubyDir + "site_ruby" + sep + Constants.RUBY_MAJOR_VERSION); addPath(rubyDir + "site_ruby" + sep + "shared"); addPath(rubyDir + Constants.RUBY_MAJOR_VERSION); } } } catch (SecurityException e) { } } // "." dir is used for relative path loads from a given file, as in require '../foo/bar' if (runtime.getSafeLevel() == 0) { addPath("."); } }
@JRubyMethod(backtrace = true) public IRubyObject java_send(ThreadContext context, IRubyObject rubyName, IRubyObject argTypes) { String name = rubyName.asJavaString(); RubyArray argTypesAry = argTypes.convertToArray(); Ruby runtime = context.getRuntime(); if (argTypesAry.size() != 0) { Class[] argTypesClasses = (Class[]) argTypesAry.toArray(new Class[argTypesAry.size()]); throw JavaMethod.newArgSizeMismatchError(runtime, argTypesClasses); } JavaMethod method = new JavaMethod(runtime, getMethod(name)); return method.invokeDirect(getObject()); }
private static void addBackTraceElement( Ruby runtime, RubyArray backtrace, RubyStackTraceElement frame, RubyStackTraceElement previousFrame) { if (frame != previousFrame && // happens with native exceptions, should not filter those out frame.getLineNumber() == previousFrame.getLineNumber() && frame.getMethodName() != null && frame.getMethodName().equals(previousFrame.getMethodName()) && frame.getFileName() != null && frame.getFileName().equals(previousFrame.getFileName())) { return; } RubyString traceLine; String fileName = frame.getFileName(); if (fileName == null) fileName = ""; if (previousFrame.getMethodName() == UNKNOWN_NAME) { traceLine = RubyString.newString(runtime, fileName + ':' + (frame.getLineNumber())); } else { traceLine = RubyString.newString( runtime, fileName + ':' + (frame.getLineNumber()) + ":in `" + previousFrame.getMethodName() + '\''); } backtrace.append(traceLine); }
private static void addBackTraceElement( Ruby runtime, RubyArray backtrace, Frame frame, Frame previousFrame) { if (frame != previousFrame && // happens with native exceptions, should not filter those out frame.getLine() == previousFrame.getLine() && frame.getName() != null && frame.getName().equals(previousFrame.getName()) && frame.getFile().equals(previousFrame.getFile())) { return; } RubyString traceLine; if (previousFrame.getName() != null) { traceLine = RubyString.newString( runtime, frame.getFile() + ':' + (frame.getLine() + 1) + ":in `" + previousFrame.getName() + '\''); } else if (runtime.is1_9()) { // TODO: This probably isn't the best hack, but it works until we can have different // root frame setup for 1.9 easily. traceLine = RubyString.newString( runtime, frame.getFile() + ':' + (frame.getLine() + 1) + ":in `<main>'"); } else { traceLine = RubyString.newString(runtime, frame.getFile() + ':' + (frame.getLine() + 1)); } backtrace.append(traceLine); }
private static void addBackTraceElement( RubyArray backtrace, RubyStackTraceElement frame, RubyStackTraceElement previousFrame, FrameType frameType) { if (frame != previousFrame && // happens with native exceptions, should not filter those out frame.getMethodName() != null && frame.getMethodName().equals(previousFrame.getMethodName()) && frame.getFileName().equals(previousFrame.getFileName()) && frame.getLineNumber() == previousFrame.getLineNumber()) { return; } StringBuilder buf = new StringBuilder(60); buf.append(frame.getFileName()).append(':').append(frame.getLineNumber()); if (previousFrame.getMethodName() != null) { switch (frameType) { case METHOD: buf.append(":in `"); buf.append(previousFrame.getMethodName()); buf.append('\''); break; case BLOCK: buf.append(":in `"); buf.append("block in " + previousFrame.getMethodName()); buf.append('\''); break; case EVAL: buf.append(":in `"); buf.append("eval in " + previousFrame.getMethodName()); buf.append('\''); break; case CLASS: buf.append(":in `"); buf.append("class in " + previousFrame.getMethodName()); buf.append('\''); break; case ROOT: buf.append(":in `<toplevel>'"); break; } } backtrace.append(backtrace.getRuntime().newString(buf.toString())); }
public static RubyArray convertWithArgs( ThreadContext context, IRubyObject recv, IRubyObject[] args, String function) { assert args.length >= 2; RubyArray array = context.getRuntime().newArray(args.length - 2); RubyIconv iconv = newIconv(context, recv, args[0], args[1]); try { for (int i = 2; i < args.length; i++) { array.append(iconv.iconv(args[i])); } } finally { iconv.close(); } return array; }
protected void addPath(String path) { // Empty paths do not need to be added if (path == null || path.length() == 0) return; synchronized (loadPath) { loadPath.append(runtime.newString(path.replace('\\', '/'))); } }
private IRubyObject inspectPuts(ThreadContext context, RubyArray array) { try { getRuntime().registerInspecting(array); return puts(context, array.toJavaArray()); } finally { getRuntime().unregisterInspecting(array); } }
public void eventHandler( ThreadContext context, String event, String file, int line, String name, IRubyObject type) { // Line numbers are 1s based. Arrays are zero based. We need to compensate for that. line -= 1; // Make sure that we have SCRIPT_LINES__ and it's a hash RubyHash scriptLines = getScriptLines(context.getRuntime()); if (scriptLines == null || !scriptLines.containsKey(file)) { return; } // make sure the file's source lines are in SCRIPT_LINES__ cover = getCover(context.getRuntime()); RubyArray lines = (RubyArray) scriptLines.get(file); if (lines == null || cover == null) { return; } // make sure file's counts are in COVER and set to zero RubyArray counts = (RubyArray) cover.get(file); if (counts == null) { counts = context.getRuntime().newArray(); for (int i = 0; i < lines.size(); i++) { counts.add(Long.valueOf(0)); } cover.put(file, counts); } // in the case of code generation (one example is instance_eval for routes optimization) // We could get here and see that we are not matched up with what we expect if (counts.size() <= line) { for (int i = counts.size(); i <= line; i++) { counts.add(Long.valueOf(0)); } } if (!context.isWithinTrace()) { try { context.setWithinTrace(true); // update counts in COVER Long count = (Long) counts.get(line); if (count == null) { count = Long.valueOf(0); } count = Long.valueOf(count.longValue() + 1); counts.set(line, count); } finally { context.setWithinTrace(false); } } }
public final IRubyObject invoke( ThreadContext context, Function function, HeapInvocationBuffer args) { final long address = invoker.invokeAddress(function, args); return RubyArray.newArray( context.getRuntime(), FFIUtil.getString(context.getRuntime(), address), new Pointer(context.getRuntime(), NativeMemoryIO.wrap(context.getRuntime(), address))); }
public static IRubyObject createRawBacktrace( Ruby runtime, StackTraceElement[] stackTrace, boolean filter) { RubyArray traceArray = RubyArray.newArray(runtime); for (int i = 0; i < stackTrace.length; i++) { StackTraceElement element = stackTrace[i]; if (filter) { if (element.getClassName().startsWith("org.jruby") || element.getLineNumber() < 0) { continue; } } RubyString str = RubyString.newString(runtime, createRubyBacktraceString(element)); traceArray.append(str); } return traceArray; }