Difference between revisions of "Documentation/DevGuide/WritingUNO/Possible Structures for Java Components"
(→Additional UNO Types) |
|||
(9 intermediate revisions by 5 users not shown) | |||
Line 5: | Line 5: | ||
|NextPage=Documentation/DevGuide/WritingUNO/Running and Debugging Java Components | |NextPage=Documentation/DevGuide/WritingUNO/Running and Debugging Java Components | ||
}} | }} | ||
+ | {{Documentation/DevGuideLanguages|Documentation/DevGuide/WritingUNO/{{SUBPAGENAME}}}} | ||
{{DISPLAYTITLE:Possible Structures for Java Components}} | {{DISPLAYTITLE:Possible Structures for Java Components}} | ||
__NOTOC__ | __NOTOC__ | ||
Line 19: | Line 20: | ||
An implementation class contains the static component operations. The following sample implements an interface <code>com.sun.star.test.XSomething</code> in an implementation class <code>JavaComp.TestComponent</code>: | An implementation class contains the static component operations. The following sample implements an interface <code>com.sun.star.test.XSomething</code> in an implementation class <code>JavaComp.TestComponent</code>: | ||
− | + | <syntaxhighlight lang="idl"> | |
// UNOIDL: interface example specification | // UNOIDL: interface example specification | ||
module com { module sun { module star { module test { | module com { module sun { module star { module test { | ||
Line 28: | Line 29: | ||
}; | }; | ||
}; }; }; }; | }; }; }; }; | ||
− | + | </syntaxhighlight> | |
A component that implements only one service supporting <code>XSomething</code> can be assembled in one class as follows: | A component that implements only one service supporting <code>XSomething</code> can be assembled in one class as follows: | ||
− | + | <syntaxhighlight lang="java"> | |
package JavaComp; | package JavaComp; | ||
Line 79: | Line 80: | ||
} | } | ||
} | } | ||
− | + | </syntaxhighlight> | |
The class implements the <code>XSomething</code> interface. The IDL description and documentation provides information about its functionality. The class also contains the functions for factory creation and registration, therefore the manifest entry must read as follows: | The class implements the <code>XSomething</code> interface. The IDL description and documentation provides information about its functionality. The class also contains the functions for factory creation and registration, therefore the manifest entry must read as follows: | ||
Line 86: | Line 87: | ||
==== Implementation Class with Component Operations and Inner Implementation Class ==== | ==== Implementation Class with Component Operations and Inner Implementation Class ==== | ||
To implement the component as inner class of the one that provides the service factory through <code>__getServiceFactory()</code>, it must be a ''static'' inner class, otherwise the factory provided by the <code>FactoryHelper</code> cannot create the component. An example for an inner implementation class is located in the sample <code>com.sun.star.comp.demo.DemoComponent.java</code> provided with the SDK. The implementation of <code>__getServiceFactory()</code> and <code>__writeRegistryServiceInfo()</code> is omitted here, because they act the same as in the implementation class with component operations above. | To implement the component as inner class of the one that provides the service factory through <code>__getServiceFactory()</code>, it must be a ''static'' inner class, otherwise the factory provided by the <code>FactoryHelper</code> cannot create the component. An example for an inner implementation class is located in the sample <code>com.sun.star.comp.demo.DemoComponent.java</code> provided with the SDK. The implementation of <code>__getServiceFactory()</code> and <code>__writeRegistryServiceInfo()</code> is omitted here, because they act the same as in the implementation class with component operations above. | ||
− | + | <syntaxhighlight lang="java"> | |
package com.sun.star.comp.demo; | package com.sun.star.comp.demo; | ||
Line 118: | Line 119: | ||
} | } | ||
− | + | </syntaxhighlight> | |
The manifest entry for this implementation structure again has to point to the class with the static component operations: | The manifest entry for this implementation structure again has to point to the class with the static component operations: | ||
Line 128: | Line 129: | ||
The following are the UNOIDL specifications for <code>XSomethingA</code> and <code>XSomethingB</code>: | The following are the UNOIDL specifications for <code>XSomethingA</code> and <code>XSomethingB</code>: | ||
− | + | <syntaxhighlight lang="idl"> | |
module com { module sun { module star { module test { | module com { module sun { module star { module test { | ||
interface XSomethingA: com::sun::star::uno::XInterface | interface XSomethingA: com::sun::star::uno::XInterface | ||
Line 142: | Line 143: | ||
}; | }; | ||
}; }; }; }; | }; }; }; }; | ||
− | + | </syntaxhighlight> | |
<code>TestComponentA</code> implements <code>XSomethingA</code>: <!--[SOURCE:Components/JavaComponent/TestComponentA.java]:--> | <code>TestComponentA</code> implements <code>XSomethingA</code>: <!--[SOURCE:Components/JavaComponent/TestComponentA.java]:--> | ||
− | + | <syntaxhighlight lang="java"> | |
package JavaComp; | package JavaComp; | ||
Line 188: | Line 189: | ||
// XServiceInfo | // XServiceInfo | ||
public boolean supportsService( /*IN*/String serviceName ) { | public boolean supportsService( /*IN*/String serviceName ) { | ||
− | + | return serviceName.equals( __serviceName); | |
− | + | ||
− | + | ||
} | } | ||
Line 200: | Line 199: | ||
} | } | ||
} | } | ||
− | + | </syntaxhighlight> | |
− | + | <code>TestComponentB</code> implements <code>XSomethingB</code>. Note that it receives the component context and initialization arguments in its constructor. | |
− | <code>TestComponentB</code> implements <code>XSomethingB</code>. Note that it receives the component context and initialization arguments in its constructor. <!--[SOURCE:Components/JavaComponent/TestComponentB.java]--> | + | <!--[SOURCE:Components/JavaComponent/TestComponentB.java]--> |
− | + | <syntaxhighlight lang="java"> | |
package JavaComp; | package JavaComp; | ||
Line 254: | Line 253: | ||
// XServiceInfo | // XServiceInfo | ||
public boolean supportsService( /*IN*/String serviceName ) { | public boolean supportsService( /*IN*/String serviceName ) { | ||
− | + | return serviceName.equals( __serviceName); | |
− | + | ||
− | + | ||
} | } | ||
Line 266: | Line 263: | ||
} | } | ||
} | } | ||
− | + | </syntaxhighlight> | |
<code>TestServiceProvider</code> implements <code>__getServiceFactory()</code> and <code>__writeRegistryServiceInfo()</code>: | <code>TestServiceProvider</code> implements <code>__getServiceFactory()</code> and <code>__writeRegistryServiceInfo()</code>: | ||
<!--[SOURCE:Components/JavaComponent/TestServiceProvider.java]--> | <!--[SOURCE:Components/JavaComponent/TestServiceProvider.java]--> | ||
− | + | <syntaxhighlight lang="java"> | |
package JavaComp; | package JavaComp; | ||
... | ... | ||
Line 296: | Line 293: | ||
} | } | ||
} | } | ||
− | + | </syntaxhighlight> | |
The corresponding manifest entry must point to the static class with the component operations, in this case <code>JavaComp.TestServiceProvider</code>: | The corresponding manifest entry must point to the static class with the component operations, in this case <code>JavaComp.TestServiceProvider</code>: | ||
Line 306: | Line 303: | ||
representing UNO types in such a way that they are available across the whole Java UNO runtime environment. | representing UNO types in such a way that they are available across the whole Java UNO runtime environment. | ||
− | If a Java UNO component requires additional UNO types, it must use a <code>UNO-Type-Path</code> manifest entry to specify the location of the UNO types. The <code>UNO-Type-Path</code> is similar to the <code>Class-Path</code> manifest entry and can contain URLs of jars and directories that contain the Java classes that represent additional UNO types. | + | If a Java UNO component requires additional UNO types, it must use a <code>UNO-Type-Path</code> manifest entry to specify the location of the UNO types. The <code>UNO-Type-Path</code> is similar to the <code>Class-Path</code> manifest entry and can contain URLs of jars and directories that contain the Java classes that represent additional UNO types. The <code>UnoClassLoader</code> evaluates the <code>UNO-Type-Path</code> manifest entry to ensure that the additional UNO types are available to the Java UNO environment. The <code>UNO-Type-Path</code> can have one of the following formats. |
* Current jar does not contain UNO types:<pre>UNO-Type-Path: </pre>(Note the final space character.) | * Current jar does not contain UNO types:<pre>UNO-Type-Path: </pre>(Note the final space character.) | ||
* Current jar contains UNO types:<pre>UNO-Type-Path: <></pre> | * Current jar contains UNO types:<pre>UNO-Type-Path: <></pre> | ||
Line 312: | Line 309: | ||
* Current jar and other jars that the current jar uses contain UNO types:<pre>UNO-Type-Path: any/other/jar.jar <> yet/another/jar.jar</pre> | * Current jar and other jars that the current jar uses contain UNO types:<pre>UNO-Type-Path: any/other/jar.jar <> yet/another/jar.jar</pre> | ||
− | {{ | + | {{Note|Note: For backwards compatibility, if you do not include the <tt>UNO-Type-Path</tt> manifest entry at all, the UNO runtime assumes that the current jar does contain UNO types.}} |
{{PDL1}} | {{PDL1}} | ||
− | [[Category: Writing UNO Components]] | + | |
+ | [[Category:Documentation/Developer's Guide/Writing UNO Components]] |
Latest revision as of 13:46, 24 December 2020
- 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
The implementation of a component depends on the needs of the implementer. The following examples show some possible ways to assemble a component. There can be one implemented object or several implemented objects per component file.
One Implementation per Component File
There are additional options if implementing one service per component file:
- Use a flat structure with the static component operations added to the service implementation class directly.
- Reserve the class with the implementation name for the static component operation and use an inner class to implement the service.
Implementation Class with Component Operations
An implementation class contains the static component operations. The following sample implements an interface com.sun.star.test.XSomething
in an implementation class JavaComp.TestComponent
:
// UNOIDL: interface example specification module com { module sun { module star { module test { interface XSomething: com::sun::star::uno::XInterface { string methodOne([in]string val); }; }; }; }; };
A component that implements only one service supporting XSomething
can be assembled in one class as follows:
package JavaComp; ... public class TestComponent implements XSomething, XTypeProvider, XServiceInfo { public static final String __serviceName="com.sun.star.test.JavaTestComponent"; public static XSingleServiceFactory __getServiceFactory(String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) { XSingleServiceFactory xSingleServiceFactory = null; if (implName.equals( TestComponent.class.getName()) ) xSingleServiceFactory = FactoryHelper.getServiceFactory( TestComponent.class, TestComponent.__serviceName, multiFactory, regKey); return xSingleServiceFactory; } public static boolean __writeRegistryServiceInfo(XRegistryKey regKey){ return FactoryHelper.writeRegistryServiceInfo( TestComponent.class.getName(), TestComponent.__serviceName, regKey); } // XSomething string methodOne(String val) { return val; } //XTypeProvider public com.sun.star.uno.Type[] getTypes( ) { ... } // XTypeProvider public byte[] getImplementationId( ) { ... } //XServiceInfo public String getImplementationName( ) { ... } // XServiceInfo public boolean supportsService( /*IN*/String serviceName ) { ... } //XServiceInfo public String[] getSupportedServiceNames( ) { ... } }
The class implements the XSomething
interface. The IDL description and documentation provides information about its functionality. The class also contains the functions for factory creation and registration, therefore the manifest entry must read as follows:
RegistrationClassName: JavaComp.TestComponent
Implementation Class with Component Operations and Inner Implementation Class
To implement the component as inner class of the one that provides the service factory through __getServiceFactory()
, it must be a static inner class, otherwise the factory provided by the FactoryHelper
cannot create the component. An example for an inner implementation class is located in the sample com.sun.star.comp.demo.DemoComponent.java
provided with the SDK. The implementation of __getServiceFactory()
and __writeRegistryServiceInfo()
is omitted here, because they act the same as in the implementation class with component operations above.
package com.sun.star.comp.demo; public class DemoComponent { ... // static inner class implements service com.sun.star.demo.DemoComponent static public class _Implementation implements XTypeProvider, XServiceInfo, XInitialization, XWindowListener, XActionListener, XTopWindowListener { static private final String __serviceName = "com.sun.star.demo.DemoComponent"; private XMultiServiceFactory _xMultiServiceFactory; // Constructor public _Implementation(XMultiServiceFactory xMultiServiceFactory) { } } // static method to get a single factory creating the given service from the factory helper public static XSingleServiceFactory __getServiceFactory(String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) { ... } // static method to write the service information into the given registry key public static boolean __writeRegistryServiceInfo(XRegistryKey regKey) { ... } }
The manifest entry for this implementation structure again has to point to the class with the static component operations:
RegistrationClassName: com.sun.star.comp.demo.DemoComponent
Multiple Implementations per Component File
To assemble several service implementations in one component file, implement each service in its own class and add a separate class containing the static component operations. The following code sample features two services: TestComponentA
and TestComponentB
implementing the interfaces XSomethingA
and XSomethingB
with a separate static class TestServiceProvider
containing the component operations.
The following are the UNOIDL specifications for XSomethingA
and XSomethingB
:
module com { module sun { module star { module test { interface XSomethingA: com::sun::star::uno::XInterface { string methodOne([in]string value); }; }; }; }; }; module com { module sun { module star { module test { interface XSomethingB: com::sun::star::uno::XInterface { string methodTwo([in]string value); }; }; }; }; };
TestComponentA
implements XSomethingA
:
package JavaComp; public class TestComponentA implements XTypeProvider, XServiceInfo, XSomethingA { static final String __serviceName= "JavaTestComponentA"; static byte[] _implementationId; public TestComponentA() { } // XSomethingA public String methodOne(String val) { return val; } //XTypeProvider public com.sun.star.uno.Type[] getTypes( ) { Type[] retValue= new Type[3]; retValue[0]= new Type( XServiceInfo.class); retValue[1]= new Type( XTypeProvider.class); retValue[2]= new Type( XSomethingA.class); return retValue; } //XTypeProvider synchronized public byte[] getImplementationId( ) { if (_implementationId == null) { _implementationId= new byte[16]; int hash = hashCode(); _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; } //XServiceInfo public String getImplementationName( ) { return getClass().getName(); } // XServiceInfo public boolean supportsService( /*IN*/String serviceName ) { return serviceName.equals( __serviceName); } //XServiceInfo public String[] getSupportedServiceNames( ) { String[] retValue= new String[0]; retValue[0]= __serviceName; return retValue; } }
TestComponentB
implements XSomethingB
. Note that it receives the component context and initialization arguments in its constructor.
package JavaComp; public class TestComponentB implements XTypeProvider, XServiceInfo, XSomethingB { static final String __serviceName= "JavaTestComponentB"; static byte[] _implementationId; private XComponentContext context; private Object[] args; public TestComponentB(XComponentContext context, Object[] args) { this.context= context; this.args= args; } // XSomethingB public String methodTwo(String val) { if (args.length > 0 && args[0] instanceof String ) return (String) args[0]; return val; } //XTypeProvider public com.sun.star.uno.Type[] getTypes( ) { Type[] retValue= new Type[3]; retValue[0]= new Type( XServiceInfo.class); retValue[1]= new Type( XTypeProvider.class); retValue[2]= new Type( XSomethingB.class); return retValue; } //XTypeProvider synchronized public byte[] getImplementationId( ) { if (_implementationId == null) { _implementationId= new byte[16]; int hash = hashCode(); _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; } //XServiceInfo public String getImplementationName( ) { return getClass().getName(); } // XServiceInfo public boolean supportsService( /*IN*/String serviceName ) { return serviceName.equals( __serviceName); } //XServiceInfo public String[] getSupportedServiceNames( ) { String[] retValue= new String[0]; retValue[0]= __serviceName; return retValue; } }
TestServiceProvider
implements __getServiceFactory()
and __writeRegistryServiceInfo()
:
package JavaComp; ... public class TestServiceProvider { public static XSingleServiceFactory __getServiceFactory(String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey) { XSingleServiceFactory xSingleServiceFactory = null; if (implName.equals( TestComponentA.class.getName()) ) xSingleServiceFactory = FactoryHelper.getServiceFactory( TestComponentA.class, TestComponentA.__serviceName, multiFactory, regKey); else if (implName.equals(TestComponentB.class.getName())) xSingleServiceFactory= FactoryHelper.getServiceFactory( TestComponentB.class, TestComponentB.__serviceName, multiFactory, regKey); return xSingleServiceFactory; } public static boolean __writeRegistryServiceInfo(XRegistryKey regKey){ boolean bregA= FactoryHelper.writeRegistryServiceInfo( TestComponentA.class.getName(), TestComponentA.__serviceName, regKey); boolean bregB= FactoryHelper.writeRegistryServiceInfo( TestComponentB.class.getName(), TestComponentB.__serviceName, regKey); return bregA && bregB; } }
The corresponding manifest entry must point to the static class with the component operations, in this case JavaComp.TestServiceProvider
:
RegistrationClassName: JavaComp.TestServiceProvider
Additional UNO Types
To make the Java UNO runtime more robust and efficient, each component is loaded with its own class loader, with one UnoClassLoader
at the root that takes care of loading all Java classes
representing UNO types in such a way that they are available across the whole Java UNO runtime environment.
If a Java UNO component requires additional UNO types, it must use a UNO-Type-Path
manifest entry to specify the location of the UNO types. The UNO-Type-Path
is similar to the Class-Path
manifest entry and can contain URLs of jars and directories that contain the Java classes that represent additional UNO types. The UnoClassLoader
evaluates the UNO-Type-Path
manifest entry to ensure that the additional UNO types are available to the Java UNO environment. The UNO-Type-Path
can have one of the following formats.
- Current jar does not contain UNO types:
UNO-Type-Path:
(Note the final space character.) - Current jar contains UNO types:
UNO-Type-Path: <>
- Current jar brings other jars that contain UNO types:
UNO-Type-Path: any/other/jar.jar yet/another/jar.jar
- Current jar and other jars that the current jar uses contain UNO types:
UNO-Type-Path: any/other/jar.jar <> yet/another/jar.jar
Note: For backwards compatibility, if you do not include the UNO-Type-Path manifest entry at all, the UNO runtime assumes that the current jar does contain UNO types. |
Content on this page is licensed under the Public Documentation License (PDL). |