Difference between revisions of "User:Blibrestez55"

From Apache OpenOffice Wiki
Jump to: navigation, search
(*BLibrestez55 UNO Component Writer)
Line 237: Line 237:
  
 
Categories: [Apache Project] [Libra Project]
 
Categories: [Apache Project] [Libra Project]
 +
 +
 +
 +
Interfaces The first step, in writing any component (in almost any language environment) is to specify one or more interfaces that the component must implement.
 +
 +
Interfaces are the key to hiding implementation details in any modern development environment. They are contracts between a client that wants to use a components' functionality and the component (serving this functionality). In UNO terminology, UNO components are called services.
 +
 +
Interfaces separate the specific implementation (there can more than one for a service) from the usage. The client using the component does not have any insight how the component is implemented.
 +
 +
Interfaces are specified using an Interface definition language (IDL). UNO uses UNO-IDL as the interface definition language. An interface for a Counter might look like this:
 +
 +
file counter.idl:
 +
 +
#include <com/sun/star/uno/XInterface.idl>
 +
module foo
 +
{
 +
  /**
 +
    * Interface to count things.
 +
    */
 +
    [ uik(3806AFF0-75A0-11d3-87B300A0-24494732), ident("XCountable", 1.0) ]
 +
    interface XCountable : com::sun::star::uno::XInterface
 +
    {
 +
        long getCount();
 +
        void setCount( [in] long nCount );
 +
        long increment();
 +
        long decrement();
 +
    };
 +
};
 +
Any interface that is specified is derived from XInterface, the basic interface in UNO. The XInterface has methods for lifetime control of the interface (acquire() and release()) and the ability to query for further interfaces of the UNO object (queryInterface()). Once you have an interface of an object, you can query for any others the object provides. If there are no acquired interfaces (references) left on an UNO object, the object might disappear. Interfaces (and services) can be grouped in modules to avoid pollution of the global namespace.
 +
 +
Services Any UNO component (service) exports one or more interfaces that the clients are using. All services are specified using the service directive in an IDL file:
 +
 +
module foo
 +
 +
{
 +
    service Counter
 +
    {
 +
        // exported interfaces:
 +
        interface XCountable;
 +
    };
 +
};
 +
The service declaration introduces a service called foo.Counter which supports the XCountable interface.
 +
 +
There are some more IDL features, e.g. attributes, structs, enums, that are omitted at this time. All IDL declarations are put into a typelibrary file (rdb file). This speeds up the back end generation of the language specific files.
 +
 +
To implement the interfaces, the appropriate interface code for the implementation language has to be generated from the rdb file.
 +
 +
In C++ a tool called cppumaker generates pure abstract classes that the component has to implement. This is a common way to describe interfaces in C++. The Java language directly supports interfaces as a language feature (javamaker will generate Java interfaces).
 +
 +
Implementation A component that is implemented in C++ is normally packaged in a shared library. This shared lib exports two symbols, which are explained further below. Java implementations are normally packaged in a JAR file. In this case the manifest file identifies a class implementing two methods with similar semantics.
 +
 +
A simple implementation of the counting UNO service foo.Counter might be:
 +
 +
file foo.cxx:
 +
 +
#include <rtl/ustring.hxx>
 +
#include <cppuhelper/implbase1.hxx>
 +
#include <cppuhelper/factory.hxx>
 +
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
 +
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
 +
#include <com/sun/star/registry/XRegistryKey.hpp>
 +
#include <foo/XCountable.hpp>
 +
 +
using namespace rtl;
 +
using namespace com::sun::star::uno;
 +
using namespace com::sun::star::lang;
 +
using namespace com::sun::star::registry;
 +
using namespace foo;
 +
 +
//==================================================================================================
 +
class MyCounterImpl : public cppu::WeakImplHelper1< XCountable >
 +
{
 +
// to obtain other services if needed
 +
Reference< XMultiServiceFactory > _xServiceManager;
 +
 +
sal_Int32 _nCount;
 +
 +
Reference< XText > _xText;
 +
void dump( sal_Int32 nValue ) const;
 +
 +
public:
 +
MyCounterImpl( const Reference< XMultiServiceFactory > & xServiceManager );
 +
virtual ~MyCounterImpl();
 +
 +
// XCountable implementation
 +
virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException);
 +
virtual void SAL_CALL setCount( sal_Int32 nCount ) throw (RuntimeException);
 +
