Difference between revisions of "Documentation/DevGuide/WritingUNO/Implementing without Helpers"
OOoWikiBot (Talk | contribs) m (Robot: Changing Category:Writing UNO Components) |
OOoWikiBot (Talk | contribs) m (Robot: Automated text replacement (-Category:Documentation/Developers Guide/Professional UNO +Category:Documentation/Developers Guide/Writing UNO)) |
||
Line 133: | Line 133: | ||
{{PDL1}} | {{PDL1}} | ||
− | [[Category:Documentation/Developers Guide/ | + | [[Category:Documentation/Developers Guide/Writing UNO]] |
Revision as of 07:19, 4 June 2008
- Class Definition with Helper Class
- Implementing Your Own Interfaces
- Providing a Single Factory Using a Helper Method
- Write Registration Info Using a Helper Method
- Implementing without Helpers
- Storing the Service Manager for Further Use
- Create Instance with Arguments
- Possible Structures for Java Components
- Running and Debugging Java Components
XInterface
As soon as the component implements any UNO interface, com.sun.star.uno.XInterface is included automatically. The Java interface definition generated by javamaker for com.sun.star.uno.XInterface only contains a TypeInfo
member used by Java UNO internally to store certain UNO type information:
// source file com/sun/star/uno/XInterface.java corresponding to the class generated by package com.sun.star.uno; public interface XInterface { // static Member public static final com.sun.star.lib.uno.typeinfo.TypeInfo UNOTYPEINFO[] = null; }
Note that XInterface
does not have any methods, in contrast to its IDL description. That means, if implements com.sun.star.uno.XInterface
is added to a class definition, there is nothing to implement.
The method queryInterface()
is unnecessary in the implementation of a UNO object, because the Java UNO runtime environment obtains interface references without support from the UNO objects themselves. Within Java, the method UnoRuntime.queryInterface()
is used to obtain interfaces instead of calling <idlml>com.sun.star.uno.XInterface:queryInterface</idlml>(), and the Java UNO language binding hands out interfaces for UNO objects to other processes on its own as well.
The methods acquire()
and release()
are used for reference counting and control the lifetime of an object, because the Java garbage collector does this, there is no reference counting in Java components.
XTypeProvider
Helper classes with default com.sun.star.lang.XTypeProvider implementations are still under development for Java. Meanwhile, every Java UNO object implementation can implement the XTypeProvider
interface as shown in the following code. In your implementation, adjust getTypes()
:
... // XTypeProvider implementation // maintain a static implementation id for all instances of ImageShrink // initialized by the first call to getImplementationId() protected static byte[] _implementationId; public com.sun.star.uno.Type[] getTypes() { // instantiate Type instances for each interface you support and place them in a Type[] array // (this object supports XServiceInfo, XTypeProvider, and XImageShrinkFilter) return new com.sun.star.uno.Type[] { new com.sun.star.uno.Type(com.sun.star.lang.XServiceInfo.class), new com.sun.star.uno.Type(com.sun.star.lang.XTypeProvider.class), new com.sun.star.uno.Type(org.openoffice.test.XImageShrinkFilter.class) }; } synchronized public byte[] getImplementationId() { if (_implementationId == null) { _implementationId= new byte[16]; int hash = hashCode(); // hashCode of this object _implementationId[0] = (byte)(hash & 0xff); _implementationId[1] = (byte)((hash >>> 8) & 0xff); _implementationId[2] = (byte)((hash >>> 16) & 0xff); _implementationId[3] = (byte)((hash >>>24) & 0xff); } return _implementationId; } ...
The suggested implementation of the getImplementationId()
method is not optimal, it uses the hashCode()
of the first instance that initializes the static field. The future UNO helper class will improve this.
XComponent
XComponent
is an optional interface that is useful when other objects hold references to the component. The notification mechanism of XComponent
enables listener objects to learn when the component stops to provide its services, so that the objects drop their references to the component. This enables the component to delete itself when its reference count drops to zero. From section Core Interfaces to Implement, there must be three things done when dispose()
is called at an XComponent
:
- Inform registered
XEventListener
s that the object is being disposed of by calling their methoddisposing()
. - Release all references the object holds, including all
XEvenListener
objects. - On further calls to the component, throw an com.sun.star.lang.DisposedException in case the required task can not be fulfilled anymore, because the component was disposed.
In Java, the object cannot be deleted, but the garbage collector will do this. It is sufficient to release all references that are currently being held to break the cyclic reference, and to call disposing()
on all com.sun.star.lang.XEventListeners.
The registration and removal of listener interfaces is a standard procedure in Java. Some IDEs even create the necessary methods automatically. The following example could be written:
... //XComponent implementation // hold a list of eventListeners private java.util.ArrayList eventListeners = new java.util.ArrayList(); public void dispose { java.util.ArrayList listeners; synchronized (this) { listeners = eventListeners; eventListeners = null; } for (java.util.Iterator i = listeners.iterator(); i.hasNext();) { fireDisposing((XEventListener) i.next()); } releaseReferences(); } public void addEventListener(XEventListener listener) { bool fire = false; synchronized (this) { if (eventListeners == null) { fire = true; } else { eventListeners.add(listener); } } if (fire) { fireDisposing(listener); } } public synchronized void removeEventListener(XEventListener listener) { if (eventListeners != null) { int i = eventListeners.indexOf(listener); if (i >= 0) { eventListeners.remove(i); } } } private void fireDisposing(XEventListener listener) { com.sun.star.uno.EventObject event = new com.sun.star.uno.EventObject(this); try { listener.disposing(event); } catch (com.sun.star.uno.DisposedException e) { // it is not an error if some listener is disposed simultaneously } } private void releaseReferences() { xComponentContext = null; // ... }
Content on this page is licensed under the Public Documentation License (PDL). |