rjb 1.3.0-universal-darwin-10

Sign up to get free protection for your applications and to get access to all the features.
data/ext/rjb.h ADDED
@@ -0,0 +1,163 @@
1
+ /*
2
+ * Rjb - Ruby <-> Java Bridge
3
+ * Copyright(c) 2004,2005 arton
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * $Id: rjb.h 139 2010-09-21 17:32:57Z arton $
16
+ * $Log: rjb.h,v $
17
+ * Revision 1.1 2005/01/16 17:36:10 arton
18
+ * Initial revision
19
+ *
20
+ *
21
+ */
22
+
23
+ #ifndef RJB_H
24
+ #define RJB_H
25
+
26
+ #if RJB_RUBY_VERSION_CODE < 190
27
+ #if !defined(RHASH_TBL)
28
+ #define RHASH_TBL(x) RHASH((x))->tbl
29
+ #endif
30
+ #endif
31
+
32
+ #if !defined(RSTRING_LEN)
33
+ #define RSTRING_LEN(s) (RSTRING(s)->len)
34
+ #endif
35
+ #if !defined(RSTRING_PTR)
36
+ #define RSTRING_PTR(s) (RSTRING(s)->ptr)
37
+ #endif
38
+ #if !defined(RARRAY_LEN)
39
+ #define RARRAY_LEN(s) (RARRAY(s)->len)
40
+ #endif
41
+ #if !defined(RARRAY_PTR)
42
+ #define RARRAY_PTR(s) (RARRAY(s)->ptr)
43
+ #endif
44
+
45
+ #if !defined(COUNTOF)
46
+ #define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
47
+ #endif
48
+
49
+ #if !defined(_I64_MIN)
50
+ #define _I64_MIN (-9223372036854775807i64 - 1)
51
+ #endif
52
+ #if !defined(_I64_MAX)
53
+ #define _I64_MAX 9223372036854775807i64
54
+ #endif
55
+
56
+ #if !defined(HAVE_LONG_LONG) && defined(__LP64__)
57
+ #define HAVE_LONG_LONG 1
58
+ #endif
59
+
60
+ /* in load.c */
61
+ extern int rjb_create_jvm(JNIEnv** pjenv, JavaVMInitArgs*, char*, VALUE);
62
+
63
+ /* in rjb.c */
64
+ extern JavaVM* rjb_jvm;
65
+ extern jclass rjb_rbridge;
66
+ extern jmethodID rjb_register_bridge;
67
+ extern VALUE rjb_loaded_classes;
68
+ extern jmethodID rjb_class_getName;
69
+ extern jclass rjb_j_throwable;
70
+ extern jmethodID rjb_throwable_getMessage;
71
+ extern JNIEnv* rjb_attach_current_thread(void);
72
+ extern jclass rjb_find_class(JNIEnv* jenv, VALUE name);
73
+ extern void rjb_release_string(JNIEnv *jenv, jstring str, const char* chrs);
74
+ extern VALUE rjb_load_vm_default();
75
+ extern VALUE rjb_safe_funcall(VALUE args);
76
+ extern VALUE jv2rv(JNIEnv* jenv, jvalue val);
77
+ extern jobject get_systemloader(JNIEnv* jenv);
78
+ extern jclass rjb_find_class_by_name(JNIEnv* jenv, const char* name);
79
+
80
+ /* in rjbexception.c */
81
+ extern VALUE rjb_get_exception_class(JNIEnv* jenv, jstring str);
82
+ extern void rjb_check_exception(JNIEnv* jenv, int t);
83
+ extern VALUE rjb_s_throw(int, VALUE*, VALUE);
84
+
85
+ /* conversion functions */
86
+ typedef void (*R2J)(JNIEnv*, VALUE, jvalue*, const char*, int);
87
+ typedef VALUE (*J2R)(JNIEnv*, jvalue);
88
+ typedef jarray (*R2JARRAY)(JNIEnv*, VALUE, const char*);
89
+ typedef void (JNICALL *RELEASEARRAY)(JNIEnv*, jobject, void*, jint);
90
+ typedef jlong (JNICALL *INVOKEAL)(JNIEnv*, jobject, jmethodID, const jvalue*);
91
+ typedef jdouble (JNICALL *INVOKEAD)(JNIEnv*, jobject, jmethodID, const jvalue*);
92
+ typedef jfloat (JNICALL *INVOKEAF)(JNIEnv*, jobject, jmethodID, const jvalue*);
93
+ typedef jboolean (JNICALL *INVOKEAZ)(JNIEnv*, jobject, jmethodID, const jvalue*);
94
+ typedef jshort (JNICALL *INVOKEAS)(JNIEnv*, jobject, jmethodID, const jvalue*);
95
+ typedef jobject (JNICALL *INVOKEA)(JNIEnv*, jobject, jmethodID, const jvalue*);
96
+ typedef VALUE (*CONV)(JNIEnv*, void*);
97
+
98
+ /*
99
+ * internal method class
100
+ */
101
+ struct cls_constructor {
102
+ jmethodID id;
103
+ int arg_count;
104
+ R2J* arg_convert;
105
+ char* method_signature;
106
+ char result_signature;
107
+ char result_arraydepth;
108
+ };
109
+
110
+ struct cls_method {
111
+ struct cls_constructor basic;
112
+ ID name;
113
+ int static_method;
114
+ off_t method;
115
+ J2R result_convert;
116
+ /* overload only */
117
+ struct cls_method* next;
118
+ };
119
+
120
+ /*
121
+ * internal field class
122
+ */
123
+ struct cls_field {
124
+ ID name;
125
+ jfieldID id;
126
+ char* field_signature;
127
+ char result_signature;
128
+ char result_arraydepth;
129
+ R2J arg_convert;
130
+ J2R value_convert;
131
+ int readonly;
132
+ int static_field;
133
+ };
134
+
135
+ /*
136
+ * Object instance
137
+ */
138
+ struct jvi_data {
139
+ jclass klass; /* class */
140
+ jobject obj; /* instance */
141
+ st_table* methods;
142
+ st_table* fields;
143
+ };
144
+
145
+ /*
146
+ * Class instance
147
+ */
148
+ struct jv_data {
149
+ struct jvi_data idata;
150
+ st_table* static_methods;
151
+ struct cls_constructor** constructors;
152
+ };
153
+
154
+ /*
155
+ * Bridge instance
156
+ */
157
+ struct rj_bridge {
158
+ jobject bridge;
159
+ jobject proxy;
160
+ VALUE wrapped;
161
+ };
162
+
163
+ #endif
@@ -0,0 +1,160 @@
1
+ /*
2
+ * Rjb - Ruby <-> Java Bridge
3
+ * Copyright(c) 2004,2005,2006,2010 arton
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * $Id: rjbexception.c 126 2010-07-22 13:58:15Z arton $
16
+ */
17
+
18
+ #include "ruby.h"
19
+ #include "extconf.h"
20
+ #if RJB_RUBY_VERSION_CODE < 190
21
+ #include "st.h"
22
+ #else
23
+ #include "ruby/st.h"
24
+ #endif
25
+ #include "jniwrap.h"
26
+ #include "riconv.h"
27
+ #include "rjb.h"
28
+
29
+ static VALUE missing_delegate(int argc, VALUE* argv, VALUE self)
30
+ {
31
+ ID rmid = rb_to_id(argv[0]);
32
+ return rb_funcall(rb_ivar_get(self, rb_intern("@cause")), rmid, argc - 1, argv + 1);
33
+ }
34
+
35
+ /*
36
+ * handle Java exception
37
+ * At this time, the Java exception is defined without the package name.
38
+ * This design may change in future release.
39
+ */
40
+ VALUE rjb_get_exception_class(JNIEnv* jenv, jstring str)
41
+ {
42
+ VALUE rexp;
43
+ char* pcls;
44
+ VALUE cname;
45
+ const char* p = (*jenv)->GetStringUTFChars(jenv, str, JNI_FALSE);
46
+ char* clsname = ALLOCA_N(char, strlen(p) + 1);
47
+ strcpy(clsname, p);
48
+ rjb_release_string(jenv, str, p);
49
+ pcls = strrchr(clsname, '.');
50
+ if (pcls)
51
+ {
52
+ pcls++;
53
+ }
54
+ else
55
+ {
56
+ pcls = clsname;
57
+ }
58
+ cname = rb_str_new2(pcls);
59
+ rexp = rb_hash_aref(rjb_loaded_classes, cname);
60
+ if (rexp == Qnil)
61
+ {
62
+ rexp = rb_define_class(pcls, rb_eStandardError);
63
+ rb_define_method(rexp, "method_missing", missing_delegate, -1);
64
+ #if defined(HAVE_RB_HASH_ASET) || defined(RUBINIUS)
65
+ rb_hash_aset(rjb_loaded_classes, cname, rexp);
66
+ #else
67
+ #ifdef RHASH_TBL
68
+ st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp);
69
+ #else
70
+ st_insert(RHASH(rjb_loaded_classes)->tbl, cname, rexp);
71
+ #endif
72
+ #endif
73
+
74
+ }
75
+ return rexp;
76
+ }
77
+
78
+ /*
79
+ * throw newly created exception with supplied message.
80
+ */
81
+ VALUE rjb_s_throw(int argc, VALUE* argv, VALUE self)
82
+ {
83
+ VALUE klass;
84
+ VALUE message;
85
+ JNIEnv* jenv = NULL;
86
+
87
+ rjb_load_vm_default();
88
+
89
+ jenv = rjb_attach_current_thread();
90
+ (*jenv)->ExceptionClear(jenv);
91
+
92
+ if (rb_scan_args(argc, argv, "11", &klass, &message) == 2)
93
+ {
94
+ jclass excep = rjb_find_class(jenv, klass);
95
+ if (excep == NULL)
96
+ {
97
+ rb_raise(rb_eRuntimeError, "`%s' not found", StringValueCStr(klass));
98
+ }
99
+ (*jenv)->ThrowNew(jenv, excep, StringValueCStr(message));
100
+ }
101
+ else
102
+ {
103
+ struct jvi_data* ptr;
104
+ Data_Get_Struct(klass, struct jvi_data, ptr);
105
+ if (!(*jenv)->IsInstanceOf(jenv, ptr->obj, rjb_j_throwable))
106
+ {
107
+ rb_raise(rb_eRuntimeError, "arg1 must be a throwable");
108
+ }
109
+ else
110
+ {
111
+ (*jenv)->Throw(jenv, ptr->obj);
112
+ }
113
+ }
114
+ return Qnil;
115
+ }
116
+
117
+ void rjb_check_exception(JNIEnv* jenv, int t)
118
+ {
119
+ jthrowable exp = (*jenv)->ExceptionOccurred(jenv);
120
+ if (exp)
121
+ {
122
+ VALUE rexp = Qnil;
123
+ if (RTEST(ruby_verbose))
124
+ {
125
+ (*jenv)->ExceptionDescribe(jenv);
126
+ }
127
+ (*jenv)->ExceptionClear(jenv);
128
+ if(1)
129
+ {
130
+ char* msg = "unknown exception";
131
+ jclass cls = (*jenv)->GetObjectClass(jenv, exp);
132
+ jstring str = (*jenv)->CallObjectMethod(jenv, exp, rjb_throwable_getMessage);
133
+ if (str)
134
+ {
135
+ const char* p = (*jenv)->GetStringUTFChars(jenv, str, JNI_FALSE);
136
+ msg = ALLOCA_N(char, strlen(p) + 1);
137
+ strcpy(msg, p);
138
+ rjb_release_string(jenv, str, p);
139
+ }
140
+ str = (*jenv)->CallObjectMethod(jenv, cls, rjb_class_getName);
141
+ if (str)
142
+ {
143
+ rexp = rjb_get_exception_class(jenv, str);
144
+ }
145
+ if (rexp == Qnil)
146
+ {
147
+ (*jenv)->DeleteLocalRef(jenv, exp);
148
+ rb_raise(rb_eRuntimeError, "%s", msg);
149
+ }
150
+ else
151
+ {
152
+ VALUE rexpi = rb_funcall(rexp, rb_intern("new"), 1, rb_str_new2(msg));
153
+ jvalue val;
154
+ val.l = exp;
155
+ rb_ivar_set(rexpi, rb_intern("@cause"), jv2rv(jenv, val));
156
+ rb_exc_raise(rexpi);
157
+ }
158
+ }
159
+ }
160
+ }
data/lib/rjb.rb ADDED
@@ -0,0 +1,98 @@
1
+ =begin
2
+ Copyright(c) 2006-2010 arton
3
+ =end
4
+
5
+ require 'rbconfig'
6
+
7
+ module RjbConf
8
+ dir = File.join(File.dirname(File.dirname(__FILE__)), 'data')
9
+ if File.exist?(dir)
10
+ datadir = dir
11
+ else
12
+ datadir = RbConfig::CONFIG['datadir']
13
+ end
14
+ BRIDGE_FILE = File.join(datadir, 'rjb', 'jp', 'co', 'infoseek', 'hp',
15
+ 'arton', 'rjb', 'RBridge.class')
16
+ unless File.exist?(BRIDGE_FILE)
17
+ raise 'bridge file not found'
18
+ end
19
+ end
20
+
21
+ require 'rjbcore'
22
+
23
+ module Rjb
24
+ module MODIFIER
25
+ def self.STATIC
26
+ 8
27
+ end
28
+ def self.PUBLIC
29
+ 1
30
+ end
31
+ end
32
+
33
+ module JMethod
34
+ def instance_method?(m)
35
+ m.modifiers & MODIFIER.STATIC == 0
36
+ end
37
+ def public_method?(m)
38
+ (m.modifiers & MODIFIER.PUBLIC) == MODIFIER.PUBLIC
39
+ end
40
+ def jmethods(org, klass, &blk)
41
+ (org + klass.getMethods.select do |m|
42
+ blk.call(m)
43
+ end.map do |m|
44
+ m.name
45
+ end).uniq
46
+ end
47
+ def format_sigs(s)
48
+ if s.size < 0
49
+ ''
50
+ elsif s.size == 1
51
+ s[0]
52
+ else
53
+ "[#{s.map{|m|m.nil? ? 'void' : m}.join(', ')}]"
54
+ end
55
+ end
56
+ end
57
+
58
+ class Rjb_JavaClass
59
+ include JMethod
60
+ def public_methods(inh = true)
61
+ jmethods(super(inh), self) do |m|
62
+ !instance_method?(m) && public_method?(m)
63
+ end
64
+ end
65
+ def methods(inh = true)
66
+ jmethods(super(inh), self) do |m|
67
+ !instance_method?(m) && public_method?(m)
68
+ end
69
+ end
70
+ def java_methods
71
+ jmethods([], self) do |m|
72
+ !instance_method?(m) && public_method?(m)
73
+ end.map do |m|
74
+ "#{m}(#{format_sigs(self.static_sigs(m))})"
75
+ end
76
+ end
77
+ end
78
+ class Rjb_JavaProxy
79
+ include JMethod
80
+ def public_methods(inh = true)
81
+ jmethods(super(inh), getClass) do |m|
82
+ instance_method?(m) && public_method?(m)
83
+ end
84
+ end
85
+ def methods(inh = true)
86
+ jmethods(super(inh), getClass) do |m|
87
+ instance_method?(m) && public_method?(m)
88
+ end
89
+ end
90
+ def java_methods
91
+ jmethods([], getClass) do |m|
92
+ instance_method?(m) && public_method?(m)
93
+ end.map do |m|
94
+ "#{m}(#{format_sigs(getClass.sigs(m))})"
95
+ end
96
+ end
97
+ end
98
+ end
Binary file
@@ -0,0 +1,128 @@
1
+ =begin
2
+ Copyright(c) 2010 arton
3
+
4
+ This library is free software; you can redistribute it and/or
5
+ modify it under the terms of the GNU Lesser General Public
6
+ License as published by the Free Software Foundation; either
7
+ version 2.1 of the License, or (at your option) any later version.
8
+
9
+ This library is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
+ Lesser General Public License for more details.
13
+
14
+ $Id: rjbextension.rb 147 2010-10-23 05:10:33Z arton $
15
+
16
+ This file is from Andreas Ronge project neo4j
17
+ http://github.com/andreasronge/neo4j/blob/rjb/lib/rjb_ext.rb
18
+
19
+ Copyright (c) 2008 Andreas Ronge
20
+
21
+ Permission is hereby granted, free of charge, to any person obtaining a copy
22
+ of this software and associated documentation files (the "Software"), to deal
23
+ in the Software without restriction, including without limitation the rights
24
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25
+ copies of the Software, and to permit persons to whom the Software is
26
+ furnished to do so, subject to the following conditions:
27
+
28
+ The above copyright notice and this permission notice shall be included in
29
+ all copies or substantial portions of the Software.
30
+
31
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
37
+ THE SOFTWARE.
38
+ =end
39
+
40
+ # Loads the JVM with the given <tt>classpath</tt> and arguments to the jre.
41
+ # All needed .jars should be included in <tt>classpath</tt>.
42
+
43
+ module Kernel
44
+ alias rjb_original_require require
45
+
46
+ def require(path)
47
+ rjb_original_require(path)
48
+ rescue LoadError
49
+ # check that it's not a jar file
50
+ raise unless path =~ /\.jar/
51
+
52
+ # This will maybe use the wrong jar file from a previous version of the GEM
53
+ # puts "LOAD PATH #{$LOAD_PATH}"
54
+ found_path = $LOAD_PATH.reverse.find{|p| File.exist?(File.join(p,path))}
55
+ raise unless found_path
56
+
57
+ abs_path = File.join(found_path, path)
58
+ # check that the file exists
59
+ raise unless File.exist?(abs_path)
60
+
61
+ # try to load it using RJB
62
+ if Rjb::loaded?
63
+ Rjb::add_jar abs_path
64
+ else
65
+ Rjb::add_classpath abs_path
66
+ end
67
+ end
68
+
69
+ def load_jvm(jargs = [])
70
+ return if Rjb::loaded?
71
+ classpath = ENV['CLASSPATH'] ||= ''
72
+ Rjb::load(classpath, jargs)
73
+ end
74
+ end
75
+
76
+ class JavaPackage
77
+
78
+ def initialize(pack_name, parent_pack = nil)
79
+ @pack_name = pack_name
80
+ @parent_pack = parent_pack
81
+ @cache = {}
82
+ end
83
+
84
+ def method_missing(m, *args)
85
+ # return if possible old module/class
86
+ @cache[m] ||= create_package_or_class(m)
87
+ end
88
+ def create_package_or_class(m)
89
+ method = m.to_s
90
+ if class?(method)
91
+ Rjb::import("#{self}.#{method}")
92
+ else
93
+ JavaPackage.new(method, self)
94
+ end
95
+ end
96
+
97
+ def to_s
98
+ if @parent_pack
99
+ "#{@parent_pack.to_s}.#@pack_name"
100
+ else
101
+ "#@pack_name"
102
+ end
103
+ end
104
+
105
+ def class?(a)
106
+ first_letter = a[0,1]
107
+ first_letter >= 'A' && first_letter <= 'Z'
108
+ end
109
+
110
+ @@cache = {}
111
+ def self.new(pack_name, parent_pack = nil)
112
+ @@cache[pack_name] ||= super
113
+ end
114
+ end
115
+
116
+ module RjbConf
117
+ # make them as singleton
118
+ ORG = JavaPackage.new('org')
119
+ JAVA = JavaPackage.new('java')
120
+ end
121
+
122
+ def org
123
+ RjbConf::ORG
124
+ end
125
+
126
+ def java
127
+ RjbConf::JAVA
128
+ end