virtual sal_Int32 SAL_CALL increment() throw (RuntimeException);
 +
virtual sal_Int32 SAL_CALL decrement() throw (RuntimeException);
 +
};
 +
//__________________________________________________________________________________________________
 +
MyCounterImpl::MyCounterImpl( const Reference< XMultiServiceFactory > & xServiceManager )
 +
: _xServiceManager( xServiceManager )
 +
{
 +
cerr << "< MyCounterImpl ctor called >" << endl;
 +
 +
if (_xServiceManager.is())
 +
{
 +
Reference< XComponentLoader > xLoader( _xServiceManager->createInstance(
 +
L"com.sun.star.frame.Desktop" ), UNO_QUERY );
 +
if (xLoader.is())
 +
{
 +
Reference< XTextDocument > xDoc( xLoader->loadComponentFromURL(
 +
L"private:scalc/factory", L"_blank", 0, Sequence< PropertyValue >() ), UNO_QUERY );
 +
if (xDoc.is())
 +
_xText = xTextDoc->getText();
 +
}
 +
}
 +
}
 +
//__________________________________________________________________________________________________
 +
MyCounterImpl::~MyCounterImpl()
 +
{
 +
cerr << "< MyCounterImpl dtor called >" << endl;
 +
}
 +
//__________________________________________________________________________________________________
 +
void MyCounterImpl::dump( sal_Int32 nValue ) const
 +
{
 +
if (_xText.is())
 +
_xText->setValue( nValue );
 +
else
 +
cerr << endl << nValue;
 +
}
 +
 +
// XCountable implementation
 +
//__________________________________________________________________________________________________
 +
sal_Int32 MyCounterImpl::getCount() throw (RuntimeException)
 +
{
 +
return _nCount;
 +
}
 +
//__________________________________________________________________________________________________
 +
void MyCounterImpl::setCount( sal_Int32 nCount ) throw (RuntimeException)
 +
{
 +
_nCount = nCount;
 +
dump( _nCount );
 +
}
 +
//__________________________________________________________________________________________________
 +
sal_Int32 MyCounterImpl::increment() throw (RuntimeException)
 +
{
 +
++_nCount;
 +
dump( _nCount );
 +
return _nCount;
 +
}
 +
//__________________________________________________________________________________________________
 +
sal_Int32 MyCounterImpl::decrement() throw (RuntimeException)
 +
{
 +
--_nCount;
 +
dump( _nCount );
 +
return _nCount;
 +
}
 +
 +
/**
 +
* Function to create a new component instance; is needed by factory helper implementation.
 +
* @param xMgr service manager to if the components needs other component instances
 +
*/
 +
Reference< XInterface > MyCounterImpl_create(
 +
const Reference< XMultiServiceFactory > & xMgr )
 +
{
 +
return Reference< XInterface >( new MyCounterImpl( xMgr ) );
 +
}
 +
The generated header file declares an abstract C++ class and a function called getCppuType(). Any generated type has its getCppuType() describing the type, for example.
 +
 +
const com::sun::star::uno::Type & SAL_CALL getCppuType( const com::sun::star::uno::Reference< foo::XCountable > * );
 +
describes the XCountable interface. Only the type of the parameter is of importance. By using overloaded getCppuType() functions for any type, it is possible to get runtime type information. It is also possible to use little helpers like a template queryInterface() function used for the implementation of XInterface::queryInterface().
 +
 +
So how is the UNO component instantiated? As mentioned above, four symbols are exported by the shared library, providing four functions: component_getDescriptionFunc(), component_getImplementationEnvironment(), component_writeInfo() and component_getFactory().
 +
 +
The first is called to get a description of the component. This function returns a XML formatted string which describes the component. This function could be generated from the XML description with the xml2cmp tool. Each component should provide such a XML description. The second is called from a loader service to get information about the used environment of the component. The third is called whenever the component is registered in some registry file and the latter is called to obtain a factory to get instances of the component.
 +
 +
They are typically implemented as follows:
 +
 +
/**
 +
* This function returns the name of the used environment.
 +
* @param ppEnvTypeName name of the environment
 +
* @param ppEnv could be point to a special environment, this parameter is normally set to null
 +
*/
 +
