rjb 1.2.0 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/ChangeLog CHANGED
@@ -1,3 +1,39 @@
1
+ Sun May 30 arton
2
+ *lib/rjbextension.rb
3
+ Rjb extension from Andreas Ronge's neo4j
4
+ - directly import jar by require method
5
+ - Rjb::import without quotations (Java class as Ruby object)
6
+ *test/exttest.rb
7
+ test for rjbextension.rb
8
+ *test/rjbtest.jar
9
+ test file for rjbextension.rb
10
+ Sat May 29 arton on behalf of atoulme
11
+ *ext/rjb.c
12
+ *ext/load.c
13
+ *ext/rjbexception.c
14
+ to accomodate with rubinius
15
+ thanks atoulme !
16
+ Wed May 12 arton
17
+ *test/test.rb
18
+ add Class name for TestMixin module because ruby 1.9 doesn't handle the constant.
19
+ Tue May 11 arton
20
+ *ext/rjb.c
21
+ fix duplicate method registering while no alias.
22
+ add class methods for inspecting method signatures.
23
+ add class_eval method for extending Java class
24
+ *test/test.rb
25
+ add class methods test for inspecting method signatures.
26
+ add mixin tests
27
+ Tue May 4 arton
28
+ *ext/load.c
29
+ corrected wrong function signature (BUG#28088), pointed and fixed by Romulo A. Ceccon (thanks)
30
+ *ext/rjb.c
31
+ using inheritance check while inspecting a object is RJB's instance (for extending it).
32
+ Tue Mar 16 arton
33
+ *ext/riconv.c
34
+ change locale setting "" to "C", fixed by Fabien Sartor (rjb-Bugs-27968)
35
+ *ext/rjb.c
36
+ RJB_VERSION -> 1.2.1
1
37
  Sun Nov 1 arton
2
38
  *ext/load.c
3
39
  load jvm pointed by JVM_LIB environment variable first (suggested by Ittay Dror).
data/ext/load.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Rjb - Ruby <-> Java Bridge
3
- * Copyright(c) 2004,2005,2006,2009 arton
3
+ * Copyright(c) 2004,2005,2006,2009,2010 arton
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: load.c 102 2009-11-01 14:01:41Z arton $
15
+ * $Id: load.c 112 2010-05-29 03:09:11Z arton $
16
16
  */
17
17
 
18
18
  #include <stdlib.h>
@@ -90,8 +90,8 @@
90
90
  #define GETDEFAULTJVMINITARGS "JNI_GetDefaultJavaVMInitArgs"
91
91
  #endif
92
92
 
93
- typedef int (*GETDEFAULTJAVAVMINITARGS)(void*);
94
- typedef int (*CREATEJAVAVM)(JavaVM**, JNIEnv**, void*);
93
+ typedef int (JNICALL *GETDEFAULTJAVAVMINITARGS)(void*);
94
+ typedef int (JNICALL *CREATEJAVAVM)(JavaVM**, JNIEnv**, void*);
95
95
 
96
96
 
97
97
  static VALUE jvmdll = Qnil;
@@ -295,7 +295,8 @@ int rjb_create_jvm(JNIEnv** pjenv, JavaVMInitArgs* vm_args, char* userpath, VALU
295
295
  }
296
296
  #endif
297
297
  }
298
- #if RJB_RUBY_VERSION_CODE < 190
298
+
299
+ #if RJB_RUBY_VERSION_CODE < 190 && !defined(RUBINIUS)
299
300
  ruby_errinfo = Qnil;
300
301
  #else
301
302
  rb_set_errinfo(Qnil);
@@ -366,4 +367,3 @@ int rjb_create_jvm(JNIEnv** pjenv, JavaVMInitArgs* vm_args, char* userpath, VALU
366
367
  }
367
368
  return result;
368
369
  }
369
-
@@ -12,7 +12,7 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: riconv.c 65 2008-03-26 13:19:29Z arton $
15
+ * $Id: riconv.c 104 2010-03-16 12:19:18Z arton $
16
16
  */
17
17
 
18
18
  #include "ruby.h"
@@ -98,14 +98,14 @@ static const char* get_charcode_name()
98
98
  #if defined _WIN32 || defined __CYGWIN__
99
99
  if (932 == GetACP()) result = CS_CP932;
100
100
  #elif defined HAVE_NL_LANGINFO
101
- setlocale(LC_ALL, ""); //initialize
101
+ setlocale(LC_ALL, "C"); //initialize
102
102
  lang = nl_langinfo(CODESET);
103
103
  if (find_table(lang, NL_EUC_TABLE))
104
104
  result = CS_EUCJP;
105
105
  else if (find_table(lang, NL_SJIS_TABLE))
106
106
  result = CS_SJIS;
107
107
  #elif defined HAVE_SETLOCALE
108
- setlocale(LC_ALL, ""); //initialize
108
+ setlocale(LC_ALL, "C"); //initialize
109
109
  result = get_charcode_name_by_locale(setlocale(LC_ALL, NULL));
110
110
  #elif defined HAVE_GETENV
111
111
  if (result = get_charcode_name_by_locale(getenv("LC_ALL")))
