Details

    • Type: New Feature New Feature
    • Status: Open Open
    • Priority: Minor Minor
    • Resolution: Unresolved
    • Affects Version/s: JRuby 1.5
    • Fix Version/s: None
    • Component/s: Embedding
    • Labels:
      None
    • Number of attachments :
      0

      Description

      It would be nice to have plug in mechanism for the marshalling of ruby objects. Currently i need a wrapper method to do this:

      private Object ruby2Java(Object obj) {
              Object l_ret;
      
              if (obj == null || obj instanceof RubyNil) {
                  return null;
              }
      
              if (!(obj instanceof IRubyObject)) {
                  return obj;
              }
      
              l_ret = (IRubyObject) obj;
      
              if (l_ret instanceof RubyObject) {
                  if (l_ret instanceof RubyHash) {
                      RubyHash l_hash = RubyHash.newHash(_rubyObj.getRuntime());
                      for (Object l_key : ((RubyHash) l_ret).keys()) {
                          l_hash.put(ruby2Java(l_key), ruby2Java(((RubyHash) l_ret).get(l_key)));
                      }
                      return l_hash;
                  }
                  if (l_ret instanceof RubyArray) {
                      RubyArray l_array = RubyArray.newArray(_rubyObj.getRuntime());
                      for (int i = 0; i < ((RubyArray) l_ret).size(); i++) {
                          l_array.add(ruby2Java(((RubyArray) l_ret).get(i)));
                      }
                      return l_array;
                  }
      
                  if( l_ret instanceof RubyTime ) {
                      return new Date( ((RubyTime)l_ret).getDateTime().getMillis() );
                  }
      
                  if ("DateTime".equals(((RubyObject) l_ret).getType().toString()) ||
                      "Date".equals(((RubyObject) l_ret).getType().toString()) ||
                      "Time".equals(((RubyObject) l_ret).getType().toString()) ) {
                      RubyString l_value = (RubyString) ((RubyObject) l_ret).callMethod("strftime", new IRubyObject[]{RubyString.newString(_rubyObj.getRuntime(), "%Q")});
                      return new Date(Long.parseLong(l_value.asJavaString()));
                  }
                  if ("At::Illumine::DomainCenter::DateSpan".equals(((RubyObject) l_ret).getType().toString())) {
                      RubyString l_value = (RubyString) ((RubyObject) l_ret).callMethod("to_s", new IRubyObject[]{});
                      return new DateSpan(l_value.asJavaString());
                  }
                  Object l_native = ((RubyObject)l_ret).toJava(((RubyObject)l_ret).getJavaClass() );
                  if( l_native != null && !(l_native instanceof RubyObject))
                      return l_native;
      
                  Object l_domain = ((RubyObject) l_ret).callMethod("session_context", new IRubyObject[]{RubyString.newString(_rubyObj.getRuntime(), "java")});
                  if (l_domain instanceof RubyNil) {
                      l_ret = DomainContainer.getInstance().create((RubyObject) l_ret);
                  } else {
                      l_ret = ((ConcreteJavaProxy) l_domain).getObject();
                  }
              }
      
              return l_ret;
          }
      
      

        Activity

        Hide
        Hiro Asari added a comment -

        Reformat description.

        Show
        Hiro Asari added a comment - Reformat description.
        Hide
        Hiro Asari added a comment -

        Hi, Alex,

        Could you give us use cases for such methods? They'll help us how best to implement the feature.

        Thanks.

        Show
        Hiro Asari added a comment - Hi, Alex, Could you give us use cases for such methods? They'll help us how best to implement the feature. Thanks.
        Hide
        Charles Oliver Nutter added a comment -

        I talked a bit with Alex about this, and the desire here is one we've had for a while. Specifically, if you have a Ruby type X that you want to be usable for calling Java methods that take a Java type Y, there should be a way to have your X be equivalent to Y for method selection purposes. There are a few ways to do this, mostly centering on providing a per-class method that lists "equivalent" types that it can substitute for. So you might have something like

        class X
          def self.java_types
            [
              java.util.Date,
              java.sql.Date
            ]
          end
        
          def to_java(cls)
            # coerce to given class, presumably either util.Date or sql.Date
        end
        

        For purposes of calling methods that expect util.Date or sql.Date, this class would now be coercible. This opens the door to allowing users to define their own Ruby to Java type equivalencies and coercions, closing the circle on how methods are selected and arguments are coerced.

        Show
        Charles Oliver Nutter added a comment - I talked a bit with Alex about this, and the desire here is one we've had for a while. Specifically, if you have a Ruby type X that you want to be usable for calling Java methods that take a Java type Y, there should be a way to have your X be equivalent to Y for method selection purposes. There are a few ways to do this, mostly centering on providing a per-class method that lists "equivalent" types that it can substitute for. So you might have something like class X def self.java_types [ java.util.Date, java.sql.Date ] end def to_java(cls) # coerce to given class, presumably either util.Date or sql.Date end For purposes of calling methods that expect util.Date or sql.Date, this class would now be coercible. This opens the door to allowing users to define their own Ruby to Java type equivalencies and coercions, closing the circle on how methods are selected and arguments are coerced.
        Hide
        Alex K added a comment -

        Sorry for the late reply - I was on vacation.

        However, I think Charles got my intentions right - nevertheless here you have my two intentions with this feature:
        1) To control the standard marshalling behavior of JRuby: As far as I know, there is no way to control in JRuby which class in Ruby should be used for a Java class - and the other way around. This is sometimes really annoying - especially when using Date/Time objects. There are plenty of DateTime implementations out there in Ruby, but I am restricted to use the Time Class, because this is the standard "definition" in JRuby.
        2) To extend JRuby: I have implemented a Time span object in Ruby and in Java. They are basically the same and I would like to have a way to tell JRuby exactly about this relation - that I do not need to take care about this conversion by myself.

        This manually conversion topic gets even more complex when working with Hashes/Arrays. I need to take care about the conversion of the key and values which is cumbersome and also robs a lot of performance.
        (Btw - the topic with hashes is generally a little bit annoying because the Java method "get" and "put" of the RubyHash Java class does not call the equivalent method [] of the Ruby Hash method which is an issue when working with default values of non-standard hash implementations. Nevertheless I understand that this has something to do witch caching and performance...).

        Please do not get me wrong in any way. I really like what you are doing and I think JRuby is great - this is also the reason why I introduced JRuby as a core component to the product I am working on. But I guess that I am one of a few which are using JRuby that way. If you need any further information or clarifications, just hit me back (I am on a business trip until Friday).

        Regards, Alex

        Show
        Alex K added a comment - Sorry for the late reply - I was on vacation. However, I think Charles got my intentions right - nevertheless here you have my two intentions with this feature: 1) To control the standard marshalling behavior of JRuby: As far as I know, there is no way to control in JRuby which class in Ruby should be used for a Java class - and the other way around. This is sometimes really annoying - especially when using Date/Time objects. There are plenty of DateTime implementations out there in Ruby, but I am restricted to use the Time Class, because this is the standard "definition" in JRuby. 2) To extend JRuby: I have implemented a Time span object in Ruby and in Java. They are basically the same and I would like to have a way to tell JRuby exactly about this relation - that I do not need to take care about this conversion by myself. This manually conversion topic gets even more complex when working with Hashes/Arrays. I need to take care about the conversion of the key and values which is cumbersome and also robs a lot of performance. (Btw - the topic with hashes is generally a little bit annoying because the Java method "get" and "put" of the RubyHash Java class does not call the equivalent method [] of the Ruby Hash method which is an issue when working with default values of non-standard hash implementations. Nevertheless I understand that this has something to do witch caching and performance...). Please do not get me wrong in any way. I really like what you are doing and I think JRuby is great - this is also the reason why I introduced JRuby as a core component to the product I am working on. But I guess that I am one of a few which are using JRuby that way. If you need any further information or clarifications, just hit me back (I am on a business trip until Friday). Regards, Alex
        Hide
        Charles Oliver Nutter added a comment -

        This would be a good improvement to finally add in 1.6. Marking it as such.

        Show
        Charles Oliver Nutter added a comment - This would be a good improvement to finally add in 1.6. Marking it as such.
        Hide
        Alex K added a comment - - edited

        postponed for 1.7 - a pitty...

        Show
        Alex K added a comment - - edited postponed for 1.7 - a pitty...

          People

          • Assignee:
            Unassigned
            Reporter:
            Alex K
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated: