OpenOffice.org Forum at OOoForum.orgThe OpenOffice.org Forum
 
 [Home]   [FAQ]   [Search]   [Memberlist]   [Usergroups]   [Register
 [Profile]   [Log in to check your private messages]   [Log in

queryInterface utility for UNO Java

 
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets
View previous topic :: View next topic  
Author Message
mrodent33
Power User
Power User


Joined: 06 Nov 2010
Posts: 74

PostPosted: Sat Jan 01, 2011 8:49 am    Post subject: queryInterface utility for UNO Java Reply with quote

Hi all,

Don't know whether the following is of interest to anyone, certainly cuts down coding using parameterised types (is that a Java 6 thing? I forget). Anyway, the idea is just add the following 2 methods to your library of utilities:

Code:
   public static <X, Y> X getUnoInterface( Y targetClass, Object obj ) throws Exception{
    Object returnedObject = UnoRuntime.queryInterface( (Class<?>)targetClass, obj );
      if( returnedObject == null )
         throw new Exception( "*** could not get class " + ((Class<?>)targetClass).getSimpleName() );
      return uncheckedCast( ((Class<?>)targetClass).cast( returnedObject ));
   }


... as for "uncheckedCast" this is as follows:
Code:
   @SuppressWarnings({ "unchecked" })
   public static <T> T uncheckedCast(Object obj) {
      return (T) obj;
   }

The point about this latter method is that it should be the only time in your entire project when you need to add that SuppressWarnings tag.

After this you can just go:
Code:

public static void entryPoint(XScriptContext xScriptContext, com.sun.star.lang.EventObject eventObject) throws Exception {

  XListBox xListBox = MyUtils.getUnoInterface(XListBox.class, eventObject.Source);

... and if the source was indeed an XListBox you get an XListBox interface. If it wasn't you get an Exception thrown which can be dealt with as you see fit - here, by throwing in the declaration.

Any use?

Mike
Back to top
View user's profile Send private message
pitonyak
Administrator
Administrator


Joined: 09 Mar 2004
Posts: 3655
Location: Columbus, Ohio, USA

PostPosted: Sat Jan 01, 2011 11:29 am    Post subject: Reply with quote

Brilliant!
_________________
--
Andrew Pitonyak
http://www.pitonyak.org/oo.php
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address
mrodent33
Power User
Power User


Joined: 06 Nov 2010
Posts: 74

PostPosted: Sat Jan 01, 2011 3:14 pm    Post subject: Reply with quote

thanks for your kind word! Especially coming from such a person as yourself...!

Actually there's no need for a second parameterised parameter, or indeed for the cast() method... but there is a need for compliance-checking - better version:

Code:
   public static <X> X getUnoInterface(Class<?> targetClass, Object obj) throws Exception {
      checkNotNull( targetClass, obj);
      String pkgName = targetClass.getPackage().getName();
      if( ! pkgName.startsWith( "com.sun.star"))
         throw new AssertionError( "*** not a UNO package: " + pkgName );
      String classSimpleName = targetClass.getSimpleName();
      if( ! classSimpleName.startsWith( "X" ))
         throw new AssertionError( "*** not a UNO interface: " + classSimpleName + " (must begin with \"X\")");
      //
      Object returnedObject = UnoRuntime.queryInterface( targetClass, obj);
      if (returnedObject == null)
         throw new Exception("*** could not get class " + targetClass.getSimpleName());
      return uncheckedCast( returnedObject );

   }


There is obviously also a need for an equivalent to Java's "instanceof" operator...
Code:

   public static boolean isUnoInterfaceInstanceOf( Class<?> someInterface, Object someObject ) {
      checkNotNull( someInterface, someObject );
      String pkgName = someInterface.getPackage().getName();
      if( ! pkgName.startsWith( "com.sun.star"))
         throw new AssertionError( "*** not a UNO package: " + pkgName );
      String classSimpleName = someInterface.getSimpleName();
      if( ! classSimpleName.startsWith( "X" ))
         throw new AssertionError( "*** not a UNO interface: " + classSimpleName + " (must begin with \"X\")");
      //
      
      return UnoRuntime.queryInterface( someInterface, someObject ) != null;
      
   }



checkNotNull goes like this
Code:
   
   public static void checkNotNull(Object... a_objs) {
      for (int i = 0, n_args = a_objs.length; i < n_args; i++) {
         if (a_objs[i] == null)
            throw new AssertionError( "*** param " + (i + 1) + " null" );
      }
   }


The thing that really puzzles me at this stage is this:
- given that Java, especially with generics, is such a type-safe, object-oriented language, why does it need to have this IDL "superstructure" of "Interfaces" and "Services" grafted on top of it??? It seems so redundant, and I suppose the explanation is that this is the price you pay for the universality of the OOo API (i.e. the ability to use it in many different languages).

Don't get me wrong, this is not me criticising but puzzling: if the Sun designers have done it this way it is for the likes of lesser mortals like me to try and understand...!

Mike
Back to top
View user's profile Send private message
pitonyak
Administrator
Administrator


Joined: 09 Mar 2004
Posts: 3655
Location: Columbus, Ohio, USA

PostPosted: Tue Feb 15, 2011 6:10 am    Post subject: Reply with quote

The implementation language is not Java, it is C++, and the infrastructure was put in place some years ago. Meanwhile, languages continue to evolve to contain abilities that they did not have years ago.

Now, think of what the IDL defines and what you have in the class. Are these really directly related? For example, start with an object. The object supports interfaces and services. Perhaps your object supports three of each. How does the object support these interfaces and services? C++ supports multiple inheritance for classes, Java only supports multiple inheritance with interfaces, not classes. I have not looked sufficiently closely that I can directly answer your question, but, it is not obvious to me that there should be a simple (and obvious) way to implement this.

Basic hides many of the implementation details from you by encapsulating the type changes and similar. This would be nice to have, but, I expect that the underlying structure does not support a direct easy mapping from the original implementation to different class hierarchies with methods and properties, especially methods and properties that will be recognized using class inspection.
_________________
--
Andrew Pitonyak
http://www.pitonyak.org/oo.php
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address
Display posts from previous:   
Post new topic   Reply to topic    OOoForum.org Forum Index -> OpenOffice.org Code Snippets All times are GMT - 8 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group