data/ext/rjb.c CHANGED
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Rjb - Ruby <-> Java Bridge
3
- * Copyright(c) 2004,2005,2006,2007,2008,2009 arton
3
+ * Copyright(c) 2004,2005,2006,2007,2008,2009,2010 arton
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -12,10 +12,10 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: rjb.c 102 2009-11-01 14:01:41Z arton $
15
+ * $Id: rjb.c 112 2010-05-29 03:09:11Z arton $
16
16
  */
17
17
 
18
- #define RJB_VERSION "1.2.0"
18
+ #define RJB_VERSION "1.2.2"
19
19
 
20
20
  #include "ruby.h"
21
21
  #include "extconf.h"
@@ -55,10 +55,12 @@
55
55
  #define RJB_LOAD_STATIC_METHOD(var, obj, name, sig) \
56
56
  var = (*jenv)->GetStaticMethodID(jenv, obj, name, sig); \
57
57
  rjb_check_exception(jenv, 1)
58
+ #define IS_RJB_OBJECT(v) (rb_class_inherited(rjbi, rb_obj_class(v)) || rb_obj_class(v) == rjb)
59
+ #define USER_INITIALIZE "@user_initialize"
58
60
 
59
61
  static void register_class(VALUE, VALUE);
60
62
  static VALUE import_class(JNIEnv* jenv, jclass, VALUE);
61
- static VALUE register_instance(JNIEnv* jenv, struct jvi_data*, jobject);
63
+ static VALUE register_instance(JNIEnv* jenv, VALUE klass, struct jv_data*, jobject);
62
64
  static VALUE rjb_s_free(struct jv_data*);
63
65
  static VALUE rjb_class_forname(int argc, VALUE* argv, VALUE self);
64
66
  static void setup_metadata(JNIEnv* jenv, VALUE self, struct jv_data*, VALUE classname);
@@ -73,6 +75,8 @@ static VALUE rjbc;
73
75
  static VALUE rjbi;
74
76
  static VALUE rjbb;
75
77
 
78
+ static ID user_initialize;
79
+
76
80
  VALUE rjb_loaded_classes;
77
81
  static VALUE proxies;
78
82
  JavaVM* rjb_jvm;
@@ -286,7 +290,7 @@ static VALUE jv2rv_r(JNIEnv* jenv, jvalue val)
286
290
  v = import_class(jenv, klass, clsname);
287
291
  }
288
292
  Data_Get_Struct(v, struct jv_data, ptr);
289
- v = register_instance(jenv, (struct jvi_data*)ptr, val.l);
293
+ v = register_instance(jenv, v, (struct jv_data*)ptr, val.l);
290
294
  (*jenv)->DeleteLocalRef(jenv, klass);
291
295
  (*jenv)->DeleteLocalRef(jenv, val.l);
292
296
  return v;