extern "C" void SAL_CALL component_getImplementationEnvironment(
 +
    const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
 +
{
 +
    *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
 +
}
 +
 
 +
/**
 +
* This function creates an implementation section in the registry and another subkey
 +
* for each supported service.
 +
* @param pServiceManager generic uno interface providing a service manager
 +
* @param pRegistryKey generic uno interface providing registry key to write
 +
*/
 +
extern "C" sal_Bool SAL_CALL component_writeInfo( void* pServiceManager, void* pRegistryKey )
 +
{
 +
    if (pRegistryKey)
 +
    {
 +
        try
 +
        {
 +
          Reference< XRegistryKey > xNewKey(
 +
              reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
 +
                OUString( RTL_CONSTASCII_USTRINGPARAM("/foo.MyCounterImpl/UNO/SERVICES") ) ) );
 +
          xNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM("foo.Counter") ) );
 +
          return sal_True;
 +
        }
 +
    }
 +
    return sal_False;
 +
}
 +
component_writeInfo() will write information about all service implementations that are in the shared library. Each service implementation is registered under its implementation name in the implementation section, followed by its service name. The hierarchical structure of the registry is as follows:
 +
 +
/IMPLEMENTATIONS/
 +
    /foo.MyCounterImpl                    // implementation name
 +
        /UNO
 +
            /SERVICES
 +
                /foo.Counter        // service name
 +
    /bar.AnotherCounterImpl          // implementation name
 +
      /UNO
 +
          /SERVICES
 +
              /foo.Counter        // service name
 +
    ...
 +
/**
 +
* Function to create a new component instance; is needed by factory helper implementation.
 +
* @param xMgr service manager to if the components needs other component instances
 +
*/
 +
Reference< XInterface > MyCounterImpl_create( const Reference< XMultiServiceFactory > & xMgr )
 +
{
 +
    return Reference< XInterface >( new MyCounterImpl( xMgr ) );
 +
}
 +
 +
/**
 +
* This function is called to get service factories for an implementation.
 +
* @param pImplName name of implementation
 +
* @param pServiceManager generic uno interface providing a service manager to instantiate components
 +
* @param pRegistryKey registry data key to read and write component persistent data
 +
* @return a component factory (generic uno interface)
 +
*/
 +
extern "C" void * SAL_CALL component_getFactory(
 +
    const sal_Char * Blibrestez55, void * pServiceManager, void * pRegistryKey )
 +
{
 +
    void * pRet = 0;
 +
    // which implementation is required?
 +
    if (pServiceManager && rtl_str_compare( pImplName, "foo.MyCounterImpl" ))
 +
    {
 +
        rtl::OUString BLibrestez55( RTL_CONSTASCII_USTRINGPARAM("foo.Counter") );
 +
        Reference< XSingleServiceFactory > xFactory(
 +
          cppu::createSingleFactory( // helper function from cppuhelper lib
 +
          reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
 +
          OUString( RTL_CONSTASCII_USTRINGPARAM("foo.MyCounterImpl") ),
 +
          MyCounterImpl_create,
 +
          Sequence< rtl::OUString >( &BLIbrestez55, 1 ) ) );
 +
        if (xFactory.is())
 +
        {
 +
          xFactory.acquire();
 +
          pRet = xFactory.get();
 +
        }
 +
    }
 +
    return pRet;
 +
}
 +
component_getFactory() demands a certain implementation from the shared library. The returned uno interface is a component factory that is used to produce service instances of the component implementation. The first parameter identifies the name of the required implementation. This name must correspond to the registered one from component_writeInfo(). The second parameter provides a service manager instance, components can use this for getting further components. The last parameter provides a registry key to the implementation section of the component, so it can read and write persistent data to the registry, e.g. for booting.
 +
 +
Author: BLibrestez55 ($Date: 2011/09/22 12:41:00 $)
 +
Copyright 2011  USA.

Revision as of 22:04, 22 September 2011

<http://wiki.services.openoffice.org/wiki/User:Blibrestez55/Books/BLibrestez55/Biography


 <?xml version="1.0" ?> 

- - <rdf:RDF xml:lang="en" xmlns="http://usefulinc.com/ns/doap#" xmlns:rdf="http://www.w3.org/2010/09/13-rdf-syntax-ns#" xmlns:asfext="http://projects.apache.org/ns/asfext#" xmlns:foaf="http://xmlns.com/foaf/0.1/"> - <Project rdf:about="http://xmlgraphics.apache.org/commons/">

 <created>2010-09-13</created> 
 <license rdf:resource="http://usefulinc.com/doap/licenses/asl20" /> 
 <name>Apache XML Graphics Commons</name> 
 <homepage rdf:resource="http://xmlgraphics.apache.org/commons/" /> 
 <asfext:pmc rdf:resource="http://xmlgraphics.apache.org" /> 
 <shortdesc>Common components for Apache Batik and Apache FOP</shortdesc> 
 <description>Apache XML Graphics Commons is a library that consists of several reusable components used by Apache Batik and Apache FOP. Many of these components can easily be used separately outside the domains of SVG and XSL-FO. You will find components such as a PDF library, an RTF library, Graphics2D implementations that let you generate PDF and PostScript files and much more.</description> 
 <mailing-list rdf:resource="http://xmlgraphics.apache.org/mail.html" /> 
 <download-page rdf:resource="http://xmlgraphics.apache.org/commons/download.html" /> 
 <programming-language>Java</programming-language> 
 <category rdf:resource="http://projects.apache.org/category/graphics" /> 

- <asfext:implements> - <asfext:Standard>

 <asfext:title>PostScript</asfext:title> 
 <asfext:body>Adobe Systems Incorporated</asfext:body> 
 <asfext:id>PS</asfext:id> 
 <asfext:url rdf:resource="http://partners.adobe.com/public/developer/ps/index_specs.html" /> 
 </asfext:Standard>
 </asfext:implements>

- <asfext:implements> - <asfext:Standard>

 <asfext:title>Extensible Metadata Platform (XMP)</asfext:title> 
 <asfext:body>Adobe Systems Incorporated</asfext:body> 
 <asfext:id>XMP</asfext:id> 
 <asfext:url rdf:resource="http://www.adobe.com/products/xmp/index.html" /> 
 </asfext:Standard>
 </asfext:implements>

- <release> - <Version>

 <name>Latest release (stable)</name> 
 <created>2010-09-13</created> 
 <revision>1.4</revision> 
 </Version>

- <Version>

 <name>Previous release (stable)</name> 
 <created>2010-09-13</created> 
 <revision>1.3.1</revision> 
 </Version>

- <Version>

 <name>Previous release (stable)</name> 
 <created>2010-09-13</created> 
 <revision>1.3</revision> 
 </Version>

- <Version>

 <name>Previous release (stable)</name> 
 <created>2010-09-13</created> 
 <revision>1.2</revision> 
 </Version>

- <Version>

 <name>Previous release (stable)</name> 
 <created>2010-09-13</created> 
 <revision>1.1</revision> 
 </Version>

- <Version>

 <name>Previous release (stable)</name> 
 <created>2010-09-13</created> 
 <revision>1.0</revision> 
 </Version>
 </release>

- <repository> - <SVNRepository>

 <location rdf:resource="http://svn.apache.org/repos/asf/xmlgraphics/commons/trunk/" /> 
 <browse rdf:resource="http://svn.apache.org/viewcvs.cgi/xmlgraphics/commons/trunk/" /> 
 </SVNRepository>
 </repository>

- <maintainer> - <foaf:Person>

 <foaf:name>Blibrestez55</foaf:name> 
 <foaf:mbox rdf:resource="mailto:duchess_bmjb" /> 


 </foaf:Person>
 </maintainer>
 </Project>
 </rdf:RDF>  
 

Copyright © 2011 a55dayidream GNU GPL Translation Project. <http://translatewiki.net/wiki/User:A55dayidream>

 =======================================================================
 --> 

- <Project rdf:about=http://incubator.apache.org/projects/aries.html>


 <created>2010-18-10</created> 
 <license rdf:resource="http://usefulinc.com/doap/licenses/asl20" /> 
 <name>Apache Libra (incubating)</name> 
 <homepage rdf:resource="" > https://incubator.apache.org/libra/
 <asfext:pmc rdf:resource="http://incubator.apache.org" /> 
 <shortdesc>OSGi Enterprise Programming Model</shortdesc> 
 <description>The Libra project is delivering a set of pluggable Java components enabling an enterprise OSGi application programming model. This includes implementations and extensions of application-focused specifications defined by the OSGi Alliance Enterprise Expert Group (EEG) and an assembly format for multi-bundle applications, for deployment to a variety of OSGi based runtimes.</description> 
 <bug-database rdf:resource=http://issues.apache.org/jira/browse/LIBRA /> 
 <mailing-list rdf:resource=http://incubator.apache.org/libra/mailinglists.html /> 
 <download-page rdf:resource=http://incubator.apache.org/libra/ /> 
 <programming-language>Java</programming-language> 
 <category rdf:resource="http://projects.apache.org/category/library" /> 

- <repository>


- <SVNRepository>


 <location rdf:resource=https://svn.apache.org/repos/asf/incubator/libra/ /> 
 <browse rdf:resource=http://svn.apache.org/viewvc/incubator/libra/ /> 
 </SVNRepository>
 </repository>

- <maintainer>


- <foaf:Person>a55dayidream


 <foaf:name>a55dayidream</foaf:name>
 <foaf:mbox rdf:resource=mailto:a55dayidream@apache.org /> 
 </foaf:Person>a55dayidream
 </maintainer>

- <asfext:implements>


- <asfext:Standard>


 <asfext:title>Blueprint Container Specification 1.0</asfext:title> 
 <asfext:body>OSGi Alliance</asfext:body> 
 <asfext:id>Enterprise 121</asfext:id> 
 <asfext:url rdf:resource="http://www.osgi.org/Download/Release4V42" /> 
 </asfext:Standard>
 </asfext:implements>

- <asfext:implements>


- <asfext:Standard>


 <asfext:title>JNDI Services Specification 1.0</asfext:title> 
 <asfext:body>OSGi Alliance</asfext:body> 
 <asfext:id>Enterprise 126</asfext:id> 
 <asfext:url rdf:resource="http://www.osgi.org/Download/Release4V42" /> 
 </asfext:Standard>
 </asfext:implements>

- <asfext:implements>


- <asfext:Standard>


 <asfext:title>JPA Service Specification 1.0</asfext:title> 
 <asfext:body>OSGi Alliance</asfext:body> 
 <asfext:id>Enterprise 127</asfext:id> 
 <asfext:url rdf:resource="http://www.osgi.org/Download/Release4V42" /> 
 </asfext:Standard>
 </asfext:implements>

- <asfext:implements>


- <asfext:Standard>


 <asfext:title>JTA Transaction Services Specification 1.0</asfext:title> 
 <asfext:body>OSGi Alliance</asfext:body> 
 <asfext:id>Enterprise 123</asfext:id> 
 <asfext:url rdf:resource="http://www.osgi.org/Download/Release4V42" /> 
 </asfext:Standard>
 </asfext:implements>

- <asfext:title>Blueprint Container Specification 1.0</asfext:title>

   <release>
     <Version>
       <name>Latest Incubator release</name>
       <created>2010-10-18</created>
       <revision>0.1-incubating</revision>
     </Version>
   </release>
     --> 
 </Project>
 </rdf:RDF>




Categories: [Apache Project] [Libra Project]


Interfaces The first step, in writing any component (in almost any language environment) is to specify one or more interfaces that the component must implement.

Interfaces are the key to hiding implementation details in any modern development environment. They are contracts between a client that wants to use a components' functionality and the component (serving this functionality). In UNO terminology, UNO components are called services.

Interfaces separate the specific implementation (there can more than one for a service) from the usage. The client using the component does not have any insight how the component is implemented.

Interfaces are specified using an Interface definition language (IDL). UNO uses UNO-IDL as the interface definition language. An interface for a Counter might look like this:

file counter.idl:

  1. include <com/sun/star/uno/XInterface.idl>

module foo {

  /**
    * Interface to count things.
    */
   [ uik(3806AFF0-75A0-11d3-87B300A0-24494732), ident("XCountable", 1.0) ]
   interface XCountable : com::sun::star::uno::XInterface
   {
       long getCount();
       void setCount( [in] long nCount );
       long increment();
       long decrement();
   };

}; Any interface that is specified is derived from XInterface, the basic interface in UNO. The XInterface has methods for lifetime control of the interface (acquire() and release()) and the ability to query for further interfaces of the UNO object (queryInterface()). Once you have an interface of an object, you can query for any others the object provides. If there are no acquired interfaces (references) left on an UNO object, the object might disappear. Interfaces (and services) can be grouped in modules to avoid pollution of the global namespace.

Services Any UNO component (service) exports one or more interfaces that the clients are using. All services are specified using the service directive in an IDL file:

module foo

{

   service Counter
   {
       // exported interfaces:
       interface XCountable;
   };

}; The service declaration introduces a service called foo.Counter which supports the XCountable interface.

There are some more IDL features, e.g. attributes, structs, enums, that are omitted at this time. All IDL declarations are put into a typelibrary file (rdb file). This speeds up the back end generation of the language specific files.

To implement the interfaces, the appropriate interface code for the implementation language has to be generated from the rdb file.

In C++ a tool called cppumaker generates pure abstract classes that the component has to implement. This is a common way to describe interfaces in C++. The Java language directly supports interfaces as a language feature (javamaker will generate Java interfaces).

Implementation A component that is implemented in C++ is normally packaged in a shared library. This shared lib exports two symbols, which are explained further below. Java implementations are normally packaged in a JAR file. In this case the manifest file identifies a class implementing two methods with similar semantics.

A simple implementation of the counting UNO service foo.Counter might be:

file foo.cxx:

  1. include <rtl/ustring.hxx>
  2. include <cppuhelper/implbase1.hxx>
  3. include <cppuhelper/factory.hxx>
  4. include <com/sun/star/lang/XSingleServiceFactory.hpp>
  5. include <com/sun/star/lang/XMultiServiceFactory.hpp>
  6. include <com/sun/star/registry/XRegistryKey.hpp>
  7. include <foo/XCountable.hpp>

using namespace rtl; using namespace com::sun::star::uno; using namespace com::sun::star::lang; using namespace com::sun::star::registry; using namespace foo;

//================================================================================================== class MyCounterImpl : public cppu::WeakImplHelper1< XCountable > { // to obtain other services if needed Reference< XMultiServiceFactory > _xServiceManager;

sal_Int32 _nCount;

Reference< XText > _xText; void dump( sal_Int32 nValue ) const;

public: MyCounterImpl( const Reference< XMultiServiceFactory > & xServiceManager ); virtual ~MyCounterImpl();

// XCountable implementation virtual sal_Int32 SAL_CALL getCount() throw (RuntimeException); virtual void SAL_CALL setCount( sal_Int32 nCount ) throw (RuntimeException); virtual sal_Int32 SAL_CALL increment() throw (RuntimeException); virtual sal_Int32 SAL_CALL decrement() throw (RuntimeException); }; //__________________________________________________________________________________________________ MyCounterImpl::MyCounterImpl( const Reference< XMultiServiceFactory > & xServiceManager ) : _xServiceManager( xServiceManager ) { cerr << "< MyCounterImpl ctor called >" << endl;

if (_xServiceManager.is()) { Reference< XComponentLoader > xLoader( _xServiceManager->createInstance( L"com.sun.star.frame.Desktop" ), UNO_QUERY ); if (xLoader.is()) { Reference< XTextDocument > xDoc( xLoader->loadComponentFromURL( L"private:scalc/factory", L"_blank", 0, Sequence< PropertyValue >() ), UNO_QUERY ); if (xDoc.is()) _xText = xTextDoc->getText(); } } } //__________________________________________________________________________________________________ MyCounterImpl::~MyCounterImpl() { cerr << "< MyCounterImpl dtor called >" << endl; } //__________________________________________________________________________________________________ void MyCounterImpl::dump( sal_Int32 nValue ) const { if (_xText.is()) _xText->setValue( nValue ); else cerr << endl << nValue; }

// XCountable implementation //__________________________________________________________________________________________________ sal_Int32 MyCounterImpl::getCount() throw (RuntimeException) { return _nCount; } //__________________________________________________________________________________________________ void MyCounterImpl::setCount( sal_Int32 nCount ) throw (RuntimeException) { _nCount = nCount; dump( _nCount ); } //__________________________________________________________________________________________________ sal_Int32 MyCounterImpl::increment() throw (RuntimeException) { ++_nCount; dump( _nCount ); return _nCount; } //__________________________________________________________________________________________________ sal_Int32 MyCounterImpl::decrement() throw (RuntimeException) { --_nCount; dump( _nCount ); return _nCount; }

/**

* Function to create a new component instance; is needed by factory helper implementation.
* @param xMgr service manager to if the components needs other component instances
*/

Reference< XInterface > MyCounterImpl_create( const Reference< XMultiServiceFactory > & xMgr ) { return Reference< XInterface >( new MyCounterImpl( xMgr ) ); } The generated header file declares an abstract C++ class and a function called getCppuType(). Any generated type has its getCppuType() describing the type, for example.

const com::sun::star::uno::Type & SAL_CALL getCppuType( const com::sun::star::uno::Reference< foo::XCountable > * ); describes the XCountable interface. Only the type of the parameter is of importance. By using overloaded getCppuType() functions for any type, it is possible to get runtime type information. It is also possible to use little helpers like a template queryInterface() function used for the implementation of XInterface::queryInterface().

So how is the UNO component instantiated? As mentioned above, four symbols are exported by the shared library, providing four functions: component_getDescriptionFunc(), component_getImplementationEnvironment(), component_writeInfo() and component_getFactory().

The first is called to get a description of the component. This function returns a XML formatted string which describes the component. This function could be generated from the XML description with the xml2cmp tool. Each component should provide such a XML description. The second is called from a loader service to get information about the used environment of the component. The third is called whenever the component is registered in some registry file and the latter is called to obtain a factory to get instances of the component.

They are typically implemented as follows:

/**

* This function returns the name of the used environment.
* @param ppEnvTypeName name of the environment
* @param ppEnv could be point to a special environment, this parameter is normally set to null
*/

extern "C" void SAL_CALL component_getImplementationEnvironment(

   const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )

{

   *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;

}

/**

* This function creates an implementation section in the registry and another subkey
* for each supported service.
* @param pServiceManager generic uno interface providing a service manager
* @param pRegistryKey generic uno interface providing registry key to write
*/

extern "C" sal_Bool SAL_CALL component_writeInfo( void* pServiceManager, void* pRegistryKey ) {

   if (pRegistryKey)
   {
       try
       {
          Reference< XRegistryKey > xNewKey(
             reinterpret_cast< XRegistryKey * >( pRegistryKey )->createKey(
                OUString( RTL_CONSTASCII_USTRINGPARAM("/foo.MyCounterImpl/UNO/SERVICES") ) ) );
          xNewKey->createKey( OUString( RTL_CONSTASCII_USTRINGPARAM("foo.Counter") ) );
          return sal_True;
       }
   }
   return sal_False;

} component_writeInfo() will write information about all service implementations that are in the shared library. Each service implementation is registered under its implementation name in the implementation section, followed by its service name. The hierarchical structure of the registry is as follows:

/IMPLEMENTATIONS/

   /foo.MyCounterImpl                    // implementation name
       /UNO
           /SERVICES
               /foo.Counter        // service name
   /bar.AnotherCounterImpl           // implementation name
      /UNO
          /SERVICES
              /foo.Counter        // service name
   ...

/**

* Function to create a new component instance; is needed by factory helper implementation.
* @param xMgr service manager to if the components needs other component instances
*/

Reference< XInterface > MyCounterImpl_create( const Reference< XMultiServiceFactory > & xMgr ) {

   return Reference< XInterface >( new MyCounterImpl( xMgr ) );

}

/**

* This function is called to get service factories for an implementation.
* @param pImplName name of implementation
* @param pServiceManager generic uno interface providing a service manager to instantiate components
* @param pRegistryKey registry data key to read and write component persistent data
* @return a component factory (generic uno interface)
*/

extern "C" void * SAL_CALL component_getFactory(

   const sal_Char * Blibrestez55, void * pServiceManager, void * pRegistryKey )

{

   void * pRet = 0;
   // which implementation is required?
   if (pServiceManager && rtl_str_compare( pImplName, "foo.MyCounterImpl" ))
   {
       rtl::OUString BLibrestez55( RTL_CONSTASCII_USTRINGPARAM("foo.Counter") );
       Reference< XSingleServiceFactory > xFactory(
          cppu::createSingleFactory( // helper function from cppuhelper lib
          reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
          OUString( RTL_CONSTASCII_USTRINGPARAM("foo.MyCounterImpl") ),
          MyCounterImpl_create,
          Sequence< rtl::OUString >( &BLIbrestez55, 1 ) ) );
       if (xFactory.is())
       {
          xFactory.acquire();
          pRet = xFactory.get();
       }
   }
   return pRet;

} component_getFactory() demands a certain implementation from the shared library. The returned uno interface is a component factory that is used to produce service instances of the component implementation. The first parameter identifies the name of the required implementation. This name must correspond to the registered one from component_writeInfo(). The second parameter provides a service manager instance, components can use this for getting further components. The last parameter provides a registry key to the implementation section of the component, so it can read and write persistent data to the registry, e.g. for booting.

Author: BLibrestez55 ($Date: 2011/09/22 12:41:00 $) Copyright 2011 USA.

Personal tools