@@ -673,8 +677,7 @@ static void rv2jstring(JNIEnv* jenv, VALUE val, jvalue* jv, const char* psig, in
673
677
  {
674
678
  if (!release)
675
679
  {
676
- if (TYPE(val) == T_DATA
677
- && (RBASIC(val)->klass == rjbi || RBASIC(val)->klass == rjb))
680
+ if (TYPE(val) == T_DATA && IS_RJB_OBJECT(val))
678
681
  {
679
682
  struct jvi_data* ptr;
680
683
  Data_Get_Struct(val, struct jvi_data, ptr);
@@ -710,7 +713,7 @@ static void rv2jstring(JNIEnv* jenv, VALUE val, jvalue* jv, const char* psig, in
710
713
  {
711
714
  if (TYPE(val) == T_DATA)
712
715
  {
713
- if (RBASIC(val)->klass == rjbi || RBASIC(val)->klass == rjb)
716
+ if (IS_RJB_OBJECT(val))
714
717
  {
715
718
  struct jvi_data* ptr;
716
719
  Data_Get_Struct(val, struct jvi_data, ptr);
@@ -764,20 +767,20 @@ static void rv2jobject(JNIEnv* jenv, VALUE val, jvalue* jv, const char* psig, in
764
767
  switch (TYPE(val))
765
768
  {
766
769
  case T_DATA:
767
- if (RBASIC(val)->klass == rjbi || RBASIC(val)->klass == rjb)
770
+ if (IS_RJB_OBJECT(val))
768
771
  {
769
- /* TODO: check instanceof (class (in psig) ) */
772
+ /* TODO: check instanceof (class (in psig) ) */
770
773
  struct jvi_data* ptr;
771
774
  Data_Get_Struct(val, struct jvi_data, ptr);
772
775
  jv->l = ptr->obj;
773
776
  }
774
- else if (RBASIC(val)->klass == rjbb)
777
+ else if (rb_obj_class(val) == rjbb)
775
778
  {
776
779
  struct rj_bridge* ptr;
777
780
  Data_Get_Struct(val, struct rj_bridge, ptr);
778
781
  jv->l = ptr->proxy;
779
782
  }
780
- else if (rb_class_inherited(rjbc, RBASIC(val)->klass))
783
+ else if (rb_class_inherited(rjbc, rb_obj_class(val)))
781
784
  {
782
785
  struct jv_data* ptr;
783
786
  Data_Get_Struct(val, struct jv_data, ptr);
@@ -1327,14 +1330,16 @@ static struct cls_method* clone_methodinfo(struct cls_method* pm)
1327
1330
  return result;
1328
1331
  }
1329
1332
 
1330
- static void make_alias(const char* jname, char* rname)
1333
+ static int make_alias(const char* jname, char* rname)
1331
1334
  {
1335
+ int ret = 0;
1332
1336
  while (*jname)
1333
1337
  {
1334
1338
  if (isupper(*jname))
1335
1339
  {
1336
1340
  *rname++ = '_';
1337
1341
  *rname++ = tolower(*jname++);
1342
+ ret = 1;
1338
1343
  }
1339
1344
  else
1340
1345
  {
@@ -1342,6 +1347,7 @@ static void make_alias(const char* jname, char* rname)
1342
1347
  }
1343
1348
  }
1344
1349
  *rname = '\0';
1350
+ return ret;
1345
1351
  }
1346
1352
 
1347
1353
  static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static_method)
@@ -1349,6 +1355,7 @@ static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static
1349
1355
  struct cls_method* result;
1350
1356
  struct cls_method* pm;
1351
1357
  const char* jname;
1358
+ int alias;
1352
1359
  jstring nm;
1353
1360
  jobjectArray parama;
1354
1361
  jobject cls;
@@ -1365,7 +1372,7 @@ static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static
1365
1372
  rjb_check_exception(jenv, 0);
1366
1373
  jname = (*jenv)->GetStringUTFChars(jenv, nm, NULL);
1367
1374
  rname = ALLOCA_N(char, strlen(jname) * 2 + 8);
1368
- make_alias(jname, rname);
1375
+ alias = make_alias(jname, rname);
1369
1376
  result->name = rb_intern(jname);
1370
1377
  rjb_release_string(jenv, nm, jname);
1371
1378
  result->basic.id = (*jenv)->FromReflectedMethod(jenv, m);
@@ -1404,7 +1411,7 @@ static void create_methodinfo(JNIEnv* jenv, st_table* tbl, jobject m, int static
1404
1411
  if (*rname == '_') rname++;
1405
1412
  strcat(rname, "?");
1406
1413
  }
1407
- else
1414
+ else if (alias)
1408
1415
  {
1409
1416
  pm = clone_methodinfo(result);
1410
1417
  }
@@ -1589,14 +1596,14 @@ static void load_constants(JNIEnv* jenv, jclass klass, VALUE self, jobjectArray
1589
1596
  strcpy(pname, cname);
1590
1597
  *pname = toupper(*pname);
1591
1598
  if (!isupper(*pname)
1592
- || rb_const_defined(RBASIC(self)->klass, rb_intern(pname)))
1599
+ || rb_const_defined(rb_obj_class(self), rb_intern(pname)))
1593
1600
  {
1594
1601
  pname = NULL;
1595
1602
  }
1596
1603
  }
1597
1604
  if (pname)
1598
1605
  {
1599
- rb_define_const(RBASIC(self)->klass, pname, j2r(jenv, jv));
1606
+ rb_define_const(rb_obj_class(self), pname, j2r(jenv, jv));
1600
1607
  }
1601
1608
  rjb_release_string(jenv, nm, cname);
1602
1609
  }
@@ -1728,7 +1735,8 @@ static VALUE rjb_s_load(int argc, VALUE* argv, VALUE self)
1728
1735
  }
1729
1736
 
1730
1737
  jklass = import_class(jenv, j_class, rb_str_new2("java.lang.Class"));
1731
- rb_define_method(RBASIC(jklass)->klass, "forName", rjb_class_forname, -1);
1738
+ rb_define_method(rb_singleton_class(jklass), "forName", rjb_class_forname, -1);
1739
+ rb_define_method(rb_singleton_class(jklass), "for_name", rjb_class_forname, -1);
1732
1740
  rb_gc_register_address(&jklass);
1733
1741
 
1734
1742
  return Qnil;
@@ -1745,6 +1753,18 @@ VALUE rjb_load_vm_default()
1745
1753
  return rjb_s_load(0, NULL, 0);
1746
1754
  }
1747
1755
 
1756
+ /*
1757
+ * common prelude
1758
+ */
1759
+ JNIEnv* rjb_prelude()
1760
+ {
1761
+ JNIEnv* jenv = NULL;
1762
+ rjb_load_vm_default();
1763
+ jenv = rjb_attach_current_thread();
1764
+ (*jenv)->ExceptionClear(jenv);
1765
+ return jenv;
1766
+ }
1767
+
1748
1768
  /*
1749
1769
  * unload Java Virtual Machine
1750
1770
  *
@@ -1760,7 +1780,16 @@ static int clear_classes(VALUE key, VALUE val, VALUE dummy)
1760
1780
  static VALUE rjb_s_unload(int argc, VALUE* argv, VALUE self)
1761
1781
  {
1762
1782
  int result = 0;
1783
+ #ifdef HAVE_RB_HASH_FOREACH
1784
+ rb_hash_foreach(rjb_loaded_classes, clear_classes, 0);
1785
+ #else
1786
+ #ifdef RHASH_TBL
1763
1787
  st_foreach(RHASH_TBL(rjb_loaded_classes), clear_classes, 0);
1788
+ #else
1789
+ st_foreach(RHASH(rjb_loaded_classes)->tbl, clear_classes, 0);
1790
+ #endif
1791
+ #endif
1792
+
1764
1793
  if (rjb_jvm)
1765
1794
  {
1766
1795
  JNIEnv* jenv = rjb_attach_current_thread();
@@ -1883,14 +1912,19 @@ static VALUE rjb_s_free(struct jv_data* ptr)
1883
1912
  * create new instance of this class
1884
1913
  */
1885
1914
  static VALUE createinstance(JNIEnv* jenv, int argc, VALUE* argv,
1886
- struct jvi_data* org, struct cls_constructor* pc)
1915
+ VALUE self, struct cls_constructor* pc)
1887
1916
  {
1888
1917
  int i;
1889
1918
  char* psig = pc->method_signature;
1890
1919
  jobject obj = NULL;
1891
1920
  VALUE result;
1892
-
1921
+ struct jv_data* jklass;
1922
+ struct jvi_data* org;
1893
1923
  jvalue* args = (argc) ? ALLOCA_N(jvalue, argc) : NULL;
1924
+
1925
+ Data_Get_Struct(self, struct jv_data, jklass);
1926
+ org = &jklass->idata;
1927
+
1894
1928
  for (i = 0; i < argc; i++)
1895
1929
  {
1896
1930
  R2J pr2j = *(pc->arg_convert + i);
@@ -1911,7 +1945,7 @@ static VALUE createinstance(JNIEnv* jenv, int argc, VALUE* argv,
1911
1945
  psig = next_sig(psig);
1912
1946
  }
1913
1947
 
1914
- result = register_instance(jenv, org, obj);
1948
+ result = register_instance(jenv, self, jklass, obj);
1915
1949
  (*jenv)->DeleteLocalRef(jenv, obj);
1916
1950
  return result;
1917
1951
  }
@@ -1941,16 +1975,29 @@ static VALUE import_class(JNIEnv* jenv, jclass jcls, VALUE clsname)
1941
1975
  return v;
1942
1976
  }
1943
1977
 
1944
- static VALUE register_instance(JNIEnv* jenv, struct jvi_data* org, jobject obj)
1978
+ static VALUE rjb_i_prepare_proxy(VALUE self)
1979
+ {
1980
+ return rb_funcall(self, rb_intern("instance_eval"), 1,
1981
+ rb_str_new2("instance_eval &" USER_INITIALIZE));
1982
+ }
1983
+
1984
+ static VALUE register_instance(JNIEnv* jenv, VALUE klass, struct jv_data* org, jobject obj)
1945
1985
  {
1946
1986
  VALUE v;
1987
+ VALUE iproc;
1947
1988
  struct jvi_data* ptr = ALLOC(struct jvi_data);
1948
1989
  memset(ptr, 0, sizeof(struct jvi_data));
1949
1990
  v = Data_Wrap_Struct(rjbi, NULL, rjb_delete_ref, ptr);
1950
- ptr->klass = org->obj;
1991
+ ptr->klass = org->idata.obj;
1951
1992
  ptr->obj = (*jenv)->NewGlobalRef(jenv, obj);
1952
- ptr->methods = org->methods;
1953
- ptr->fields = org->fields;
1993
+ ptr->methods = org->idata.methods;
1994
+ ptr->fields = org->idata.fields;
1995
+ iproc = rb_ivar_get(klass, user_initialize);
1996
+ if (iproc != Qnil)
1997
+ {
1998
+ rb_ivar_set(v, user_initialize, iproc);
1999
+ rb_funcall(v, rb_intern("_prepare_proxy"), 0, 0);
2000
+ }
1954
2001
  return v;
1955
2002
  }
1956
2003
 
@@ -1990,7 +2037,7 @@ static int check_rtype(JNIEnv* jenv, VALUE v, char* p)
1990
2037
  case T_ARRAY:
1991
2038
  return *p == '[';
1992
2039
  case T_DATA:
1993
- if (RBASIC(v)->klass == rjbi && pcls)
2040
+ if (IS_RJB_OBJECT(v) && pcls)
1994
2041
  {
1995
2042
  /* imported object */
1996
2043
  jclass cls;
@@ -2028,11 +2075,7 @@ static VALUE rjb_newinstance_s(int argc, VALUE* argv, VALUE self)
2028
2075
  VALUE ret = Qnil;
2029
2076
  struct jv_data* ptr;
2030
2077
  int found = 0;
2031
- JNIEnv* jenv = NULL;
2032
-
2033
- rjb_load_vm_default();
2034
- jenv = rjb_attach_current_thread();
2035
- (*jenv)->ExceptionClear(jenv);
2078
+ JNIEnv* jenv = rjb_prelude();
2036
2079
 
2037
2080
  rb_scan_args(argc, argv, "1*", &vsig, &rest);
2038
2081
  sig = StringValueCStr(vsig);
@@ -2046,7 +2089,7 @@ static VALUE rjb_newinstance_s(int argc, VALUE* argv, VALUE self)
2046
2089
  && !strcmp(sig, (*pc)->method_signature))
2047
2090
  {
2048
2091
  found = 1;
2049
- ret = createinstance(jenv, argc - 1, argv + 1, &ptr->idata, *pc);
2092
+ ret = createinstance(jenv, argc - 1, argv + 1, self, *pc);
2050
2093
  break;
2051
2094
  }
2052
2095
  }
@@ -2063,12 +2106,8 @@ static VALUE rjb_newinstance(int argc, VALUE* argv, VALUE self)
2063
2106
  struct jv_data* ptr;
2064
2107
  struct cls_constructor** pc;
2065
2108
  int found = 0;
2066
- JNIEnv* jenv = NULL;
2109
+ JNIEnv* jenv = rjb_prelude();
2067
2110
 
2068
- rjb_load_vm_default();
2069
- jenv = rjb_attach_current_thread();
2070
- (*jenv)->ExceptionClear(jenv);
2071
-
2072
2111
  Data_Get_Struct(self, struct jv_data, ptr);
2073
2112
 
2074
2113
  if (ptr->constructors)
@@ -2092,7 +2131,7 @@ static VALUE rjb_newinstance(int argc, VALUE* argv, VALUE self)
2092
2131
  }
2093
2132
  if (found)
2094
2133
  {
2095
- ret = createinstance(jenv, argc, argv, &ptr->idata, *pc);
2134
+ ret = createinstance(jenv, argc, argv, self, *pc);
2096
2135
  break;
2097
2136
  }
2098
2137
  }
@@ -2118,18 +2157,71 @@ jclass rjb_find_class(JNIEnv* jenv, VALUE name)
2118
2157
  return (*jenv)->FindClass(jenv, java2jniname(jnicls));
2119
2158
  }
2120
2159
 
2160
+ /*
2161
+ * get specified method signature
2162
+ */
2163
+ static VALUE get_signatures(VALUE mname, st_table* st)
2164
+ {
2165
+ VALUE ret;
2166
+ struct cls_method* pm;
2167
+ ID rmid = rb_to_id(mname);
2168
+
2169
+ if (!st_lookup(st, rmid, (st_data_t*)&pm))
2170
+ {
2171
+ const char* tname = rb_id2name(rmid);
2172
+ rb_raise(rb_eRuntimeError, "Fail: unknown method name `%s'", tname);
2173
+ }
2174
+ ret = rb_ary_new();
2175
+ for (; pm; pm = pm->next)
2176
+ {
2177
+ rb_ary_push(ret, rb_str_new2(pm->basic.method_signature));
2178
+ }
2179
+ return ret;
2180
+ }
2181
+
2182
+ static VALUE rjb_get_signatures(VALUE self, VALUE mname)
2183
+ {
2184
+ struct jv_data* ptr;
2185
+
2186
+ Data_Get_Struct(self, struct jv_data, ptr);
2187
+ return get_signatures(mname, ptr->idata.methods);
2188
+ }
2189
+
2190
+ static VALUE rjb_get_static_signatures(VALUE self, VALUE mname)
2191
+ {
2192
+ struct jv_data* ptr;
2193
+
2194
+ Data_Get_Struct(self, struct jv_data, ptr);
2195
+ return get_signatures(mname, ptr->static_methods);
2196
+ }
2197
+
2198
+ static VALUE rjb_get_ctor_signatures(VALUE self)
2199
+ {
2200
+ VALUE ret;
2201
+ struct jv_data* ptr;
2202
+ struct cls_constructor** pc;
2203
+
2204
+ Data_Get_Struct(self, struct jv_data, ptr);
2205
+ ret = rb_ary_new();
2206
+ if (ptr->constructors)
2207
+ {
2208
+ for (pc = ptr->constructors; *pc; pc++)
2209
+ {
2210
+ rb_ary_push(ret, rb_str_new2((*pc)->method_signature));
2211
+ }
2212
+ }
2213
+ return ret;
2214
+ }
2215
+
2121
2216
  /*
2122
2217
  * jclass Rjb::bind(rbobj, interface_name)
2123
2218
  */
2124
2219
  static VALUE rjb_s_bind(VALUE self, VALUE rbobj, VALUE itfname)
2125
2220
  {
2126
2221
  VALUE result = Qnil;
2127
- JNIEnv* jenv = NULL;
2128
2222
  jclass itf;
2223
+ JNIEnv* jenv = rjb_prelude();
2129
2224
 
2130
- rjb_load_vm_default();
2131
- jenv = rjb_attach_current_thread();
2132
- (*jenv)->ExceptionClear(jenv);
2133
2225
  itf = rjb_find_class(jenv, itfname);
2134
2226
  rjb_check_exception(jenv, 1);
2135
2227
  if (itf)
@@ -2154,15 +2246,24 @@ static VALUE rjb_s_bind(VALUE self, VALUE rbobj, VALUE itfname)
2154
2246
  return result;
2155
2247
  }
2156
2248
 
2249
+ /*
2250
+ * Rjb's class is not Class but Object, so add class_eval for the Java class.
2251
+ */
2252
+ static VALUE rjb_class_eval(int argc, VALUE* argv, VALUE self)
2253
+ {
2254
+ if (rb_block_given_p())
2255
+ {
2256
+ rb_ivar_set(self, user_initialize, rb_block_proc());
2257
+ }
2258
+ return self;
2259
+ }
2260
+
2157
2261
  /*
2158
2262
  * jclass Rjb::bind(rbobj, interface_name)
2159
2263
  */
2160
2264
  static VALUE rjb_s_unbind(VALUE self, VALUE rbobj)
2161
2265
  {
2162
- JNIEnv* jenv;
2163
- rjb_load_vm_default();
2164
- jenv = rjb_attach_current_thread();
2165
- (*jenv)->ExceptionClear(jenv);
2266
+ JNIEnv* jenv = rjb_prelude();
2166
2267
  return rb_ary_delete(proxies, rbobj);
2167
2268
  }
2168
2269
 
@@ -2179,9 +2280,7 @@ static VALUE rjb_s_import(VALUE self, VALUE clsname)
2179
2280
  return v;
2180
2281
  }
2181
2282
 
2182
- rjb_load_vm_default();
2183
- jenv = rjb_attach_current_thread();
2184
- (*jenv)->ExceptionClear(jenv);
2283
+ jenv = rjb_prelude();
2185
2284
  jcls = rjb_find_class(jenv, clsname);
2186
2285
  if (!jcls)
2187
2286
  {
@@ -2196,10 +2295,23 @@ static void register_class(VALUE self, VALUE clsname)
2196
2295
  {
2197
2296
  rb_define_singleton_method(self, "new", rjb_newinstance, -1);
2198
2297
  rb_define_singleton_method(self, "new_with_sig", rjb_newinstance_s, -1);
2298
+ rb_define_singleton_method(self, "class_eval", rjb_class_eval, -1);
2299
+ rb_define_singleton_method(self, "sigs", rjb_get_signatures, 1);
2300
+ rb_define_singleton_method(self, "static_sigs", rjb_get_static_signatures, 1);
2301
+ rb_define_singleton_method(self, "ctor_sigs", rjb_get_ctor_signatures, 0);
2199
2302
  /*
2200
2303
  * the hash was frozen, so it need to call st_ func directly.
2201
2304
  */
2305
+
2306
+ #ifdef HAVE_RB_HASH_ASET
2307
+ rb_hash_aset(rjb_loaded_classes, clsname, self);
2308
+ #else
2309
+ #ifdef RHASH_TBL
2202
2310
  st_insert(RHASH_TBL(rjb_loaded_classes), clsname, self);
2311
+ #else
2312
+ st_insert(RHASH(rjb_loaded_classes)->tbl, clsname, self);
2313
+ #endif
2314
+ #endif
2203
2315
  }
2204
2316
 
2205
2317
  /*
@@ -2702,7 +2814,7 @@ static VALUE rjb_missing(int argc, VALUE* argv, VALUE self)
2702
2814
  {
2703
2815
  VALUE r, args[2];
2704
2816
  int state = 0;
2705
- args[0] = RBASIC(self)->klass;
2817
+ args[0] = rb_obj_class(self);
2706
2818
  args[1] = rmid;
2707
2819
  r = rb_protect(find_const, (VALUE)args, &state);
2708
2820
  if (!state)
@@ -2741,10 +2853,13 @@ void Init_rjbcore()
2741
2853
  rb_protect((VALUE(*)(VALUE))rb_require, (VALUE)"iconv", NULL);
2742
2854
 
2743
2855
  rjb_loaded_classes = rb_hash_new();
2856
+ #ifndef RUBINIUS
2744
2857
  OBJ_FREEZE(rjb_loaded_classes);
2858
+ #endif
2745
2859
  rb_global_variable(&rjb_loaded_classes);
2746
2860
  proxies = rb_ary_new();
2747
2861
  rb_global_variable(&proxies);
2862
+ user_initialize = rb_intern(USER_INITIALIZE);
2748
2863
 
2749
2864
  rjb = rb_define_module("Rjb");
2750
2865
  rb_define_module_function(rjb, "load", rjb_s_load, -1);
@@ -2763,7 +2878,7 @@ void Init_rjbcore()
2763
2878
  rb_gc_register_address(&rjbc);
2764
2879
  rb_define_method(rjbc, "method_missing", rjb_missing, -1);
2765
2880
  rb_define_method(rjbc, "_invoke", rjb_invoke, -1);
2766
- rb_define_method(rjbc, "_classname", rjb_i_class, 0);
2881
+ rb_define_method(rjbc, "_classname", rjb_i_class, 0);
2767
2882
 
2768
2883
  /* Java instance object */
2769
2884
  rjbi = rb_class_new(rb_cObject);
@@ -2771,6 +2886,8 @@ void Init_rjbcore()
2771
2886
  rb_define_method(rjbi, "method_missing", rjb_i_missing, -1);
2772
2887
  rb_define_method(rjbi, "_invoke", rjb_i_invoke, -1);
2773
2888
  rb_define_method(rjbi, "_classname", rjb_i_class, 0);
2889
+ rb_define_method(rjbi, "_prepare_proxy", rjb_i_prepare_proxy, 0);
2890
+ rb_define_alias(rjbi, "include", "extend");
2774
2891
 
2775
2892
  /* Ruby-Java Bridge object */
2776
2893
  rjbb = rb_class_new(rb_cObject);
@@ -1,6 +1,6 @@
1
1
  /*
2
2
  * Rjb - Ruby <-> Java Bridge
3
- * Copyright(c) 2004,2005,2006 arton
3
+ * Copyright(c) 2004,2005,2006,2010 arton
4
4
  *
5
5
  * This library is free software; you can redistribute it and/or
6
6
  * modify it under the terms of the GNU Lesser General Public
@@ -12,7 +12,7 @@
12
12
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
13
  * Lesser General Public License for more details.
14
14
  *
15
- * $Id: rjbexception.c 94 2009-09-10 13:54:42Z arton $
15
+ * $Id: rjbexception.c 112 2010-05-29 03:09:11Z arton $
16
16
  */
17
17
 
18
18
  #include "ruby.h"
@@ -54,7 +54,16 @@ VALUE rjb_get_exception_class(JNIEnv* jenv, jstring str)
54
54
  if (rexp == Qnil)
55
55
  {
56
56
  rexp = rb_define_class(pcls, rb_eStandardError);
57
- st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp);
57
+ #ifdef HAVE_RB_HASH_ASET
58
+ rb_hash_aset(rjb_loaded_classes, cname, rexp);
59
+ #else
60
+ #ifdef RHASH_TBL
61
+ st_insert(RHASH_TBL(rjb_loaded_classes), cname, rexp);
62
+ #else
63
+ st_insert(RHASH(rjb_loaded_classes)->tbl, cname, rexp);
64
+ #endif
65
+ #endif
66
+
58
67
  }
59
68
  return rexp;
60
69
  }
@@ -137,4 +146,3 @@ void rjb_check_exception(JNIEnv* jenv, int t)
137
146
  }
138
147
  }
139
148
  }
140
-
data/lib/rjb.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  =begin
2
- Copyright(c) 2006 arton
2
+ Copyright(c) 2006-2010 arton
3
3
  =end
4
4
 
5
5
  require 'rbconfig'
@@ -20,3 +20,4 @@ end
20
20
 
21
21
  require 'rjbcore'
22
22
 
23
+
@@ -0,0 +1,135 @@
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:$
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
+ @@rjb_jars ||= []
63
+ @@rjb_jars << abs_path unless @@rjb_jars.include?(abs_path)
64
+ # TODO
65
+ end
66
+
67
+ @@jvm_loaded = false
68
+
69
+ def load_jvm(jargs = [])
70
+ # avoid starting the JVM twice
71
+ return if @@jvm_loaded
72
+
73
+ @@jvm_loaded = true
74
+ classpath = ENV['CLASSPATH'] ||= ''
75
+ @@rjb_jars.each do |jar|
76
+ classpath += File::PATH_SEPARATOR unless classpath.empty?
77
+ classpath += jar
78
+ end
79
+ Rjb::load(classpath, jargs)
80
+ end
81
+ end
82
+
83
+ class JavaPackage
84
+
85
+ def initialize(pack_name, parent_pack = nil)
86
+ @pack_name = pack_name
87
+ @parent_pack = parent_pack
88
+ @cache = {}
89
+ end
90
+
91
+ def method_missing(m, *args)
92
+ # return if possible old module/class
93
+ @cache[m] ||= create_package_or_class(m)
94
+ end
95
+ def create_package_or_class(m)
96
+ method = m.to_s
97
+ if class?(method)
98
+ Rjb::import("#{self}.#{method}")
99
+ else
100
+ JavaPackage.new(method, self)
101
+ end
102
+ end
103
+
104
+ def to_s
105
+ if @parent_pack
106
+ "#{@parent_pack.to_s}.#@pack_name"
107
+ else
108
+ "#@pack_name"
109
+ end
110
+ end
111
+
112
+ def class?(a)
113
+ first_letter = a[0,1]
114
+ first_letter >= 'A' && first_letter <= 'Z'
115
+ end
116
+
117
+ @@cache = {}
118
+ def self.new(pack_name, parent_pack = nil)
119
+ @@cache[pack_name] ||= super
120
+ end
121
+ end
122
+
123
+ module RjbConf
124
+ # make them as singleton
125
+ ORG = JavaPackage.new('org')
126
+ JAVA = JavaPackage.new('java')
127
+ end
128
+
129
+ def org
130
+ RjbConf::ORG
131
+ end
132
+
133
+ def java
134
+ RjbConf::JAVA
135
+ end
@@ -0,0 +1,34 @@
1
+ #!/usr/local/env ruby -Ku
2
+ # encoding: utf-8
3
+ # $Id:$
4
+
5
+ begin
6
+ require 'rjb'
7
+ rescue LoadError
8
+ require 'rubygems'
9
+ require 'rjb'
10
+ end
11
+
12
+ if Rjb::VERSION < '1.2.2'
13
+ puts "Rjb #{Rjb::VERSION} does not support rjbextension. exit"
14
+ exit 0
15
+ end
16
+
17
+ require 'rjbextension'
18
+ require 'test/unit'
19
+
20
+ puts "start RJB(#{Rjb::VERSION}) test"
21
+ class ExtTestRjb < Test::Unit::TestCase
22
+
23
+ def jp
24
+ JavaPackage.new('jp')
25
+ end
26
+
27
+ def test_require_extension
28
+ require 'rjbtest.jar'
29
+ load_jvm
30
+
31
+ base = jp.co.infoseek.hp.arton.rjb.Base.new
32
+ assert_equal('hello', base.instance_var)
33
+ end
34
+ end
Binary file
@@ -1,6 +1,6 @@
1
1
  #!/usr/local/env ruby -Ku
2
2
  # encoding: utf-8
3
- # $Id: test.rb 87 2009-02-15 12:25:36Z arton $
3
+ # $Id: test.rb 111 2010-05-12 12:34:28Z arton $
4
4
 
5
5
  begin
6
6
  require 'rjb'
@@ -18,14 +18,14 @@ class TestRjb < Test::Unit::TestCase
18
18
  Rjb::primitive_conversion = false
19
19
 
20
20
  @jString = import('java.lang.String')
21
- @jInteger = Rjb::import('java.lang.Integer')
22
- @jShort = Rjb::import('java.lang.Short')
23
- @jDouble = Rjb::import('java.lang.Double')
24
- @jFloat = Rjb::import('java.lang.Float')
25
- @jBoolean = Rjb::import('java.lang.Boolean')
26
- @jByte = Rjb::import('java.lang.Byte')
27
- @jLong = Rjb::import('java.lang.Long')
28
- @jChar = Rjb::import('java.lang.Character')
21
+ @jInteger = import('java.lang.Integer')
22
+ @jShort = import('java.lang.Short')
23
+ @jDouble = import('java.lang.Double')
24
+ @jFloat = import('java.lang.Float')
25
+ @jBoolean = import('java.lang.Boolean')
26
+ @jByte = import('java.lang.Byte')
27
+ @jLong = import('java.lang.Long')
28
+ @jChar = import('java.lang.Character')
29
29
  end
30
30
 
31
31
  def teardown
@@ -650,5 +650,48 @@ class TestRjb < Test::Unit::TestCase
650
650
  assert_equal "can't create Java VM", $!.message
651
651
  end
652
652
  end
653
+
654
+ module TestMixin
655
+ def test_hello(s)
656
+ 'hello ' + s
657
+ end
658
+ end
659
+ def test_extend
660
+ @jString.class_eval do
661
+ include TestRjb::TestMixin
662
+ end
663
+ s = @jString.new
664
+ assert_equal('hello world', s.test_hello('world'))
665
+ end
666
+ def test_extend_with_factory
667
+ point = import('java.awt.Point')
668
+ point.class_eval do
669
+ include TestRjb::TestMixin
670
+ end
671
+ p = point.new(11, 12)
672
+ assert_equal(11, p.x)
673
+ assert_equal(12, p.y)
674
+ assert_equal('hello world', p.test_hello('world'))
675
+ p = p.location
676
+ assert_equal(11, p.x)
677
+ assert_equal(12, p.y)
678
+ assert_equal('hello world', p.test_hello('world'))
679
+ end
680
+ def test_fetch_method_signature
681
+ expected = ['I', 'II', 'Ljava.lang.String;', 'Ljava.lang.String;I']
682
+ sig = @jString.sigs('indexOf').sort
683
+ assert_equal(expected, sig)
684
+ end
685
+ def test_fetch_static_method_signature
686
+ expected = ['Ljava.lang.String;[Ljava.lang.Object;',
687
+ 'Ljava.util.Locale;Ljava.lang.String;[Ljava.lang.Object;']
688
+ sig = @jString.static_sigs('format').sort
689
+ assert_equal(expected, sig)
690
+ end
691
+ def test_fetch_ctor_signature
692
+ expected = ['I', 'Ljava.lang.String;']
693
+ sig = @jInteger.ctor_sigs.sort
694
+ assert_equal(expected, sig)
695
+ end
653
696
  end
654
697
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rjb
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - arton
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-11-01 00:00:00 +09:00
12
+ date: 2010-05-30 00:00:00 +09:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -36,14 +36,17 @@ files:
36
36
  - ext/depend
37
37
  - data/rjb/jp/co/infoseek/hp/arton/rjb/RBridge.class
38
38
  - lib/rjb.rb
39
+ - lib/rjbextension.rb
39
40
  - samples/filechooser.rb
40
41
  - test/test.rb
42
+ - test/exttest.rb
41
43
  - test/gctest.rb
42
44
  - test/jp/co/infoseek/hp/arton/rjb/Base.class
43
45
  - test/jp/co/infoseek/hp/arton/rjb/IBase.class
44
46
  - test/jp/co/infoseek/hp/arton/rjb/Test.class
45
47
  - test/jp/co/infoseek/hp/arton/rjb/Test$TestTypes.class
46
48
  - test/jp/co/infoseek/hp/arton/rjb/ExtBase.class
49
+ - test/rjbtest.jar
47
50
  - COPYING
48
51
  - ChangeLog
49
52
  - readme.sj