summaryrefslogtreecommitdiff
path: root/stoc/source
diff options
context:
space:
mode:
Diffstat (limited to 'stoc/source')
-rw-r--r--stoc/source/bootstrap/bootstrap.xml358
-rw-r--r--stoc/source/bootstrap/makefile.mk50
-rw-r--r--stoc/source/bootstrap/services.cxx141
-rw-r--r--stoc/source/corereflection/base.hxx453
-rw-r--r--stoc/source/corereflection/corefl.xml44
-rw-r--r--stoc/source/corereflection/crarray.cxx232
-rw-r--r--stoc/source/corereflection/crbase.cxx291
-rw-r--r--stoc/source/corereflection/crcomp.cxx405
-rw-r--r--stoc/source/corereflection/crefl.cxx514
-rw-r--r--stoc/source/corereflection/crenum.cxx247
-rw-r--r--stoc/source/corereflection/criface.cxx993
-rw-r--r--stoc/source/corereflection/lrucache.hxx244
-rw-r--r--stoc/source/corereflection/makefile.mk82
-rw-r--r--stoc/source/corereflection/reflection.component35
-rw-r--r--stoc/source/cppumaker.mk41
-rw-r--r--stoc/source/defaultregistry/defaultregistry.cxx1423
-rw-r--r--stoc/source/defaultregistry/makefile.mk46
-rw-r--r--stoc/source/implementationregistration/implreg.cxx1925
-rw-r--r--stoc/source/implementationregistration/makefile.mk47
-rw-r--r--stoc/source/implementationregistration/mergekeys.cxx186
-rw-r--r--stoc/source/implementationregistration/mergekeys.hxx52
-rw-r--r--stoc/source/inspect/insp.xml59
-rw-r--r--stoc/source/inspect/introspection.component34
-rw-r--r--stoc/source/inspect/introspection.cxx3091
-rw-r--r--stoc/source/inspect/makefile.mk73
-rw-r--r--stoc/source/invocation/inv.xml77
-rw-r--r--stoc/source/invocation/invocation.component34
-rw-r--r--stoc/source/invocation/invocation.cxx1262
-rw-r--r--stoc/source/invocation/makefile.mk71
-rw-r--r--stoc/source/invocation_adapterfactory/iafactory.cxx1025
-rw-r--r--stoc/source/invocation_adapterfactory/invadp.xml41
-rw-r--r--stoc/source/invocation_adapterfactory/invocadapt.component34
-rw-r--r--stoc/source/invocation_adapterfactory/makefile.mk73
-rw-r--r--stoc/source/javaloader/javaloader.component35
-rw-r--r--stoc/source/javaloader/javaloader.cxx480
-rw-r--r--stoc/source/javaloader/javaloader.xml39
-rw-r--r--stoc/source/javaloader/makefile.mk79
-rw-r--r--stoc/source/javavm/interact.cxx125
-rw-r--r--stoc/source/javavm/interact.hxx75
-rw-r--r--stoc/source/javavm/javavm.component35
-rw-r--r--stoc/source/javavm/javavm.cxx1776
-rw-r--r--stoc/source/javavm/javavm.hxx172
-rw-r--r--stoc/source/javavm/jen.xml70
-rw-r--r--stoc/source/javavm/jvmargs.cxx66
-rw-r--r--stoc/source/javavm/jvmargs.hxx58
-rw-r--r--stoc/source/javavm/makefile.mk94
-rw-r--r--stoc/source/loader/dllcomponentloader.cxx261
-rw-r--r--stoc/source/loader/makefile.mk47
-rw-r--r--stoc/source/module-description.dtd54
-rw-r--r--stoc/source/namingservice/makefile.mk73
-rw-r--r--stoc/source/namingservice/namingservice.component34
-rw-r--r--stoc/source/namingservice/namingservice.cxx246
-rw-r--r--stoc/source/namingservice/namingservice.xml37
-rw-r--r--stoc/source/proxy_factory/makefile.mk73
-rw-r--r--stoc/source/proxy_factory/proxyfac.component34
-rw-r--r--stoc/source/proxy_factory/proxyfac.cxx537
-rw-r--r--stoc/source/proxy_factory/proxyfac.xml37
-rw-r--r--stoc/source/registry_tdprovider/base.hxx647
-rw-r--r--stoc/source/registry_tdprovider/functiondescription.cxx115
-rw-r--r--stoc/source/registry_tdprovider/functiondescription.hxx86
-rw-r--r--stoc/source/registry_tdprovider/makefile.mk61
-rw-r--r--stoc/source/registry_tdprovider/methoddescription.cxx144
-rw-r--r--stoc/source/registry_tdprovider/methoddescription.hxx82
-rw-r--r--stoc/source/registry_tdprovider/rdbtdp_tdenumeration.cxx643
-rw-r--r--stoc/source/registry_tdprovider/rdbtdp_tdenumeration.hxx116
-rw-r--r--stoc/source/registry_tdprovider/structtypedescription.cxx139
-rw-r--r--stoc/source/registry_tdprovider/structtypedescription.hxx105
-rw-r--r--stoc/source/registry_tdprovider/td.cxx80
-rw-r--r--stoc/source/registry_tdprovider/tdcomp.cxx187
-rw-r--r--stoc/source/registry_tdprovider/tdconsts.cxx110
-rw-r--r--stoc/source/registry_tdprovider/tdef.cxx82
-rw-r--r--stoc/source/registry_tdprovider/tdenum.cxx135
-rw-r--r--stoc/source/registry_tdprovider/tdiface.cxx585
-rw-r--r--stoc/source/registry_tdprovider/tdmodule.cxx126
-rw-r--r--stoc/source/registry_tdprovider/tdprop.cxx68
-rw-r--r--stoc/source/registry_tdprovider/tdprovider.cxx629
-rw-r--r--stoc/source/registry_tdprovider/tdservice.cxx565
-rw-r--r--stoc/source/registry_tdprovider/tdsingleton.cxx132
-rw-r--r--stoc/source/security/access_controller.cxx1061
-rw-r--r--stoc/source/security/file_policy.cxx603
-rw-r--r--stoc/source/security/lru_cache.h279
-rw-r--r--stoc/source/security/makefile.mk62
-rw-r--r--stoc/source/security/permissions.cxx666
-rw-r--r--stoc/source/security/permissions.h102
-rw-r--r--stoc/source/servicemanager/makefile.mk47
-rw-r--r--stoc/source/servicemanager/servicemanager.cxx2059
-rw-r--r--stoc/source/simpleregistry/makefile.mk47
-rwxr-xr-xstoc/source/simpleregistry/simpleregistry.cxx1320
-rw-r--r--stoc/source/simpleregistry/textualservices.cxx1228
-rw-r--r--stoc/source/simpleregistry/textualservices.hxx67
-rw-r--r--stoc/source/stocservices/makefile.mk49
-rw-r--r--stoc/source/stocservices/stocserv.xml98
-rw-r--r--stoc/source/stocservices/stocservices.cxx111
-rw-r--r--stoc/source/tdmanager/lrucache.hxx247
-rw-r--r--stoc/source/tdmanager/makefile.mk49
-rw-r--r--stoc/source/tdmanager/tdmgr.cxx1163
-rw-r--r--stoc/source/tdmanager/tdmgr_check.cxx556
-rw-r--r--stoc/source/tdmanager/tdmgr_common.hxx60
-rw-r--r--stoc/source/tdmanager/tdmgr_tdenumeration.cxx187
-rw-r--r--stoc/source/tdmanager/tdmgr_tdenumeration.hxx89
-rw-r--r--stoc/source/typeconv/convert.cxx963
-rw-r--r--stoc/source/typeconv/makefile.mk48
-rw-r--r--stoc/source/uriproc/ExternalUriReferenceTranslator.cxx240
-rw-r--r--stoc/source/uriproc/ExternalUriReferenceTranslator.hxx59
-rw-r--r--stoc/source/uriproc/UriReference.cxx206
-rw-r--r--stoc/source/uriproc/UriReference.hxx108
-rw-r--r--stoc/source/uriproc/UriReferenceFactory.cxx724
-rw-r--r--stoc/source/uriproc/UriReferenceFactory.hxx59
-rw-r--r--stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.cxx268
-rw-r--r--stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.hxx62
-rw-r--r--stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx485
-rw-r--r--stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.hxx61
-rw-r--r--stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.cxx167
-rw-r--r--stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.hxx59
-rw-r--r--stoc/source/uriproc/makefile.mk53
-rw-r--r--stoc/source/uriproc/supportsService.cxx51
-rw-r--r--stoc/source/uriproc/supportsService.hxx43
117 files changed, 36863 insertions, 0 deletions
diff --git a/stoc/source/bootstrap/bootstrap.xml b/stoc/source/bootstrap/bootstrap.xml
new file mode 100644
index 000000000000..3a90bbdccf71
--- /dev/null
+++ b/stoc/source/bootstrap/bootstrap.xml
@@ -0,0 +1,358 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> bootstrap.uno </module-name>
+ <component-description>
+ <author> Juergen Schmidt </author>
+ <name> com.sun.star.comp.stoc.DLLComponentLoader </name>
+ <description>
+ This component provides a mechanism to load an external compoment implemented as
+ a shared library.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.loader.SharedLibrary </supported-service>
+ <type> com.sun.star.util.XMacroExpander </type>
+ <type> com.sun.star.loader.XImplementationLoader </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.container.XSet </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.DeploymentException </type>
+ </component-description>
+ <component-description>
+ <author> Juergen Schmidt </author>
+ <name> com.sun.star.comp.stoc.NestedRegistry </name>
+ <description>
+ This component provides access to a simple hierachical registry. The registry based on
+ two registry file.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.registry.NestedRegistry </supported-service>
+ <reference-docu xlink:href="http://www.sun.com" xlink:type="simple"/>
+ <service-dependency> com.sun.star.registry.SimpleRegistry </service-dependency>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.container.XEnumerationAccess </type>
+ </component-description>
+ <component-description>
+ <author> Juergen Schmidt </author>
+ <name> com.sun.star.comp.stoc.ImplementationRegistration </name>
+ <description>
+ This component provides a mechanism to register or deregister an external component
+ to the current uno environment or better to the current service manager.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.registry.ImplementationRegistration </supported-service>
+ <service-dependency> com.sun.star.registry.SimpleRegistry </service-dependency>
+ <service-dependency> com.sun.star.loader.SharedLibrary </service-dependency>
+ <service-dependency> com.sun.star.loader.Java </service-dependency>
+ <type> com.sun.star.loader.XImplementationLoader </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.registry.XImplementationRegistration2 </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.container.XSet </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.reflection.XServiceTypeDescription </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ </component-description>
+ <component-description>
+ <author> Daniel Boelzle </author>
+ <name> com.sun.star.comp.stoc.RegistryTypeDescriptionProvider </name>
+ <description>
+This provider service supports the XHierarchicalNameAccess interface to read type descriptions
+and constants from a registry source.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.reflection.TypeDescriptionProvider </supported-service>
+ <service-dependency>com.sun.star.reflection.TypeDescriptionManager</service-dependency>
+ <type> com.sun.star.reflection.XTypeDescription </type>
+ <type> com.sun.star.reflection.XConstantsTypeDescription </type>
+ <type> com.sun.star.reflection.XEnumTypeDescription </type>
+ <type> com.sun.star.reflection.XIndirectTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceMemberTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceAttributeTypeDescription2 </type>
+ <type> com.sun.star.reflection.XMethodParameter </type>
+ <type> com.sun.star.reflection.XModuleTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceMethodTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceTypeDescription2 </type>
+ <type> com.sun.star.reflection.XCompoundTypeDescription </type>
+ <type> com.sun.star.reflection.XServiceConstructorDescription </type>
+ <type> com.sun.star.reflection.XServiceTypeDescription </type>
+ <type> com.sun.star.reflection.XServiceTypeDescription2 </type>
+ <type> com.sun.star.reflection.XSingletonTypeDescription2 </type>
+ <type> com.sun.star.reflection.XTypeDescriptionEnumerationAccess </type>
+ <type> com.sun.star.reflection.XParameter </type>
+ <type> com.sun.star.reflection.XPublished</type>
+ <type> com.sun.star.reflection.XStructTypeDescription</type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiComponentFactory </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.container.NoSuchElementException </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.container.XSet </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.XInterface </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.RuntimeException </type>
+ </component-description>
+ <component-description>
+ <author>boelzle@sun.com</author>
+ <name>com.sun.star.security.comp.stoc.AccessController</name>
+<description>
+This service is an implementation of the com.sun.star.security.AccessController service.
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="under construction"/>
+ <supported-service>com.sun.star.security.AccessController</supported-service>
+ <service-dependency> unknown, because of used policy </service-dependency>
+ <type>com.sun.star.security.XAccessController</type>
+ <type>com.sun.star.security.XPolicy</type>
+ <type>com.sun.star.security.RuntimePermission</type>
+ <type>com.sun.star.security.AllPermission</type>
+ <type>com.sun.star.io.FilePermission</type>
+ <type>com.sun.star.connection.SocketPermission</type>
+ <type>com.sun.star.registry.XRegistryKey</type>
+ <type>com.sun.star.lang.DisposedException</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.lang.XComponent</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XSingleComponentFactory</type>
+ <type>com.sun.star.lang.XSingleServiceFactory</type>
+ <type>com.sun.star.lang.XMultiComponentFactory</type>
+ <type>com.sun.star.lang.XMultiServiceFactory</type>
+ <type>com.sun.star.lang.XInitialization</type>
+ <type>com.sun.star.uno.XWeak</type>
+ <type>com.sun.star.uno.XAggregation</type>
+ <type>com.sun.star.uno.DeploymentException</type>
+ <type>com.sun.star.uno.XCurrentContext</type>
+ <type>com.sun.star.uno.XComponentContext</type>
+ <type>com.sun.star.uno.TypeClass</type>
+ </component-description>
+ <component-description>
+ <author>boelzle@sun.com</author>
+ <name>com.sun.star.security.comp.stoc.FilePolicy</name>
+<description>
+This service is an implementation of the com.sun.star.security.Policy service.
+</description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="under construction"/>
+ <supported-service>com.sun.star.security.Policy</supported-service>
+ <type>com.sun.star.security.XAccessController</type>
+ <type>com.sun.star.security.XPolicy</type>
+ <type>com.sun.star.security.RuntimePermission</type>
+ <type>com.sun.star.security.AllPermission</type>
+ <type>com.sun.star.io.FilePermission</type>
+ <type>com.sun.star.connection.SocketPermission</type>
+ <type>com.sun.star.registry.XRegistryKey</type>
+ <type>com.sun.star.lang.XTypeProvider</type>
+ <type>com.sun.star.lang.XComponent</type>
+ <type>com.sun.star.lang.XServiceInfo</type>
+ <type>com.sun.star.lang.XSingleComponentFactory</type>
+ <type>com.sun.star.lang.XSingleServiceFactory</type>
+ <type>com.sun.star.lang.XMultiComponentFactory</type>
+ <type>com.sun.star.lang.XMultiServiceFactory</type>
+ <type>com.sun.star.uno.XWeak</type>
+ <type>com.sun.star.uno.XAggregation</type>
+ <type>com.sun.star.uno.XCurrentContext</type>
+ <type>com.sun.star.uno.XComponentContext</type>
+ <type>com.sun.star.uno.TypeClass</type>
+ </component-description>
+ <component-description>
+ <author> Juergen Schmidt </author>
+ <name> com.sun.star.comp.stoc.SimpleRegistry </name>
+ <description>
+ This component provides access to a simple hierachical registry. The registry based on
+ one registry file.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.registry.SimpleRegistry </supported-service>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XMultiComponentFactory </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ </component-description>
+ <component-description>
+ <author> Juergen Schmidt </author>
+ <name> com.sun.star.comp.stoc.OServiceManager </name>
+ <description>
+ This component provides an administration object which manages
+ factories for many services. The services could be accessed with
+ the service name by using createInstance or createInstanceWithArguments.
+ To support the servicemanager with the needed information about a
+ service implementation, for e.g. which component implements the service,
+ two ways are possible:
+ - register a component persistent in a registry on which the servicemanager
+ works, using the com.sun.star.registry.ImplementationRegistration service.
+ - insert a corresponding factory for the service directly using the
+ interface XSet.
+
+ For creating an object of a requested service the service manager checks
+ if a factory for this service is avaible, if not the registry will be
+ searched for information about this service. If there is an appropriate
+ entry, the component is loaded, a factory is created and announced to the
+ service manager. Finding a factory the service manager calls the factory
+ for creating new objects.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.lang.MultiServiceFactory </supported-service>
+ <supported-service> com.sun.star.lang.ServiceManager </supported-service>
+ <type> com.sun.star.lang.XUnoTunnel </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XEventListener </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.container.XSet </type>
+ <type> com.sun.star.container.XEnumeration </type>
+ <type> com.sun.star.container.XContentEnumerationAccess </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XUnloadingPreference </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ </component-description>
+ <component-description>
+ <author> Daniel Boelzle </author>
+ <name> com.sun.star.comp.stoc.TypeDescriptionManager </name>
+ <description>
+This service is the central manager supporting the XHierarchicalNameAccess interface.
+At runtime there will only be at most a single instance of the service.
+A manager instance is hooked into the C UNO runtime typelib and lives until the service manager
+is going down.
+You can manually add a provider by inserting it via the XSet interface.
+At startup of this service, you must call an initialization, adding all known
+providers.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.reflection.TypeDescriptionManager </supported-service>
+ <service-dependency> ... </service-dependency>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.reflection.XTypeDescription </type>
+ <type> com.sun.star.reflection.XEnumTypeDescription </type>
+ <type> com.sun.star.reflection.XArrayTypeDescription </type>
+ <type> com.sun.star.reflection.XIndirectTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceMemberTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceAttributeTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceAttributeTypeDescription2 </type>
+ <type> com.sun.star.reflection.XMethodParameter </type>
+ <type> com.sun.star.reflection.XInterfaceMethodTypeDescription </type>
+ <type> com.sun.star.reflection.XInterfaceTypeDescription2 </type>
+ <type> com.sun.star.reflection.XStructTypeDescription </type>
+ <type> com.sun.star.reflection.XServiceTypeDescription </type>
+ <type> com.sun.star.reflection.XServiceTypeDescription2 </type>
+ <type> com.sun.star.reflection.XPropertyTypeDescription </type>
+ <type> com.sun.star.reflection.XConstantTypeDescription </type>
+ <type> com.sun.star.reflection.XConstantsTypeDescription </type>
+ <type> com.sun.star.reflection.XSingletonTypeDescription </type>
+ <type> com.sun.star.reflection.XSingletonTypeDescription2 </type>
+ <type> com.sun.star.reflection.XUnionTypeDescription </type>
+ <type> com.sun.star.reflection.XTypeDescriptionEnumerationAccess </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XEventListener </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiComponentFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.container.XSet </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.container.XContentEnumerationAccess </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> registry </project-build-dependency>
+ <project-build-dependency> store </project-build-dependency>
+ <project-build-dependency> salhelper </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> reg3 </runtime-module-dependency>
+ <runtime-module-dependency> store3 </runtime-module-dependency>
+ <runtime-module-dependency> reg3 </runtime-module-dependency>
+ <runtime-module-dependency> store3 </runtime-module-dependency>
+ <runtime-module-dependency> salhelper3(COM) </runtime-module-dependency>
+ <runtime-module-dependency> salhelper3(COM) </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/bootstrap/makefile.mk b/stoc/source/bootstrap/makefile.mk
new file mode 100644
index 000000000000..9eb1a11cbad9
--- /dev/null
+++ b/stoc/source/bootstrap/makefile.mk
@@ -0,0 +1,50 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = bootstrap
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+COMP1TYPELIST = bootstrap
+
+# --- openoffice.org.orig/Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+# --- openoffice.org.orig/Files ------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/services.obj
+
+# --- openoffice.org.orig/Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/stoc/source/bootstrap/services.cxx b/stoc/source/bootstrap/services.cxx
new file mode 100644
index 000000000000..7d295f4de78c
--- /dev/null
+++ b/stoc/source/bootstrap/services.cxx
@@ -0,0 +1,141 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "bootstrapservices.hxx"
+
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "sal/types.h"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+
+#include <stdio.h>
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+using namespace stoc_bootstrap;
+
+static struct ImplementationEntry g_entries[] =
+{
+ //servicemanager
+ {
+ OServiceManager_CreateInstance, smgr_getImplementationName,
+ smgr_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ {
+ ORegistryServiceManager_CreateInstance, regsmgr_getImplementationName,
+ regsmgr_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ {
+ OServiceManagerWrapper_CreateInstance, smgr_wrapper_getImplementationName,
+ smgr_wrapper_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ //security
+ {
+ ac_create, ac_getImplementationName,
+ ac_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt, 0
+ },
+ {
+ filepolicy_create, filepolicy_getImplementationName,
+ filepolicy_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt, 0
+ },
+ //simpleregistry
+ {
+ SimpleRegistry_CreateInstance, simreg_getImplementationName,
+ simreg_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ //defaultregistry
+ {
+ NestedRegistry_CreateInstance, defreg_getImplementationName,
+ defreg_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ //implementationregistry
+ {
+ ImplementationRegistration_CreateInstance, impreg_getImplementationName,
+ impreg_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ //loader
+ {
+ DllComponentLoader_CreateInstance, loader_getImplementationName,
+ loader_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ //registry_tdprovider
+ {
+ ProviderImpl_create, rdbtdp_getImplementationName,
+ rdbtdp_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ //tdmanager
+ {
+ ManagerImpl_create, tdmgr_getImplementationName,
+ tdmgr_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ //end
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+
+}
diff --git a/stoc/source/corereflection/base.hxx b/stoc/source/corereflection/base.hxx
new file mode 100644
index 000000000000..2ef60da60d0b
--- /dev/null
+++ b/stoc/source/corereflection/base.hxx
@@ -0,0 +1,453 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// #define TEST_LIST_CLASSES
+// #define TRACE(x) OSL_TRACE(x)
+#define TRACE(x)
+
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <uno/mapping.hxx>
+#include <uno/dispatcher.h>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/component.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+#include "lrucache.hxx"
+
+#ifdef TEST_LIST_CLASSES
+#include <list>
+#include <algorithm>
+#endif
+#include <hash_map>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlField.hpp>
+#include <com/sun/star/reflection/XIdlField2.hpp>
+#include <com/sun/star/reflection/XIdlMethod.hpp>
+
+using namespace std;
+using namespace osl;
+using namespace rtl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::container;
+
+
+namespace stoc_corefl
+{
+
+#ifdef TEST_LIST_CLASSES
+typedef list< OUString > ClassNameList;
+extern ClassNameList g_aClassNames;
+#endif
+
+//--------------------------------------------------------------------------------------------------
+Mutex & getMutexAccess();
+
+//--------------------------------------------------------------------------------------------------
+inline bool td_equals( typelib_TypeDescription * pTD, typelib_TypeDescriptionReference * pType )
+{
+ return (pTD->pWeakRef == pType ||
+ (pTD->pTypeName->length == pType->pTypeName->length &&
+ rtl_ustr_compare( pTD->pTypeName->buffer, pType->pTypeName->buffer ) == 0));
+}
+//--------------------------------------------------------------------------------------------------
+inline typelib_TypeDescription * getTypeByName( const OUString & rName )
+{
+ typelib_TypeDescription * pTypeDescr = 0;
+ typelib_typedescription_getByName( &pTypeDescr, rName.pData );
+ if (! pTypeDescr->bComplete)
+ typelib_typedescription_complete( &pTypeDescr );
+ return pTypeDescr;
+}
+
+typedef std::hash_map< OUString, WeakReference< XIdlField >,
+ FctHashOUString, equal_to< OUString > > OUString2Field;
+typedef std::hash_map< OUString, WeakReference< XIdlMethod >,
+ FctHashOUString, equal_to< OUString > > OUString2Method;
+
+//==================================================================================================
+class IdlReflectionServiceImpl
+ : public OComponentHelper
+ , public XIdlReflection
+ , public XHierarchicalNameAccess
+ , public XServiceInfo
+{
+ Mutex _aComponentMutex;
+ Reference< XMultiServiceFactory > _xMgr;
+ Reference< XHierarchicalNameAccess > _xTDMgr;
+
+ // caching
+ LRU_CacheAnyByOUString _aElements;
+
+ Mapping _aCpp2Uno;
+ Mapping _aUno2Cpp;
+
+ inline Reference< XIdlClass > constructClass( typelib_TypeDescription * pTypeDescr );
+public:
+ Reference< XHierarchicalNameAccess > getTDMgr() const
+ { return _xTDMgr; }
+ Reference< XMultiServiceFactory > getSMgr() const
+ { return _xMgr; }
+
+ const Mapping & getCpp2Uno() throw(::com::sun::star::uno::RuntimeException);
+ const Mapping & getUno2Cpp() throw(::com::sun::star::uno::RuntimeException);
+ uno_Interface * mapToUno( const Any & rObj, typelib_InterfaceTypeDescription * pTo ) throw(::com::sun::star::uno::RuntimeException);
+
+ // ctor/ dtor
+ IdlReflectionServiceImpl( const Reference< XComponentContext > & xContext );
+ virtual ~IdlReflectionServiceImpl();
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // some XComponent part from OComponentHelper
+ virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // XIdlReflection
+ virtual Reference< XIdlClass > SAL_CALL forName( const OUString & rTypeName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlClass > SAL_CALL getType( const Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalNameAccess
+ virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+
+ Reference< XIdlClass > forType( typelib_TypeDescription * pTypeDescr ) throw(::com::sun::star::uno::RuntimeException);
+ Reference< XIdlClass > forType( typelib_TypeDescriptionReference * pRef ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class IdlClassImpl
+ : public WeakImplHelper1< XIdlClass >
+{
+ IdlReflectionServiceImpl * _pReflection;
+
+ OUString _aName;
+ TypeClass _eTypeClass;
+
+ typelib_TypeDescription * _pTypeDescr;
+
+public:
+ typelib_TypeDescription * getTypeDescr() const
+ { return _pTypeDescr; }
+ IdlReflectionServiceImpl * getReflection() const
+ { return _pReflection; }
+ Reference< XMultiServiceFactory > getSMgr() const
+ { return _pReflection->getSMgr(); }
+ Reference< XHierarchicalNameAccess > getTDMgr() const
+ { return getReflection()->getTDMgr(); }
+
+ // Ctor
+ IdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr );
+ virtual ~IdlClassImpl();
+
+ // XIdlClassImpl default implementation
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL equals( const Reference< XIdlClass >& xType ) throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
+
+ // def impl ????
+ virtual Sequence< Reference< XIdlClass > > SAL_CALL getClasses() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlClass > SAL_CALL getClass( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlClass > > SAL_CALL getInterfaces() throw(::com::sun::star::uno::RuntimeException);
+
+ // structs, interfaces
+ virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException);
+ // structs
+ virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
+ // interfaces
+ virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException);
+ // array
+ virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class InterfaceIdlClassImpl
+ : public IdlClassImpl
+{
+ typedef pair< OUString, typelib_TypeDescription * > MemberInit;
+
+ Sequence< Reference< XIdlClass > > _xSuperClasses;
+
+ MemberInit * _pSortedMemberInit; // first methods, then attributes
+ OUString2Field _aName2Field;
+ OUString2Method _aName2Method;
+ sal_Int32 _nMethods;
+ sal_Int32 _nAttributes;
+
+ void initMembers();
+
+public:
+ typelib_InterfaceTypeDescription * getTypeDescr() const
+ { return (typelib_InterfaceTypeDescription *)IdlClassImpl::getTypeDescr(); }
+
+ // ctor/ dtor
+ InterfaceIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ , _pSortedMemberInit( 0 )
+ , _nMethods( 0 )
+ , _nAttributes( 0 )
+ {}
+ virtual ~InterfaceIdlClassImpl();
+
+ // IdlClassImpl modifications
+ virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException);
+ virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlMethod > SAL_CALL getMethod( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlMethod > > SAL_CALL getMethods() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class CompoundIdlClassImpl
+ : public IdlClassImpl
+{
+ Reference< XIdlClass > _xSuperClass;
+
+ Sequence< Reference< XIdlField > > * _pFields;
+ OUString2Field _aName2Field;
+
+public:
+ typelib_CompoundTypeDescription * getTypeDescr() const
+ { return (typelib_CompoundTypeDescription *)IdlClassImpl::getTypeDescr(); }
+
+ // ctor/ dtor
+ CompoundIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ , _pFields( 0 )
+ {}
+ virtual ~CompoundIdlClassImpl();
+
+ // IdlClassImpl modifications
+ virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlClass > > SAL_CALL getSuperclasses() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class ArrayIdlClassImpl
+ : public IdlClassImpl
+ , public XIdlArray
+{
+public:
+ typelib_IndirectTypeDescription * getTypeDescr() const
+ { return (typelib_IndirectTypeDescription *)IdlClassImpl::getTypeDescr(); }
+
+ // ctor
+ ArrayIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ {}
+
+ virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // IdlClassImpl modifications
+ virtual sal_Bool SAL_CALL isAssignableFrom( const Reference< XIdlClass > & xType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlClass > SAL_CALL getComponentType() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XIdlArray > SAL_CALL getArray() throw(::com::sun::star::uno::RuntimeException);
+
+ // XIdlArray
+ virtual void SAL_CALL realloc( Any & rArray, sal_Int32 nLen ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getLen( const Any & rArray ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL get( const Any & rArray, sal_Int32 nIndex ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class EnumIdlClassImpl
+ : public IdlClassImpl
+{
+ Sequence< Reference< XIdlField > > * _pFields;
+ OUString2Field _aName2Field;
+
+public:
+ typelib_EnumTypeDescription * getTypeDescr() const
+ { return (typelib_EnumTypeDescription *)IdlClassImpl::getTypeDescr(); }
+
+ // ctor/ dtor
+ EnumIdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : IdlClassImpl( pReflection, rName, eTypeClass, pTypeDescr )
+ , _pFields( 0 )
+ {}
+ virtual ~EnumIdlClassImpl();
+
+ // IdlClassImpl modifications
+ virtual Reference< XIdlField > SAL_CALL getField( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlField > > SAL_CALL getFields() throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL createObject( Any & rObj ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class IdlMemberImpl
+ : public WeakImplHelper1< XIdlMember >
+{
+ IdlReflectionServiceImpl * _pReflection;
+ OUString _aName;
+
+ typelib_TypeDescription * _pTypeDescr;
+ typelib_TypeDescription * _pDeclTypeDescr;
+
+protected:
+ Reference< XIdlClass > _xDeclClass;
+
+public:
+ IdlReflectionServiceImpl * getReflection() const
+ { return _pReflection; }
+ Reference< XMultiServiceFactory > getSMgr() const
+ { return _pReflection->getSMgr(); }
+ typelib_TypeDescription * getTypeDescr() const
+ { return _pTypeDescr; }
+ typelib_TypeDescription * getDeclTypeDescr() const
+ { return _pDeclTypeDescr; }
+
+ // ctor/ dtor
+ IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
+ typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr );
+ virtual ~IdlMemberImpl();
+
+ // XIdlMember
+ virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+};
+
+//--------------------------------------------------------------------------------------------------
+// coerces to type descr pTo else queries for it: the interface pointer is returned via rDest
+// ## type to XidlClass coercion possible
+inline sal_Bool extract(
+ const Any & rObj, typelib_InterfaceTypeDescription * pTo,
+ Reference< XInterface > & rDest,
+ IdlReflectionServiceImpl * pRefl )
+{
+ rDest.clear();
+ if (0 != pTo)
+ {
+ if (! rObj.hasValue())
+ return sal_True;
+ if (rObj.getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ return ::uno_type_assignData(
+ &rDest, ((typelib_TypeDescription *)pTo)->pWeakRef,
+ const_cast< void * >( rObj.getValue() ), rObj.getValueTypeRef(),
+ reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ }
+ else if (rObj.getValueTypeClass() == TypeClass_TYPE)
+ {
+ rDest = pRefl->forType( reinterpret_cast< const Type * >( rObj.getValue() )->getTypeLibType() );
+ return rDest.is();
+ }
+ }
+ return sal_False;
+}
+//--------------------------------------------------------------------------------------------------
+inline sal_Bool coerce_assign(
+ void * pDest, typelib_TypeDescription * pTD, const Any & rSource,
+ IdlReflectionServiceImpl * pRefl )
+{
+ if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
+ {
+ Reference< XInterface > xVal;
+ if (extract( rSource, (typelib_InterfaceTypeDescription *)pTD, xVal, pRefl ))
+ {
+ if (*(XInterface **)pDest)
+ (*(XInterface **)pDest)->release();
+ *(XInterface **)pDest = xVal.get();
+ if (*(XInterface **)pDest)
+ (*(XInterface **)pDest)->acquire();
+ return sal_True;
+ }
+ return sal_False;
+ }
+ else if (pTD->eTypeClass == typelib_TypeClass_ANY)
+ {
+ return uno_assignData(
+ pDest, pTD,
+ (void *)&rSource, pTD,
+ reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ }
+ else
+ {
+ return uno_type_assignData(
+ pDest, pTD->pWeakRef,
+ (void *)rSource.getValue(), rSource.getValueTypeRef(),
+ reinterpret_cast< uno_QueryInterfaceFunc >(cpp_queryInterface),
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ }
+}
+
+}
+
+
diff --git a/stoc/source/corereflection/corefl.xml b/stoc/source/corereflection/corefl.xml
new file mode 100644
index 000000000000..5dba80b6abff
--- /dev/null
+++ b/stoc/source/corereflection/corefl.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> corereflection.uno </module-name>
+ <component-description>
+ <author> Daniel Boelzle </author>
+ <name> com.sun.star.comp.stoc.CoreReflection </name>
+ <description>
+This service is the implementation of XIdlClassProvider.
+The service provides reflection and access to all uno types
+(interfaces, structs, enums, ...).
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.reflection.CoreReflection </supported-service>
+ <service-dependency> ... </service-dependency>
+ <type>com.sun.star.lang.DisposedException</type>
+ <type> com.sun.star.reflection.XTypeDescription </type>
+ <type> com.sun.star.reflection.XIdlReflection </type>
+ <type> com.sun.star.reflection.XIdlClass </type>
+ <type> com.sun.star.reflection.XIdlField2 </type>
+ <type> com.sun.star.container.XHierarchicalNameAccess </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiComponentFactory </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.WrappedTargetRuntimeException </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/corereflection/crarray.cxx b/stoc/source/corereflection/crarray.cxx
new file mode 100644
index 000000000000..1546b2389fbb
--- /dev/null
+++ b/stoc/source/corereflection/crarray.cxx
@@ -0,0 +1,232 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <typelib/typedescription.h>
+#include <uno/data.h>
+
+#include "base.hxx"
+
+
+namespace stoc_corefl
+{
+
+// XInterface
+//__________________________________________________________________________________________________
+Any ArrayIdlClassImpl::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlArray * >( this ) ) );
+ return (aRet.hasValue() ? aRet : IdlClassImpl::queryInterface( rType ));
+}
+//__________________________________________________________________________________________________
+void ArrayIdlClassImpl::acquire() throw()
+{
+ IdlClassImpl::acquire();
+}
+//__________________________________________________________________________________________________
+void ArrayIdlClassImpl::release() throw()
+{
+ IdlClassImpl::release();
+}
+
+// XTypeProvider
+//__________________________________________________________________________________________________
+Sequence< Type > ArrayIdlClassImpl::getTypes()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIdlArray > *)0 ),
+ IdlClassImpl::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int8 > ArrayIdlClassImpl::getImplementationId()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+// XIdlArray
+//__________________________________________________________________________________________________
+void ArrayIdlClassImpl::realloc( Any & rArray, sal_Int32 nLen )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ TypeClass eTC = rArray.getValueTypeClass();
+ if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+ if (nLen < 0)
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal length given!") ),
+ (XWeak *)(OWeakObject *)this, 1 );
+ }
+
+ uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue();
+ uno_sequence_realloc( ppSeq, (typelib_TypeDescription *)getTypeDescr(),
+ nLen,
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ rArray.pData = ppSeq;
+}
+//__________________________________________________________________________________________________
+sal_Int32 ArrayIdlClassImpl::getLen( const Any & rArray )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ TypeClass eTC = rArray.getValueTypeClass();
+ if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+
+ return (*(uno_Sequence **)rArray.getValue())->nElements;
+}
+//__________________________________________________________________________________________________
+Any ArrayIdlClassImpl::get( const Any & rArray, sal_Int32 nIndex )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
+{
+ TypeClass eTC = rArray.getValueTypeClass();
+ if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+
+ uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue();
+ if (pSeq->nElements <= nIndex)
+ {
+ throw ArrayIndexOutOfBoundsException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+
+ Any aRet;
+ typelib_TypeDescription * pElemTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType );
+ uno_any_destruct( &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_any_construct( &aRet, &pSeq->elements[nIndex * pElemTypeDescr->nSize],
+ pElemTypeDescr,
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
+ TYPELIB_DANGER_RELEASE( pElemTypeDescr );
+ return aRet;
+}
+
+//__________________________________________________________________________________________________
+void ArrayIdlClassImpl::set( Any & rArray, sal_Int32 nIndex, const Any & rNewValue )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::ArrayIndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException)
+{
+ TypeClass eTC = rArray.getValueTypeClass();
+ if (eTC != TypeClass_SEQUENCE && eTC != TypeClass_ARRAY)
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no sequence given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+
+ uno_Sequence * pSeq = *(uno_Sequence **)rArray.getValue();
+ if (pSeq->nElements <= nIndex)
+ {
+ throw ArrayIndexOutOfBoundsException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal index given!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+
+ uno_Sequence ** ppSeq = (uno_Sequence **)rArray.getValue();
+ uno_sequence_reference2One(
+ ppSeq, (typelib_TypeDescription *)getTypeDescr(),
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ rArray.pData = ppSeq;
+ pSeq = *ppSeq;
+
+ typelib_TypeDescription * pElemTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pElemTypeDescr, getTypeDescr()->pType );
+
+ if (! coerce_assign( &pSeq->elements[nIndex * pElemTypeDescr->nSize],
+ pElemTypeDescr, rNewValue, getReflection() ))
+ {
+ TYPELIB_DANGER_RELEASE( pElemTypeDescr );
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("sequence element is not assignable by given value!") ),
+ (XWeak *)(OWeakObject *)this, 2 );
+ }
+ TYPELIB_DANGER_RELEASE( pElemTypeDescr );
+}
+
+// ArrayIdlClassImpl
+//__________________________________________________________________________________________________
+sal_Bool ArrayIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (xType.is() &&
+ (equals( xType ) ||
+ (xType->getTypeClass() == getTypeClass() && // must be sequence|array
+ getComponentType()->isAssignableFrom( xType->getComponentType() ))));
+}
+//__________________________________________________________________________________________________
+Reference< XIdlClass > ArrayIdlClassImpl::getComponentType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return getReflection()->forType( getTypeDescr()->pType );
+}
+//__________________________________________________________________________________________________
+Reference< XIdlArray > ArrayIdlClassImpl::getArray()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return this;
+}
+
+}
+
+
diff --git a/stoc/source/corereflection/crbase.cxx b/stoc/source/corereflection/crbase.cxx
new file mode 100644
index 000000000000..93d6aa4f2d24
--- /dev/null
+++ b/stoc/source/corereflection/crbase.cxx
@@ -0,0 +1,291 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <cppuhelper/queryinterface.hxx>
+#include <uno/any2.h>
+
+#include "base.hxx"
+
+namespace stoc_corefl
+{
+
+#ifdef TEST_LIST_CLASSES
+ClassNameList g_aClassNames;
+#endif
+
+//--------------------------------------------------------------------------------------------------
+Mutex & getMutexAccess()
+{
+ static Mutex * s_pMutex = 0;
+ if (! s_pMutex)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pMutex)
+ {
+ static Mutex s_aMutex;
+ s_pMutex = &s_aMutex;
+ }
+ }
+ return *s_pMutex;
+}
+
+//__________________________________________________________________________________________________
+IdlClassImpl::IdlClassImpl( IdlReflectionServiceImpl * pReflection,
+ const OUString & rName, typelib_TypeClass eTypeClass,
+ typelib_TypeDescription * pTypeDescr )
+ : _pReflection( pReflection )
+ , _aName( rName )
+ , _eTypeClass( (TypeClass)eTypeClass )
+ , _pTypeDescr( pTypeDescr )
+{
+ if (_pReflection)
+ _pReflection->acquire();
+ if (_pTypeDescr)
+ {
+ typelib_typedescription_acquire( _pTypeDescr );
+ if (! _pTypeDescr->bComplete)
+ typelib_typedescription_complete( &_pTypeDescr );
+ }
+
+#ifdef TEST_LIST_CLASSES
+ ClassNameList::const_iterator iFind( find( g_aClassNames.begin(), g_aClassNames.end(), _aName ) );
+ OSL_ENSURE( iFind == g_aClassNames.end(), "### idl class already exists!" );
+ g_aClassNames.push_front( _aName );
+#endif
+}
+//__________________________________________________________________________________________________
+IdlClassImpl::~IdlClassImpl()
+{
+ if (_pTypeDescr)
+ typelib_typedescription_release( _pTypeDescr );
+ if (_pReflection)
+ _pReflection->release();
+
+#ifdef TEST_LIST_CLASSES
+ ClassNameList::iterator iFind( find( g_aClassNames.begin(), g_aClassNames.end(), _aName ) );
+ OSL_ENSURE( iFind != g_aClassNames.end(), "### idl class does not exist!" );
+ g_aClassNames.erase( iFind );
+#endif
+}
+
+// XIdlClassImpl default implementation
+//__________________________________________________________________________________________________
+TypeClass IdlClassImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _eTypeClass;
+}
+//__________________________________________________________________________________________________
+OUString IdlClassImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+//__________________________________________________________________________________________________
+sal_Bool IdlClassImpl::equals( const Reference< XIdlClass >& xType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (xType.is() &&
+ (xType->getTypeClass() == _eTypeClass) && (xType->getName() == _aName));
+}
+
+static sal_Bool s_aAssignableFromTab[11][11] =
+{
+ /* from CH,BO,BY,SH,US,LO,UL,HY,UH,FL,DO */
+/* TypeClass_CHAR */ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_BOOLEAN */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_BYTE */ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_UNSIGNED_SHORT */ { 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
+/* TypeClass_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+/* TypeClass_UNSIGNED_LONG */ { 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0 },
+/* TypeClass_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+/* TypeClass_UNSIGNED_HYPER */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },
+/* TypeClass_FLOAT */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0 },
+/* TypeClass_DOUBLE */ { 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
+};
+//__________________________________________________________________________________________________
+sal_Bool IdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ TypeClass eAssign = getTypeClass();
+ if (equals( xType ) || eAssign == TypeClass_ANY) // default shot
+ {
+ return sal_True;
+ }
+ else
+ {
+ TypeClass eFrom = xType->getTypeClass();
+ if (eAssign > TypeClass_VOID && eAssign < TypeClass_STRING &&
+ eFrom > TypeClass_VOID && eFrom < TypeClass_STRING)
+ {
+ return s_aAssignableFromTab[eAssign-1][eFrom-1];
+ }
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+void IdlClassImpl::createObject( Any & rObj )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ rObj.clear();
+ uno_any_destruct( &rObj, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_any_construct( &rObj, 0, getTypeDescr(), 0 );
+}
+
+// what TODO ????
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlClass > > IdlClassImpl::getClasses()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ OSL_ENSURE( sal_False, "### unexpected use!" );
+ return Sequence< Reference< XIdlClass > >();
+}
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlClassImpl::getClass( const OUString & )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ OSL_ENSURE( sal_False, "### unexpected use!" );
+ return Reference< XIdlClass >();
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlClass > > IdlClassImpl::getInterfaces()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+// OSL_ENSURE( sal_False, "### unexpected use!" );
+ return Sequence< Reference< XIdlClass > >();
+}
+
+// structs, interfaces
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlClass > > IdlClassImpl::getSuperclasses() throw(::com::sun::star::uno::RuntimeException)
+{
+ return Sequence< Reference< XIdlClass > >();
+}
+// structs
+//__________________________________________________________________________________________________
+Reference< XIdlField > IdlClassImpl::getField( const OUString & )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XIdlField >();
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlField > > IdlClassImpl::getFields()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Sequence< Reference< XIdlField > >();
+}
+// interfaces
+//__________________________________________________________________________________________________
+Uik IdlClassImpl::getUik()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Uik();
+}
+//__________________________________________________________________________________________________
+Reference< XIdlMethod > IdlClassImpl::getMethod( const OUString & )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XIdlMethod >();
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlMethod > > IdlClassImpl::getMethods()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Sequence< Reference< XIdlMethod > >();
+}
+// array
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlClassImpl::getComponentType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XIdlClass >();
+}
+//__________________________________________________________________________________________________
+Reference< XIdlArray > IdlClassImpl::getArray()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Reference< XIdlArray >();
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//__________________________________________________________________________________________________
+IdlMemberImpl::IdlMemberImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
+ typelib_TypeDescription * pTypeDescr,
+ typelib_TypeDescription * pDeclTypeDescr )
+ : _pReflection( pReflection )
+ , _aName( rName )
+ , _pTypeDescr( pTypeDescr )
+ , _pDeclTypeDescr( pDeclTypeDescr )
+{
+ _pReflection->acquire();
+ typelib_typedescription_acquire( _pTypeDescr );
+ if (! _pTypeDescr->bComplete)
+ typelib_typedescription_complete( &_pTypeDescr );
+ typelib_typedescription_acquire( _pDeclTypeDescr );
+ if (! _pDeclTypeDescr->bComplete)
+ typelib_typedescription_complete( &_pDeclTypeDescr );
+}
+//__________________________________________________________________________________________________
+IdlMemberImpl::~IdlMemberImpl()
+{
+ typelib_typedescription_release( _pDeclTypeDescr );
+ typelib_typedescription_release( _pTypeDescr );
+ _pReflection->release();
+}
+
+// XIdlMember
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlMemberImpl::getDeclaringClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _xDeclClass.is())
+ {
+ Reference< XIdlClass > xDeclClass( getReflection()->forType( getDeclTypeDescr() ) );
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _xDeclClass.is())
+ _xDeclClass = xDeclClass;
+ }
+ return _xDeclClass;
+}
+//__________________________________________________________________________________________________
+OUString IdlMemberImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+}
+
+
diff --git a/stoc/source/corereflection/crcomp.cxx b/stoc/source/corereflection/crcomp.cxx
new file mode 100644
index 000000000000..db3c2741322f
--- /dev/null
+++ b/stoc/source/corereflection/crcomp.cxx
@@ -0,0 +1,405 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <rtl/strbuf.hxx>
+
+#include <com/sun/star/reflection/XIdlField.hpp>
+#include <com/sun/star/reflection/XIdlField2.hpp>
+#include "com/sun/star/uno/TypeClass.hpp"
+
+#include "base.hxx"
+
+
+namespace stoc_corefl
+{
+
+//==================================================================================================
+class IdlCompFieldImpl
+ : public IdlMemberImpl
+ , public XIdlField
+ , public XIdlField2
+{
+ sal_Int32 _nOffset;
+
+public:
+ IdlCompFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
+ typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr,
+ sal_Int32 nOffset )
+ : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
+ , _nOffset( nOffset )
+ {}
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type & rType ) throw (::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw ();
+ virtual void SAL_CALL release() throw ();
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // XIdlMember
+ virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+ // XIdlField
+ virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
+ virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ // XIdlField2: getType, getAccessMode and get are equal to XIdlField
+ virtual void SAL_CALL set( Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+};
+
+// XInterface
+//__________________________________________________________________________________________________
+Any IdlCompFieldImpl::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface( rType,
+ static_cast< XIdlField * >( this ),
+ static_cast< XIdlField2 * >( this ) ) );
+ return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
+}
+//__________________________________________________________________________________________________
+void IdlCompFieldImpl::acquire() throw()
+{
+ IdlMemberImpl::acquire();
+}
+//__________________________________________________________________________________________________
+void IdlCompFieldImpl::release() throw()
+{
+ IdlMemberImpl::release();
+}
+
+// XTypeProvider
+//__________________________________________________________________________________________________
+Sequence< Type > IdlCompFieldImpl::getTypes()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIdlField2 > *)0 ),
+ ::getCppuType( (const Reference< XIdlField > *)0 ),
+ IdlMemberImpl::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int8 > IdlCompFieldImpl::getImplementationId()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+// XIdlMember
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlCompFieldImpl::getDeclaringClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _xDeclClass.is())
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _xDeclClass.is())
+ {
+ typelib_CompoundTypeDescription * pTD =
+ (typelib_CompoundTypeDescription *)getDeclTypeDescr();
+ while (pTD)
+ {
+ typelib_TypeDescriptionReference ** ppTypeRefs = pTD->ppTypeRefs;
+ for ( sal_Int32 nPos = pTD->nMembers; nPos--; )
+ {
+ if (td_equals( (typelib_TypeDescription *)getTypeDescr(), ppTypeRefs[nPos] ))
+ {
+ _xDeclClass = getReflection()->forType( (typelib_TypeDescription *)pTD );
+ return _xDeclClass;
+ }
+ }
+ pTD = pTD->pBaseTypeDescription;
+ }
+ }
+ }
+ return _xDeclClass;
+}
+//__________________________________________________________________________________________________
+OUString IdlCompFieldImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return IdlMemberImpl::getName();
+}
+
+// XIdlField
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlCompFieldImpl::getType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return getReflection()->forType( getTypeDescr() );
+}
+//__________________________________________________________________________________________________
+FieldAccessMode IdlCompFieldImpl::getAccessMode()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return FieldAccessMode_READWRITE;
+}
+//__________________________________________________________________________________________________
+Any IdlCompFieldImpl::get( const Any & rObj )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
+ rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pObjTD = 0;
+ TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
+
+ typelib_TypeDescription * pTD = pObjTD;
+ typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
+ while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
+ pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
+
+ OSL_ENSURE( pTD, "### illegal object type!" );
+ if (pTD)
+ {
+ TYPELIB_DANGER_RELEASE( pObjTD );
+ Any aRet;
+ uno_any_destruct(
+ &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_any_construct(
+ &aRet, (char *)rObj.getValue() + _nOffset, getTypeDescr(),
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
+ return aRet;
+ }
+ TYPELIB_DANGER_RELEASE( pObjTD );
+ }
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+}
+//__________________________________________________________________________________________________
+void IdlCompFieldImpl::set( const Any & rObj, const Any & rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
+ rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pObjTD = 0;
+ TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
+
+ typelib_TypeDescription * pTD = pObjTD;
+ typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
+ while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
+ pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
+
+ OSL_ENSURE( pTD, "### illegal object type!" );
+ if (pTD)
+ {
+ TYPELIB_DANGER_RELEASE( pObjTD );
+ if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
+ {
+ return;
+ }
+ else
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
+ (XWeak *)(OWeakObject *)this, 1 );
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pObjTD );
+ }
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+}
+
+//__________________________________________________________________________________________________
+void IdlCompFieldImpl::set( Any & rObj, const Any & rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ if (rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_STRUCT ||
+ rObj.getValueTypeClass() == com::sun::star::uno::TypeClass_EXCEPTION)
+ {
+ typelib_TypeDescription * pObjTD = 0;
+ TYPELIB_DANGER_GET( &pObjTD, rObj.getValueTypeRef() );
+
+ typelib_TypeDescription * pTD = pObjTD;
+ typelib_TypeDescription * pDeclTD = getDeclTypeDescr();
+ while (pTD && !typelib_typedescription_equals( pTD, pDeclTD ))
+ pTD = (typelib_TypeDescription *)((typelib_CompoundTypeDescription *)pTD)->pBaseTypeDescription;
+
+ OSL_ENSURE( pTD, "### illegal object type!" );
+ if (pTD)
+ {
+ TYPELIB_DANGER_RELEASE( pObjTD );
+ if (coerce_assign( (char *)rObj.getValue() + _nOffset, getTypeDescr(), rValue, getReflection() ))
+ {
+ return;
+ }
+ else
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
+ (XWeak *)(OWeakObject *)this, 1 );
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pObjTD );
+ }
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//__________________________________________________________________________________________________
+CompoundIdlClassImpl::~CompoundIdlClassImpl()
+{
+ delete _pFields;
+}
+
+//__________________________________________________________________________________________________
+sal_Bool CompoundIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (xType.is())
+ {
+ TypeClass eTC = xType->getTypeClass();
+ if (eTC == TypeClass_STRUCT || eTC == TypeClass_EXCEPTION)
+ {
+ if (equals( xType ))
+ return sal_True;
+ else
+ {
+ const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses();
+ if (rSeq.getLength())
+ {
+ OSL_ENSURE( rSeq.getLength() == 1, "### unexpected len of super classes!" );
+ return isAssignableFrom( rSeq[0] );
+ }
+ }
+ }
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlClass > > CompoundIdlClassImpl::getSuperclasses()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _xSuperClass.is())
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _xSuperClass.is())
+ {
+ typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr()->pBaseTypeDescription;
+ if (pCompTypeDescr)
+ _xSuperClass = getReflection()->forType( (typelib_TypeDescription *)pCompTypeDescr );
+ }
+ }
+ if (_xSuperClass.is())
+ return Sequence< Reference< XIdlClass > >( &_xSuperClass, 1 );
+ else
+ return Sequence< Reference< XIdlClass > >();
+}
+//__________________________________________________________________________________________________
+Reference< XIdlField > CompoundIdlClassImpl::getField( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pFields)
+ getFields(); // init fields
+
+ const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
+ if (iFind != _aName2Field.end())
+ return Reference< XIdlField >( (*iFind).second );
+ else
+ return Reference< XIdlField >();
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlField > > CompoundIdlClassImpl::getFields()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pFields)
+ {
+ sal_Int32 nAll = 0;
+ typelib_CompoundTypeDescription * pCompTypeDescr = getTypeDescr();
+ for ( ; pCompTypeDescr; pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ nAll += pCompTypeDescr->nMembers;
+
+ Sequence< Reference< XIdlField > > * pFields =
+ new Sequence< Reference< XIdlField > >( nAll );
+ Reference< XIdlField > * pSeq = pFields->getArray();
+
+ for ( pCompTypeDescr = getTypeDescr(); pCompTypeDescr;
+ pCompTypeDescr = pCompTypeDescr->pBaseTypeDescription )
+ {
+ typelib_TypeDescriptionReference ** ppTypeRefs = pCompTypeDescr->ppTypeRefs;
+ rtl_uString ** ppNames = pCompTypeDescr->ppMemberNames;
+ sal_Int32 * pMemberOffsets = pCompTypeDescr->pMemberOffsets;
+
+ for ( sal_Int32 nPos = pCompTypeDescr->nMembers; nPos--; )
+ {
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, ppTypeRefs[nPos] );
+ OSL_ENSURE( pTD, "### cannot get field in struct!" );
+ if (pTD)
+ {
+ OUString aName( ppNames[nPos] );
+ _aName2Field[aName] = pSeq[--nAll] = new IdlCompFieldImpl(
+ getReflection(), aName, pTD, IdlClassImpl::getTypeDescr(), pMemberOffsets[nPos] );
+ TYPELIB_DANGER_RELEASE( pTD );
+ }
+ }
+ }
+
+ _pFields = pFields;
+ }
+ return *_pFields;
+}
+
+}
+
+
diff --git a/stoc/source/corereflection/crefl.cxx b/stoc/source/corereflection/crefl.cxx
new file mode 100644
index 000000000000..d3ebed762bac
--- /dev/null
+++ b/stoc/source/corereflection/crefl.cxx
@@ -0,0 +1,514 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <cppuhelper/queryinterface.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/reflection/XTypeDescription.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+using namespace com::sun::star;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+
+#include "base.hxx"
+
+
+namespace stoc_corefl
+{
+
+static const sal_Int32 CACHE_SIZE = 256;
+
+#define SERVICENAME "com.sun.star.reflection.CoreReflection"
+#define IMPLNAME "com.sun.star.comp.stoc.CoreReflection"
+
+// can be static, as every client of the core reflection keeps a reference to the
+// core reflection, so refcounting can be done here.
+static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+static Sequence< OUString > core_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString( RTL_CONSTASCII_USTRINGPARAM(SERVICENAME) );
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+static OUString core_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+//__________________________________________________________________________________________________
+IdlReflectionServiceImpl::IdlReflectionServiceImpl(
+ const Reference< XComponentContext > & xContext )
+ : OComponentHelper( _aComponentMutex )
+ , _xMgr( xContext->getServiceManager(), UNO_QUERY )
+ , _aElements( CACHE_SIZE )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ xContext->getValueByName( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.reflection.theTypeDescriptionManager") ) ) >>= _xTDMgr;
+ OSL_ENSURE( _xTDMgr.is(), "### cannot get singleton \"TypeDescriptionManager\" from context!" );
+}
+//__________________________________________________________________________________________________
+IdlReflectionServiceImpl::~IdlReflectionServiceImpl()
+{
+ TRACE( "> IdlReflectionServiceImpl dtor <\n" );
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XInterface
+//__________________________________________________________________________________________________
+Any IdlReflectionServiceImpl::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface(
+ rType,
+ static_cast< XIdlReflection * >( this ),
+ static_cast< XHierarchicalNameAccess * >( this ),
+ static_cast< XServiceInfo * >( this ) ) );
+
+ return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
+}
+//__________________________________________________________________________________________________
+void IdlReflectionServiceImpl::acquire() throw()
+{
+ OComponentHelper::acquire();
+}
+//__________________________________________________________________________________________________
+void IdlReflectionServiceImpl::release() throw()
+{
+ OComponentHelper::release();
+}
+
+// XTypeProvider
+//__________________________________________________________________________________________________
+Sequence< Type > IdlReflectionServiceImpl::getTypes()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( _aComponentMutex );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIdlReflection > *)0 ),
+ ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 ),
+ ::getCppuType( (const Reference< XServiceInfo > *)0 ),
+ OComponentHelper::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int8 > IdlReflectionServiceImpl::getImplementationId()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( _aComponentMutex );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+// XComponent
+//__________________________________________________________________________________________________
+void IdlReflectionServiceImpl::dispose()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ TRACE( "> disposing corereflection... <" );
+ OComponentHelper::dispose();
+
+ MutexGuard aGuard( _aComponentMutex );
+ _aElements.clear();
+#ifdef TEST_LIST_CLASSES
+ OSL_ENSURE( g_aClassNames.size() == 0, "### idl classes still alive!" );
+ ClassNameList::const_iterator iPos( g_aClassNames.begin() );
+ while (iPos != g_aClassNames.end())
+ {
+ OUString aName( *iPos );
+ ++iPos;
+ }
+#endif
+}
+
+// XServiceInfo
+//__________________________________________________________________________________________________
+OUString IdlReflectionServiceImpl::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return core_getImplementationName();
+}
+//__________________________________________________________________________________________________
+sal_Bool IdlReflectionServiceImpl::supportsService( const OUString & rServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ const Sequence< OUString > & rSNL = getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (pArray[nPos] == rServiceName)
+ return sal_True;
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > IdlReflectionServiceImpl::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return core_getSupportedServiceNames();
+}
+
+// XIdlReflection
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlReflectionServiceImpl::getType( const Any & rObj )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (rObj.hasValue() ? forType( rObj.getValueTypeRef() ) : Reference< XIdlClass >());
+}
+
+//__________________________________________________________________________________________________
+inline Reference< XIdlClass > IdlReflectionServiceImpl::constructClass(
+ typelib_TypeDescription * pTypeDescr )
+{
+ OSL_ENSURE( pTypeDescr->eTypeClass != typelib_TypeClass_TYPEDEF, "### unexpected typedef!" );
+
+ switch (pTypeDescr->eTypeClass)
+ {
+ case typelib_TypeClass_VOID:
+ case typelib_TypeClass_CHAR:
+ case typelib_TypeClass_BOOLEAN:
+ case typelib_TypeClass_BYTE:
+ case typelib_TypeClass_SHORT:
+ case typelib_TypeClass_UNSIGNED_SHORT:
+ case typelib_TypeClass_LONG:
+ case typelib_TypeClass_UNSIGNED_LONG:
+ case typelib_TypeClass_HYPER:
+ case typelib_TypeClass_UNSIGNED_HYPER:
+ case typelib_TypeClass_FLOAT:
+ case typelib_TypeClass_DOUBLE:
+ case typelib_TypeClass_STRING:
+ case typelib_TypeClass_ANY:
+ return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
+
+ case TypeClass_ENUM:
+ return new EnumIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
+
+ case typelib_TypeClass_STRUCT:
+ case typelib_TypeClass_UNION:
+ case typelib_TypeClass_EXCEPTION:
+ return new CompoundIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
+
+ case typelib_TypeClass_ARRAY:
+ case typelib_TypeClass_SEQUENCE:
+ return new ArrayIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
+
+ case typelib_TypeClass_INTERFACE:
+ return new InterfaceIdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
+
+ case typelib_TypeClass_TYPE:
+ return new IdlClassImpl( this, pTypeDescr->pTypeName, pTypeDescr->eTypeClass, pTypeDescr );
+
+ default:
+#if OSL_DEBUG_LEVEL > 1
+ OSL_TRACE( "### corereflection type unsupported: " );
+ OString aName( OUStringToOString( pTypeDescr->pTypeName, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( aName.getStr() );
+ OSL_TRACE( "\n" );
+#endif
+ return Reference< XIdlClass >();
+ }
+}
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlReflectionServiceImpl::forName( const OUString & rTypeName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference< XIdlClass > xRet;
+ Any aAny( _aElements.getValue( rTypeName ) );
+
+ if (aAny.hasValue())
+ {
+ if (aAny.getValueTypeClass() == TypeClass_INTERFACE)
+ xRet = *(const Reference< XIdlClass > *)aAny.getValue();
+ }
+ else
+ {
+ // try to get _type_ by name
+ typelib_TypeDescription * pTD = 0;
+ typelib_typedescription_getByName( &pTD, rTypeName.pData );
+ if (pTD)
+ {
+ if ((xRet = constructClass( pTD )).is())
+ _aElements.setValue( rTypeName, makeAny( xRet ) ); // update
+ typelib_typedescription_release( pTD );
+ }
+ }
+
+ return xRet;
+}
+
+// XHierarchicalNameAccess
+//__________________________________________________________________________________________________
+Any IdlReflectionServiceImpl::getByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( _aElements.getValue( rName ) );
+ if (! aRet.hasValue())
+ {
+ // first look for constants exclusivly!
+ aRet = _xTDMgr->getByHierarchicalName( rName );
+ if (aRet.getValueTypeClass() == TypeClass_INTERFACE) // if no constant,
+ // i.e. XTypeDescription for a type
+ {
+ // type retrieved from tdmgr
+ OSL_ASSERT( (*(Reference< XInterface > *)aRet.getValue())->queryInterface(
+ ::getCppuType( (const Reference< XTypeDescription > *)0 ) ).hasValue() );
+
+ // if you are interested in a type then CALL forName()!!!
+ // this way is NOT recommended for types, because this method looks for constants first
+
+ // if td manager found some type, it will be in the cache (hopefully.. we just got it)
+ // so the second retrieving via c typelib callback chain should succeed...
+
+ // try to get _type_ by name
+ typelib_TypeDescription * pTD = 0;
+ typelib_typedescription_getByName( &pTD, rName.pData );
+
+ aRet.clear(); // kick XTypeDescription interface
+
+ if (pTD)
+ {
+ Reference< XIdlClass > xIdlClass( constructClass( pTD ) );
+ aRet.setValue( &xIdlClass, ::getCppuType( (const Reference< XIdlClass > *)0 ) );
+ typelib_typedescription_release( pTD );
+ }
+ }
+ // else is constant
+
+ // update
+ if (aRet.hasValue())
+ _aElements.setValue( rName, aRet );
+ else
+ {
+ throw NoSuchElementException( rName, Reference< XInterface >() );
+ }
+ }
+ return aRet;
+}
+//__________________________________________________________________________________________________
+sal_Bool IdlReflectionServiceImpl::hasByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ try
+ {
+ return getByHierarchicalName( rName ).hasValue();
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ return sal_False;
+}
+
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescription * pTypeDescr )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference< XIdlClass > xRet;
+ OUString aName( pTypeDescr->pTypeName );
+ Any aAny( _aElements.getValue( aName ) );
+
+ if (aAny.hasValue())
+ {
+ if (aAny.getValueTypeClass() == TypeClass_INTERFACE)
+ xRet = *(const Reference< XIdlClass > *)aAny.getValue();
+ }
+ else
+ {
+ if (pTypeDescr && (xRet = constructClass( pTypeDescr )).is())
+ _aElements.setValue( aName, makeAny( xRet ) ); // update
+ }
+
+ return xRet;
+}
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlReflectionServiceImpl::forType( typelib_TypeDescriptionReference * pRef )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ typelib_TypeDescription * pTD = 0;
+ TYPELIB_DANGER_GET( &pTD, pRef );
+ if (pTD)
+ {
+ Reference< XIdlClass > xRet = forType( pTD );
+ TYPELIB_DANGER_RELEASE( pTD );
+ return xRet;
+ }
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("IdlReflectionServiceImpl::forType() failed!") ),
+ (XWeak *)(OWeakObject *)this );
+}
+
+//__________________________________________________________________________________________________
+const Mapping & IdlReflectionServiceImpl::getCpp2Uno()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _aCpp2Uno.is())
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _aCpp2Uno.is())
+ {
+ _aCpp2Uno = Mapping(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ),
+ OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ) );
+ OSL_ENSURE( _aCpp2Uno.is(), "### cannot get c++ to uno mapping!" );
+ if (! _aCpp2Uno.is())
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get c++ to uno mapping!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+ }
+ }
+ return _aCpp2Uno;
+}
+//__________________________________________________________________________________________________
+const Mapping & IdlReflectionServiceImpl::getUno2Cpp()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _aUno2Cpp.is())
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _aUno2Cpp.is())
+ {
+ _aUno2Cpp = Mapping(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(UNO_LB_UNO) ),
+ OUString( RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME) ) );
+ OSL_ENSURE( _aUno2Cpp.is(), "### cannot get uno to c++ mapping!" );
+ if (! _aUno2Cpp.is())
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get uno to c++ mapping!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+ }
+ }
+ return _aUno2Cpp;
+}
+//__________________________________________________________________________________________________
+uno_Interface * IdlReflectionServiceImpl::mapToUno(
+ const Any & rObj, typelib_InterfaceTypeDescription * pTo )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference< XInterface > xObj;
+ if (extract( rObj, pTo, xObj, this ))
+ return (uno_Interface *)getCpp2Uno().mapInterface( xObj.get(), pTo );
+
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
+ (XWeak *)(OWeakObject *)this );
+}
+
+//==================================================================================================
+Reference< XInterface > SAL_CALL IdlReflectionServiceImpl_create(
+ const Reference< XComponentContext > & xContext )
+ throw(::com::sun::star::uno::Exception)
+{
+ return Reference< XInterface >( (XWeak *)(OWeakObject *)new IdlReflectionServiceImpl( xContext ) );
+}
+
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+using namespace stoc_corefl;
+
+static struct ImplementationEntry g_entries[] =
+{
+ {
+ IdlReflectionServiceImpl_create, core_getImplementationName,
+ core_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+}
diff --git a/stoc/source/corereflection/crenum.cxx b/stoc/source/corereflection/crenum.cxx
new file mode 100644
index 000000000000..174e177080fe
--- /dev/null
+++ b/stoc/source/corereflection/crenum.cxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "base.hxx"
+
+namespace stoc_corefl
+{
+
+//==================================================================================================
+class IdlEnumFieldImpl
+ : public IdlMemberImpl
+ , public XIdlField
+ , public XIdlField2
+{
+ sal_Int32 _nValue;
+
+public:
+ IdlEnumFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
+ typelib_TypeDescription * pTypeDescr, sal_Int32 nValue )
+ : IdlMemberImpl( pReflection, rName, pTypeDescr, pTypeDescr )
+ , _nValue( nValue )
+ {}
+ virtual ~IdlEnumFieldImpl();
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // XIdlMember
+ virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+ // XIdlField
+ virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
+ virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ // XIdlField2: getType, getAccessMode and get are equal to XIdlField
+ virtual void SAL_CALL set( Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+};
+//__________________________________________________________________________________________________
+IdlEnumFieldImpl::~IdlEnumFieldImpl()
+{
+}
+
+// XInterface
+//__________________________________________________________________________________________________
+Any IdlEnumFieldImpl::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface( rType,
+ static_cast< XIdlField * >( this ),
+ static_cast< XIdlField2 * >( this ) ) );
+ return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
+}
+//__________________________________________________________________________________________________
+void IdlEnumFieldImpl::acquire() throw()
+{
+ IdlMemberImpl::acquire();
+}
+//__________________________________________________________________________________________________
+void IdlEnumFieldImpl::release() throw()
+{
+ IdlMemberImpl::release();
+}
+
+// XTypeProvider
+//__________________________________________________________________________________________________
+Sequence< Type > IdlEnumFieldImpl::getTypes()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIdlField2 > *)0 ),
+ ::getCppuType( (const Reference< XIdlField > *)0 ),
+ IdlMemberImpl::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int8 > IdlEnumFieldImpl::getImplementationId()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+// XIdlMember
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlEnumFieldImpl::getDeclaringClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return IdlMemberImpl::getDeclaringClass();
+}
+//__________________________________________________________________________________________________
+OUString IdlEnumFieldImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return IdlMemberImpl::getName();
+}
+
+// XIdlField
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlEnumFieldImpl::getType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return getDeclaringClass();
+}
+//__________________________________________________________________________________________________
+FieldAccessMode IdlEnumFieldImpl::getAccessMode()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return FieldAccessMode_READONLY;
+}
+//__________________________________________________________________________________________________
+Any IdlEnumFieldImpl::get( const Any & )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ return Any( &_nValue, getTypeDescr() );
+}
+//__________________________________________________________________________________________________
+void IdlEnumFieldImpl::set( const Any &, const Any & )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ throw IllegalAccessException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("enum field is constant!") ),
+ (XWeak *)(OWeakObject *)this );
+}
+//__________________________________________________________________________________________________
+void IdlEnumFieldImpl::set( Any &, const Any & )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ throw IllegalAccessException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("enum field is constant!") ),
+ (XWeak *)(OWeakObject *)this );
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//__________________________________________________________________________________________________
+EnumIdlClassImpl::~EnumIdlClassImpl()
+{
+ delete _pFields;
+}
+
+// IdlClassImpl modifications
+//__________________________________________________________________________________________________
+Reference< XIdlField > EnumIdlClassImpl::getField( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pFields)
+ getFields(); // init members
+
+ const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
+ if (iFind != _aName2Field.end())
+ return (*iFind).second;
+ else
+ return Reference< XIdlField >();
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlField > > EnumIdlClassImpl::getFields()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pFields)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pFields)
+ {
+ sal_Int32 nFields = getTypeDescr()->nEnumValues;
+ Sequence< Reference< XIdlField > > * pFields =
+ new Sequence< Reference< XIdlField > >( nFields );
+ Reference< XIdlField > * pSeq = pFields->getArray();
+
+ while (nFields--)
+ {
+ OUString aName( getTypeDescr()->ppEnumNames[nFields] );
+ _aName2Field[aName] = pSeq[nFields] = new IdlEnumFieldImpl(
+ getReflection(), aName, IdlClassImpl::getTypeDescr(), getTypeDescr()->pEnumValues[nFields] );
+ }
+
+ _pFields = pFields;
+ }
+ }
+ return *_pFields;
+}
+//__________________________________________________________________________________________________
+void EnumIdlClassImpl::createObject( Any & rObj )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ sal_Int32 eVal =
+ ((typelib_EnumTypeDescription *)IdlClassImpl::getTypeDescr())->nDefaultEnumValue;
+ rObj.setValue( &eVal, IdlClassImpl::getTypeDescr() );
+}
+
+}
+
+
diff --git a/stoc/source/corereflection/criface.cxx b/stoc/source/corereflection/criface.cxx
new file mode 100644
index 000000000000..95d9990257f5
--- /dev/null
+++ b/stoc/source/corereflection/criface.cxx
@@ -0,0 +1,993 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <sal/config.h>
+#ifdef SAL_UNX
+#include <sal/alloca.h>
+#endif
+#if !(defined(MACOSX) || defined(FREEBSD))
+#include <malloc.h>
+#endif
+#include <rtl/alloc.h>
+#include <typelib/typedescription.hxx>
+#include <uno/data.h>
+
+#include "base.hxx"
+
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "cppuhelper/exc_hlp.hxx"
+
+namespace stoc_corefl
+{
+
+//==================================================================================================
+class IdlAttributeFieldImpl
+ : public IdlMemberImpl
+ , public XIdlField
+ , public XIdlField2
+{
+public:
+ typelib_InterfaceAttributeTypeDescription * getAttributeTypeDescr()
+ { return (typelib_InterfaceAttributeTypeDescription *)getTypeDescr(); }
+
+ IdlAttributeFieldImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
+ typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr )
+ : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
+ {}
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // XIdlMember
+ virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+ // XIdlField
+ virtual Reference< XIdlClass > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
+ virtual FieldAccessMode SAL_CALL getAccessMode() throw(::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL get( const Any & rObj ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL set( const Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+ // XIdlField2: getType, getAccessMode and get are equal to XIdlField
+ virtual void SAL_CALL set( Any & rObj, const Any & rValue ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ void checkException(
+ uno_Any * exception, Reference< XInterface > const & context);
+};
+
+// XInterface
+//__________________________________________________________________________________________________
+Any IdlAttributeFieldImpl::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface( rType,
+ static_cast< XIdlField * >( this ),
+ static_cast< XIdlField2 * >( this ) ) );
+ return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
+}
+//__________________________________________________________________________________________________
+void IdlAttributeFieldImpl::acquire() throw()
+{
+ IdlMemberImpl::acquire();
+}
+//__________________________________________________________________________________________________
+void IdlAttributeFieldImpl::release() throw()
+{
+ IdlMemberImpl::release();
+}
+
+// XTypeProvider
+//__________________________________________________________________________________________________
+Sequence< Type > IdlAttributeFieldImpl::getTypes()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIdlField2 > *)0 ),
+ ::getCppuType( (const Reference< XIdlField > *)0 ),
+ IdlMemberImpl::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int8 > IdlAttributeFieldImpl::getImplementationId()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+// XIdlMember
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlAttributeFieldImpl::getDeclaringClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _xDeclClass.is())
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _xDeclClass.is())
+ {
+ rtl::OUString aName(getAttributeTypeDescr()->aBase.aBase.pTypeName);
+ sal_Int32 i = aName.indexOf(':');
+ OSL_ASSERT(i >= 0);
+ _xDeclClass = getReflection()->forName(aName.copy(0, i));
+ }
+ }
+ return _xDeclClass;
+}
+//__________________________________________________________________________________________________
+OUString IdlAttributeFieldImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return IdlMemberImpl::getName();
+}
+
+// XIdlField
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlAttributeFieldImpl::getType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return getReflection()->forType(
+ getAttributeTypeDescr()->pAttributeTypeRef );
+}
+//__________________________________________________________________________________________________
+FieldAccessMode IdlAttributeFieldImpl::getAccessMode()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (((typelib_InterfaceAttributeTypeDescription *)getAttributeTypeDescr())->bReadOnly
+ ? FieldAccessMode_READONLY : FieldAccessMode_READWRITE);
+}
+//__________________________________________________________________________________________________
+Any IdlAttributeFieldImpl::get( const Any & rObj )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
+{
+ uno_Interface * pUnoI = getReflection()->mapToUno(
+ rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() );
+ OSL_ENSURE( pUnoI, "### illegal destination object given!" );
+ if (pUnoI)
+ {
+ TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef );
+ typelib_TypeDescription * pTD = aTD.get();
+
+ uno_Any aExc;
+ uno_Any * pExc = &aExc;
+ void * pReturn = alloca( pTD->nSize );
+
+ (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), pReturn, 0, &pExc );
+ (*pUnoI->release)( pUnoI );
+
+ checkException(
+ pExc,
+ *static_cast< Reference< XInterface > const * >(rObj.getValue()));
+ Any aRet;
+ uno_any_destruct(
+ &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_any_constructAndConvert( &aRet, pReturn, pTD, getReflection()->getUno2Cpp().get() );
+ uno_destructData( pReturn, pTD, 0 );
+ return aRet;
+ }
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal object given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+}
+//__________________________________________________________________________________________________
+void IdlAttributeFieldImpl::set( Any & rObj, const Any & rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ if (getAttributeTypeDescr()->bReadOnly)
+ {
+ throw IllegalAccessException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot set readonly attribute!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+
+ uno_Interface * pUnoI = getReflection()->mapToUno(
+ rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() );
+ OSL_ENSURE( pUnoI, "### illegal destination object given!" );
+ if (pUnoI)
+ {
+ TypeDescription aTD( getAttributeTypeDescr()->pAttributeTypeRef );
+ typelib_TypeDescription * pTD = aTD.get();
+
+ // construct uno value to be set
+ void * pArgs[1];
+ void * pArg = pArgs[0] = alloca( pTD->nSize );
+
+ sal_Bool bAssign;
+ if (pTD->eTypeClass == typelib_TypeClass_ANY)
+ {
+ uno_copyAndConvertData( pArg, SAL_CONST_CAST( Any *, &rValue ),
+ pTD, getReflection()->getCpp2Uno().get() );
+ bAssign = sal_True;
+ }
+ else if (typelib_typedescriptionreference_equals( rValue.getValueTypeRef(), pTD->pWeakRef ))
+ {
+ uno_copyAndConvertData( pArg, SAL_CONST_CAST( void *, rValue.getValue() ),
+ pTD, getReflection()->getCpp2Uno().get() );
+ bAssign = sal_True;
+ }
+ else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
+ {
+ Reference< XInterface > xObj;
+ bAssign = extract(
+ rValue, (typelib_InterfaceTypeDescription *)pTD, xObj,
+ getReflection() );
+ if (bAssign)
+ {
+ *(void **)pArg = getReflection()->getCpp2Uno().mapInterface(
+ xObj.get(), (typelib_InterfaceTypeDescription *)pTD );
+ }
+ }
+ else
+ {
+ typelib_TypeDescription * pValueTD = 0;
+ TYPELIB_DANGER_GET( &pValueTD, rValue.getValueTypeRef() );
+ // construct temp uno val to do proper assignment: todo opt
+ void * pTemp = alloca( pValueTD->nSize );
+ uno_copyAndConvertData(
+ pTemp, (void *)rValue.getValue(), pValueTD, getReflection()->getCpp2Uno().get() );
+ uno_constructData(
+ pArg, pTD );
+ // assignment does simple conversion
+ bAssign = uno_assignData(
+ pArg, pTD, pTemp, pValueTD, 0, 0, 0 );
+ uno_destructData(
+ pTemp, pValueTD, 0 );
+ TYPELIB_DANGER_RELEASE( pValueTD );
+ }
+
+ if (bAssign)
+ {
+ uno_Any aExc;
+ uno_Any * pExc = &aExc;
+ (*pUnoI->pDispatcher)( pUnoI, getTypeDescr(), 0, pArgs, &pExc );
+ (*pUnoI->release)( pUnoI );
+
+ uno_destructData( pArg, pTD, 0 );
+ checkException(
+ pExc,
+ *static_cast< Reference< XInterface > const * >(
+ rObj.getValue()));
+ return;
+ }
+ (*pUnoI->release)( pUnoI );
+
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal value given!") ),
+ *(const Reference< XInterface > *)rObj.getValue(), 1 );
+ }
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+}
+//__________________________________________________________________________________________________
+void IdlAttributeFieldImpl::set( const Any & rObj, const Any & rValue )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::IllegalAccessException, ::com::sun::star::uno::RuntimeException)
+{
+ IdlAttributeFieldImpl::set( const_cast< Any & >( rObj ), rValue );
+}
+
+void IdlAttributeFieldImpl::checkException(
+ uno_Any * exception, Reference< XInterface > const & context)
+{
+ if (exception != 0) {
+ Any e;
+ uno_any_destruct(&e, reinterpret_cast< uno_ReleaseFunc >(cpp_release));
+ uno_type_any_constructAndConvert(
+ &e, exception->pData, exception->pType,
+ getReflection()->getUno2Cpp().get());
+ uno_any_destruct(exception, 0);
+ if (e.isExtractableTo(
+ getCppuType(static_cast< RuntimeException const * >(0))))
+ {
+ cppu::throwException(e);
+ } else {
+ throw WrappedTargetRuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "non-RuntimeException occured when accessing an"
+ " interface type attribute")),
+ context, e);
+ }
+ }
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+class IdlInterfaceMethodImpl
+ : public IdlMemberImpl
+ , public XIdlMethod
+{
+ Sequence< Reference< XIdlClass > > * _pExceptionTypes;
+ Sequence< Reference< XIdlClass > > * _pParamTypes;
+ Sequence< ParamInfo > * _pParamInfos;
+
+public:
+ typelib_InterfaceMethodTypeDescription * getMethodTypeDescr()
+ { return (typelib_InterfaceMethodTypeDescription *)getTypeDescr(); }
+
+ IdlInterfaceMethodImpl( IdlReflectionServiceImpl * pReflection, const OUString & rName,
+ typelib_TypeDescription * pTypeDescr, typelib_TypeDescription * pDeclTypeDescr )
+ : IdlMemberImpl( pReflection, rName, pTypeDescr, pDeclTypeDescr )
+ , _pExceptionTypes( 0 )
+ , _pParamTypes( 0 )
+ , _pParamInfos( 0 )
+ {}
+ virtual ~IdlInterfaceMethodImpl();
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type & rType ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XTypeProvider
+ virtual Sequence< Type > SAL_CALL getTypes() throw (::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId() throw (::com::sun::star::uno::RuntimeException);
+
+ // XIdlMember
+ virtual Reference< XIdlClass > SAL_CALL getDeclaringClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+ // XIdlMethod
+ virtual Reference< XIdlClass > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlClass > > SAL_CALL getParameterTypes() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< ParamInfo > SAL_CALL getParameterInfos() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XIdlClass > > SAL_CALL getExceptionTypes() throw(::com::sun::star::uno::RuntimeException);
+ virtual MethodMode SAL_CALL getMode() throw(::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL invoke( const Any & rObj, Sequence< Any > & rArgs ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::reflection::InvocationTargetException, ::com::sun::star::uno::RuntimeException);
+};
+//__________________________________________________________________________________________________
+IdlInterfaceMethodImpl::~IdlInterfaceMethodImpl()
+{
+ delete _pParamInfos;
+ delete _pParamTypes;
+ delete _pExceptionTypes;
+}
+
+// XInterface
+//__________________________________________________________________________________________________
+Any IdlInterfaceMethodImpl::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface( rType, static_cast< XIdlMethod * >( this ) ) );
+ return (aRet.hasValue() ? aRet : IdlMemberImpl::queryInterface( rType ));
+}
+//__________________________________________________________________________________________________
+void IdlInterfaceMethodImpl::acquire() throw()
+{
+ IdlMemberImpl::acquire();
+}
+//__________________________________________________________________________________________________
+void IdlInterfaceMethodImpl::release() throw()
+{
+ IdlMemberImpl::release();
+}
+
+// XTypeProvider
+//__________________________________________________________________________________________________
+Sequence< Type > IdlInterfaceMethodImpl::getTypes()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIdlMethod > *)0 ),
+ IdlMemberImpl::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int8 > IdlInterfaceMethodImpl::getImplementationId()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+// XIdlMember
+//__________________________________________________________________________________________________
+Reference< XIdlClass > IdlInterfaceMethodImpl::getDeclaringClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _xDeclClass.is())
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _xDeclClass.is())
+ {
+ rtl::OUString aName(getMethodTypeDescr()->aBase.aBase.pTypeName);
+ sal_Int32 i = aName.indexOf(':');
+ OSL_ASSERT(i >= 0);
+ _xDeclClass = getReflection()->forName(aName.copy(0, i));
+ }
+ }
+ return _xDeclClass;
+}
+//__________________________________________________________________________________________________
+OUString IdlInterfaceMethodImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return IdlMemberImpl::getName();
+}
+
+// XIdlMethod
+//__________________________________________________________________________________________________
+Reference< XIdlClass > SAL_CALL IdlInterfaceMethodImpl::getReturnType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return getReflection()->forType( getMethodTypeDescr()->pReturnTypeRef );
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getExceptionTypes()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pExceptionTypes)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pExceptionTypes)
+ {
+ sal_Int32 nExc = getMethodTypeDescr()->nExceptions;
+ Sequence< Reference< XIdlClass > > * pTempExceptionTypes =
+ new Sequence< Reference< XIdlClass > >( nExc );
+ Reference< XIdlClass > * pExceptionTypes = pTempExceptionTypes->getArray();
+
+ typelib_TypeDescriptionReference ** ppExc =
+ getMethodTypeDescr()->ppExceptions;
+ IdlReflectionServiceImpl * pRefl = getReflection();
+
+ while (nExc--)
+ pExceptionTypes[nExc] = pRefl->forType( ppExc[nExc] );
+
+ _pExceptionTypes = pTempExceptionTypes;
+ }
+ }
+ return *_pExceptionTypes;
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlClass > > IdlInterfaceMethodImpl::getParameterTypes()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pParamTypes)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pParamTypes)
+ {
+ sal_Int32 nParams = getMethodTypeDescr()->nParams;
+ Sequence< Reference< XIdlClass > > * pTempParamTypes =
+ new Sequence< Reference< XIdlClass > >( nParams );
+ Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray();
+
+ typelib_MethodParameter * pTypelibParams =
+ getMethodTypeDescr()->pParams;
+ IdlReflectionServiceImpl * pRefl = getReflection();
+
+ while (nParams--)
+ pParamTypes[nParams] = pRefl->forType( pTypelibParams[nParams].pTypeRef );
+
+ _pParamTypes = pTempParamTypes;
+ }
+ }
+ return *_pParamTypes;
+}
+//__________________________________________________________________________________________________
+Sequence< ParamInfo > IdlInterfaceMethodImpl::getParameterInfos()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pParamInfos)
+ {
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pParamInfos)
+ {
+ sal_Int32 nParams = getMethodTypeDescr()->nParams;
+ Sequence< ParamInfo > * pTempParamInfos = new Sequence< ParamInfo >( nParams );
+ ParamInfo * pParamInfos = pTempParamInfos->getArray();
+
+ typelib_MethodParameter * pTypelibParams =
+ getMethodTypeDescr()->pParams;
+
+ if (_pParamTypes) // use param types
+ {
+ const Reference< XIdlClass > * pParamTypes = _pParamTypes->getConstArray();
+
+ while (nParams--)
+ {
+ const typelib_MethodParameter & rParam = pTypelibParams[nParams];
+ ParamInfo & rInfo = pParamInfos[nParams];
+ rInfo.aName = rParam.pName;
+ if (rParam.bIn)
+ rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN);
+ else
+ rInfo.aMode = ParamMode_OUT;
+ rInfo.aType = pParamTypes[nParams];
+ }
+ }
+ else // make also param types sequence if not already initialized
+ {
+ Sequence< Reference< XIdlClass > > * pTempParamTypes =
+ new Sequence< Reference< XIdlClass > >( nParams );
+ Reference< XIdlClass > * pParamTypes = pTempParamTypes->getArray();
+
+ IdlReflectionServiceImpl * pRefl = getReflection();
+
+ while (nParams--)
+ {
+ const typelib_MethodParameter & rParam = pTypelibParams[nParams];
+ ParamInfo & rInfo = pParamInfos[nParams];
+ rInfo.aName = rParam.pName;
+ if (rParam.bIn)
+ rInfo.aMode = (rParam.bOut ? ParamMode_INOUT : ParamMode_IN);
+ else
+ rInfo.aMode = ParamMode_OUT;
+ rInfo.aType = pParamTypes[nParams] = pRefl->forType( rParam.pTypeRef );
+ }
+
+ _pParamTypes = pTempParamTypes;
+ }
+
+ _pParamInfos = pTempParamInfos;
+ }
+ }
+ return *_pParamInfos;
+}
+//__________________________________________________________________________________________________
+MethodMode SAL_CALL IdlInterfaceMethodImpl::getMode()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return
+ getMethodTypeDescr()->bOneWay ? MethodMode_ONEWAY : MethodMode_TWOWAY;
+}
+//__________________________________________________________________________________________________
+Any SAL_CALL IdlInterfaceMethodImpl::invoke( const Any & rObj, Sequence< Any > & rArgs )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::reflection::InvocationTargetException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ if (rObj.getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ // acquire()/ release()
+ if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer,
+ "com.sun.star.uno.XInterface::acquire" ) == 0)
+ {
+ (*(const Reference< XInterface > *)rObj.getValue())->acquire();
+ return Any();
+ }
+ else if (rtl_ustr_ascii_compare( getTypeDescr()->pTypeName->buffer,
+ "com.sun.star.uno.XInterface::release" ) == 0)
+ {
+ (*(const Reference< XInterface > *)rObj.getValue())->release();
+ return Any();
+ }
+ }
+
+ uno_Interface * pUnoI = getReflection()->mapToUno(
+ rObj, (typelib_InterfaceTypeDescription *)getDeclTypeDescr() );
+ OSL_ENSURE( pUnoI, "### illegal destination object given!" );
+ if (pUnoI)
+ {
+ sal_Int32 nParams = getMethodTypeDescr()->nParams;
+ if (rArgs.getLength() != nParams)
+ {
+ (*pUnoI->release)( pUnoI );
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("arguments len differ!") ),
+ *(const Reference< XInterface > *)rObj.getValue(), 1 );
+ }
+
+ Any * pCppArgs = rArgs.getArray();
+ typelib_MethodParameter * pParams = getMethodTypeDescr()->pParams;
+ typelib_TypeDescription * pReturnType = 0;
+ TYPELIB_DANGER_GET(
+ &pReturnType, getMethodTypeDescr()->pReturnTypeRef );
+
+ void * pUnoReturn = alloca( pReturnType->nSize );
+ void ** ppUnoArgs = (void **)alloca( sizeof(void *) * nParams *2 );
+ typelib_TypeDescription ** ppParamTypes = (typelib_TypeDescription **)(ppUnoArgs + nParams);
+
+ // convert arguments
+ for ( sal_Int32 nPos = 0; nPos < nParams; ++nPos )
+ {
+ ppParamTypes[nPos] = 0;
+ TYPELIB_DANGER_GET( ppParamTypes + nPos, pParams[nPos].pTypeRef );
+ typelib_TypeDescription * pTD = ppParamTypes[nPos];
+
+ ppUnoArgs[nPos] = alloca( pTD->nSize );
+ if (pParams[nPos].bIn)
+ {
+ sal_Bool bAssign;
+ if (typelib_typedescriptionreference_equals(
+ pCppArgs[nPos].getValueTypeRef(), pTD->pWeakRef ))
+ {
+ uno_type_copyAndConvertData(
+ ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(),
+ pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() );
+ bAssign = sal_True;
+ }
+ else if (pTD->eTypeClass == typelib_TypeClass_ANY)
+ {
+ uno_type_any_constructAndConvert(
+ (uno_Any *)ppUnoArgs[nPos], (void *)pCppArgs[nPos].getValue(),
+ pCppArgs[nPos].getValueTypeRef(), getReflection()->getCpp2Uno().get() );
+ bAssign = sal_True;
+ }
+ else if (pTD->eTypeClass == typelib_TypeClass_INTERFACE)
+ {
+ Reference< XInterface > xDest;
+ bAssign = extract(
+ pCppArgs[nPos], (typelib_InterfaceTypeDescription *)pTD,
+ xDest, getReflection() );
+ if (bAssign)
+ {
+ *(void **)ppUnoArgs[nPos] = getReflection()->getCpp2Uno().mapInterface(
+ xDest.get(), (typelib_InterfaceTypeDescription *)pTD );
+ }
+ }
+ else
+ {
+ typelib_TypeDescription * pValueTD = 0;
+ TYPELIB_DANGER_GET( &pValueTD, pCppArgs[nPos].getValueTypeRef() );
+ // construct temp uno val to do proper assignment: todo opt
+ void * pTemp = alloca( pValueTD->nSize );
+ uno_copyAndConvertData(
+ pTemp, (void *)pCppArgs[nPos].getValue(), pValueTD,
+ getReflection()->getCpp2Uno().get() );
+ uno_constructData(
+ ppUnoArgs[nPos], pTD );
+ // assignment does simple conversion
+ bAssign = uno_assignData(
+ ppUnoArgs[nPos], pTD, pTemp, pValueTD, 0, 0, 0 );
+ uno_destructData(
+ pTemp, pValueTD, 0 );
+ TYPELIB_DANGER_RELEASE( pValueTD );
+ }
+
+ if (! bAssign)
+ {
+ IllegalArgumentException aExc(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot coerce argument type during corereflection call!") ),
+ *(const Reference< XInterface > *)rObj.getValue(), (sal_Int16)nPos );
+
+ // cleanup
+ while (nPos--)
+ {
+ if (pParams[nPos].bIn)
+ uno_destructData( ppUnoArgs[nPos], ppParamTypes[nPos], 0 );
+ TYPELIB_DANGER_RELEASE( ppParamTypes[nPos] );
+ }
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ (*pUnoI->release)( pUnoI );
+
+ throw aExc;
+ }
+ }
+ }
+
+ uno_Any aUnoExc;
+ uno_Any * pUnoExc = &aUnoExc;
+
+ (*pUnoI->pDispatcher)(
+ pUnoI, getTypeDescr(), pUnoReturn, ppUnoArgs, &pUnoExc );
+ (*pUnoI->release)( pUnoI );
+
+ Any aRet;
+ if (pUnoExc)
+ {
+ // cleanup
+ while (nParams--)
+ {
+ if (pParams[nParams].bIn)
+ uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 );
+ TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] );
+ }
+ TYPELIB_DANGER_RELEASE( pReturnType );
+
+ InvocationTargetException aExc;
+ aExc.Context = *(const Reference< XInterface > *)rObj.getValue();
+ aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("exception occured during invocation!") );
+ uno_any_destruct(
+ &aExc.TargetException,
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_type_copyAndConvertData(
+ &aExc.TargetException, pUnoExc, ::getCppuType( (const Any *)0 ).getTypeLibType(),
+ getReflection()->getUno2Cpp().get() );
+ uno_any_destruct( pUnoExc, 0 );
+ throw aExc;
+ }
+ else
+ {
+ // reconvert arguments and cleanup
+ while (nParams--)
+ {
+ if (pParams[nParams].bOut) // write back
+ {
+ uno_any_destruct(
+ &pCppArgs[nParams],
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_any_constructAndConvert(
+ &pCppArgs[nParams], ppUnoArgs[nParams], ppParamTypes[nParams],
+ getReflection()->getUno2Cpp().get() );
+ }
+ uno_destructData( ppUnoArgs[nParams], ppParamTypes[nParams], 0 );
+ TYPELIB_DANGER_RELEASE( ppParamTypes[nParams] );
+ }
+ uno_any_destruct(
+ &aRet, reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ uno_any_constructAndConvert(
+ &aRet, pUnoReturn, pReturnType,
+ getReflection()->getUno2Cpp().get() );
+ uno_destructData( pUnoReturn, pReturnType, 0 );
+ TYPELIB_DANGER_RELEASE( pReturnType );
+ }
+ return aRet;
+ }
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("illegal destination object given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//__________________________________________________________________________________________________
+InterfaceIdlClassImpl::~InterfaceIdlClassImpl()
+{
+ for ( sal_Int32 nPos = _nMethods + _nAttributes; nPos--; )
+ typelib_typedescription_release( _pSortedMemberInit[nPos].second );
+
+ delete [] _pSortedMemberInit;
+}
+
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlClass > > InterfaceIdlClassImpl::getSuperclasses()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard(getMutexAccess());
+ if (_xSuperClasses.getLength() == 0) {
+ typelib_InterfaceTypeDescription * pType = getTypeDescr();
+ _xSuperClasses.realloc(pType->nBaseTypes);
+ for (sal_Int32 i = 0; i < pType->nBaseTypes; ++i) {
+ _xSuperClasses[i] = getReflection()->forType(
+ &pType->ppBaseTypes[i]->aBase);
+ OSL_ASSERT(_xSuperClasses[i].is());
+ }
+ }
+ return Sequence< Reference< XIdlClass > >(_xSuperClasses);
+}
+//__________________________________________________________________________________________________
+void InterfaceIdlClassImpl::initMembers()
+{
+ sal_Int32 nAll = getTypeDescr()->nAllMembers;
+ MemberInit * pSortedMemberInit = new MemberInit[nAll];
+ typelib_TypeDescriptionReference ** ppAllMembers = getTypeDescr()->ppAllMembers;
+
+ for ( sal_Int32 nPos = 0; nPos < nAll; ++nPos )
+ {
+ sal_Int32 nIndex;
+ if (ppAllMembers[nPos]->eTypeClass == typelib_TypeClass_INTERFACE_METHOD)
+ {
+ // methods to front
+ nIndex = _nMethods;
+ ++_nMethods;
+ }
+ else
+ {
+ ++_nAttributes;
+ nIndex = (nAll - _nAttributes);
+ // attributes at the back
+ }
+
+ typelib_TypeDescription * pTD = 0;
+ typelib_typedescriptionreference_getDescription( &pTD, ppAllMembers[nPos] );
+ OSL_ENSURE( pTD, "### cannot get type description!" );
+ pSortedMemberInit[nIndex].first = ((typelib_InterfaceMemberTypeDescription *)pTD)->pMemberName;
+ pSortedMemberInit[nIndex].second = pTD;
+ }
+
+ _pSortedMemberInit = pSortedMemberInit;
+}
+//__________________________________________________________________________________________________
+sal_Bool InterfaceIdlClassImpl::isAssignableFrom( const Reference< XIdlClass > & xType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (xType.is() && xType->getTypeClass() == TypeClass_INTERFACE)
+ {
+ if (equals( xType ))
+ return sal_True;
+ else
+ {
+ const Sequence< Reference< XIdlClass > > & rSeq = xType->getSuperclasses();
+ for (sal_Int32 i = 0; i < rSeq.getLength(); ++i) {
+ if (isAssignableFrom(rSeq[i])) {
+ return true;
+ }
+ }
+ }
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Uik InterfaceIdlClassImpl::getUik()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Uik(0, 0, 0, 0, 0);
+ // Uiks are deprecated and this function must not be called
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlMethod > > InterfaceIdlClassImpl::getMethods()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pSortedMemberInit)
+ initMembers();
+
+ // create methods sequence
+ Sequence< Reference< XIdlMethod > > aRet( _nMethods );
+ Reference< XIdlMethod > * pRet = aRet.getArray();
+ for ( sal_Int32 nPos = _nMethods; nPos--; )
+ {
+
+ /*_aName2Method[_pSortedMemberInit[nPos].first] = */pRet[nPos] = new IdlInterfaceMethodImpl(
+ getReflection(), _pSortedMemberInit[nPos].first,
+ _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() );
+ }
+ return aRet;
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XIdlField > > InterfaceIdlClassImpl::getFields()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pSortedMemberInit)
+ initMembers();
+
+ // create fields sequence
+ Sequence< Reference< XIdlField > > aRet( _nAttributes );
+ Reference< XIdlField > * pRet = aRet.getArray();
+ for ( sal_Int32 nPos = _nAttributes; nPos--; )
+ {
+ /*_aName2Field[_pSortedMemberInit[_nMethods+nPos].first] = */pRet[_nAttributes-nPos-1] =
+ new IdlAttributeFieldImpl(
+ getReflection(), _pSortedMemberInit[_nMethods+nPos].first,
+ _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() );
+ }
+ return aRet;
+}
+//__________________________________________________________________________________________________
+Reference< XIdlMethod > InterfaceIdlClassImpl::getMethod( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pSortedMemberInit)
+ initMembers();
+
+ Reference< XIdlMethod > xRet;
+
+ // try weak map
+ const OUString2Method::const_iterator iFind( _aName2Method.find( rName ) );
+ if (iFind != _aName2Method.end())
+ xRet = (*iFind).second; // harden ref
+
+ if (! xRet.is())
+ {
+ for ( sal_Int32 nPos = _nMethods; nPos--; )
+ {
+ if (_pSortedMemberInit[nPos].first == rName)
+ {
+ _aName2Method[rName] = xRet = new IdlInterfaceMethodImpl(
+ getReflection(), rName,
+ _pSortedMemberInit[nPos].second, IdlClassImpl::getTypeDescr() );
+ break;
+ }
+ }
+ }
+ return xRet;
+}
+//__________________________________________________________________________________________________
+Reference< XIdlField > InterfaceIdlClassImpl::getField( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( getMutexAccess() );
+ if (! _pSortedMemberInit)
+ initMembers();
+
+ Reference< XIdlField > xRet;
+
+ // try weak map
+ const OUString2Field::const_iterator iFind( _aName2Field.find( rName ) );
+ if (iFind != _aName2Field.end())
+ xRet = (*iFind).second; // harden ref
+
+ if (! xRet.is())
+ {
+ for ( sal_Int32 nPos = _nAttributes; nPos--; )
+ {
+ if (_pSortedMemberInit[_nMethods+nPos].first == rName)
+ {
+ _aName2Field[rName] = xRet = new IdlAttributeFieldImpl(
+ getReflection(), rName,
+ _pSortedMemberInit[_nMethods+nPos].second, IdlClassImpl::getTypeDescr() );
+ break;
+ }
+ }
+ }
+ return xRet;
+}
+//__________________________________________________________________________________________________
+void InterfaceIdlClassImpl::createObject( Any & rObj )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ // interfaces cannot be constructed
+ rObj.clear();
+}
+
+}
+
+
diff --git a/stoc/source/corereflection/lrucache.hxx b/stoc/source/corereflection/lrucache.hxx
new file mode 100644
index 000000000000..98c5faf4586d
--- /dev/null
+++ b/stoc/source/corereflection/lrucache.hxx
@@ -0,0 +1,244 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _LRU_CACHE_HXX_
+#define _LRU_CACHE_HXX_
+
+// __CACHE_DIAGNOSE forces cache size to 4 and works only for OUString keys
+// #define __CACHE_DIAGNOSE 1
+
+#include <osl/mutex.hxx>
+#include "rtl/ustring.hxx"
+
+#include <hash_map>
+
+/** Implementation of a least recently used (lru) cache.
+ <br>
+ @author Daniel Boelzle
+*/
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+class LRU_Cache
+{
+ struct CacheEntry
+ {
+ t_Key aKey;
+ t_Val aVal;
+ CacheEntry * pPred;
+ CacheEntry * pSucc;
+ };
+ typedef ::std::hash_map< t_Key, CacheEntry *, t_KeyHash, t_KeyEqual > t_Key2Element;
+
+ mutable ::osl::Mutex _aCacheMutex;
+ sal_Int32 _nCachedElements;
+ t_Key2Element _aKey2Element;
+
+ CacheEntry * _pBlock;
+ mutable CacheEntry * _pHead;
+ mutable CacheEntry * _pTail;
+ inline void toFront( CacheEntry * pEntry ) const;
+
+public:
+ /** Constructor:
+ <br>
+ @param nCachedElements number of elements to be cached; default param set to 128
+ */
+ inline LRU_Cache( sal_Int32 nCachedElements = 128 );
+ /** Destructor: releases all cached elements and keys.
+ <br>
+ */
+ inline ~LRU_Cache();
+
+ /** Retrieves a value from the cache. Returns default constructed value,
+ if none was found.
+ <br>
+ @param rKey a key
+ @return value
+ */
+ inline t_Val getValue( const t_Key & rKey ) const;
+ /** Sets a value to be cached for given key.
+ <br>
+ @param rKey a key
+ @param rValue a value
+ */
+ inline void setValue( const t_Key & rKey, const t_Val & rValue );
+ /** Tests whether a value is cached for given key.
+ <br>
+ @param rKey a key
+ @return true, if value is cached
+ */
+ inline sal_Bool hasValue( const t_Key & rKey ) const;
+ /** Clears the cache, thus releasing all cached elements and keys.
+ <br>
+ */
+ inline void clear();
+};
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::LRU_Cache( sal_Int32 nCachedElements )
+#ifdef __CACHE_DIAGNOSE
+ : _nCachedElements( 4 )
+#else
+ : _nCachedElements( nCachedElements )
+#endif
+ , _pBlock( 0 )
+{
+ if (_nCachedElements > 0)
+ {
+ _pBlock = new CacheEntry[_nCachedElements];
+ _pHead = _pBlock;
+ _pTail = _pBlock + _nCachedElements -1;
+ for ( sal_Int32 nPos = _nCachedElements; nPos--; )
+ {
+ _pBlock[nPos].pPred = _pBlock + nPos -1;
+ _pBlock[nPos].pSucc = _pBlock + nPos +1;
+ }
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::~LRU_Cache()
+{
+ delete [] _pBlock;
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::toFront( CacheEntry * pEntry ) const
+{
+ if (pEntry != _pHead)
+ {
+ // cut out element
+ if (pEntry == _pTail)
+ {
+ _pTail = pEntry->pPred;
+ }
+ else
+ {
+ pEntry->pSucc->pPred = pEntry->pPred;
+ pEntry->pPred->pSucc = pEntry->pSucc;
+ }
+ // push to front
+ _pHead->pPred = pEntry;
+ pEntry->pSucc = _pHead;
+ _pHead = pEntry;
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline sal_Bool LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::hasValue( const t_Key & rKey ) const
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) );
+ return (iFind != _aKey2Element.end());
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline t_Val LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::getValue( const t_Key & rKey ) const
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) );
+ if (iFind != _aKey2Element.end())
+ {
+ CacheEntry * pEntry = (*iFind).second;
+ toFront( pEntry );
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> retrieved element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" from cache <\n" );
+#endif
+ return pEntry->aVal;
+ }
+ return t_Val();
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::setValue(
+ const t_Key & rKey, const t_Val & rValue )
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ if (_nCachedElements > 0)
+ {
+ const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) );
+
+ CacheEntry * pEntry;
+ if (iFind == _aKey2Element.end())
+ {
+ pEntry = _pTail; // erase last element
+#ifdef __CACHE_DIAGNOSE
+ if (pEntry->aKey.getLength())
+ {
+ OSL_TRACE( "> kicking element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" from cache <\n" );
+ }
+#endif
+ _aKey2Element.erase( pEntry->aKey );
+ _aKey2Element[ pEntry->aKey = rKey ] = pEntry;
+ }
+ else
+ {
+ pEntry = (*iFind).second;
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> replacing element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" in cache <\n" );
+#endif
+ }
+ pEntry->aVal = rValue;
+ toFront( pEntry );
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::clear()
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ _aKey2Element.clear();
+ for ( sal_Int32 nPos = _nCachedElements; nPos--; )
+ {
+ _pBlock[nPos].aKey = t_Key();
+ _pBlock[nPos].aVal = t_Val();
+ }
+ _nCachedElements = 0;
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> cleared cache <\n" );
+#endif
+}
+
+//==================================================================================================
+struct FctHashOUString : public ::std::unary_function< const ::rtl::OUString &, size_t >
+{
+ size_t operator()( const ::rtl::OUString & rKey ) const
+ { return rKey.hashCode(); }
+};
+
+/** Template instance for OUString keys, Any values.<br>
+*/
+typedef LRU_Cache< ::rtl::OUString, ::com::sun::star::uno::Any,
+ FctHashOUString, ::std::equal_to< ::rtl::OUString > >
+ LRU_CacheAnyByOUString;
+
+
+#endif
diff --git a/stoc/source/corereflection/makefile.mk b/stoc/source/corereflection/makefile.mk
new file mode 100644
index 000000000000..7156f6d63cc4
--- /dev/null
+++ b/stoc/source/corereflection/makefile.mk
@@ -0,0 +1,82 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = reflection.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = corefl
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/crefl.obj \
+ $(SLO)$/crbase.obj \
+ $(SLO)$/crarray.obj \
+ $(SLO)$/crcomp.obj \
+ $(SLO)$/criface.obj \
+ $(SLO)$/crenum.obj
+
+# internal compiler error with Forte 6 update 1 (x86)
+# to be reconsidered after compiler upgrade
+.IF "$(OS)$(CPU)"=="SOLARISI"
+NOOPTFILES += $(SLO)$/criface.obj
+.ENDIF
+
+SHL1TARGET= $(TARGET)
+SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1RPATH= URELIB
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/reflection.component
+
+$(MISC)/reflection.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ reflection.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt reflection.component
diff --git a/stoc/source/corereflection/reflection.component b/stoc/source/corereflection/reflection.component
new file mode 100644
index 000000000000..00772a448367
--- /dev/null
+++ b/stoc/source/corereflection/reflection.component
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.stoc.CoreReflection">
+ <service name="com.sun.star.reflection.CoreReflection"/>
+ <singleton name="com.sun.star.reflection.theCoreReflection"/>
+ </implementation>
+</component>
diff --git a/stoc/source/cppumaker.mk b/stoc/source/cppumaker.mk
new file mode 100644
index 000000000000..899c43292834
--- /dev/null
+++ b/stoc/source/cppumaker.mk
@@ -0,0 +1,41 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+.IF "$(BOOTSTRAP_SERVICE)" != ""
+# fully functional C++-UNO (no bridging); no types.rdb needed at runtime
+CPPUMAKERFLAGS =
+.ENDIF
+
+.IF "$(debug)" != ""
+
+# MSVC++: no inlining
+.IF "$(COM)" == "MSC"
+CFLAGS += -Ob0
+.ENDIF
+
+.ENDIF
+
diff --git a/stoc/source/defaultregistry/defaultregistry.cxx b/stoc/source/defaultregistry/defaultregistry.cxx
new file mode 100644
index 000000000000..b56e47698c02
--- /dev/null
+++ b/stoc/source/defaultregistry/defaultregistry.cxx
@@ -0,0 +1,1423 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/mutex.hxx>
+#ifndef _OSL_DIAGNOSE_HXX_
+#include <osl/diagnose.h>
+#endif
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase4.hxx>
+#include <cppuhelper/implbase3.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+#include <registry/registry.hxx>
+
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+
+#include <bootstrapservices.hxx>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+
+
+#define SERVICENAME "com.sun.star.registry.NestedRegistry"
+#define IMPLNAME "com.sun.star.comp.stoc.NestedRegistry"
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_bootstrap
+{
+Sequence< OUString > defreg_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString defreg_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+}
+
+namespace stoc_defreg
+{
+//*************************************************************************
+// NestedRegistryImpl
+//*************************************************************************
+class NestedKeyImpl;
+
+class NestedRegistryImpl : public WeakAggImplHelper4 < XSimpleRegistry, XInitialization, XServiceInfo, XEnumerationAccess >
+{
+public:
+ NestedRegistryImpl( );
+
+ ~NestedRegistryImpl();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any >& aArguments )
+ throw(Exception, RuntimeException);
+
+ // XSimpleRegistry
+ virtual OUString SAL_CALL getURL() throw(RuntimeException);
+ virtual void SAL_CALL open( const OUString& rURL, sal_Bool bReadOnly, sal_Bool bCreate ) throw(InvalidRegistryException, RuntimeException);
+ virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException);
+ virtual void SAL_CALL close( ) throw(InvalidRegistryException, RuntimeException);
+ virtual void SAL_CALL destroy( ) throw(InvalidRegistryException, RuntimeException);
+ virtual Reference< XRegistryKey > SAL_CALL getRootKey( ) throw(InvalidRegistryException, RuntimeException);
+ virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException);
+ virtual void SAL_CALL mergeKey( const OUString& aKeyName, const OUString& aUrl ) throw(InvalidRegistryException, MergeConflictException, RuntimeException);
+
+ // XEnumerationAccess
+ virtual Reference< XEnumeration > SAL_CALL createEnumeration( ) throw (RuntimeException);
+ virtual Type SAL_CALL getElementType( ) throw (RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements( ) throw (RuntimeException);
+
+ friend class NestedKeyImpl;
+protected:
+ Mutex m_mutex;
+ sal_uInt32 m_state;
+ Reference<XSimpleRegistry> m_localReg;
+ Reference<XSimpleRegistry> m_defaultReg;
+
+};
+
+//*************************************************************************
+// class NestedKeyImpl the implenetation of interface XRegistryKey
+//*************************************************************************
+class NestedKeyImpl : public WeakImplHelper1< XRegistryKey >
+{
+public:
+ NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
+ Reference<XRegistryKey>& localKey,
+ Reference<XRegistryKey>& defaultKey);
+
+ NestedKeyImpl( const OUString& aKeyName,
+ NestedKeyImpl* pKey);
+
+ ~NestedKeyImpl();
+
+ // XRegistryKey
+ virtual OUString SAL_CALL getKeyName() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL isReadOnly( ) throw(InvalidRegistryException, RuntimeException);
+ virtual sal_Bool SAL_CALL isValid( ) throw(RuntimeException);
+ virtual RegistryKeyType SAL_CALL getKeyType( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException);
+ virtual RegistryValueType SAL_CALL getValueType( ) throw(InvalidRegistryException, RuntimeException);
+ virtual sal_Int32 SAL_CALL getLongValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
+ virtual void SAL_CALL setLongValue( sal_Int32 value ) throw(InvalidRegistryException, RuntimeException);
+ virtual Sequence< sal_Int32 > SAL_CALL getLongListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
+ virtual void SAL_CALL setLongListValue( const ::com::sun::star::uno::Sequence< sal_Int32 >& seqValue ) throw(InvalidRegistryException, RuntimeException);
+ virtual OUString SAL_CALL getAsciiValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
+ virtual void SAL_CALL setAsciiValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getAsciiListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
+ virtual void SAL_CALL setAsciiListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException);
+ virtual OUString SAL_CALL getStringValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
+ virtual void SAL_CALL setStringValue( const OUString& value ) throw(InvalidRegistryException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getStringListValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
+ virtual void SAL_CALL setStringListValue( const ::com::sun::star::uno::Sequence< OUString >& seqValue ) throw(InvalidRegistryException, RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getBinaryValue( ) throw(InvalidRegistryException, InvalidValueException, RuntimeException);
+ virtual void SAL_CALL setBinaryValue( const ::com::sun::star::uno::Sequence< sal_Int8 >& value ) throw(InvalidRegistryException, RuntimeException);
+ virtual Reference< XRegistryKey > SAL_CALL openKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
+ virtual Reference< XRegistryKey > SAL_CALL createKey( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
+ virtual void SAL_CALL closeKey( ) throw(InvalidRegistryException, RuntimeException);
+ virtual void SAL_CALL deleteKey( const OUString& rKeyName ) throw(InvalidRegistryException, RuntimeException);
+ virtual Sequence< Reference< XRegistryKey > > SAL_CALL openKeys( ) throw(InvalidRegistryException, RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getKeyNames( ) throw(InvalidRegistryException, RuntimeException);
+ virtual sal_Bool SAL_CALL createLink( const OUString& aLinkName, const OUString& aLinkTarget ) throw(InvalidRegistryException, RuntimeException);
+ virtual void SAL_CALL deleteLink( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException);
+ virtual OUString SAL_CALL getLinkTarget( const OUString& rLinkName ) throw(InvalidRegistryException, RuntimeException);
+ virtual OUString SAL_CALL getResolvedName( const OUString& aKeyName ) throw(InvalidRegistryException, RuntimeException);
+
+protected:
+ void computeChanges();
+ OUString computeName(const OUString& name);
+
+ OUString m_name;
+ sal_uInt32 m_state;
+ NestedRegistryImpl* m_pRegistry;
+ Reference<XRegistryKey> m_localKey;
+ Reference<XRegistryKey> m_defaultKey;
+};
+
+
+//*************************************************************************
+NestedKeyImpl::NestedKeyImpl( NestedRegistryImpl* pDefaultRegistry,
+ Reference<XRegistryKey>& localKey,
+ Reference<XRegistryKey>& defaultKey )
+ : m_pRegistry(pDefaultRegistry)
+{
+ m_pRegistry->acquire();
+
+ m_localKey = localKey;
+ m_defaultKey = defaultKey;
+
+ if (m_localKey.is())
+ {
+ m_name = m_localKey->getKeyName();
+ } else
+ if (m_defaultKey.is())
+ {
+ m_name = m_defaultKey->getKeyName();
+ }
+
+ m_state = m_pRegistry->m_state;
+}
+
+//*************************************************************************
+NestedKeyImpl::NestedKeyImpl( const OUString& rKeyName,
+ NestedKeyImpl* pKey)
+ : m_pRegistry(pKey->m_pRegistry)
+{
+ m_pRegistry->acquire();
+
+ if (pKey->m_localKey.is() && pKey->m_localKey->isValid())
+ {
+ m_localKey = pKey->m_localKey->openKey(rKeyName);
+ }
+ if (pKey->m_defaultKey.is() && pKey->m_defaultKey->isValid())
+ {
+ m_defaultKey = pKey->m_defaultKey->openKey(rKeyName);
+ }
+
+ if (m_localKey.is())
+ {
+ m_name = m_localKey->getKeyName();
+ } else
+ if (m_defaultKey.is())
+ {
+ m_name = m_defaultKey->getKeyName();
+ }
+
+ m_state = m_pRegistry->m_state;
+}
+
+//*************************************************************************
+NestedKeyImpl::~NestedKeyImpl()
+{
+ if ( m_pRegistry )
+ m_pRegistry->release();
+}
+
+//*************************************************************************
+void NestedKeyImpl::computeChanges()
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( m_state != m_pRegistry->m_state )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+
+ Reference<XRegistryKey> tmpKey = rootKey->openKey(m_name);
+
+ if ( tmpKey.is() )
+ {
+ m_localKey = rootKey->openKey(m_name);
+ }
+
+ m_state = m_pRegistry->m_state;
+ }
+}
+
+//*************************************************************************
+// NestedKey_Impl::computeName()
+//
+OUString NestedKeyImpl::computeName(const OUString& name)
+{
+ OUString resLocalName, resDefaultName;
+
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ try
+ {
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ resLocalName = m_localKey->getResolvedName(name);
+ } else
+ {
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ return m_defaultKey->getResolvedName(name);
+ }
+
+ if ( resLocalName.getLength() > 0 && m_pRegistry->m_defaultReg->isValid() )
+ {
+ Reference<XRegistryKey> localRoot(m_pRegistry->m_localReg->getRootKey());
+ Reference<XRegistryKey> defaultRoot(m_pRegistry->m_defaultReg->getRootKey());
+
+ resDefaultName = defaultRoot->getResolvedName(resLocalName);
+
+ sal_uInt32 count = 100;
+
+ while (resLocalName != resDefaultName && count > 0)
+ {
+ count--;
+
+ if (resLocalName.getLength() == 0 || resDefaultName.getLength() == 0)
+ throw InvalidRegistryException();
+
+ resLocalName = localRoot->getResolvedName(resDefaultName);
+ resDefaultName = defaultRoot->getResolvedName(resLocalName);
+ }
+ }
+ }
+ catch(InvalidRegistryException& )
+ {
+ }
+
+ return resLocalName;
+}
+
+//*************************************************************************
+OUString SAL_CALL NestedKeyImpl::getKeyName() throw(RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ return m_name;
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL NestedKeyImpl::isReadOnly( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ return m_localKey->isReadOnly();
+ else
+ throw InvalidRegistryException();
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL NestedKeyImpl::isValid( ) throw(RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ return ((m_localKey.is() && m_localKey->isValid()) ||
+ (m_defaultKey.is() && m_defaultKey->isValid()) );
+}
+
+//*************************************************************************
+RegistryKeyType SAL_CALL NestedKeyImpl::getKeyType( const OUString& rKeyName )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getKeyType(rKeyName);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getKeyType(rKeyName);
+ }
+
+ return RegistryKeyType_KEY;
+}
+
+//*************************************************************************
+RegistryValueType SAL_CALL NestedKeyImpl::getValueType( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getValueType();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getValueType();
+ }
+
+ return RegistryValueType_NOT_DEFINED;
+}
+
+//*************************************************************************
+sal_Int32 SAL_CALL NestedKeyImpl::getLongValue( )
+ throw(InvalidRegistryException, InvalidValueException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getLongValue();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getLongValue();
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::setLongValue( sal_Int32 value )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->setLongValue(value);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+ m_localKey->setLongValue(value);
+ m_state = m_pRegistry->m_state++;
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+Sequence< sal_Int32 > SAL_CALL NestedKeyImpl::getLongListValue( )
+ throw(InvalidRegistryException, InvalidValueException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getLongListValue();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getLongListValue();
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::setLongListValue( const Sequence< sal_Int32 >& seqValue )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->setLongListValue(seqValue);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+ m_localKey->setLongListValue(seqValue);
+ m_state = m_pRegistry->m_state++;
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+OUString SAL_CALL NestedKeyImpl::getAsciiValue( )
+ throw(InvalidRegistryException, InvalidValueException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getAsciiValue();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getAsciiValue();
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::setAsciiValue( const OUString& value )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->setAsciiValue(value);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+ m_localKey->setAsciiValue(value);
+ m_state = m_pRegistry->m_state++;
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+Sequence< OUString > SAL_CALL NestedKeyImpl::getAsciiListValue( )
+ throw(InvalidRegistryException, InvalidValueException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getAsciiListValue();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getAsciiListValue();
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::setAsciiListValue( const Sequence< OUString >& seqValue )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->setAsciiListValue(seqValue);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+ m_localKey->setAsciiListValue(seqValue);
+ m_state = m_pRegistry->m_state++;
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+OUString SAL_CALL NestedKeyImpl::getStringValue( )
+ throw(InvalidRegistryException, InvalidValueException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getStringValue();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getStringValue();
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::setStringValue( const OUString& value )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->setStringValue(value);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+ m_localKey->setStringValue(value);
+ m_state = m_pRegistry->m_state++;
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+Sequence< OUString > SAL_CALL NestedKeyImpl::getStringListValue( )
+ throw(InvalidRegistryException, InvalidValueException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getStringListValue();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getStringListValue();
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::setStringListValue( const Sequence< OUString >& seqValue )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->setStringListValue(seqValue);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+ m_localKey->setStringListValue(seqValue);
+ m_state = m_pRegistry->m_state++;
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+Sequence< sal_Int8 > SAL_CALL NestedKeyImpl::getBinaryValue( )
+ throw(InvalidRegistryException, InvalidValueException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ return m_localKey->getBinaryValue();
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ return m_defaultKey->getBinaryValue();
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::setBinaryValue( const Sequence< sal_Int8 >& value )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ computeChanges();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->setBinaryValue(value);
+ } else
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+ m_localKey->setBinaryValue(value);
+ m_state = m_pRegistry->m_state++;
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+Reference< XRegistryKey > SAL_CALL NestedKeyImpl::openKey( const OUString& aKeyName )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( !m_localKey.is() && !m_defaultKey.is() )
+ {
+ throw InvalidRegistryException();
+ }
+
+ OUString resolvedName = computeName(aKeyName);
+
+ if ( resolvedName.getLength() == 0 )
+ throw InvalidRegistryException();
+
+ Reference<XRegistryKey> localKey, defaultKey;
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ localKey = m_pRegistry->m_localReg->getRootKey()->openKey(resolvedName);
+ }
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
+ }
+
+ if ( localKey.is() || defaultKey.is() )
+ {
+ return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
+ } else
+ {
+ return Reference<XRegistryKey>();
+ }
+}
+
+//*************************************************************************
+Reference< XRegistryKey > SAL_CALL NestedKeyImpl::createKey( const OUString& aKeyName )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( (!m_localKey.is() && !m_defaultKey.is()) ||
+ (m_localKey.is() && m_localKey->isReadOnly()) )
+ {
+ throw InvalidRegistryException();
+ }
+
+ OUString resolvedName = computeName(aKeyName);
+
+ if ( resolvedName.getLength() == 0 )
+ throw InvalidRegistryException();
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ Reference<XRegistryKey> localKey, defaultKey;
+
+ localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName);
+ if ( localKey.is() )
+ {
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
+ }
+
+ m_state = m_pRegistry->m_state++;
+
+ return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
+ }
+ } else
+ {
+ Reference<XRegistryKey> localKey, defaultKey;
+
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+
+ localKey = m_pRegistry->m_localReg->getRootKey()->createKey(resolvedName);
+
+ if ( localKey.is() )
+ {
+ defaultKey = m_pRegistry->m_defaultReg->getRootKey()->openKey(resolvedName);
+
+ m_state = m_pRegistry->m_state++;
+
+ return ((XRegistryKey*)new NestedKeyImpl(m_pRegistry, localKey, defaultKey));
+ }
+ }
+ }
+
+ return Reference<XRegistryKey>();
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::closeKey( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ m_localKey->closeKey();
+ }
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ m_defaultKey->closeKey();
+ }
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::deleteKey( const OUString& rKeyName )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( m_localKey.is() && m_localKey->isValid() &&
+ !m_localKey->isReadOnly() )
+ {
+ OUString resolvedName = computeName(rKeyName);
+
+ if ( resolvedName.getLength() == 0 )
+ {
+ throw InvalidRegistryException();
+ }
+
+ m_pRegistry->m_localReg->getRootKey()->deleteKey(resolvedName);
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+Sequence< Reference< XRegistryKey > > SAL_CALL NestedKeyImpl::openKeys( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( !m_localKey.is() && !m_defaultKey.is() )
+ {
+ throw InvalidRegistryException();
+ }
+
+ Sequence<OUString> localSeq, defaultSeq;
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ localSeq = m_localKey->getKeyNames();
+ }
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ defaultSeq = m_defaultKey->getKeyNames();
+ }
+
+ sal_uInt32 local = localSeq.getLength();
+ sal_uInt32 def = defaultSeq.getLength();
+ sal_uInt32 len = 0;
+
+ sal_uInt32 i, j;
+ for (i=0; i < local; i++)
+ {
+ for (j=0 ; j < def; j++)
+ {
+ if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
+ {
+ len++;
+ break;
+ }
+ }
+ }
+
+ Sequence< Reference<XRegistryKey> > retSeq(local + def - len);
+ sal_Bool insert = sal_True;
+ OUString name;
+ sal_Int32 lastIndex;
+
+ for (i=0; i < local; i++)
+ {
+ name = localSeq.getConstArray()[i];
+ lastIndex = name.lastIndexOf('/');
+ name = name.copy(lastIndex);
+ retSeq.getArray()[i] =
+ (XRegistryKey*)new NestedKeyImpl(name, this);
+ }
+
+ sal_uInt32 k = local;
+ for (i=0; i < def; i++)
+ {
+ insert = sal_True;
+
+ for (j=0 ; j < local; j++)
+ {
+ if ( retSeq.getConstArray()[j]->getKeyName()
+ == defaultSeq.getConstArray()[i] )
+ {
+ insert = sal_False;
+ break;
+ }
+ }
+
+ if ( insert )
+ {
+ name = defaultSeq.getConstArray()[i];
+ lastIndex = name.lastIndexOf('/');
+ name = name.copy(lastIndex);
+ retSeq.getArray()[k++] =
+ (XRegistryKey*)new NestedKeyImpl(name, this);
+ }
+ }
+
+ return retSeq;
+}
+
+//*************************************************************************
+Sequence< OUString > SAL_CALL NestedKeyImpl::getKeyNames( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( !m_localKey.is() && !m_defaultKey.is() )
+ {
+ throw InvalidRegistryException();
+ }
+
+ Sequence<OUString> localSeq, defaultSeq;
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ localSeq = m_localKey->getKeyNames();
+ }
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ defaultSeq = m_defaultKey->getKeyNames();
+ }
+
+ sal_uInt32 local = localSeq.getLength();
+ sal_uInt32 def = defaultSeq.getLength();
+ sal_uInt32 len = 0;
+
+ sal_uInt32 i, j;
+ for (i=0; i < local; i++)
+ {
+ for (j=0 ; j < def; j++)
+ {
+ if ( localSeq.getConstArray()[i] == defaultSeq.getConstArray()[j] )
+ {
+ len++;
+ break;
+ }
+ }
+ }
+
+ Sequence<OUString> retSeq(local + def - len);
+ sal_Bool insert = sal_True;
+
+ for (i=0; i < local; i++)
+ {
+ retSeq.getArray()[i] = localSeq.getConstArray()[i];
+ }
+
+ sal_uInt32 k = local;
+ for (i=0; i < def; i++)
+ {
+ insert = sal_True;
+
+ for (j=0 ; j < local; j++)
+ {
+ if ( retSeq.getConstArray()[j] == defaultSeq.getConstArray()[i] )
+ {
+ insert = sal_False;
+ break;
+ }
+ }
+
+ if ( insert )
+ retSeq.getArray()[k++] = defaultSeq.getConstArray()[i];
+ }
+
+ return retSeq;
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL NestedKeyImpl::createLink( const OUString& aLinkName, const OUString& aLinkTarget )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+
+ sal_Bool isCreated = sal_False;
+ if ( !m_localKey.is() && !m_defaultKey.is() )
+ {
+ throw InvalidRegistryException();
+ }
+
+ OUString linkName;
+ OUString resolvedName;
+ sal_Int32 lastIndex = aLinkName.lastIndexOf('/');
+
+ if ( lastIndex > 0 )
+ {
+ linkName = aLinkName.copy(0, lastIndex);
+
+ resolvedName = computeName(linkName);
+
+ if ( resolvedName.getLength() == 0 )
+ {
+ throw InvalidRegistryException();
+ }
+
+ resolvedName = resolvedName + aLinkName.copy(lastIndex);
+ } else
+ {
+ if ( lastIndex == 0 )
+ resolvedName = m_name + aLinkName;
+ else
+ resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + aLinkName;
+ }
+
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
+ } else
+ {
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ {
+ Reference<XRegistryKey> rootKey(m_pRegistry->m_localReg->getRootKey());
+ m_localKey = rootKey->createKey(m_name);
+
+ isCreated = m_pRegistry->m_localReg->getRootKey()->createLink(resolvedName, aLinkTarget);
+ }
+ }
+
+ if ( isCreated )
+ m_state = m_pRegistry->m_state++;
+
+ return isCreated;
+}
+
+//*************************************************************************
+void SAL_CALL NestedKeyImpl::deleteLink( const OUString& rLinkName )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( !m_localKey.is() && !m_defaultKey.is() )
+ {
+ throw InvalidRegistryException();
+ }
+
+ OUString linkName;
+ OUString resolvedName;
+ sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
+
+ if ( lastIndex > 0 )
+ {
+ linkName = rLinkName.copy(0, lastIndex);
+
+ resolvedName = computeName(linkName);
+
+ if ( resolvedName.getLength() == 0 )
+ {
+ throw InvalidRegistryException();
+ }
+
+ resolvedName = resolvedName + rLinkName.copy(lastIndex);
+ } else
+ {
+ if ( lastIndex == 0 )
+ resolvedName = m_name + rLinkName;
+ else
+ resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName;
+ }
+
+ if ( m_localKey.is() && m_localKey->isValid() &&
+ !m_localKey->isReadOnly() )
+ {
+ m_pRegistry->m_localReg->getRootKey()->deleteLink(resolvedName);
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+}
+
+//*************************************************************************
+OUString SAL_CALL NestedKeyImpl::getLinkTarget( const OUString& rLinkName )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( !m_localKey.is() && !m_defaultKey.is() )
+ {
+ throw InvalidRegistryException();
+ }
+
+ OUString linkName;
+ OUString resolvedName;
+ sal_Int32 lastIndex = rLinkName.lastIndexOf('/');
+
+ if ( lastIndex > 0 )
+ {
+ linkName = rLinkName.copy(0, lastIndex);
+
+ resolvedName = computeName(linkName);
+
+ if ( resolvedName.getLength() == 0 )
+ {
+ throw InvalidRegistryException();
+ }
+
+ resolvedName = resolvedName + rLinkName.copy(lastIndex);
+ } else
+ {
+ if ( lastIndex == 0 )
+ resolvedName = m_name + rLinkName;
+ else
+ resolvedName = m_name + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + rLinkName;
+ }
+
+ OUString linkTarget;
+ if ( m_localKey.is() && m_localKey->isValid() )
+ {
+ try
+ {
+ linkTarget = m_pRegistry->m_localReg->getRootKey()->getLinkTarget(resolvedName);
+ return linkTarget;
+ }
+ catch(InvalidRegistryException& )
+ {
+ }
+ }
+
+ if ( m_defaultKey.is() && m_defaultKey->isValid() )
+ linkTarget = m_pRegistry->m_defaultReg->getRootKey()->getLinkTarget(resolvedName);
+
+ return linkTarget;
+}
+
+//*************************************************************************
+OUString SAL_CALL NestedKeyImpl::getResolvedName( const OUString& aKeyName )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_pRegistry->m_mutex );
+ if ( !m_localKey.is() && !m_defaultKey.is() )
+ {
+ throw InvalidRegistryException();
+ }
+
+ OUString resolvedName = computeName(aKeyName);
+
+ if ( resolvedName.getLength() == 0 )
+ {
+ throw InvalidRegistryException();
+ }
+
+ return resolvedName;
+}
+
+//*************************************************************************
+//
+// DefaultRegistry Implementation
+//
+//*************************************************************************
+NestedRegistryImpl::NestedRegistryImpl( )
+ : m_state(0)
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+
+//*************************************************************************
+NestedRegistryImpl::~NestedRegistryImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+
+class RegistryEnumueration : public WeakImplHelper1< XEnumeration >
+{
+public:
+ RegistryEnumueration(
+ const Reference< XSimpleRegistry > &r1,
+ const Reference< XSimpleRegistry > &r2 )
+ : m_xReg1( r1 ) , m_xReg2( r2 )
+ {}
+public:
+ virtual sal_Bool SAL_CALL hasMoreElements( ) throw (RuntimeException);
+ virtual Any SAL_CALL nextElement( ) throw (NoSuchElementException, WrappedTargetException, RuntimeException);
+
+private:
+ Reference< XSimpleRegistry > m_xReg1;
+ Reference< XSimpleRegistry > m_xReg2;
+};
+
+sal_Bool RegistryEnumueration::hasMoreElements( ) throw (RuntimeException)
+{
+ return m_xReg1.is() || m_xReg2.is();
+}
+
+Any RegistryEnumueration::nextElement( )
+ throw (NoSuchElementException, WrappedTargetException, RuntimeException)
+{
+ Any a;
+ if( m_xReg1.is() )
+ {
+ a <<= m_xReg1;
+ m_xReg1.clear();
+ }
+ else if( m_xReg2.is() )
+ {
+ a <<= m_xReg2;
+ m_xReg2.clear();
+ }
+ else
+ {
+ throw NoSuchElementException( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "NestedRegistry: no nextElement() !" ) ),Reference< XInterface > () );
+ }
+ return a;
+}
+
+
+Reference< XEnumeration > NestedRegistryImpl::createEnumeration( ) throw (RuntimeException)
+{
+ MutexGuard guard( m_mutex );
+ return new RegistryEnumueration( m_localReg, m_defaultReg );
+}
+
+Type NestedRegistryImpl::getElementType( ) throw (RuntimeException)
+{
+ return getCppuType( &m_localReg );
+}
+
+sal_Bool SAL_CALL NestedRegistryImpl::hasElements( ) throw (RuntimeException)
+{
+ MutexGuard guard( m_mutex );
+ return m_localReg.is() || m_defaultReg.is();
+}
+
+
+
+//*************************************************************************
+OUString SAL_CALL NestedRegistryImpl::getImplementationName( )
+ throw(RuntimeException)
+{
+ return stoc_bootstrap::defreg_getImplementationName();
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL NestedRegistryImpl::supportsService( const OUString& ServiceName )
+ throw(RuntimeException)
+{
+ Guard< Mutex > aGuard( m_mutex );
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+//*************************************************************************
+Sequence<OUString> SAL_CALL NestedRegistryImpl::getSupportedServiceNames( )
+ throw(RuntimeException)
+{
+ return stoc_bootstrap::defreg_getSupportedServiceNames();
+}
+
+//*************************************************************************
+void SAL_CALL NestedRegistryImpl::initialize( const Sequence< Any >& aArguments )
+ throw( Exception, RuntimeException )
+{
+ Guard< Mutex > aGuard( m_mutex );
+ if ( (aArguments.getLength() == 2) &&
+ (aArguments[0].getValueType().getTypeClass() == TypeClass_INTERFACE) &&
+ (aArguments[1].getValueType().getTypeClass() == TypeClass_INTERFACE) )
+ {
+ aArguments[0] >>= m_localReg;
+ aArguments[1] >>= m_defaultReg;
+ if ( m_localReg == m_defaultReg )
+ m_defaultReg = Reference< XSimpleRegistry >();
+ }
+}
+
+//*************************************************************************
+OUString SAL_CALL NestedRegistryImpl::getURL() throw(RuntimeException)
+{
+ Guard< Mutex > aGuard( m_mutex );
+ try
+ {
+ if ( m_localReg.is() && m_localReg->isValid() )
+ return m_localReg->getURL();
+ }
+ catch(InvalidRegistryException& )
+ {
+ }
+
+ return OUString();
+}
+
+//*************************************************************************
+void SAL_CALL NestedRegistryImpl::open( const OUString&, sal_Bool, sal_Bool )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ throw InvalidRegistryException(
+ OUString::createFromAscii("the 'open' method is not specified for a nested registry"),
+ Reference< XInterface >() );
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL NestedRegistryImpl::isValid( ) throw(RuntimeException)
+{
+ Guard< Mutex > aGuard( m_mutex );
+ try
+ {
+ if ( (m_localReg.is() && m_localReg->isValid()) ||
+ (m_defaultReg.is() && m_defaultReg->isValid()) )
+ return sal_True;
+ }
+ catch(InvalidRegistryException& )
+ {
+ }
+
+ return sal_False;
+}
+
+//*************************************************************************
+void SAL_CALL NestedRegistryImpl::close( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_mutex );
+ if ( m_localReg.is() && m_localReg->isValid() )
+ {
+ m_localReg->close();
+ }
+ if ( m_defaultReg.is() && m_defaultReg->isValid() )
+ {
+ m_defaultReg->close();
+ }
+/*
+ throw InvalidRegistryException(
+ OUString::createFromAscii("the 'close' method is not specified for a nested registry"),
+ Reference< XInterface >() );
+*/
+}
+
+//*************************************************************************
+void SAL_CALL NestedRegistryImpl::destroy( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ throw InvalidRegistryException(
+ OUString::createFromAscii("the 'destroy' method is not specified for a nested registry"),
+ Reference< XInterface >() );
+}
+
+//*************************************************************************
+Reference< XRegistryKey > SAL_CALL NestedRegistryImpl::getRootKey( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Reference<XRegistryKey> tmpKey;
+
+ Guard< Mutex > aGuard( m_mutex );
+ if ( m_localReg.is() && m_localReg->isValid() )
+ {
+ Reference<XRegistryKey> localKey, defaultKey;
+
+ localKey = m_localReg->getRootKey();
+
+ if ( localKey.is() )
+ {
+ if ( m_defaultReg.is() && m_defaultReg->isValid() )
+ {
+ defaultKey = m_defaultReg->getRootKey();
+ }
+
+ return ((XRegistryKey*)new NestedKeyImpl(this, localKey, defaultKey));
+ }
+ } else
+ {
+ throw InvalidRegistryException();
+ }
+
+ return Reference<XRegistryKey>();
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL NestedRegistryImpl::isReadOnly( )
+ throw(InvalidRegistryException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_mutex );
+ try
+ {
+ if ( m_localReg.is() && m_localReg->isValid() )
+ return m_localReg->isReadOnly();
+ }
+ catch(InvalidRegistryException& )
+ {
+ }
+
+ return sal_False;
+}
+
+//*************************************************************************
+void SAL_CALL NestedRegistryImpl::mergeKey( const OUString& aKeyName, const OUString& aUrl )
+ throw(InvalidRegistryException, MergeConflictException, RuntimeException)
+{
+ Guard< Mutex > aGuard( m_mutex );
+ if ( m_localReg.is() && m_localReg->isValid() )
+ {
+ m_localReg->mergeKey(aKeyName, aUrl);
+
+ m_state++;
+ }
+}
+} // namespace stco_defreg
+
+namespace stoc_bootstrap
+{
+//*************************************************************************
+Reference<XInterface> SAL_CALL NestedRegistry_CreateInstance( const Reference<XComponentContext>& )
+ throw(Exception)
+{
+ Reference<XInterface> xRet;
+ XSimpleRegistry *pRegistry = (XSimpleRegistry*) new stoc_defreg::NestedRegistryImpl;
+
+ if (pRegistry)
+ {
+ xRet = Reference<XInterface>::query(pRegistry);
+ }
+
+ return xRet;
+}
+
+}
+
diff --git a/stoc/source/defaultregistry/makefile.mk b/stoc/source/defaultregistry/makefile.mk
new file mode 100644
index 000000000000..17f25999d169
--- /dev/null
+++ b/stoc/source/defaultregistry/makefile.mk
@@ -0,0 +1,46 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = nestedreg
+ENABLE_EXCEPTIONS=TRUE
+UNOUCROUT= $(OUT)$/inc$/bootstrap
+BOOTSTRAP_SERVICE=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/defaultregistry.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/stoc/source/implementationregistration/implreg.cxx b/stoc/source/implementationregistration/implreg.cxx
new file mode 100644
index 000000000000..cbb49c162fe1
--- /dev/null
+++ b/stoc/source/implementationregistration/implreg.cxx
@@ -0,0 +1,1925 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <stdlib.h>
+#include <string.h>
+#include <list>
+
+#include <unistd.h>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/servicefactory.hxx>
+#ifndef _CPPUHELPER_IMPLBASE3_HXX
+#include <cppuhelper/implbase3.hxx>
+#endif
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+
+#include <uno/mapping.hxx>
+#include <osl/thread.h>
+
+#include <rtl/ustring.hxx>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <osl/process.h>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/loader/XImplementationLoader.hpp>
+#include <com/sun/star/registry/XImplementationRegistration2.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/reflection/XServiceTypeDescription.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "mergekeys.hxx"
+
+#if defined(SAL_W32) || defined(SAL_OS2)
+#include <io.h>
+#endif
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::loader;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+
+#define IMPLNAME "com.sun.star.comp.stoc.ImplementationRegistration"
+#define SERVICENAME "com.sun.star.registry.ImplementationRegistration"
+namespace stoc_impreg
+{
+struct StringPool
+{
+ OUString sImplementationName;
+ OUString sServiceName;
+ OUString TMP;
+ OUString TEMP;
+ OUString slash_UNO_slash_REGISTRY_LINKS;
+ OUString slash_IMPLEMENTATIONS;
+ OUString slash_UNO;
+ OUString slash_UNO_slash_SERVICES;
+ OUString slash_UNO_slash_SINGLETONS;
+ OUString slash_SERVICES;
+ OUString slash_UNO_slash_LOCATION;
+ OUString slash_UNO_slash_ACTIVATOR;
+ OUString colon_old;
+ OUString com_sun_star_registry_SimpleRegistry;
+ OUString Registry;
+ StringPool()
+ : sImplementationName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) )
+ , sServiceName( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME ) )
+ , TMP( RTL_CONSTASCII_USTRINGPARAM( "TMP" ) )
+ , TEMP( RTL_CONSTASCII_USTRINGPARAM( "TEMP" ) )
+ , slash_UNO_slash_REGISTRY_LINKS( RTL_CONSTASCII_USTRINGPARAM("/UNO/REGISTRY_LINKS"))
+ , slash_IMPLEMENTATIONS( RTL_CONSTASCII_USTRINGPARAM( "/IMPLEMENTATIONS" ) )
+ , slash_UNO( RTL_CONSTASCII_USTRINGPARAM("/UNO"))
+ , slash_UNO_slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/UNO/SERVICES"))
+ , slash_UNO_slash_SINGLETONS( RTL_CONSTASCII_USTRINGPARAM("/UNO/SINGLETONS"))
+ , slash_SERVICES( RTL_CONSTASCII_USTRINGPARAM("/SERVICES/") )
+ , slash_UNO_slash_LOCATION( RTL_CONSTASCII_USTRINGPARAM("/UNO/LOCATION") )
+ , slash_UNO_slash_ACTIVATOR( RTL_CONSTASCII_USTRINGPARAM("/UNO/ACTIVATOR") )
+ , colon_old( RTL_CONSTASCII_USTRINGPARAM(":old"))
+ , com_sun_star_registry_SimpleRegistry(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry") )
+ , Registry( RTL_CONSTASCII_USTRINGPARAM("Registry") )
+ {}
+private:
+ StringPool( const StringPool & );
+};
+
+const StringPool &spool()
+{
+ static StringPool *pPool = 0;
+ if( ! pPool )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pPool )
+ {
+ static StringPool pool;
+ pPool = &pool;
+ }
+ }
+ return *pPool;
+}
+}
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_bootstrap
+{
+Sequence< OUString > impreg_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = stoc_impreg::spool().sServiceName;
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString impreg_getImplementationName()
+{
+ return stoc_impreg::spool().sImplementationName;
+}
+}
+
+namespace stoc_impreg
+{
+//*************************************************************************
+// static deleteAllLinkReferences()
+//
+static void deleteAllLinkReferences(const Reference < XSimpleRegistry >& xReg,
+ const Reference < XRegistryKey >& xSource)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ Reference < XRegistryKey > xKey = xSource->openKey(
+ spool().slash_UNO_slash_REGISTRY_LINKS );
+
+ if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
+ {
+ Sequence<OUString> linkNames = xKey->getAsciiListValue();
+
+ if (linkNames.getLength())
+ {
+ const OUString* pLinkNames = linkNames.getConstArray();
+
+ OUString aLinkName;
+ OUString aLinkParent;
+ Reference < XRegistryKey > xLinkParent;
+ const sal_Unicode* pTmpName = NULL;
+ const sal_Unicode* pShortName = NULL;
+ sal_Int32 sEnd = 0;
+
+ for (sal_Int32 i = 0; i < linkNames.getLength(); i++)
+ {
+ aLinkName = pLinkNames[i];
+
+ pTmpName = aLinkName.getStr();
+
+ if (pTmpName[0] != L'/')
+ continue;
+
+ sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
+ if ( nIndex == -1 )
+ pShortName = 0;
+ else
+ pShortName = pTmpName+nIndex;
+
+ while (pShortName && pShortName[1] == L'%')
+ {
+ nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
+ if ( nIndex == -1 )
+ pShortName = 0;
+ else
+ pShortName += nIndex+2;
+ }
+
+ if (pShortName)
+ {
+ aLinkName = aLinkName.copy(0, pShortName - pTmpName);
+ }
+
+ xReg->getRootKey()->deleteLink(aLinkName);
+
+ sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
+
+ aLinkParent = aLinkName.copy(0, sEnd);
+
+ while(aLinkParent.getLength())
+ {
+ xLinkParent = xReg->getRootKey()->openKey(aLinkParent);
+
+ if (xLinkParent.is() && (xLinkParent->getKeyNames().getLength() == 0))
+ {
+ aLinkName = aLinkParent;
+
+ xReg->getRootKey()->deleteKey(aLinkParent);
+
+ sEnd = rtl_ustr_lastIndexOfChar( aLinkName.getStr(), '/' );
+
+ aLinkParent = aLinkName.copy(0, sEnd);
+ } else
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+//*************************************************************************
+// static prepareLink
+//
+static void prepareLink( const Reference < XSimpleRegistry > & xDest,
+ const Reference < XRegistryKey > & xSource,
+ const OUString& link)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ OUString linkRefName = xSource->getKeyName();
+ OUString linkName(link);
+ sal_Bool isRelativ = sal_False;
+
+ const sal_Unicode* pTmpName = link.getStr();
+ const sal_Unicode* pShortName;
+ sal_Int32 nIndex = rtl_ustr_indexOfChar( pTmpName, '%' );
+ if ( nIndex == -1 )
+ pShortName = 0;
+ else
+ pShortName = pTmpName+nIndex;
+
+ if (pTmpName[0] != L'/')
+ isRelativ = sal_True;
+
+ while (pShortName && pShortName[1] == L'%')
+ {
+ nIndex = rtl_ustr_indexOfChar( pShortName+2, '%' );
+ if ( nIndex == -1 )
+ pShortName = 0;
+ else
+ pShortName += nIndex+2;
+ }
+
+ if (pShortName)
+ {
+ linkRefName = linkRefName + link.copy(pShortName - pTmpName + 1);
+ linkName = link.copy(0, pShortName - pTmpName);
+ }
+
+ if (isRelativ)
+ xSource->createLink(linkName, linkRefName);
+ else
+ xDest->getRootKey()->createLink(linkName, linkRefName);
+}
+
+//*************************************************************************
+// static searchImplForLink
+//
+static OUString searchImplForLink(
+ const Reference < XRegistryKey > & xRootKey,
+ const OUString& linkName,
+ const OUString& implName )
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ const StringPool & pool = spool();
+ Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
+ if (xKey.is())
+ {
+ Sequence< Reference < XRegistryKey > > subKeys( xKey->openKeys() );
+ const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
+ OUString key_name( pool.slash_UNO + linkName );
+
+ for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
+ {
+ try
+ {
+ Reference < XRegistryKey > xImplKey( pSubKeys[i] );
+ if (xImplKey->getKeyType( key_name ) == RegistryKeyType_LINK)
+ {
+ OUString oldImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
+ if (implName != oldImplName)
+ {
+ return oldImplName;
+ }
+ }
+ }
+ catch(InvalidRegistryException&)
+ {
+ }
+ }
+ }
+
+ return OUString();
+}
+
+//*************************************************************************
+// static searchLinkTargetForImpl
+//
+static OUString searchLinkTargetForImpl(const Reference < XRegistryKey >& xRootKey,
+ const OUString& linkName,
+ const OUString& implName)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ OUString ret;
+
+// try
+// {
+ const StringPool & pool = spool();
+ Reference < XRegistryKey > xKey = xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
+
+ if (xKey.is())
+ {
+ Sequence< Reference < XRegistryKey > > subKeys = xKey->openKeys();
+
+ const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
+ Reference < XRegistryKey > xImplKey;
+
+ for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
+ {
+ xImplKey = pSubKeys[i];
+
+ OUString tmpImplName = xImplKey->getKeyName().copy(strlen("/IMPLEMENTATIONS/"));
+ OUString qualifiedLinkName( pool.slash_UNO );
+ qualifiedLinkName += linkName;
+ if (tmpImplName == implName &&
+ xImplKey->getKeyType( qualifiedLinkName ) == RegistryKeyType_LINK)
+ {
+ return xImplKey->getLinkTarget( qualifiedLinkName );
+ }
+ }
+ }
+// }
+// catch(InvalidRegistryException&)
+// {
+// }
+
+ return ret;
+}
+
+//*************************************************************************
+// static createUniqueSubEntry
+//
+static void createUniqueSubEntry(const Reference < XRegistryKey > & xSuperKey,
+ const OUString& value)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ if (xSuperKey.is())
+ {
+// try
+// {
+ if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
+ {
+ sal_Int32 length = 0;
+ sal_Bool bReady = sal_False;
+
+ Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
+ length = implEntries.getLength();
+
+ for (sal_Int32 i = 0; !bReady && (i < length); i++)
+ {
+ bReady = (implEntries.getConstArray()[i] == value);
+ }
+
+ if (bReady)
+ {
+ Sequence<OUString> implEntriesNew(length);
+ implEntriesNew.getArray()[0] = value;
+
+ for (sal_Int32 i=0, j=1; i < length; i++)
+ {
+ if (implEntries.getConstArray()[i] != value)
+ implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
+ }
+ xSuperKey->setAsciiListValue(implEntriesNew);
+ } else
+ {
+ Sequence<OUString> implEntriesNew(length+1);
+ implEntriesNew.getArray()[0] = value;
+
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ implEntriesNew.getArray()[i+1] = implEntries.getConstArray()[i];
+ }
+ xSuperKey->setAsciiListValue(implEntriesNew);
+ }
+ } else
+ {
+ Sequence<OUString> implEntriesNew(1);
+
+ implEntriesNew.getArray()[0] = value;
+
+ xSuperKey->setAsciiListValue(implEntriesNew);
+ }
+// }
+// catch(InvalidRegistryException&)
+// {
+// }
+ }
+}
+
+//*************************************************************************
+// static deleteSubEntry
+//
+static sal_Bool deleteSubEntry(const Reference < XRegistryKey >& xSuperKey, const OUString& value)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ if (xSuperKey->getValueType() == RegistryValueType_ASCIILIST)
+ {
+ Sequence<OUString> implEntries = xSuperKey->getAsciiListValue();
+ sal_Int32 length = implEntries.getLength();
+ sal_Int32 equals = 0;
+ sal_Bool hasNoImplementations = sal_False;
+
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ if (implEntries.getConstArray()[i] == value)
+ equals++;
+ }
+
+ if (equals == length)
+ {
+ hasNoImplementations = sal_True;
+ } else
+ {
+ Sequence<OUString> implEntriesNew(length - equals);
+
+ sal_Int32 j = 0;
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ if (implEntries.getConstArray()[i] != value)
+ {
+ implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
+ }
+ }
+ xSuperKey->setAsciiListValue(implEntriesNew);
+ }
+
+ if (hasNoImplementations)
+ {
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+
+//*************************************************************************
+// static prepareUserLink
+//
+static void prepareUserLink(const Reference < XSimpleRegistry >& xDest,
+ const OUString& linkName,
+ const OUString& linkTarget,
+ const OUString& implName)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ sal_Bool ret = sal_False;
+
+ Reference < XRegistryKey > xRootKey;
+
+// try
+// {
+ xRootKey = xDest->getRootKey();
+
+ if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
+ {
+ OUString oldImplName(searchImplForLink(xRootKey, linkName, implName));
+
+ if (oldImplName.getLength())
+ {
+ createUniqueSubEntry(xDest->getRootKey()->createKey(
+ linkName + spool().colon_old ), oldImplName);
+ }
+ }
+// }
+// catch (InvalidRegistryException&)
+// {
+// }
+
+// try
+// {
+ if (xRootKey->isValid())
+ {
+ ret = xRootKey->createLink(linkName, linkTarget);
+ }
+// }
+// catch(InvalidRegistryException&)
+// {
+// }
+
+// return ret;
+}
+
+//*************************************************************************
+// static deleteUserLink
+//
+static void deletePathIfPossible(const Reference < XRegistryKey >& xRootKey,
+ const OUString& path)
+{
+ try
+ {
+ Sequence<OUString> keyNames(xRootKey->openKey(path)->getKeyNames());
+
+ if (keyNames.getLength() == 0 &&
+ xRootKey->openKey(path)->getValueType() == RegistryValueType_NOT_DEFINED)
+ {
+ xRootKey->deleteKey(path);
+
+ OUString tmpPath(path);
+ OUString newPath = tmpPath.copy(0, tmpPath.lastIndexOf('/'));
+
+ if (newPath.getLength() > 1)
+ deletePathIfPossible(xRootKey, newPath);
+ }
+ }
+ catch(InvalidRegistryException&)
+ {
+ }
+}
+
+
+//*************************************************************************
+// static deleteUserLink
+//
+static void deleteUserLink(const Reference < XRegistryKey >& xRootKey,
+ const OUString& linkName,
+ const OUString& linkTarget,
+ const OUString& implName)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ sal_Bool bClean = sal_False;
+
+ if (xRootKey->getKeyType(linkName) == RegistryKeyType_LINK)
+ {
+ OUString tmpTarget = xRootKey->getLinkTarget(linkName);
+
+ if (tmpTarget == linkTarget)
+ {
+ xRootKey->deleteLink(linkName);
+ }
+ }
+
+ Reference < XRegistryKey > xOldKey = xRootKey->openKey(
+ linkName + spool().colon_old );
+ if (xOldKey.is())
+ {
+ sal_Bool hasNoImplementations = sal_False;
+
+ if (xOldKey->getValueType() == RegistryValueType_ASCIILIST)
+ {
+ Sequence<OUString> implEntries = xOldKey->getAsciiListValue();
+ sal_Int32 length = implEntries.getLength();
+ sal_Int32 equals = 0;
+
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ if (implEntries.getConstArray()[i] == implName)
+ equals++;
+ }
+
+ if (equals == length)
+ {
+ hasNoImplementations = sal_True;
+ } else
+ {
+ OUString oldImpl;
+
+ if (length > equals + 1)
+ {
+ Sequence<OUString> implEntriesNew(length - equals - 1);
+
+ sal_Int32 j = 0;
+ sal_Bool first = sal_True;
+ for (sal_Int32 i = 0; i < length; i++)
+ {
+ if (implEntries.getConstArray()[i] != implName)
+ {
+ if (first)
+ {
+ oldImpl = implEntries.getConstArray()[i];
+ first = sal_False;
+ } else
+ {
+ implEntriesNew.getArray()[j++] = implEntries.getConstArray()[i];
+ }
+ }
+ }
+
+ xOldKey->setAsciiListValue(implEntriesNew);
+ } else
+ {
+ oldImpl = implEntries.getConstArray()[0];
+ rtl::OUString path(xOldKey->getKeyName());
+ xOldKey->closeKey();
+ xRootKey->deleteKey(path);
+ }
+
+ OUString oldTarget = searchLinkTargetForImpl(xRootKey, linkName, oldImpl);
+ if (oldTarget.getLength())
+ {
+ xRootKey->createLink(linkName, oldTarget);
+ }
+ }
+
+ if (hasNoImplementations)
+ {
+ bClean = sal_True;
+ hasNoImplementations = sal_False;
+ rtl::OUString path(xOldKey->getKeyName());
+ xOldKey->closeKey();
+ xRootKey->deleteKey(path);
+ }
+ }
+ } else
+ {
+ bClean = sal_True;
+ }
+
+ if (bClean)
+ {
+ OUString tmpName(linkName);
+ OUString path = tmpName.copy(0, tmpName.lastIndexOf('/'));
+ deletePathIfPossible(xRootKey, path);
+ }
+}
+
+//*************************************************************************
+// static prepareUserKeys
+//
+static void prepareUserKeys(const Reference < XSimpleRegistry >& xDest,
+ const Reference < XRegistryKey >& xUnoKey,
+ const Reference < XRegistryKey >& xKey,
+ const OUString& implName,
+ sal_Bool bRegister)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ sal_Bool hasSubKeys = sal_False;
+
+ Sequence<OUString> keyNames = xKey->getKeyNames();
+
+ OUString relativKey;
+ if (keyNames.getLength())
+ relativKey = keyNames.getConstArray()[0].copy(xKey->getKeyName().getLength()+1);
+
+ if (keyNames.getLength() == 1 &&
+ xKey->getKeyType(relativKey) == RegistryKeyType_LINK)
+ {
+ hasSubKeys = sal_True;
+
+ OUString linkTarget = xKey->getLinkTarget(relativKey);
+ OUString linkName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
+
+ linkName = linkName + OUString( RTL_CONSTASCII_USTRINGPARAM("/") ) + relativKey;
+
+ if (bRegister)
+ {
+ prepareUserLink(xDest, linkName, linkTarget, implName);
+ } else
+ {
+ deleteUserLink(xDest->getRootKey(), linkName, linkTarget, implName);
+ }
+ } else
+ {
+ Sequence< Reference < XRegistryKey> > subKeys = xKey->openKeys();
+
+ if (subKeys.getLength())
+ {
+ hasSubKeys = sal_True;
+ const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
+
+ for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
+ {
+ prepareUserKeys(xDest, xUnoKey, pSubKeys[i], implName, bRegister);
+ }
+ }
+ }
+
+ if (! hasSubKeys)
+ {
+ OUString keyName(xKey->getKeyName().copy(xUnoKey->getKeyName().getLength()));
+
+ Reference < XRegistryKey > xRootKey = xDest->getRootKey();
+ if (bRegister)
+ {
+ createUniqueSubEntry(xRootKey->createKey(keyName), implName);
+ }
+ else
+ {
+ Reference< XRegistryKey > rKey = xRootKey->openKey(keyName);
+ if( rKey.is() )
+ {
+ deleteSubEntry(rKey, implName);
+ xRootKey->deleteKey(keyName);
+ }
+
+ OUString path = keyName.copy(0, keyName.lastIndexOf('/'));
+ if( path.getLength() )
+ {
+ deletePathIfPossible(xRootKey, path);
+ }
+ }
+ }
+ return;
+}
+
+//*************************************************************************
+// static deleteAllImplementations
+//
+static void deleteAllImplementations( const Reference < XSimpleRegistry >& xReg,
+ const Reference < XRegistryKey >& xSource,
+ const OUString& locationUrl,
+ std::list<OUString> & implNames)
+ // throw (InvalidRegistryException, RuntimeException)
+{
+ Sequence < Reference < XRegistryKey > > subKeys = xSource->openKeys();
+
+ if (subKeys.getLength() > 0)
+ {
+ const Reference < XRegistryKey> * pSubKeys = subKeys.getConstArray();
+ Reference < XRegistryKey > xImplKey;
+ sal_Bool hasLocationUrl = sal_False;
+
+ const StringPool &pool = spool();
+ for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
+ {
+ xImplKey = pSubKeys[i];
+ Reference < XRegistryKey > xKey = xImplKey->openKey(
+ pool.slash_UNO_slash_LOCATION );
+
+ if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCII))
+ {
+ if (xKey->getAsciiValue() == locationUrl)
+ {
+ hasLocationUrl = sal_True;
+
+ OUString implName(xImplKey->getKeyName().getStr() + 1);
+ sal_Int32 firstDot = implName.indexOf('/');
+
+ if (firstDot >= 0)
+ implName = implName.copy(firstDot + 1);
+
+ implNames.push_back(implName);
+
+ deleteAllLinkReferences(xReg, xImplKey);
+
+ xKey = xImplKey->openKey( pool.slash_UNO );
+ if (xKey.is())
+ {
+ Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
+
+ if (subKeys2.getLength())
+ {
+ const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
+
+ for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
+ {
+ if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES ) &&
+ pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
+ pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_ACTIVATOR ) &&
+ pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ) &&
+ pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_LOCATION) )
+ {
+ prepareUserKeys(xReg, xKey, pSubKeys2[j], implName, sal_False);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (hasLocationUrl)
+ {
+ hasLocationUrl = sal_False;
+ rtl::OUString path(xImplKey->getKeyName());
+ xImplKey->closeKey();
+ xReg->getRootKey()->deleteKey(path);
+ }
+ }
+
+ subKeys = xSource->openKeys();
+ if (subKeys.getLength() == 0)
+ {
+ rtl::OUString path(xSource->getKeyName());
+ xSource->closeKey();
+ xReg->getRootKey()->deleteKey(path);
+ }
+ } else
+ {
+ rtl::OUString path(xSource->getKeyName());
+ xSource->closeKey();
+ xReg->getRootKey()->deleteKey(path);
+ }
+}
+
+//==================================================================================================
+static void delete_all_singleton_entries(
+ Reference < registry::XRegistryKey > const & xSingletons_section,
+ ::std::list< OUString > const & impl_names )
+ // throw (InvalidRegistryException, RuntimeException)
+{
+ Sequence< Reference< registry::XRegistryKey > > singletons( xSingletons_section->openKeys() );
+ Reference< registry::XRegistryKey > const * subkeys = singletons.getConstArray();
+ for ( sal_Int32 nPos = singletons.getLength(); nPos--; )
+ {
+ Reference< registry::XRegistryKey > const & xSingleton = subkeys[ nPos ];
+ Reference< registry::XRegistryKey > xRegisteredImplNames(
+ xSingleton->openKey( OUSTR("REGISTERED_BY") ) );
+ if (xRegisteredImplNames.is() && xRegisteredImplNames->isValid())
+ {
+ Sequence< OUString > registered_implnames;
+ try
+ {
+ registered_implnames = xRegisteredImplNames->getAsciiListValue();
+ }
+ catch (registry::InvalidValueException &)
+ {
+ }
+ OUString const * p = registered_implnames.getConstArray();
+ sal_Int32 nOrigRegLength = registered_implnames.getLength();
+ sal_Int32 nNewLength = nOrigRegLength;
+ for ( sal_Int32 n = nOrigRegLength; n--; )
+ {
+ OUString const & registered_implname = p[ n ];
+
+ ::std::list< OUString >::const_iterator iPos( impl_names.begin() );
+ ::std::list< OUString >::const_iterator const iEnd( impl_names.end() );
+ for ( ; iPos != iEnd; ++iPos )
+ {
+ if (iPos->equals( registered_implname ))
+ {
+ registered_implnames[ n ] = p[ nNewLength -1 ];
+ --nNewLength;
+ }
+ }
+ }
+
+ if (nNewLength != nOrigRegLength)
+ {
+ if (0 == nNewLength)
+ {
+ // remove whole entry
+ xRegisteredImplNames->closeKey();
+ xSingleton->deleteKey( OUSTR("REGISTERED_BY") );
+ // registry key cannot provide its relative name, only absolute :(
+ OUString abs( xSingleton->getKeyName() );
+ xSingletons_section->deleteKey( abs.copy( abs.lastIndexOf( '/' ) +1 ) );
+ }
+ else
+ {
+ registered_implnames.realloc( nNewLength );
+ xRegisteredImplNames->setAsciiListValue( registered_implnames );
+ }
+ }
+ }
+ }
+}
+
+//*************************************************************************
+// static deleteAllServiceEntries
+//
+static void deleteAllServiceEntries( const Reference < XSimpleRegistry >& xReg,
+ const Reference < XRegistryKey >& xSource,
+ const OUString& implName)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
+
+ if (subKeys.getLength() > 0)
+ {
+ const Reference < XRegistryKey > * pSubKeys = subKeys.getConstArray();
+ Reference < XRegistryKey > xServiceKey;
+ sal_Bool hasNoImplementations = sal_False;
+
+ for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
+ {
+ xServiceKey = pSubKeys[i];
+
+ if (xServiceKey->getValueType() == RegistryValueType_ASCIILIST)
+ {
+ Sequence<OUString> implEntries = xServiceKey->getAsciiListValue();
+ sal_Int32 length = implEntries.getLength();
+ sal_Int32 equals = 0;
+
+ for (sal_Int32 j = 0; j < length; j++)
+ {
+ if (implEntries.getConstArray()[j] == implName)
+ equals++;
+ }
+
+ if (equals == length)
+ {
+ hasNoImplementations = sal_True;
+ } else
+ {
+ if (equals > 0)
+ {
+ Sequence<OUString> implEntriesNew(length-equals);
+
+ sal_Int32 j = 0;
+ for (sal_Int32 k = 0; k < length; k++)
+ {
+ if (implEntries.getConstArray()[k] != implName)
+ {
+ implEntriesNew.getArray()[j++] = implEntries.getConstArray()[k];
+ }
+ }
+
+ xServiceKey->setAsciiListValue(implEntriesNew);
+ }
+ }
+ }
+
+ if (hasNoImplementations)
+ {
+ hasNoImplementations = sal_False;
+ rtl::OUString path(xServiceKey->getKeyName());
+ xServiceKey->closeKey();
+ xReg->getRootKey()->deleteKey(path);
+ }
+ }
+
+ subKeys = xSource->openKeys();
+ if (subKeys.getLength() == 0)
+ {
+ rtl::OUString path(xSource->getKeyName());
+ xSource->closeKey();
+ xReg->getRootKey()->deleteKey(path);
+ }
+ } else
+ {
+ rtl::OUString path(xSource->getKeyName());
+ xSource->closeKey();
+ xReg->getRootKey()->deleteKey(path);
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+static bool is_supported_service(
+ OUString const & service_name,
+ Reference< reflection::XServiceTypeDescription > const & xService_td )
+{
+ if (xService_td->getName().equals( service_name ))
+ return true;
+ Sequence< Reference< reflection::XServiceTypeDescription > > seq(
+ xService_td->getMandatoryServices() );
+ Reference< reflection::XServiceTypeDescription > const * p = seq.getConstArray();
+ for ( sal_Int32 nPos = seq.getLength(); nPos--; )
+ {
+ if (is_supported_service( service_name, p[ nPos ] ))
+ return true;
+ }
+ return false;
+}
+
+//--------------------------------------------------------------------------------------------------
+static void insert_singletons(
+ Reference< registry::XSimpleRegistry > const & xDest,
+ Reference< registry::XRegistryKey > const & xImplKey,
+ Reference< XComponentContext > const & xContext )
+ // throw( registry::InvalidRegistryException, registry::CannotRegisterImplementationException, RuntimeException )
+{
+ // singletons
+ Reference< registry::XRegistryKey > xKey( xImplKey->openKey( OUSTR("UNO/SINGLETONS") ) );
+ if (xKey.is() && xKey->isValid())
+ {
+ OUString implname( xImplKey->getKeyName().copy( sizeof ("/IMPLEMENTATIONS/") -1 ) );
+ // singleton entries
+ Sequence< Reference< registry::XRegistryKey > > xSingletons_section( xKey->openKeys() );
+ Reference< registry::XRegistryKey > const * p = xSingletons_section.getConstArray();
+ for ( sal_Int32 nPos = xSingletons_section.getLength(); nPos--; )
+ {
+ Reference< registry::XRegistryKey > const & xSingleton = p[ nPos ];
+ OUString singleton_name(
+ xSingleton->getKeyName().copy(
+ implname.getLength() + sizeof ("/IMPLEMENTATIONS//UNO/SINGLETONS/") -1 ) );
+ OUString service_name( xSingleton->getStringValue() );
+
+ OUString keyname( OUSTR("/SINGLETONS/") + singleton_name );
+ Reference< registry::XRegistryKey > xKey2( xDest->getRootKey()->openKey( keyname ) );
+ if (xKey2.is() && xKey2->isValid())
+ {
+ try
+ {
+ OUString existing_name( xKey2->getStringValue() );
+ if (! existing_name.equals( service_name ))
+ {
+ Reference< container::XHierarchicalNameAccess > xTDMgr;
+ OUString the_tdmgr =
+ OUSTR("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
+ xContext->getValueByName( the_tdmgr ) >>= xTDMgr;
+ if (! xTDMgr.is())
+ {
+ throw RuntimeException(
+ OUSTR("cannot get singleton ") + the_tdmgr,
+ Reference< XInterface >() );
+ }
+ try
+ {
+ Reference< reflection::XServiceTypeDescription > xExistingService_td;
+ xTDMgr->getByHierarchicalName( existing_name ) >>= xExistingService_td;
+ if (! xExistingService_td.is())
+ {
+ throw RuntimeException(
+ OUSTR("cannot get service type description: ") + existing_name,
+ Reference< XInterface >() );
+ }
+
+ // everything's fine if existing service entry supports the one
+ // to be registered
+ if (! is_supported_service( service_name, xExistingService_td ))
+ {
+ OUStringBuffer buf( 64 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("existing singleton service (") );
+ buf.append( singleton_name );
+ buf.append( (sal_Unicode)'=' );
+ buf.append( existing_name );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM(") does not support given one: ") );
+ buf.append( service_name );
+ throw registry::CannotRegisterImplementationException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+ }
+ catch (container::NoSuchElementException & exc)
+ {
+ throw RuntimeException(
+ OUSTR("cannot get service type description: ") + exc.Message,
+ Reference< XInterface >() );
+ }
+ }
+ }
+ catch (registry::InvalidValueException &)
+ {
+ // repair
+ xKey2->setStringValue( service_name );
+ }
+ }
+ else
+ {
+ // insert singleton entry
+ xKey2 = xDest->getRootKey()->createKey( keyname );
+ xKey2->setStringValue( service_name );
+ }
+
+ Reference< registry::XRegistryKey > xRegisteredImplNames(
+ xKey2->openKey( OUSTR("REGISTERED_BY") ) );
+ if (!xRegisteredImplNames.is() || !xRegisteredImplNames->isValid())
+ {
+ // create
+ xRegisteredImplNames = xKey2->createKey( OUSTR("REGISTERED_BY") );
+ }
+
+ Sequence< OUString > implnames;
+ try
+ {
+ implnames = xRegisteredImplNames->getAsciiListValue();
+ }
+ catch (registry::InvalidValueException &)
+ {
+ }
+ // check implname is already in
+ sal_Int32 nPos_implnames = implnames.getLength();
+ OUString const * pImplnames = implnames.getConstArray();
+ while (nPos_implnames--)
+ {
+ if (implname.equals( pImplnames[ nPos_implnames ] ))
+ break;
+ }
+ if (nPos_implnames < 0)
+ {
+ // append and write back
+ implnames.realloc( implnames.getLength() +1 );
+ implnames[ implnames.getLength() -1 ] = implname;
+ xRegisteredImplNames->setAsciiListValue( implnames );
+ }
+ }
+ }
+}
+
+
+//*************************************************************************
+// static prepareRegistry
+//
+static void prepareRegistry(
+ const Reference < XSimpleRegistry >& xDest,
+ const Reference < XRegistryKey >& xSource,
+ const OUString& implementationLoaderUrl,
+ const OUString& locationUrl,
+ Reference< XComponentContext > const & xContext )
+ // throw ( InvalidRegistryException, CannotRegisterImplementationException, RuntimeException )
+{
+ Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
+
+ if (!subKeys.getLength())
+ {
+ throw InvalidRegistryException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "prepareRegistry(): source registry is empty" ) ),
+ Reference< XInterface > () );
+ }
+
+ const StringPool & pool = spool();
+
+ const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
+ Reference < XRegistryKey > xImplKey;
+
+ for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
+ {
+ xImplKey = pSubKeys[i];
+
+ Reference < XRegistryKey > xKey = xImplKey->openKey(
+ pool.slash_UNO_slash_SERVICES );
+
+ if (xKey.is())
+ {
+ // update entries in SERVICES section
+ Sequence< Reference < XRegistryKey > > serviceKeys = xKey->openKeys();
+ const Reference < XRegistryKey > * pServiceKeys = serviceKeys.getConstArray();
+
+ OUString implName = OUString(xImplKey->getKeyName().getStr() + 1);
+ sal_Int32 firstDot = implName.indexOf('/');
+
+ if (firstDot >= 0)
+ implName = implName.copy(firstDot + 1);
+
+ sal_Int32 offset = xKey->getKeyName().getLength() + 1;
+
+ for (sal_Int32 j = 0; j < serviceKeys.getLength(); j++)
+ {
+ OUString serviceName = pServiceKeys[j]->getKeyName().copy(offset);
+
+ createUniqueSubEntry(
+ xDest->getRootKey()->createKey(
+ pool.slash_SERVICES + serviceName ),
+ implName);
+ }
+
+ xKey = xImplKey->openKey( pool.slash_UNO );
+ if (xKey.is())
+ {
+ Sequence< Reference < XRegistryKey > > subKeys2 = xKey->openKeys();
+
+ if (subKeys2.getLength())
+ {
+ const Reference < XRegistryKey > * pSubKeys2 = subKeys2.getConstArray();
+
+ for (sal_Int32 j = 0; j < subKeys2.getLength(); j++)
+ {
+ if (pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SERVICES) &&
+ pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_REGISTRY_LINKS ) &&
+ pSubKeys2[j]->getKeyName() != (xImplKey->getKeyName() + pool.slash_UNO_slash_SINGLETONS ))
+ {
+ prepareUserKeys(xDest, xKey, pSubKeys2[j], implName, sal_True);
+ }
+ }
+ }
+ }
+ }
+
+ // update LOCATION entry
+ xKey = xImplKey->createKey( pool.slash_UNO_slash_LOCATION );
+
+ if (xKey.is())
+ {
+ xKey->setAsciiValue(locationUrl);
+ }
+
+ // update ACTIVATOR entry
+ xKey = xImplKey->createKey( pool.slash_UNO_slash_ACTIVATOR );
+
+ if (xKey.is())
+ {
+ xKey->setAsciiValue(implementationLoaderUrl);
+ }
+
+ xKey = xImplKey->openKey( pool.slash_UNO_slash_SERVICES );
+
+ if (xKey.is() && (xKey->getValueType() == RegistryValueType_ASCIILIST))
+ {
+ // update link entries in REGISTRY_LINKS section
+ Sequence<OUString> linkNames = xKey->getAsciiListValue();
+
+ if (linkNames.getLength())
+ {
+ const OUString* pLinkNames = linkNames.getConstArray();
+
+ for (sal_Int32 j = 0; j < linkNames.getLength(); j++)
+ {
+ prepareLink(xDest, xImplKey, pLinkNames[j]);
+ }
+ }
+ }
+
+ insert_singletons( xDest, xImplKey, xContext );
+ }
+}
+
+
+static void findImplementations( const Reference < XRegistryKey > & xSource,
+ std::list <OUString>& implNames)
+{
+ sal_Bool isImplKey = sal_False;
+
+ try
+ {
+ Reference < XRegistryKey > xKey = xSource->openKey(
+ spool().slash_UNO_slash_SERVICES );
+
+ if (xKey.is() && (xKey->getKeyNames().getLength() > 0))
+ {
+ isImplKey = sal_True;
+
+ OUString implName = OUString(xSource->getKeyName().getStr() + 1).replace('/', '.').getStr();
+ sal_Int32 firstDot = implName.indexOf('.');
+
+ if (firstDot >= 0)
+ implName = implName.copy(firstDot + 1);
+
+ implNames.push_back(implName);
+ }
+ }
+ catch(InvalidRegistryException&)
+ {
+ }
+
+ if (isImplKey) return;
+
+ try
+ {
+ Sequence< Reference < XRegistryKey > > subKeys = xSource->openKeys();
+
+ if (subKeys.getLength() > 0)
+ {
+ const Reference < XRegistryKey >* pSubKeys = subKeys.getConstArray();
+
+ for (sal_Int32 i = 0; i < subKeys.getLength(); i++)
+ {
+ findImplementations(pSubKeys[i], implNames);
+ }
+
+ }
+ }
+ catch(InvalidRegistryException&)
+ {
+ }
+}
+
+
+class ImplementationRegistration
+ : public WeakImplHelper3< XImplementationRegistration2, XServiceInfo, XInitialization >
+{
+public:
+ ImplementationRegistration( const Reference < XComponentContext > & rSMgr );
+ ~ImplementationRegistration();
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() throw(RuntimeException);
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(RuntimeException);
+ Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw(RuntimeException);
+
+ // XImplementationRegistration
+ virtual void SAL_CALL registerImplementation(
+ const OUString& implementationLoader,
+ const OUString& location,
+ const Reference < XSimpleRegistry > & xReg)
+ throw( CannotRegisterImplementationException, RuntimeException );
+
+ virtual sal_Bool SAL_CALL revokeImplementation(
+ const OUString& location,
+ const Reference < XSimpleRegistry >& xReg)
+ throw( RuntimeException );
+
+ virtual Sequence< OUString > SAL_CALL getImplementations(
+ const OUString& implementationLoader,
+ const OUString& location)
+ throw( RuntimeException );
+ virtual Sequence< OUString > SAL_CALL checkInstantiation(
+ const OUString& implementationName)
+ throw( RuntimeException );
+
+ // XImplementationRegistration2
+ virtual void SAL_CALL registerImplementationWithLocation(
+ const OUString& implementationLoader,
+ const OUString& location,
+ const OUString& registeredLocation,
+ const Reference < XSimpleRegistry > & xReg)
+ throw( CannotRegisterImplementationException, RuntimeException );
+
+ // XInitialization
+ virtual void SAL_CALL initialize(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments )
+ throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+private: // helper methods
+ void prepareRegister(
+ const OUString& implementationLoader,
+ const OUString& location,
+ const OUString& registeredLocation,
+ const Reference < XSimpleRegistry > & xReg);
+ // throw( CannotRegisterImplementationException, RuntimeException )
+
+ static void doRegister( const Reference < XMultiComponentFactory >& xSMgr,
+ const Reference < XComponentContext > &xCtx,
+ const Reference < XImplementationLoader >& xAct,
+ const Reference < XSimpleRegistry >& xDest,
+ const OUString& implementationLoaderUrl,
+ const OUString& locationUrl,
+ const OUString& registeredLocationUrl);
+ /* throw ( InvalidRegistryException,
+ MergeConflictException,
+ CannotRegisterImplementationException, RuntimeException ) */
+
+ static void doRevoke( const Reference < XSimpleRegistry >& xDest,
+ const OUString& locationUrl );
+ // throw( InvalidRegistryException, RuntimeException )
+ Reference< XSimpleRegistry > getRegistryFromServiceManager();
+
+ static Reference< XSimpleRegistry > createTemporarySimpleRegistry(
+ const Reference< XMultiComponentFactory > &rSMgr,
+ const Reference < XComponentContext > & rCtx );
+
+private: // members
+ Reference < XMultiComponentFactory > m_xSMgr;
+ Reference < XComponentContext > m_xCtx;
+};
+
+//*************************************************************************
+// ImplementationRegistration()
+//
+ImplementationRegistration::ImplementationRegistration( const Reference < XComponentContext > & xCtx )
+ : m_xSMgr( xCtx->getServiceManager() )
+ , m_xCtx( xCtx )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+
+//*************************************************************************
+// ~ImplementationRegistration()
+//
+ImplementationRegistration::~ImplementationRegistration()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+
+// XServiceInfo
+OUString ImplementationRegistration::getImplementationName() throw(RuntimeException)
+{
+ return stoc_bootstrap::impreg_getImplementationName();
+}
+
+// XServiceInfo
+sal_Bool ImplementationRegistration::supportsService(const OUString& ServiceName) throw(RuntimeException)
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > ImplementationRegistration::getSupportedServiceNames(void) throw(RuntimeException)
+{
+ return stoc_bootstrap::impreg_getSupportedServiceNames();
+}
+
+Reference< XSimpleRegistry > ImplementationRegistration::getRegistryFromServiceManager()
+{
+ Reference < XPropertySet > xPropSet( m_xSMgr, UNO_QUERY );
+ Reference < XSimpleRegistry > xRegistry;
+
+ if( xPropSet.is() ) {
+
+ try { // the implementation does not support XIntrospectionAccess !
+
+ Any aAny = xPropSet->getPropertyValue( spool().Registry );
+
+ if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE ) {
+ aAny >>= xRegistry;
+ }
+ }
+ catch( UnknownPropertyException & ) {
+ // empty reference is error signal !
+ }
+ }
+
+ return xRegistry;
+}
+
+
+//************************************************************************
+// XInitialization
+//
+void ImplementationRegistration::initialize(
+ const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArgs )
+ throw( ::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+
+ if( aArgs.getLength() != 4 ) {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "ImplementationRegistration::initialize() expects 4 parameters, got "));
+ buf.append( (sal_Int32) aArgs.getLength() );
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference<XInterface > (),
+ 0 );
+ }
+
+ Reference< XImplementationLoader > rLoader;
+ OUString loaderServiceName;
+ OUString locationUrl;
+ Reference< XSimpleRegistry > rReg;
+
+ // 1st argument : An instance of an implementation loader
+ if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
+ aArgs.getConstArray()[0] >>= rLoader;
+ }
+ if( !rLoader.is()) {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "ImplementationRegistration::initialize() invalid first parameter,"
+ "expected " ) );
+ buf.append( getCppuType( &rLoader ).getTypeName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ", got " ) );
+ buf.append( aArgs.getConstArray()[0].getValueTypeName() );
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference< XInterface > (),
+ 0 );
+ }
+
+ // 2nd argument : The service name of the loader. This name is written into the registry
+ if( aArgs.getConstArray()[1].getValueType().getTypeClass() == TypeClass_STRING ) {
+ aArgs.getConstArray()[1] >>= loaderServiceName;
+ }
+ if( ! loaderServiceName.getLength() ) {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "ImplementationRegistration::initialize() invalid second parameter,"
+ "expected string, got " ) );
+ buf.append( aArgs.getConstArray()[1].getValueTypeName() );
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference< XInterface > (),
+ 0 );
+ }
+
+ // 3rd argument : The file name of the dll, that contains the loader
+ if( aArgs.getConstArray()[2].getValueType().getTypeClass() == TypeClass_STRING ) {
+ aArgs.getConstArray()[2] >>= locationUrl;
+ }
+ if( ! locationUrl.getLength() ) {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "ImplementationRegistration::initialize() invalid third parameter,"
+ "expected string, got " ) );
+ buf.append( aArgs.getConstArray()[2].getValueTypeName() );
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference< XInterface > (),
+ 0 );
+ }
+
+ // 4th argument : The registry, the service should be written to
+ if( aArgs.getConstArray()[3].getValueType().getTypeClass() == TypeClass_INTERFACE ) {
+ aArgs.getConstArray()[3] >>= rReg;
+ }
+
+ if( !rReg.is() ) {
+ rReg = getRegistryFromServiceManager();
+ if( !rReg.is() ) {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "ImplementationRegistration::initialize() invalid fourth parameter,"
+ "expected " ));
+ buf.append( getCppuType( &rReg ).getTypeName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", got " ) );
+ buf.append( aArgs.getConstArray()[3].getValueTypeName() );
+ throw IllegalArgumentException( buf.makeStringAndClear(),
+ Reference< XInterface > (),
+ 0 );
+ }
+ }
+
+ doRegister(m_xSMgr, m_xCtx, rLoader , rReg, loaderServiceName , locationUrl, locationUrl);
+}
+
+
+
+//*************************************************************************
+// virtual function registerImplementationWithLocation of XImplementationRegistration2
+//
+void ImplementationRegistration::registerImplementationWithLocation(
+ const OUString& implementationLoaderUrl,
+ const OUString& locationUrl,
+ const OUString& registeredLocationUrl,
+ const Reference < XSimpleRegistry > & xReg)
+ throw( CannotRegisterImplementationException, RuntimeException )
+{
+ prepareRegister(
+ implementationLoaderUrl, locationUrl, registeredLocationUrl, xReg);
+}
+
+// helper function
+void ImplementationRegistration::prepareRegister(
+ const OUString& implementationLoaderUrl,
+ const OUString& locationUrl,
+ const OUString& registeredLocationUrl,
+ const Reference < XSimpleRegistry > & xReg)
+ // throw( CannotRegisterImplementationException, RuntimeException )
+{
+ OUString implLoaderUrl(implementationLoaderUrl);
+ OUString activatorName;
+
+ if (implementationLoaderUrl.getLength() > 0)
+ {
+ OUString tmpActivator(implementationLoaderUrl);
+ sal_Int32 nIndex = 0;
+ activatorName = tmpActivator.getToken(0, ':', nIndex );
+ } else
+ {
+ // check locationUrl to find out what kind of loader is needed
+ // set iimplLoaderUrl
+ }
+
+ if( m_xSMgr.is() ) {
+ try
+ {
+ Reference < XImplementationLoader > xAct(
+ m_xSMgr->createInstanceWithContext(activatorName, m_xCtx) , UNO_QUERY );
+ if (xAct.is())
+ {
+ Reference < XSimpleRegistry > xRegistry;
+
+ if (xReg.is())
+ {
+ // registry supplied by user
+ xRegistry = xReg;
+ }
+ else
+ {
+ xRegistry = getRegistryFromServiceManager();
+ }
+
+ if ( xRegistry.is())
+ {
+ doRegister(m_xSMgr, m_xCtx, xAct, xRegistry, implLoaderUrl,
+ locationUrl, registeredLocationUrl);
+ }
+ }
+ else
+ {
+ OUStringBuffer buf( 128 );
+ buf.appendAscii( "ImplementationRegistration::registerImplementation() - The service " );
+ buf.append( activatorName );
+ buf.appendAscii( " cannot be instantiated\n" );
+ throw CannotRegisterImplementationException(
+ buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ }
+ catch( CannotRegisterImplementationException & )
+ {
+ throw;
+ }
+ catch( InvalidRegistryException & e )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "ImplementationRegistration::registerImplementation() "
+ "InvalidRegistryException during registration (" ));
+ buf.append( e.Message );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
+ throw CannotRegisterImplementationException(
+ buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ catch( MergeConflictException & e )
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "ImplementationRegistration::registerImplementation() "
+ "MergeConflictException during registration (" ));
+ buf.append( e.Message );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( ")" ) );
+ throw CannotRegisterImplementationException(
+ buf.makeStringAndClear(), Reference< XInterface > () );
+ }
+ }
+ else
+ {
+ throw CannotRegisterImplementationException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ImplementationRegistration::registerImplementation() "
+ "no componentcontext available to instantiate loader")),
+ Reference< XInterface > () );
+ }
+}
+
+//*************************************************************************
+// virtual function registerImplementation of XImplementationRegistration
+//
+void ImplementationRegistration::registerImplementation(
+ const OUString& implementationLoaderUrl,
+ const OUString& locationUrl,
+ const Reference < XSimpleRegistry > & xReg)
+ throw( CannotRegisterImplementationException, RuntimeException )
+{
+ prepareRegister(implementationLoaderUrl, locationUrl, locationUrl, xReg);
+}
+
+
+//*************************************************************************
+// virtual function revokeImplementation of XImplementationRegistration
+//
+sal_Bool ImplementationRegistration::revokeImplementation(const OUString& location,
+ const Reference < XSimpleRegistry >& xReg)
+ throw ( RuntimeException )
+{
+ sal_Bool ret = sal_False;
+
+ Reference < XSimpleRegistry > xRegistry;
+
+ if (xReg.is()) {
+ xRegistry = xReg;
+ }
+ else {
+ Reference < XPropertySet > xPropSet = Reference< XPropertySet >::query( m_xSMgr );
+ if( xPropSet.is() ) {
+ try {
+ Any aAny = xPropSet->getPropertyValue( spool().Registry );
+
+ if( aAny.getValueType().getTypeClass() == TypeClass_INTERFACE )
+ {
+ aAny >>= xRegistry;
+ }
+ }
+ catch ( UnknownPropertyException & ) {
+ }
+ }
+ }
+
+ if (xRegistry.is())
+ {
+ try
+ {
+ doRevoke(xRegistry, location);
+ ret = sal_True;
+ }
+ catch( InvalidRegistryException & )
+ {
+ // no way to transport the error, as no exception is specified and a runtime
+ // exception is not appropriate.
+ OSL_ENSURE( 0 , "InvalidRegistryException during revokeImplementation" );
+ }
+ }
+
+ return ret;
+}
+
+//*************************************************************************
+// virtual function getImplementations of XImplementationRegistration
+//
+Sequence< OUString > ImplementationRegistration::getImplementations(
+ const OUString & implementationLoaderUrl,
+ const OUString & locationUrl)
+ throw ( RuntimeException )
+{
+ OUString implLoaderUrl(implementationLoaderUrl);
+ OUString activatorName;
+
+ if (implementationLoaderUrl.getLength() > 0)
+ {
+ OUString tmpActivator(implementationLoaderUrl);
+ sal_Int32 nIndex = 0;
+ activatorName = tmpActivator.getToken(0, ':', nIndex );
+ } else
+ {
+ // check locationUrl to find out what kind of loader is needed
+ // set implLoaderUrl
+ }
+
+ if( m_xSMgr.is() ) {
+
+ Reference < XImplementationLoader > xAct(
+ m_xSMgr->createInstanceWithContext( activatorName, m_xCtx ), UNO_QUERY );
+
+ if (xAct.is())
+ {
+
+ Reference < XSimpleRegistry > xReg =
+ createTemporarySimpleRegistry( m_xSMgr, m_xCtx);
+
+ if (xReg.is())
+ {
+ try
+ {
+ xReg->open(OUString() /* in mem */, sal_False, sal_True);
+ Reference < XRegistryKey > xImpl;
+
+ { // only necessary for deleting the temporary variable of rootkey
+ xImpl = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
+ }
+ if (xAct->writeRegistryInfo(xImpl, implementationLoaderUrl, locationUrl))
+ {
+ std::list <OUString> implNames;
+
+ findImplementations(xImpl, implNames);
+
+ if (!implNames.empty())
+ {
+ std::list<OUString>::const_iterator iter = implNames.begin();
+
+ Sequence<OUString> seqImpl(implNames.size());
+ OUString *pImplNames = seqImpl.getArray();
+
+ sal_Int32 index = 0;
+ while (iter != implNames.end())
+ {
+ pImplNames[index] = *iter;
+ index++;
+ ++iter;
+ }
+
+ xImpl->closeKey();
+ return seqImpl;
+ }
+ }
+
+ xImpl->closeKey();
+ }
+ catch(MergeConflictException&)
+ {
+ }
+ catch(InvalidRegistryException&)
+ {
+ }
+ }
+ }
+ }
+
+ return Sequence<OUString>();
+}
+
+//*************************************************************************
+// virtual function checkInstantiation of XImplementationRegistration
+//
+Sequence< OUString > ImplementationRegistration::checkInstantiation(const OUString&)
+ throw ( RuntimeException )
+{
+ OSL_ENSURE( sal_False, "ImplementationRegistration::checkInstantiation not implemented" );
+ return Sequence<OUString>();
+}
+
+//*************************************************************************
+// helper function doRegistration
+//
+
+void ImplementationRegistration::doRevoke(
+ const Reference < XSimpleRegistry >& xDest,
+ const OUString& locationUrl)
+ // throw ( InvalidRegistryException, RuntimeException )
+{
+ if( xDest.is() )
+ {
+ std::list<OUString> aNames;
+
+ const StringPool &pool = spool();
+ Reference < XRegistryKey > xRootKey( xDest->getRootKey() );
+
+ Reference < XRegistryKey > xKey =
+ xRootKey->openKey( pool.slash_IMPLEMENTATIONS );
+ if (xKey.is() && xKey->isValid())
+ {
+ deleteAllImplementations(xDest, xKey, locationUrl, aNames);
+ }
+
+ xKey = xRootKey->openKey( pool.slash_SERVICES );
+ if (xKey.is())
+ {
+ std::list<OUString>::const_iterator iter = aNames.begin();
+
+ while (iter != aNames.end())
+ {
+ deleteAllServiceEntries(xDest, xKey, *iter);
+ ++iter;
+ }
+ }
+
+ xKey = xRootKey->openKey( OUSTR("/SINGLETONS") );
+ if (xKey.is() && xKey->isValid())
+ {
+ delete_all_singleton_entries( xKey, aNames );
+ }
+
+ if (xRootKey.is())
+ xRootKey->closeKey();
+ if (xKey.is() && xKey->isValid() )
+ xKey->closeKey();
+ }
+}
+
+void ImplementationRegistration::doRegister(
+ const Reference< XMultiComponentFactory > & xSMgr,
+ const Reference< XComponentContext > &xCtx,
+ const Reference < XImplementationLoader > & xAct,
+ const Reference < XSimpleRegistry >& xDest,
+ const OUString& implementationLoaderUrl,
+ const OUString& locationUrl,
+ const OUString& registeredLocationUrl)
+ /* throw ( InvalidRegistryException,
+ MergeConflictException,
+ CannotRegisterImplementationException, RuntimeException ) */
+{
+ Reference < XSimpleRegistry > xReg =
+ createTemporarySimpleRegistry( xSMgr, xCtx );
+ Reference < XRegistryKey > xSourceKey;
+
+ if (xAct.is() && xReg.is() && xDest.is())
+ {
+ try
+ {
+ xReg->open(OUString() /* in mem */, sal_False, sal_True);
+
+ { // only necessary for deleting the temporary variable of rootkey
+ xSourceKey = xReg->getRootKey()->createKey( spool().slash_IMPLEMENTATIONS );
+ }
+
+ sal_Bool bSuccess =
+ xAct->writeRegistryInfo(xSourceKey, implementationLoaderUrl, locationUrl);
+ if ( bSuccess )
+ {
+ prepareRegistry(xDest, xSourceKey, implementationLoaderUrl, registeredLocationUrl, xCtx);
+
+ xSourceKey->closeKey();
+
+ xSourceKey = xReg->getRootKey();
+ Reference < XRegistryKey > xDestKey = xDest->getRootKey();
+ mergeKeys( xDestKey, xSourceKey );
+ xDestKey->closeKey();
+ xSourceKey->closeKey();
+ }
+ else
+ {
+ throw CannotRegisterImplementationException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM( "ImplementationRegistration::doRegistration() component registration signaled failure" ) ),
+ Reference< XInterface > () );
+ }
+
+ // Cleanup Source registry.
+ if ( xSourceKey->isValid() )
+ xSourceKey->closeKey();
+ }
+ catch(CannotRegisterImplementationException&)
+ {
+ if ( xSourceKey->isValid() )
+ xSourceKey->closeKey();
+ // and throw again
+ throw;
+ }
+ }
+}
+
+
+
+Reference< XSimpleRegistry > ImplementationRegistration::createTemporarySimpleRegistry(
+ const Reference< XMultiComponentFactory > &rSMgr,
+ const Reference < XComponentContext > & xCtx)
+{
+
+ Reference < XSimpleRegistry > xReg(
+ rSMgr->createInstanceWithContext(
+ spool().com_sun_star_registry_SimpleRegistry, xCtx ),
+ UNO_QUERY);
+ OSL_ASSERT( xReg.is() );
+ return xReg;
+}
+}
+
+namespace stoc_bootstrap
+{
+//*************************************************************************
+Reference<XInterface> SAL_CALL ImplementationRegistration_CreateInstance(
+ const Reference<XComponentContext> & xCtx ) // throw(Exception)
+{
+ return (XImplementationRegistration *)new stoc_impreg::ImplementationRegistration(xCtx);
+}
+
+}
+
diff --git a/stoc/source/implementationregistration/makefile.mk b/stoc/source/implementationregistration/makefile.mk
new file mode 100644
index 000000000000..2de7fe91cb21
--- /dev/null
+++ b/stoc/source/implementationregistration/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = implreg
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT= $(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/mergekeys.obj \
+ $(SLO)$/implreg.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/stoc/source/implementationregistration/mergekeys.cxx b/stoc/source/implementationregistration/mergekeys.cxx
new file mode 100644
index 000000000000..acfec677badf
--- /dev/null
+++ b/stoc/source/implementationregistration/mergekeys.cxx
@@ -0,0 +1,186 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <vector>
+
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/registry/MergeConflictException.hpp>
+
+#include "mergekeys.hxx"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star;
+
+namespace stoc_impreg
+{
+
+struct Link
+{
+ OUString m_name;
+ OUString m_target;
+
+ inline Link( OUString const & name, OUString const & target )
+ : m_name( name )
+ , m_target( target )
+ {}
+};
+typedef ::std::vector< Link > t_links;
+
+//==================================================================================================
+static void mergeKeys(
+ Reference< registry::XRegistryKey > const & xDest,
+ Reference< registry::XRegistryKey > const & xSource,
+ t_links & links )
+ // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException )
+{
+ if (!xSource.is() || !xSource->isValid()) {
+ throw registry::InvalidRegistryException(
+ OUSTR("source key is null or invalid!"),
+ Reference<XInterface>() );
+ }
+ if (!xDest.is() || !xDest->isValid()) {
+ throw registry::InvalidRegistryException(
+ OUSTR("destination key is null or invalid!"),
+ Reference<XInterface>() );
+ }
+
+ // write value
+ switch (xSource->getValueType())
+ {
+ case registry::RegistryValueType_NOT_DEFINED:
+ break;
+ case registry::RegistryValueType_LONG:
+ xDest->setLongValue( xSource->getLongValue() );
+ break;
+ case registry::RegistryValueType_ASCII:
+ xDest->setAsciiValue( xSource->getAsciiValue() );
+ break;
+ case registry::RegistryValueType_STRING:
+ xDest->setStringValue( xSource->getStringValue() );
+ break;
+ case registry::RegistryValueType_BINARY:
+ xDest->setBinaryValue( xSource->getBinaryValue() );
+ break;
+ case registry::RegistryValueType_LONGLIST:
+ xDest->setLongListValue( xSource->getLongListValue() );
+ break;
+ case registry::RegistryValueType_ASCIILIST:
+ xDest->setAsciiListValue( xSource->getAsciiListValue() );
+ break;
+ case registry::RegistryValueType_STRINGLIST:
+ xDest->setStringListValue( xSource->getStringListValue() );
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+
+ // sub keys
+ Sequence< OUString > sourceKeys( xSource->getKeyNames() );
+ OUString const * pSourceKeys = sourceKeys.getConstArray();
+ for ( sal_Int32 nPos = sourceKeys.getLength(); nPos--; )
+ {
+ // key name
+ OUString name( pSourceKeys[ nPos ] );
+ sal_Int32 nSlash = name.lastIndexOf( '/' );
+ if (nSlash >= 0)
+ {
+ name = name.copy( nSlash +1 );
+ }
+
+ if (xSource->getKeyType( name ) == registry::RegistryKeyType_KEY)
+ {
+ // try to open exisiting dest key or create new one
+ Reference< registry::XRegistryKey > xDestKey( xDest->createKey( name ) );
+ Reference< registry::XRegistryKey > xSourceKey( xSource->openKey( name ) );
+ mergeKeys( xDestKey, xSourceKey, links );
+ xSourceKey->closeKey();
+ xDestKey->closeKey();
+ }
+ else // link
+ {
+ // remove existing key
+ Reference< registry::XRegistryKey > xDestKey( xDest->openKey( name ) );
+ if (xDestKey.is() && xDestKey->isValid()) // something to remove
+ {
+ xDestKey->closeKey();
+ if (xDest->getKeyType( name ) == registry::RegistryKeyType_LINK)
+ {
+ xDest->deleteLink( name );
+ }
+ else
+ {
+ xDest->deleteKey( name );
+ }
+ }
+
+ links.push_back( Link(
+ pSourceKeys[ nPos ], // abs path
+ xSource->getResolvedName( name ) // abs resolved name
+ ) );
+ }
+ }
+}
+
+//==================================================================================================
+void mergeKeys(
+ Reference< registry::XRegistryKey > const & xDest,
+ Reference< registry::XRegistryKey > const & xSource )
+ // throw( registry::InvalidRegistryException, registry::MergeConflictException, RuntimeException )
+{
+ if (!xDest.is() || !xDest->isValid()) {
+ throw registry::InvalidRegistryException(
+ OUSTR("destination key is null or invalid!"),
+ Reference<XInterface>() );
+ }
+ if (xDest->isReadOnly())
+ {
+ throw registry::InvalidRegistryException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "destination registry is read-only! cannot merge!") ),
+ Reference< XInterface >() );
+ }
+
+ t_links links;
+ links.reserve( 16 );
+ mergeKeys( xDest, xSource, links );
+
+ for ( size_t nPos = links.size(); nPos--; )
+ {
+ Link const & r = links[ nPos ];
+ OSL_VERIFY( xDest->createLink( r.m_name, r.m_target ) );
+ }
+}
+
+}
diff --git a/stoc/source/implementationregistration/mergekeys.hxx b/stoc/source/implementationregistration/mergekeys.hxx
new file mode 100644
index 000000000000..3a8bd177b56d
--- /dev/null
+++ b/stoc/source/implementationregistration/mergekeys.hxx
@@ -0,0 +1,52 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_STOC_SOURCE_IMPLEMENTATIONREGISTRATION_MERGEKEYS_HXX
+#define INCLUDED_STOC_SOURCE_IMPLEMENTATIONREGISTRATION_MERGEKEYS_HXX
+
+#include "sal/config.h"
+
+#include "com/sun/star/uno/Reference.hxx"
+
+namespace com { namespace sun { namespace star { namespace registry {
+ class XRegistryKey;
+} } } }
+
+namespace stoc_impreg {
+
+// throws ::com::sun::star::registry::InvalidRegistryException,
+// ::com::sun::star::registry::MergeConflictException,
+// ::com::sun::star::uno::RuntimeException:
+void mergeKeys(
+ ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >
+ const & xDest,
+ ::com::sun::star::uno::Reference< ::com::sun::star::registry::XRegistryKey >
+ const & xSource);
+
+}
+
+#endif
diff --git a/stoc/source/inspect/insp.xml b/stoc/source/inspect/insp.xml
new file mode 100644
index 000000000000..48b46d273cb1
--- /dev/null
+++ b/stoc/source/inspect/insp.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> introspection.uno </module-name>
+ <component-description>
+ <author> Juergen Schmidt </author>
+ <name> com.sun.star.comp.stoc.Introspection </name>
+ <description>
+ This component implements XIntrospection. The method XIntrospection::inspect(any object)
+ returns an XIntrospectionAccess that provides information about the methods, properties
+ and listeners supported by the inspected object. Matching pairs of getName/setName()
+ methods will also be offered as property "Name".
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.beans.Introspection </supported-service>
+ <service-dependency> com.sun.star.reflection.CoreReflection </service-dependency>
+ <type>com.sun.star.lang.DisposedException</type>
+ <type> com.sun.star.beans.XIntrospection </type>
+ <type> com.sun.star.beans.XIntrospectionAccess </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.beans.XFastPropertySet </type>
+ <type> com.sun.star.beans.XMaterialHolder </type>
+ <type> com.sun.star.beans.XExactName </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertyConcept </type>
+ <type> com.sun.star.beans.MethodConcept </type>
+ <type> com.sun.star.lang.XEventListener </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.DeploymentException </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.container.XEnumerationAccess </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.container.XIndexContainer </type>
+ <type> com.sun.star.reflection.XIdlReflection </type>
+ <type> com.sun.star.reflection.XIdlClassProvider </type>
+ <type> com.sun.star.reflection.XIdlClass </type>
+ <type> com.sun.star.reflection.XIdlField2 </type>
+ <type> com.sun.star.reflection.XIdlArray </type>
+ <type> com.sun.star.reflection.FieldAccessMode </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/inspect/introspection.component b/stoc/source/inspect/introspection.component
new file mode 100644
index 000000000000..349fb0c9dfbe
--- /dev/null
+++ b/stoc/source/inspect/introspection.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.stoc.Introspection">
+ <service name="com.sun.star.beans.Introspection"/>
+ </implementation>
+</component>
diff --git a/stoc/source/inspect/introspection.cxx b/stoc/source/inspect/introspection.cxx
new file mode 100644
index 000000000000..051ff3e2ae3c
--- /dev/null
+++ b/stoc/source/inspect/introspection.cxx
@@ -0,0 +1,3091 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <string.h>
+
+// Schalter fuer Introspection-Caching
+#ifndef OS2
+#define USE_INTROSPECTION_CACHE
+#endif
+
+#ifdef USE_INTROSPECTION_CACHE
+#define INTROSPECTION_CACHE_MAX_SIZE 100
+#endif
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <osl/thread.h>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/component.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/reflection/XIdlClassProvider.hpp>
+#include <com/sun/star/reflection/XIdlClass.hpp>
+#include <com/sun/star/reflection/XIdlField2.hpp>
+#include <com/sun/star/beans/UnknownPropertyException.hpp>
+#include <com/sun/star/beans/Property.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/XFastPropertySet.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/XIntrospectionAccess.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+#include <hash_map>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::container;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::beans::PropertyAttribute;
+using namespace com::sun::star::beans::PropertyConcept;
+using namespace com::sun::star::beans::MethodConcept;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+
+#define IMPLEMENTATION_NAME "com.sun.star.comp.stoc.Introspection"
+#define SERVICE_NAME "com.sun.star.beans.Introspection"
+
+namespace stoc_inspect
+{
+
+typedef WeakImplHelper3< XIntrospectionAccess, XMaterialHolder, XExactName > IntrospectionAccessHelper;
+
+
+//==================================================================================================
+
+// Spezial-Wert fuer Method-Concept, um "normale" Funktionen kennzeichnen zu koennen
+#define MethodConcept_NORMAL_IMPL 0x80000000
+
+
+// Methode zur Feststellung, ob eine Klasse von einer anderen abgeleitet ist
+sal_Bool isDerivedFrom( Reference<XIdlClass> xToTestClass, Reference<XIdlClass> xDerivedFromClass )
+{
+ Sequence< Reference<XIdlClass> > aClassesSeq = xToTestClass->getSuperclasses();
+ const Reference<XIdlClass>* pClassesArray = aClassesSeq.getConstArray();
+ sal_Int32 nSuperClassCount = aClassesSeq.getLength();
+ sal_Int32 i;
+ for( i = 0 ; i < nSuperClassCount ; i++ )
+ {
+ const Reference<XIdlClass>& rxClass = pClassesArray[i];
+ if( xDerivedFromClass->equals( rxClass ) )
+ {
+ // Treffer
+ return sal_True;
+ }
+ else
+ {
+ // Rekursiv weitersuchen
+ return isDerivedFrom( rxClass, xDerivedFromClass );
+ }
+ }
+ return sal_False;
+}
+
+//========================================================================
+
+// *** Klassifizierung der Properties (kein enum, um Sequence verwenden zu koennen) ***
+// Properties aus einem PropertySet-Interface
+#define MAP_PROPERTY_SET 0
+// Properties aus Fields
+#define MAP_FIELD 1
+// Properties, die durch get/set-Methoden beschrieben werden
+#define MAP_GETSET 2
+// Properties, die nur eine set-Methode haben
+#define MAP_SETONLY 3
+
+
+// Schrittweite, in der die Groesse der Sequences angepasst wird
+#define ARRAY_SIZE_STEP 20
+
+
+
+//**************************************
+//*** IntrospectionAccessStatic_Impl ***
+//**************************************
+// Entspricht dem alten IntrospectionAccessImpl, bildet jetzt den statischen
+// Anteil des neuen Instanz-bezogenen ImplIntrospectionAccess
+
+// ACHTUNG !!! Von Hand refcounten !!!
+
+
+// Hashtable fuer die Suche nach Namen
+struct hashName_Impl
+{
+ size_t operator()(const OUString Str) const
+ {
+ return (size_t)Str.hashCode();
+ }
+};
+
+struct eqName_Impl
+{
+ sal_Bool operator()(const OUString Str1, const OUString Str2) const
+ {
+ return ( Str1 == Str2 );
+ }
+};
+
+typedef std::hash_map
+<
+ OUString,
+ sal_Int32,
+ hashName_Impl,
+ eqName_Impl
+>
+IntrospectionNameMap;
+
+
+// Hashtable zur Zuordnung der exakten Namen zu den zu Lower-Case
+// konvertierten Namen, dient zur Unterst�tzung von XExactName
+typedef std::hash_map
+<
+ OUString,
+ OUString,
+ hashName_Impl,
+ eqName_Impl
+>
+LowerToExactNameMap;
+
+
+class ImplIntrospectionAccess;
+class IntrospectionAccessStatic_Impl
+{
+ friend class ImplIntrospection;
+ friend class ImplIntrospectionAccess;
+
+ // CoreReflection halten
+ Reference< XIdlReflection > mxCoreReflection;
+
+ // InterfaceSequences, um Zusatz-Infos zu einer Property speichern zu koennen.
+ // z.B. das Field bei MAP_FIELD, die get/set-Methoden bei MAP_GETSET usw.
+ Sequence< Reference<XInterface> > aInterfaceSeq1;
+ Sequence< Reference<XInterface> > aInterfaceSeq2;
+
+ // Hashtables fuer die Namen
+ IntrospectionNameMap maPropertyNameMap;
+ IntrospectionNameMap maMethodNameMap;
+ LowerToExactNameMap maLowerToExactNameMap;
+
+ // Sequence aller Properties, auch zum Liefern aus getProperties()
+ Sequence<Property> maAllPropertySeq;
+
+ // Mapping der Properties auf Zugriffs-Arten
+ Sequence<sal_Int16> maMapTypeSeq;
+
+ // Klassifizierung der gefundenen Methoden
+ Sequence<sal_Int32> maPropertyConceptSeq;
+
+ // Anzahl der Properties
+ sal_Int32 mnPropCount;
+
+ // Anzahl der Properties, die den jeweiligen Konzepten zugeordnet sind
+ //sal_Int32 mnDangerousPropCount;
+ sal_Int32 mnPropertySetPropCount;
+ sal_Int32 mnAttributePropCount;
+ sal_Int32 mnMethodPropCount;
+
+ // Flag, ob ein FastPropertySet unterstuetzt wird
+ sal_Bool mbFastPropSet;
+
+ // Original-Handles eines FastPropertySets
+ sal_Int32* mpOrgPropertyHandleArray;
+
+ // MethodSequence, die alle Methoden aufnimmt
+ Sequence< Reference<XIdlMethod> > maAllMethodSeq;
+
+ // Klassifizierung der gefundenen Methoden
+ Sequence<sal_Int32> maMethodConceptSeq;
+
+ // Anzahl der Methoden
+ sal_Int32 mnMethCount;
+
+ // Sequence der Listener, die angemeldet werden koennen
+ Sequence< Type > maSupportedListenerSeq;
+
+ // BaseInit (soll spaeter in der Applikation erfolgen!)
+ void BaseInit( void );
+
+ // Hilfs-Methoden zur Groessen-Anpassung der Sequences
+ void checkPropertyArraysSize
+ (
+ Property*& rpAllPropArray,
+ sal_Int16*& rpMapTypeArray,
+ sal_Int32*& rpPropertyConceptArray,
+ sal_Int32 iNextIndex
+ );
+ void checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq, Reference<XInterface>*& rpInterfaceArray,
+ sal_Int32 iNextIndex );
+
+ // RefCount
+ sal_Int32 nRefCount;
+
+
+public:
+ IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ );
+ ~IntrospectionAccessStatic_Impl()
+ {
+ delete[] mpOrgPropertyHandleArray;
+ }
+ sal_Int32 getPropertyIndex( const OUString& aPropertyName ) const;
+ sal_Int32 getMethodIndex( const OUString& aMethodName ) const;
+
+ void acquire() { nRefCount++; }
+ void release()
+ {
+ nRefCount--;
+ if( nRefCount <= 0 )
+ delete this;
+ }
+
+ // Methoden von XIntrospectionAccess (ALT, jetzt nur Impl)
+ void setPropertyValue(const Any& obj, const OUString& aPropertyName, const Any& aValue) const;
+// void setPropertyValue(Any& obj, const OUString& aPropertyName, const Any& aValue) const;
+ Any getPropertyValue(const Any& obj, const OUString& aPropertyName) const;
+ void setPropertyValueByIndex(const Any& obj, sal_Int32 nIndex, const Any& aValue) const;
+// void setPropertyValueByIndex(Any& obj, sal_Int32 nIndex, const Any& aValue) const;
+ Any getPropertyValueByIndex(const Any& obj, sal_Int32 nIndex) const;
+
+ Sequence<Property> getProperties(void) const { return maAllPropertySeq; }
+ Sequence< Reference<XIdlMethod> > getMethods(void) const { return maAllMethodSeq; }
+ Sequence< Type > getSupportedListeners(void) const { return maSupportedListenerSeq; }
+ Sequence<sal_Int32> getPropertyConcepts(void) const { return maPropertyConceptSeq; }
+ Sequence<sal_Int32> getMethodConcepts(void) const { return maMethodConceptSeq; }
+};
+
+
+// Ctor
+IntrospectionAccessStatic_Impl::IntrospectionAccessStatic_Impl( Reference< XIdlReflection > xCoreReflection_ )
+ : mxCoreReflection( xCoreReflection_ )
+{
+ aInterfaceSeq1.realloc( ARRAY_SIZE_STEP );
+ aInterfaceSeq2.realloc( ARRAY_SIZE_STEP );
+
+ // Property-Daten
+ maAllPropertySeq.realloc( ARRAY_SIZE_STEP );
+ maMapTypeSeq.realloc( ARRAY_SIZE_STEP );
+ maPropertyConceptSeq.realloc( ARRAY_SIZE_STEP );
+
+ mbFastPropSet = sal_False;
+ mpOrgPropertyHandleArray = NULL;
+
+ mnPropCount = 0;
+ //mnDangerousPropCount = 0;
+ mnPropertySetPropCount = 0;
+ mnAttributePropCount = 0;
+ mnMethodPropCount = 0;
+
+ // Method-Daten
+ mnMethCount = 0;
+
+ // Eigenens RefCounting
+ nRefCount = 0;
+}
+
+// Von Hand refcounten !!!
+
+
+sal_Int32 IntrospectionAccessStatic_Impl::getPropertyIndex( const OUString& aPropertyName ) const
+{
+ sal_Int32 iHashResult = -1;
+ IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
+ IntrospectionNameMap::iterator aIt = pThis->maPropertyNameMap.find( aPropertyName );
+ if( !( aIt == pThis->maPropertyNameMap.end() ) )
+ iHashResult = (*aIt).second;
+ return iHashResult;
+}
+
+sal_Int32 IntrospectionAccessStatic_Impl::getMethodIndex( const OUString& aMethodName ) const
+{
+ sal_Int32 iHashResult = -1;
+ IntrospectionAccessStatic_Impl* pThis = (IntrospectionAccessStatic_Impl*)this;
+ IntrospectionNameMap::iterator aIt = pThis->maMethodNameMap.find( aMethodName );
+ if( !( aIt == pThis->maMethodNameMap.end() ) )
+ {
+ iHashResult = (*aIt).second;
+ }
+ // #95159 Check if full qualified name matches
+ else
+ {
+ sal_Int32 nSearchFrom = aMethodName.getLength();
+ nSearchFrom = aMethodName.getLength();
+ while( true )
+ {
+ // Strategy: Search back until the first '_' is found
+ sal_Int32 nFound = aMethodName.lastIndexOf( '_', nSearchFrom );
+ if( nFound == -1 )
+ break;
+
+ OUString aPureMethodName = aMethodName.copy( nFound + 1 );
+
+ aIt = pThis->maMethodNameMap.find( aPureMethodName );
+ if( !( aIt == pThis->maMethodNameMap.end() ) )
+ {
+ // Check if it can be a type?
+ // Problem: Does not work if package names contain _ ?!
+ OUString aStr = aMethodName.copy( 0, nFound );
+ OUString aTypeName = aStr.replace( '_', '.' );
+ Reference< XIdlClass > xClass = mxCoreReflection->forName( aTypeName );
+ if( xClass.is() )
+ {
+ // If this is a valid class it could be the right method
+
+ // Could be the right method, type has to be checked
+ iHashResult = (*aIt).second;
+
+ const Reference<XIdlMethod>* pMethods = maAllMethodSeq.getConstArray();
+ const Reference<XIdlMethod> xMethod = pMethods[ iHashResult ];
+
+ Reference< XIdlClass > xMethClass = xMethod->getDeclaringClass();
+ if( xClass->equals( xMethClass ) )
+ {
+ break;
+ }
+ else
+ {
+ iHashResult = -1;
+
+ // Could also be another method with the same name
+ // Iterate over all methods
+ sal_Int32 nLen = maAllMethodSeq.getLength();
+ for( int i = 0 ; i < nLen ; ++i )
+ {
+ const Reference<XIdlMethod> xMethod2 = pMethods[ i ];
+
+ OUString aTestClassName = xMethod2->getDeclaringClass()->getName();
+ OUString aTestMethodName = xMethod2->getName();
+
+ if( xMethod2->getName() == aPureMethodName )
+ {
+ Reference< XIdlClass > xMethClass2 = xMethod2->getDeclaringClass();
+
+ if( xClass->equals( xMethClass2 ) )
+ {
+ iHashResult = i;
+ break;
+ }
+ }
+ }
+
+ if( iHashResult != -1 )
+ break;
+ }
+ }
+ }
+
+ nSearchFrom = nFound - 1;
+ if( nSearchFrom < 0 )
+ break;
+ }
+ }
+ return iHashResult;
+}
+
+void IntrospectionAccessStatic_Impl::setPropertyValue( const Any& obj, const OUString& aPropertyName, const Any& aValue ) const
+//void IntrospectionAccessStatic_Impl::setPropertyValue( Any& obj, const OUString& aPropertyName, const Any& aValue ) const
+{
+ sal_Int32 i = getPropertyIndex( aPropertyName );
+ if( i != -1 )
+ setPropertyValueByIndex( obj, (sal_Int32)i, aValue );
+ else
+ throw UnknownPropertyException();
+}
+
+void IntrospectionAccessStatic_Impl::setPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
+//void IntrospectionAccessStatic_Impl::setPropertyValueByIndex( Any& obj, sal_Int32 nSequenceIndex, const Any& aValue) const
+{
+ // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
+ TypeClass eObjType = obj.getValueType().getTypeClass();
+
+ Reference<XInterface> xInterface;
+ if( eObjType == TypeClass_INTERFACE )
+ {
+ xInterface = *( Reference<XInterface>*)obj.getValue();
+ }
+ else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
+ {
+ throw IllegalArgumentException();
+ }
+
+ // Flags pruefen
+ const Property* pProps = maAllPropertySeq.getConstArray();
+ if( (pProps[ nSequenceIndex ].Attributes & READONLY) != 0 )
+ {
+ throw UnknownPropertyException();
+ }
+
+ const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
+ switch( pMapTypeArray[ nSequenceIndex ] )
+ {
+ case MAP_PROPERTY_SET:
+ {
+ // Property besorgen
+ const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
+
+ // Interface-Parameter auf den richtigen Typ bringen
+ sal_Bool bUseCopy = sal_False;
+ Any aRealValue;
+
+ TypeClass eValType = aValue.getValueType().getTypeClass();
+ if( eValType == TypeClass_INTERFACE )
+ {
+ Type aPropType = rProp.Type;
+ OUString aTypeName( aPropType.getTypeName() );
+ Reference< XIdlClass > xPropClass = mxCoreReflection->forName( aTypeName );
+ //Reference<XIdlClass> xPropClass = rProp.Type;
+ if( xPropClass.is() && xPropClass->getTypeClass() == TypeClass_INTERFACE )
+ {
+ Reference<XInterface> valInterface = *(Reference<XInterface>*)aValue.getValue();
+ if( valInterface.is() )
+ {
+ //Any queryInterface( const Type& rType );
+ aRealValue = valInterface->queryInterface( aPropType );
+ if( aRealValue.hasValue() )
+ bUseCopy = sal_True;
+ }
+ }
+ }
+
+ // Haben wir ein FastPropertySet und ein gueltiges Handle?
+ // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
+ // zu Beginn des Introspection-Vorgangs abgefragt wird.
+ sal_Int32 nOrgHandle;
+ if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
+ {
+ // PropertySet-Interface holen
+ Reference<XFastPropertySet> xFastPropSet =
+ Reference<XFastPropertySet>::query( xInterface );
+ if( xFastPropSet.is() )
+ {
+ xFastPropSet->setFastPropertyValue( nOrgHandle, bUseCopy ? aRealValue : aValue );
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ }
+ }
+ // sonst eben das normale nehmen
+ else
+ {
+ // PropertySet-Interface holen
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( xInterface );
+ if( xPropSet.is() )
+ {
+ xPropSet->setPropertyValue( rProp.Name, bUseCopy ? aRealValue : aValue );
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ }
+ }
+ }
+ break;
+
+ case MAP_FIELD:
+ {
+ Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
+ Reference<XIdlField2> xField2(xField, UNO_QUERY);
+ if( xField2.is() )
+ {
+ xField2->set( (Any&)obj, aValue );
+ // IllegalArgumentException
+ // NullPointerException
+ } else
+ if( xField.is() )
+ {
+ xField->set( obj, aValue );
+ // IllegalArgumentException
+ // NullPointerException
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ }
+ }
+ break;
+
+ case MAP_GETSET:
+ case MAP_SETONLY:
+ {
+ // set-Methode holen
+ Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq2.getConstArray()[ nSequenceIndex ].get());
+ if( xMethod.is() )
+ {
+ Sequence<Any> args( 1 );
+ args.getArray()[0] = aValue;
+ xMethod->invoke( obj, args );
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ }
+ }
+ break;
+ }
+}
+
+Any IntrospectionAccessStatic_Impl::getPropertyValue( const Any& obj, const OUString& aPropertyName ) const
+{
+ sal_Int32 i = getPropertyIndex( aPropertyName );
+ if( i != -1 )
+ return getPropertyValueByIndex( obj, i );
+
+ throw UnknownPropertyException();
+}
+
+Any IntrospectionAccessStatic_Impl::getPropertyValueByIndex(const Any& obj, sal_Int32 nSequenceIndex) const
+{
+ Any aRet;
+
+ // Handelt es sich bei dem uebergebenen Objekt ueberhaupt um was passendes?
+ TypeClass eObjType = obj.getValueType().getTypeClass();
+
+ Reference<XInterface> xInterface;
+ if( eObjType == TypeClass_INTERFACE )
+ {
+ xInterface = *(Reference<XInterface>*)obj.getValue();
+ }
+ else if( nSequenceIndex >= mnPropCount || ( eObjType != TypeClass_STRUCT && eObjType != TypeClass_EXCEPTION ) )
+ {
+ // throw IllegalArgumentException();
+ return aRet;
+ }
+
+ const sal_Int16* pMapTypeArray = maMapTypeSeq.getConstArray();
+ switch( pMapTypeArray[ nSequenceIndex ] )
+ {
+ case MAP_PROPERTY_SET:
+ {
+ // Property besorgen
+ const Property& rProp = maAllPropertySeq.getConstArray()[ nSequenceIndex ];
+
+ // Haben wir ein FastPropertySet und ein gueltiges Handle?
+ // ACHTUNG: An dieser Stelle wird ausgenutzt, dass das PropertySet
+ // zu Beginn des Introspection-Vorgangs abgefragt wird.
+ sal_Int32 nOrgHandle;
+ if( mbFastPropSet && ( nOrgHandle = mpOrgPropertyHandleArray[ nSequenceIndex ] ) != -1 )
+ {
+ // PropertySet-Interface holen
+ Reference<XFastPropertySet> xFastPropSet =
+ Reference<XFastPropertySet>::query( xInterface );
+ if( xFastPropSet.is() )
+ {
+ aRet = xFastPropSet->getFastPropertyValue( nOrgHandle);
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ return aRet;
+ }
+ }
+ // sonst eben das normale nehmen
+ else
+ {
+ // PropertySet-Interface holen
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( xInterface );
+ if( xPropSet.is() )
+ {
+ aRet = xPropSet->getPropertyValue( rProp.Name );
+ }
+ else
+ {
+ // throw UnknownPropertyException
+ return aRet;
+ }
+ }
+ }
+ break;
+
+ case MAP_FIELD:
+ {
+ Reference<XIdlField> xField = (XIdlField*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
+ if( xField.is() )
+ {
+ aRet = xField->get( obj );
+ // IllegalArgumentException
+ // NullPointerException
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ return aRet;
+ }
+ }
+ break;
+
+ case MAP_GETSET:
+ {
+ // get-Methode holen
+ Reference<XIdlMethod> xMethod = (XIdlMethod*)(aInterfaceSeq1.getConstArray()[ nSequenceIndex ].get());
+ if( xMethod.is() )
+ {
+ Sequence<Any> args;
+ aRet = xMethod->invoke( obj, args );
+ }
+ else
+ {
+ // throw IllegalArgumentException();
+ return aRet;
+ }
+ }
+ break;
+
+ case MAP_SETONLY:
+ // get-Methode gibt es nicht
+ // throw WriteOnlyPropertyException();
+ return aRet;
+ }
+ return aRet;
+}
+
+
+// Hilfs-Methoden zur Groessen-Anpassung der Sequences
+void IntrospectionAccessStatic_Impl::checkPropertyArraysSize
+(
+ Property*& rpAllPropArray,
+ sal_Int16*& rpMapTypeArray,
+ sal_Int32*& rpPropertyConceptArray,
+ sal_Int32 iNextIndex
+)
+{
+ sal_Int32 nLen = maAllPropertySeq.getLength();
+ if( iNextIndex >= nLen )
+ {
+ maAllPropertySeq.realloc( nLen + ARRAY_SIZE_STEP );
+ rpAllPropArray = maAllPropertySeq.getArray();
+
+ maMapTypeSeq.realloc( nLen + ARRAY_SIZE_STEP );
+ rpMapTypeArray = maMapTypeSeq.getArray();
+
+ maPropertyConceptSeq.realloc( nLen + ARRAY_SIZE_STEP );
+ rpPropertyConceptArray = maPropertyConceptSeq.getArray();
+ }
+}
+
+void IntrospectionAccessStatic_Impl::checkInterfaceArraySize( Sequence< Reference<XInterface> >& rSeq,
+ Reference<XInterface>*& rpInterfaceArray, sal_Int32 iNextIndex )
+{
+ sal_Int32 nLen = rSeq.getLength();
+ if( iNextIndex >= nLen )
+ {
+ // Neue Groesse mit ARRAY_SIZE_STEP abgleichen
+ sal_Int32 nMissingSize = iNextIndex - nLen + 1;
+ sal_Int32 nSteps = nMissingSize / ARRAY_SIZE_STEP + 1;
+ sal_Int32 nNewSize = nLen + nSteps * ARRAY_SIZE_STEP;
+
+ rSeq.realloc( nNewSize );
+ rpInterfaceArray = rSeq.getArray();
+ }
+}
+
+
+//*******************************
+//*** ImplIntrospectionAdapter ***
+//*******************************
+
+// Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
+// Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
+// ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
+class ImplIntrospectionAdapter :
+ public XPropertySet, public XFastPropertySet, public XPropertySetInfo,
+ public XNameContainer, public XIndexContainer,
+ public XEnumerationAccess, public XIdlArray,
+ public OWeakObject
+{
+ // Parent-Objekt
+ ImplIntrospectionAccess* mpAccess;
+
+ // Untersuchtes Objekt
+ const Any& mrInspectedObject;
+
+ // Statische Daten der Introspection
+ IntrospectionAccessStatic_Impl* mpStaticImpl;
+
+ // Objekt als Interface
+ Reference<XInterface> mxIface;
+
+ // Original-Interfaces des Objekts
+ Reference<XElementAccess> mxObjElementAccess;
+ Reference<XNameContainer> mxObjNameContainer;
+ Reference<XNameAccess> mxObjNameAccess;
+ Reference<XIndexAccess> mxObjIndexAccess;
+ Reference<XIndexContainer> mxObjIndexContainer;
+ Reference<XEnumerationAccess> mxObjEnumerationAccess;
+ Reference<XIdlArray> mxObjIdlArray;
+
+public:
+ ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
+ const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ );
+ ~ImplIntrospectionAdapter();
+
+ // Methoden von XInterface
+ virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
+ virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ virtual void SAL_CALL release() throw() { OWeakObject::release(); }
+
+ // Methoden von XPropertySet
+ virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() throw( RuntimeException );
+ virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, const Any& aValue)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
+ virtual Any SAL_CALL getPropertyValue(const OUString& aPropertyName)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XFastPropertySet
+ virtual void SAL_CALL setFastPropertyValue(sal_Int32 nHandle, const Any& aValue)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException );
+ virtual Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XPropertySetInfo
+ virtual Sequence< Property > SAL_CALL getProperties(void) throw( RuntimeException );
+ virtual Property SAL_CALL getPropertyByName(const OUString& Name) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasPropertyByName(const OUString& Name) throw( RuntimeException );
+
+ // Methoden von XElementAccess
+ virtual Type SAL_CALL getElementType(void) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException );
+
+ // Methoden von XNameAccess
+ virtual Any SAL_CALL getByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException );
+ virtual Sequence<OUString> SAL_CALL getElementNames(void) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasByName(const OUString& Name) throw( RuntimeException );
+
+ // Methoden von XNameContainer
+ virtual void SAL_CALL insertByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL replaceByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removeByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException );
+ virtual Any SAL_CALL getByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XIndexContainer
+ virtual void SAL_CALL insertByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL replaceByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+ virtual void SAL_CALL removeByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException );
+
+ // Methoden von XEnumerationAccess
+ virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException );
+
+ // Methoden von XIdlArray
+ virtual void SAL_CALL realloc(Any& array, sal_Int32 length)
+ throw( IllegalArgumentException, RuntimeException );
+ virtual sal_Int32 SAL_CALL getLen(const Any& array) throw( IllegalArgumentException, RuntimeException );
+ virtual Any SAL_CALL get(const Any& array, sal_Int32 index)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
+ virtual void SAL_CALL set(Any& array, sal_Int32 index, const Any& value)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException );
+};
+
+ImplIntrospectionAdapter::ImplIntrospectionAdapter( ImplIntrospectionAccess* pAccess_,
+ const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ )
+ : mpAccess( pAccess_), mrInspectedObject( obj ), mpStaticImpl( pStaticImpl_ )
+{
+ mpStaticImpl->acquire();
+
+ // Objekt als Interfaceholen
+ TypeClass eType = mrInspectedObject.getValueType().getTypeClass();
+ if( eType == TypeClass_INTERFACE )
+ {
+ mxIface = *( Reference< XInterface >*)mrInspectedObject.getValue();
+
+ mxObjElementAccess = Reference<XElementAccess>::query( mxIface );
+ mxObjNameAccess = Reference<XNameAccess>::query( mxIface );
+ mxObjNameContainer = Reference<XNameContainer>::query( mxIface );
+ mxObjIndexAccess = Reference<XIndexAccess>::query( mxIface );
+ mxObjIndexContainer = Reference<XIndexContainer>::query( mxIface );
+ mxObjEnumerationAccess = Reference<XEnumerationAccess>::query( mxIface );
+ mxObjIdlArray = Reference<XIdlArray>::query( mxIface );
+ }
+}
+
+ImplIntrospectionAdapter::~ImplIntrospectionAdapter()
+{
+ mpStaticImpl->release();
+}
+
+// Methoden von XInterface
+Any SAL_CALL ImplIntrospectionAdapter::queryInterface( const Type& rType )
+ throw( RuntimeException )
+{
+ Any aRet( ::cppu::queryInterface(
+ rType,
+ static_cast< XPropertySet * >( this ),
+ static_cast< XFastPropertySet * >( this ),
+ static_cast< XPropertySetInfo * >( this ) ) );
+ if( !aRet.hasValue() )
+ aRet = OWeakObject::queryInterface( rType );
+
+ if( !aRet.hasValue() )
+ {
+ // Wrapper fuer die Objekt-Interfaces
+ if( ( mxObjElementAccess.is() && (aRet = ::cppu::queryInterface
+ ( rType, static_cast< XElementAccess* >( static_cast< XNameAccess* >( this ) ) ) ).hasValue() )
+ || ( mxObjNameAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameAccess* >( this ) ) ).hasValue() )
+ || ( mxObjNameContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XNameContainer* >( this ) ) ).hasValue() )
+ || ( mxObjIndexAccess.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexAccess* >( this ) ) ).hasValue() )
+ || ( mxObjIndexContainer.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIndexContainer* >( this ) ) ).hasValue() )
+ || ( mxObjEnumerationAccess .is() && (aRet = ::cppu::queryInterface( rType, static_cast< XEnumerationAccess* >( this ) ) ).hasValue() )
+ || ( mxObjIdlArray.is() && (aRet = ::cppu::queryInterface( rType, static_cast< XIdlArray* >( this ) ) ).hasValue() )
+ )
+ {
+ }
+ }
+ return aRet;
+}
+
+
+//*******************************
+//*** ImplIntrospectionAccess ***
+//*******************************
+
+// Neue Impl-Klasse im Rahmen der Introspection-Umstellung auf Instanz-gebundene
+// Introspection mit Property-Zugriff ueber XPropertySet. Die alte Klasse
+// ImplIntrospectionAccess lebt als IntrospectionAccessStatic_Impl
+class ImplIntrospectionAccess : IntrospectionAccessHelper
+{
+ friend class ImplIntrospection;
+
+ // Untersuchtes Objekt
+ Any maInspectedObject;
+
+ // Als Interface
+ Reference<XInterface> mxIface;
+
+ // Statische Daten der Introspection
+ IntrospectionAccessStatic_Impl* mpStaticImpl;
+
+ // Adapter-Implementation
+ ImplIntrospectionAdapter* mpAdapter;
+
+ // Letzte Sequence, die bei getProperties geliefert wurde (Optimierung)
+ Sequence<Property> maLastPropertySeq;
+ sal_Int32 mnLastPropertyConcept;
+
+ // Letzte Sequence, die bei getMethods geliefert wurde (Optimierung)
+ Sequence<Reference<XIdlMethod> > maLastMethodSeq;
+ sal_Int32 mnLastMethodConcept;
+
+public:
+ ImplIntrospectionAccess( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ );
+ ~ImplIntrospectionAccess();
+
+ // Methoden von XIntrospectionAccess
+ virtual sal_Int32 SAL_CALL getSuppliedMethodConcepts(void)
+ throw( RuntimeException );
+ virtual sal_Int32 SAL_CALL getSuppliedPropertyConcepts(void)
+ throw( RuntimeException );
+ virtual Property SAL_CALL getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( NoSuchElementException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( RuntimeException );
+ virtual Sequence< Property > SAL_CALL getProperties(sal_Int32 PropertyConcepts)
+ throw( RuntimeException );
+ virtual Reference<XIdlMethod> SAL_CALL getMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( NoSuchMethodException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( RuntimeException );
+ virtual Sequence< Reference<XIdlMethod> > SAL_CALL getMethods(sal_Int32 MethodConcepts)
+ throw( RuntimeException );
+ virtual Sequence< Type > SAL_CALL getSupportedListeners(void)
+ throw( RuntimeException );
+ using OWeakObject::queryAdapter;
+ virtual Reference<XInterface> SAL_CALL queryAdapter( const Type& rType )
+ throw( IllegalTypeException, RuntimeException );
+
+ // Methoden von XMaterialHolder
+ virtual Any SAL_CALL getMaterial(void) throw(RuntimeException);
+
+ // Methoden von XExactName
+ virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException );
+};
+
+ImplIntrospectionAccess::ImplIntrospectionAccess
+ ( const Any& obj, IntrospectionAccessStatic_Impl* pStaticImpl_ )
+ : maInspectedObject( obj ), mpStaticImpl( pStaticImpl_ ), mpAdapter( NULL )
+{
+ mpStaticImpl->acquire();
+
+ // Objekt als Interface merken, wenn moeglich
+ TypeClass eType = maInspectedObject.getValueType().getTypeClass();
+ if( eType == TypeClass_INTERFACE )
+ mxIface = *(Reference<XInterface>*)maInspectedObject.getValue();
+
+ mnLastPropertyConcept = -1;
+ mnLastMethodConcept = -1;
+}
+
+ImplIntrospectionAccess::~ImplIntrospectionAccess()
+{
+ mpStaticImpl->release();
+
+ // Eigene Referenz loslassen
+ if (mpAdapter)
+ mpAdapter->release();
+}
+
+
+//***************************************************
+//*** Implementation von ImplIntrospectionAdapter ***
+//***************************************************
+
+// Methoden von XPropertySet
+Reference<XPropertySetInfo> ImplIntrospectionAdapter::getPropertySetInfo(void)
+ throw( RuntimeException )
+{
+ return (XPropertySetInfo *)this;
+}
+
+void ImplIntrospectionAdapter::setPropertyValue(const OUString& aPropertyName, const Any& aValue)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
+{
+ mpStaticImpl->setPropertyValue( mrInspectedObject, aPropertyName, aValue );
+}
+
+Any ImplIntrospectionAdapter::getPropertyValue(const OUString& aPropertyName)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ return mpStaticImpl->getPropertyValue( mrInspectedObject, aPropertyName );
+}
+
+void ImplIntrospectionAdapter::addPropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
+ if( xPropSet.is() )
+ xPropSet->addPropertyChangeListener(aPropertyName, aListener);
+ }
+}
+
+void ImplIntrospectionAdapter::removePropertyChangeListener(const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
+ if( xPropSet.is() )
+ xPropSet->removePropertyChangeListener(aPropertyName, aListener);
+ }
+}
+
+void ImplIntrospectionAdapter::addVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ //Reference<XPropertySet> xPropSet( mxIface, USR_QUERY );
+ if( xPropSet.is() )
+ xPropSet->addVetoableChangeListener(aPropertyName, aListener);
+ }
+}
+
+void ImplIntrospectionAdapter::removeVetoableChangeListener(const OUString& aPropertyName, const Reference<XVetoableChangeListener>& aListener)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ if( mxIface.is() )
+ {
+ Reference<XPropertySet> xPropSet =
+ Reference<XPropertySet>::query( mxIface );
+ if( xPropSet.is() )
+ xPropSet->removeVetoableChangeListener(aPropertyName, aListener);
+ }
+}
+
+
+// Methoden von XFastPropertySet
+void ImplIntrospectionAdapter::setFastPropertyValue(sal_Int32, const Any&)
+ throw( UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
+{
+}
+
+Any ImplIntrospectionAdapter::getFastPropertyValue(sal_Int32)
+ throw( UnknownPropertyException, WrappedTargetException, RuntimeException )
+{
+ return Any();
+}
+
+// Methoden von XPropertySetInfo
+Sequence< Property > ImplIntrospectionAdapter::getProperties(void) throw( RuntimeException )
+{
+ return mpStaticImpl->getProperties();
+}
+
+Property ImplIntrospectionAdapter::getPropertyByName(const OUString& Name)
+ throw( RuntimeException )
+{
+ return mpAccess->getProperty( Name, PropertyConcept::ALL );
+}
+
+sal_Bool ImplIntrospectionAdapter::hasPropertyByName(const OUString& Name)
+ throw( RuntimeException )
+{
+ return mpAccess->hasProperty( Name, PropertyConcept::ALL );
+}
+
+// Methoden von XElementAccess
+Type ImplIntrospectionAdapter::getElementType(void) throw( RuntimeException )
+{
+ return mxObjElementAccess->getElementType();
+}
+
+sal_Bool ImplIntrospectionAdapter::hasElements(void) throw( RuntimeException )
+{
+ return mxObjElementAccess->hasElements();
+}
+
+// Methoden von XNameAccess
+Any ImplIntrospectionAdapter::getByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ return mxObjNameAccess->getByName( Name );
+}
+
+Sequence< OUString > ImplIntrospectionAdapter::getElementNames(void)
+ throw( RuntimeException )
+{
+ return mxObjNameAccess->getElementNames();
+}
+
+sal_Bool ImplIntrospectionAdapter::hasByName(const OUString& Name)
+ throw( RuntimeException )
+{
+ return mxObjNameAccess->hasByName( Name );
+}
+
+// Methoden von XNameContainer
+void ImplIntrospectionAdapter::insertByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
+{
+ mxObjNameContainer->insertByName( Name, Element );
+}
+
+void ImplIntrospectionAdapter::replaceByName(const OUString& Name, const Any& Element)
+ throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ mxObjNameContainer->replaceByName( Name, Element );
+}
+
+void ImplIntrospectionAdapter::removeByName(const OUString& Name)
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+{
+ mxObjNameContainer->removeByName( Name );
+}
+
+// Methoden von XIndexAccess
+// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const
+sal_Int32 ImplIntrospectionAdapter::getCount(void) throw( RuntimeException )
+{
+ return mxObjIndexAccess->getCount();
+}
+
+Any ImplIntrospectionAdapter::getByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ return mxObjIndexAccess->getByIndex( Index );
+}
+
+// Methoden von XIndexContainer
+void ImplIntrospectionAdapter::insertByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ mxObjIndexContainer->insertByIndex( Index, Element );
+}
+
+void ImplIntrospectionAdapter::replaceByIndex(sal_Int32 Index, const Any& Element)
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ mxObjIndexContainer->replaceByIndex( Index, Element );
+}
+
+void ImplIntrospectionAdapter::removeByIndex(sal_Int32 Index)
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+{
+ mxObjIndexContainer->removeByIndex( Index );
+}
+
+// Methoden von XEnumerationAccess
+// Schon in XNameAccess: virtual Reference<XIdlClass> getElementType(void) const;
+Reference<XEnumeration> ImplIntrospectionAdapter::createEnumeration(void) throw( RuntimeException )
+{
+ return mxObjEnumerationAccess->createEnumeration();
+}
+
+// Methoden von XIdlArray
+void ImplIntrospectionAdapter::realloc(Any& array, sal_Int32 length)
+ throw( IllegalArgumentException, RuntimeException )
+{
+ mxObjIdlArray->realloc( array, length );
+}
+
+sal_Int32 ImplIntrospectionAdapter::getLen(const Any& array)
+ throw( IllegalArgumentException, RuntimeException )
+{
+ return mxObjIdlArray->getLen( array );
+}
+
+Any ImplIntrospectionAdapter::get(const Any& array, sal_Int32 index)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
+{
+ return mxObjIdlArray->get( array, index );
+}
+
+void ImplIntrospectionAdapter::set(Any& array, sal_Int32 index, const Any& value)
+ throw( IllegalArgumentException, ArrayIndexOutOfBoundsException, RuntimeException )
+{
+ mxObjIdlArray->set( array, index, value );
+}
+
+
+//**************************************************
+//*** Implementation von ImplIntrospectionAccess ***
+//**************************************************
+
+// Methoden von XIntrospectionAccess
+sal_Int32 ImplIntrospectionAccess::getSuppliedMethodConcepts(void)
+ throw( RuntimeException )
+{
+ return MethodConcept::DANGEROUS |
+ PROPERTY |
+ LISTENER |
+ ENUMERATION |
+ NAMECONTAINER |
+ INDEXCONTAINER;
+}
+
+sal_Int32 ImplIntrospectionAccess::getSuppliedPropertyConcepts(void)
+ throw( RuntimeException )
+{
+ return PropertyConcept::DANGEROUS |
+ PROPERTYSET |
+ ATTRIBUTES |
+ METHODS;
+}
+
+Property ImplIntrospectionAccess::getProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( NoSuchElementException, RuntimeException )
+{
+ Property aRet;
+ sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
+ sal_Bool bFound = sal_False;
+ if( i != -1 )
+ {
+ sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
+ if( (PropertyConcepts & nConcept) != 0 )
+ {
+ const Property* pProps = mpStaticImpl->getProperties().getConstArray();
+ aRet = pProps[ i ];
+ bFound = sal_True;
+ }
+ }
+ if( !bFound )
+ throw NoSuchElementException() ;
+ return aRet;
+}
+
+sal_Bool ImplIntrospectionAccess::hasProperty(const OUString& Name, sal_Int32 PropertyConcepts)
+ throw( RuntimeException )
+{
+ sal_Int32 i = mpStaticImpl->getPropertyIndex( Name );
+ sal_Bool bRet = sal_False;
+ if( i != -1 )
+ {
+ sal_Int32 nConcept = mpStaticImpl->getPropertyConcepts().getConstArray()[ i ];
+ if( (PropertyConcepts & nConcept) != 0 )
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+Sequence< Property > ImplIntrospectionAccess::getProperties(sal_Int32 PropertyConcepts)
+ throw( RuntimeException )
+{
+ // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
+ sal_Int32 nAllSupportedMask = PROPERTYSET |
+ ATTRIBUTES |
+ METHODS;
+ if( ( PropertyConcepts & nAllSupportedMask ) == nAllSupportedMask )
+ {
+ return mpStaticImpl->getProperties();
+ }
+
+ // Gleiche Sequence wie beim vorigen mal?
+ if( mnLastPropertyConcept == PropertyConcepts )
+ {
+ return maLastPropertySeq;
+ }
+
+ // Anzahl der zu liefernden Properties
+ sal_Int32 nCount = 0;
+
+ // Es gibt zur Zeit keine DANGEROUS-Properties
+ // if( PropertyConcepts & DANGEROUS )
+ // nCount += mpStaticImpl->mnDangerousPropCount;
+ if( PropertyConcepts & PROPERTYSET )
+ nCount += mpStaticImpl->mnPropertySetPropCount;
+ if( PropertyConcepts & ATTRIBUTES )
+ nCount += mpStaticImpl->mnAttributePropCount;
+ if( PropertyConcepts & METHODS )
+ nCount += mpStaticImpl->mnMethodPropCount;
+
+ // Sequence entsprechend der geforderten Anzahl reallocieren
+ ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
+ pThis->maLastPropertySeq.realloc( nCount );
+ Property* pDestProps = pThis->maLastPropertySeq.getArray();
+
+ // Alle Properties durchgehen und entsprechend der Concepte uebernehmen
+ Sequence<Property> aPropSeq = mpStaticImpl->getProperties();
+ const Property* pSourceProps = aPropSeq.getConstArray();
+ const sal_Int32* pConcepts = mpStaticImpl->getPropertyConcepts().getConstArray();
+ sal_Int32 nLen = aPropSeq.getLength();
+
+ sal_Int32 iDest = 0;
+ for( sal_Int32 i = 0 ; i < nLen ; i++ )
+ {
+ sal_Int32 nConcept = pConcepts[ i ];
+ if( nConcept & PropertyConcepts )
+ pDestProps[ iDest++ ] = pSourceProps[ i ];
+
+ /*
+ // Property mit Concepts ausgeben
+ OUString aPropName = pSourceProps[ i ].Name;
+ String aNameStr = OOUStringToString(aPropName, CHARSET_SYSTEM);
+ String ConceptStr;
+ if( nConcept & PROPERTYSET )
+ ConceptStr += "PROPERTYSET";
+ if( nConcept & ATTRIBUTES )
+ ConceptStr += "ATTRIBUTES";
+ if( nConcept & METHODS )
+ ConceptStr += "METHODS";
+ printf( "Property %ld: %s, Concept = %s\n", i, aNameStr.GetStr(), ConceptStr.GetStr() );
+ */
+ }
+
+ // PropertyConcept merken, dies entspricht maLastPropertySeq
+ pThis->mnLastPropertyConcept = PropertyConcepts;
+
+ // Zusammengebastelte Sequence liefern
+ return maLastPropertySeq;
+}
+
+Reference<XIdlMethod> ImplIntrospectionAccess::getMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( NoSuchMethodException, RuntimeException )
+{
+ Reference<XIdlMethod> xRet;
+ sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
+ if( i != -1 )
+ {
+
+ sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
+ if( (MethodConcepts & nConcept) != 0 )
+ {
+ const Reference<XIdlMethod>* pMethods = mpStaticImpl->getMethods().getConstArray();
+ xRet = pMethods[i];
+ }
+ }
+ if( !xRet.is() )
+ throw NoSuchMethodException();
+ return xRet;
+}
+
+sal_Bool ImplIntrospectionAccess::hasMethod(const OUString& Name, sal_Int32 MethodConcepts)
+ throw( RuntimeException )
+{
+ sal_Int32 i = mpStaticImpl->getMethodIndex( Name );
+ sal_Bool bRet = sal_False;
+ if( i != -1 )
+ {
+ sal_Int32 nConcept = mpStaticImpl->getMethodConcepts().getConstArray()[ i ];
+ if( (MethodConcepts & nConcept) != 0 )
+ bRet = sal_True;
+ }
+ return bRet;
+}
+
+Sequence< Reference<XIdlMethod> > ImplIntrospectionAccess::getMethods(sal_Int32 MethodConcepts)
+ throw( RuntimeException )
+{
+ ImplIntrospectionAccess* pThis = (ImplIntrospectionAccess*)this; // const umgehen
+
+ // Wenn alle unterstuetzten Konzepte gefordert werden, Sequence einfach durchreichen
+ sal_Int32 nAllSupportedMask = MethodConcept::DANGEROUS |
+ PROPERTY |
+ LISTENER |
+ ENUMERATION |
+ NAMECONTAINER |
+ INDEXCONTAINER |
+ MethodConcept_NORMAL_IMPL;
+ if( ( MethodConcepts & nAllSupportedMask ) == nAllSupportedMask )
+ {
+ return mpStaticImpl->getMethods();
+ }
+
+ // Gleiche Sequence wie beim vorigen mal?
+ if( mnLastMethodConcept == MethodConcepts )
+ {
+ return maLastMethodSeq;
+ }
+
+ // Methoden-Sequences besorgen
+ Sequence< Reference<XIdlMethod> > aMethodSeq = mpStaticImpl->getMethods();
+ const Reference<XIdlMethod>* pSourceMethods = aMethodSeq.getConstArray();
+ const sal_Int32* pConcepts = mpStaticImpl->getMethodConcepts().getConstArray();
+ sal_Int32 nLen = aMethodSeq.getLength();
+
+ // Sequence entsprechend der geforderten Anzahl reallocieren
+ // Anders als bei den Properties kann die Anzahl nicht durch
+ // Zaehler in inspect() vorher ermittelt werden, da Methoden
+ // mehreren Konzepten angehoeren koennen
+ pThis->maLastMethodSeq.realloc( nLen );
+ Reference<XIdlMethod>* pDestMethods = pThis->maLastMethodSeq.getArray();
+
+ // Alle Methods durchgehen und entsprechend der Concepte uebernehmen
+ sal_Int32 iDest = 0;
+ for( sal_Int32 i = 0 ; i < nLen ; i++ )
+ {
+ sal_Int32 nConcept = pConcepts[ i ];
+ if( nConcept & MethodConcepts )
+ pDestMethods[ iDest++ ] = pSourceMethods[ i ];
+
+ #if OSL_DEBUG_LEVEL > 0
+ static bool debug = false;
+ if ( debug )
+ {
+ // Methode mit Concepts ausgeben
+ const Reference< XIdlMethod >& rxMethod = pSourceMethods[ i ];
+ ::rtl::OString aNameStr = ::rtl::OUStringToOString( rxMethod->getName(), osl_getThreadTextEncoding() );
+ ::rtl::OString ConceptStr;
+ if( nConcept & MethodConcept::DANGEROUS )
+ ConceptStr += "DANGEROUS |";
+ if( nConcept & MethodConcept::PROPERTY )
+ ConceptStr += "PROPERTY |";
+ if( nConcept & MethodConcept::LISTENER )
+ ConceptStr += "LISTENER |";
+ if( nConcept & MethodConcept::ENUMERATION )
+ ConceptStr += "ENUMERATION |";
+ if( nConcept & MethodConcept::NAMECONTAINER )
+ ConceptStr += "NAMECONTAINER |";
+ if( nConcept & MethodConcept::INDEXCONTAINER )
+ ConceptStr += "INDEXCONTAINER |";
+ OSL_TRACE( "Method %ld: %s, Concepts = %s", i, aNameStr.getStr(), ConceptStr.getStr() );
+ }
+ #endif
+ }
+
+ // Auf die richtige Laenge bringen
+ pThis->maLastMethodSeq.realloc( iDest );
+
+ // MethodConcept merken, dies entspricht maLastMethodSeq
+ pThis->mnLastMethodConcept = MethodConcepts;
+
+ // Zusammengebastelte Sequence liefern
+ return maLastMethodSeq;
+}
+
+Sequence< Type > ImplIntrospectionAccess::getSupportedListeners(void)
+ throw( RuntimeException )
+{
+ return mpStaticImpl->getSupportedListeners();
+}
+
+Reference<XInterface> SAL_CALL ImplIntrospectionAccess::queryAdapter( const Type& rType )
+ throw( IllegalTypeException, RuntimeException )
+{
+ // Gibt es schon einen Adapter?
+ if( !mpAdapter )
+ {
+ ((ImplIntrospectionAccess*)this)->mpAdapter =
+ new ImplIntrospectionAdapter( this, maInspectedObject, mpStaticImpl );
+
+ // Selbst eine Referenz halten
+ mpAdapter->acquire();
+ }
+
+ Reference<XInterface> xRet;
+ Any aIfaceAny( mpAdapter->queryInterface( rType ) );
+ if( aIfaceAny.hasValue() )
+ xRet = *(Reference<XInterface>*)aIfaceAny.getValue();
+
+ return xRet;
+}
+
+// Methoden von XMaterialHolder
+Any ImplIntrospectionAccess::getMaterial(void) throw(RuntimeException)
+{
+ return maInspectedObject;
+}
+
+// Hilfs-Funktion zur LowerCase-Wandlung eines OUString
+OUString toLower( OUString aUStr )
+{
+ // Tabelle fuer XExactName pflegen
+ ::rtl::OUString aOWStr( aUStr.getStr() );
+ ::rtl::OUString aOWLowerStr = aOWStr.toAsciiLowerCase();
+ OUString aLowerUStr( aOWLowerStr.getStr() );
+ return aLowerUStr;
+}
+
+// Methoden von XExactName
+OUString ImplIntrospectionAccess::getExactName( const OUString& rApproximateName ) throw( RuntimeException )
+{
+ OUString aRetStr;
+ LowerToExactNameMap::iterator aIt =
+ mpStaticImpl->maLowerToExactNameMap.find( toLower( rApproximateName ) );
+ if( !( aIt == mpStaticImpl->maLowerToExactNameMap.end() ) )
+ aRetStr = (*aIt).second;
+ return aRetStr;
+}
+
+
+//-----------------------------------------------------------------------------
+
+#ifdef USE_INTROSPECTION_CACHE
+
+struct hashIntrospectionKey_Impl
+{
+ Sequence< Reference<XIdlClass> > aIdlClasses;
+ Reference<XPropertySetInfo> xPropInfo;
+ Reference<XIdlClass> xImplClass;
+ sal_Int32 nHitCount;
+
+ void IncHitCount() const { ((hashIntrospectionKey_Impl*)this)->nHitCount++; }
+ hashIntrospectionKey_Impl() : nHitCount( 0 ) {}
+ hashIntrospectionKey_Impl( const Sequence< Reference<XIdlClass> > & rIdlClasses,
+ const Reference<XPropertySetInfo> & rxPropInfo,
+ const Reference<XIdlClass> & rxImplClass );
+};
+
+hashIntrospectionKey_Impl::hashIntrospectionKey_Impl
+(
+ const Sequence< Reference<XIdlClass> > & rIdlClasses,
+ const Reference<XPropertySetInfo> & rxPropInfo,
+ const Reference<XIdlClass> & rxImplClass
+)
+ : aIdlClasses( rIdlClasses )
+ , xPropInfo( rxPropInfo )
+ , xImplClass( rxImplClass )
+ , nHitCount( 0 )
+{}
+
+
+struct hashIntrospectionAccessCache_Impl
+{
+ size_t operator()(const hashIntrospectionKey_Impl & rObj ) const
+ {
+ return (size_t)rObj.xImplClass.get() ^ (size_t)rObj.xPropInfo.get();
+ }
+
+ bool operator()( const hashIntrospectionKey_Impl & rObj1,
+ const hashIntrospectionKey_Impl & rObj2 ) const
+ {
+ if( rObj1.xPropInfo != rObj2.xPropInfo
+ || rObj1.xImplClass != rObj2.xImplClass )
+ return sal_False;
+
+ sal_Int32 nCount1 = rObj1.aIdlClasses.getLength();
+ sal_Int32 nCount2 = rObj2.aIdlClasses.getLength();
+ if( nCount1 != nCount2 )
+ return sal_False;
+
+ const Reference<XIdlClass>* pRefs1 = rObj1.aIdlClasses.getConstArray();
+ const Reference<XIdlClass>* pRefs2 = rObj2.aIdlClasses.getConstArray();
+ return memcmp( pRefs1, pRefs2, nCount1 * sizeof( Reference<XIdlClass> ) ) == 0;
+ }
+
+};
+
+typedef std::hash_map
+<
+ hashIntrospectionKey_Impl,
+ IntrospectionAccessStatic_Impl*,
+ hashIntrospectionAccessCache_Impl,
+ hashIntrospectionAccessCache_Impl
+>
+IntrospectionAccessCacheMap_Impl;
+
+class IntrospectionAccessCacheMap : public IntrospectionAccessCacheMap_Impl
+{
+public:
+ ~IntrospectionAccessCacheMap()
+ {
+ IntrospectionAccessCacheMap::iterator iter = begin();
+ IntrospectionAccessCacheMap::iterator stop = this->end();
+ while( iter != stop )
+ {
+
+ (*iter).second->release();
+ (*iter).second = NULL;
+ iter++;
+ }
+ }
+};
+
+
+// For XTypeProvider
+struct hashTypeProviderKey_Impl
+{
+ Reference<XPropertySetInfo> xPropInfo;
+ Sequence< sal_Int8 > maImpIdSeq;
+ sal_Int32 nHitCount;
+
+ void IncHitCount() const { ((hashTypeProviderKey_Impl*)this)->nHitCount++; }
+ hashTypeProviderKey_Impl() : nHitCount( 0 ) {}
+ hashTypeProviderKey_Impl( const Reference<XPropertySetInfo> & rxPropInfo, const Sequence< sal_Int8 > & aImpIdSeq_ );
+};
+
+hashTypeProviderKey_Impl::hashTypeProviderKey_Impl
+(
+ const Reference<XPropertySetInfo> & rxPropInfo,
+ const Sequence< sal_Int8 > & aImpIdSeq_
+)
+ : xPropInfo( rxPropInfo )
+ , maImpIdSeq( aImpIdSeq_ )
+ , nHitCount( 0 )
+{}
+
+
+struct TypeProviderAccessCache_Impl
+{
+ size_t operator()(const hashTypeProviderKey_Impl & rObj ) const;
+
+ bool operator()( const hashTypeProviderKey_Impl & rObj1,
+ const hashTypeProviderKey_Impl & rObj2 ) const
+ {
+ if( rObj1.xPropInfo != rObj2.xPropInfo )
+ return sal_False;
+
+ bool bEqual = false;
+ sal_Int32 nLen1 = rObj1.maImpIdSeq.getLength();
+ sal_Int32 nLen2 = rObj2.maImpIdSeq.getLength();
+ if( nLen1 == nLen2 && nLen1 > 0 )
+ {
+ const sal_Int8* pId1 = rObj1.maImpIdSeq.getConstArray();
+ const sal_Int8* pId2 = rObj2.maImpIdSeq.getConstArray();
+ bEqual = (memcmp( pId1, pId2, nLen1 * sizeof( sal_Int8 ) ) == 0 );
+ }
+ return bEqual;
+ }
+};
+
+size_t TypeProviderAccessCache_Impl::operator()(const hashTypeProviderKey_Impl & rObj ) const
+{
+ const sal_Int32* pBytesAsInt32Array = (const sal_Int32*)rObj.maImpIdSeq.getConstArray();
+ sal_Int32 nLen = rObj.maImpIdSeq.getLength();
+ sal_Int32 nCount32 = nLen / 4;
+ sal_Int32 nMod32 = nLen % 4;
+
+ // XOR with full 32 bit values
+ sal_Int32 nId32 = 0;
+ sal_Int32 i;
+ for( i = 0 ; i < nCount32 ; i++ )
+ nId32 ^= *(pBytesAsInt32Array++);
+
+ // XOR with remaining byte values
+ if( nMod32 )
+ {
+ const sal_Int8* pBytes = (const sal_Int8*)pBytesAsInt32Array;
+ sal_Int8* pInt8_Id32 = (sal_Int8*)&nId32;
+ for( i = 0 ; i < nMod32 ; i++ )
+ *(pInt8_Id32++) ^= *(pBytes++);
+ }
+
+ return (size_t)nId32;
+}
+
+
+typedef std::hash_map
+<
+ hashTypeProviderKey_Impl,
+ IntrospectionAccessStatic_Impl*,
+ TypeProviderAccessCache_Impl,
+ TypeProviderAccessCache_Impl
+>
+TypeProviderAccessCacheMap_Impl;
+
+class TypeProviderAccessCacheMap : public TypeProviderAccessCacheMap_Impl
+{
+public:
+ ~TypeProviderAccessCacheMap()
+ {
+ TypeProviderAccessCacheMap::iterator iter = begin();
+ TypeProviderAccessCacheMap::iterator stop = this->end();
+ while( iter != stop )
+ {
+ (*iter).second->release();
+ (*iter).second = NULL;
+ iter++;
+ }
+ }
+};
+
+#endif
+
+
+//*************************
+//*** ImplIntrospection ***
+//*************************
+
+struct OIntrospectionMutex
+{
+ Mutex m_mutex;
+};
+
+class ImplIntrospection : public XIntrospection
+ , public XServiceInfo
+ , public OIntrospectionMutex
+ , public OComponentHelper
+{
+ friend class ImplMergeIntrospection;
+ friend class ImplMVCIntrospection;
+
+ // Implementation der Introspection.
+ // ACHTUNG: RefCounting von Hand !!!
+ IntrospectionAccessStatic_Impl* implInspect(const Any& aToInspectObj);
+
+ // Save XMultiServiceFactory from createComponent
+ Reference<XMultiServiceFactory> m_xSMgr;
+
+ // CoreReflection halten
+ Reference< XIdlReflection > mxCoreReflection;
+
+ // Klassen, deren Methoden eine spezielle Rolle spielen
+ Reference<XIdlClass> mxElementAccessClass;
+ Reference<XIdlClass> mxNameContainerClass;
+ Reference<XIdlClass> mxNameAccessClass;
+ Reference<XIdlClass> mxIndexContainerClass;
+ Reference<XIdlClass> mxIndexAccessClass;
+ Reference<XIdlClass> mxEnumerationAccessClass;
+ Reference<XIdlClass> mxInterfaceClass;
+ Reference<XIdlClass> mxAggregationClass;
+ sal_Bool mbDisposed;
+
+#ifdef USE_INTROSPECTION_CACHE
+ sal_uInt16 mnCacheEntryCount;
+ sal_uInt16 mnTPCacheEntryCount;
+ IntrospectionAccessCacheMap* mpCache;
+ TypeProviderAccessCacheMap* mpTypeProviderCache;
+#endif
+
+public:
+ ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr );
+
+ // Methoden von XInterface
+ virtual Any SAL_CALL queryInterface( const Type& rType ) throw( RuntimeException );
+ virtual void SAL_CALL acquire() throw() { OComponentHelper::acquire(); }
+ virtual void SAL_CALL release() throw() { OComponentHelper::release(); }
+
+ // XTypeProvider
+ Sequence< Type > SAL_CALL getTypes( ) throw( RuntimeException );
+ Sequence<sal_Int8> SAL_CALL getImplementationId( ) throw( RuntimeException );
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() throw();
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw();
+ Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw();
+ static OUString SAL_CALL getImplementationName_Static( );
+ static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static(void) throw();
+
+ // Methoden von XIntrospection
+ virtual Reference<XIntrospectionAccess> SAL_CALL inspect(const Any& aToInspectObj)
+ throw( RuntimeException );
+
+protected:
+ // some XComponent part from OComponentHelper
+ virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+};
+
+enum MethodType
+{
+ STANDARD_METHOD, // normale Methode, kein Bezug zu Properties oder Listenern
+ GETSET_METHOD, // gehoert zu einer get/set-Property
+ ADD_LISTENER_METHOD, // add-Methode einer Listener-Schnittstelle
+ REMOVE_LISTENER_METHOD, // remove-Methode einer Listener-Schnittstelle
+ INVALID_METHOD // Methode, deren Klasse nicht beruecksichtigt wird, z.B. XPropertySet
+};
+
+// Ctor
+ImplIntrospection::ImplIntrospection( const Reference<XMultiServiceFactory> & rXSMgr )
+ : OComponentHelper( m_mutex )
+ , m_xSMgr( rXSMgr )
+{
+#ifdef USE_INTROSPECTION_CACHE
+ mnCacheEntryCount = 0;
+ mnTPCacheEntryCount = 0;
+ mpCache = NULL;
+ mpTypeProviderCache = NULL;
+#endif
+
+ // Spezielle Klassen holen
+// Reference< XInterface > xServiceIface = m_xSMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) );
+// if( xServiceIface.is() )
+// mxCoreReflection = Reference< XIdlReflection >::query( xServiceIface );
+ Reference< XPropertySet > xProps( rXSMgr, UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ Reference< XComponentContext > xContext;
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xContext;
+ OSL_ASSERT( xContext.is() );
+ if (xContext.is())
+ {
+ xContext->getValueByName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection") ) ) >>= mxCoreReflection;
+ OSL_ENSURE( mxCoreReflection.is(), "### CoreReflection singleton not accessible!?" );
+ }
+ }
+ if (! mxCoreReflection.is())
+ {
+ throw DeploymentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessible") ),
+ Reference< XInterface >() );
+ }
+
+ mxElementAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XElementAccess")) );
+ mxNameContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameContainer")) );
+ mxNameAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XNameAccess")) );
+ mxIndexContainerClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexContainer")) );
+ mxIndexAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XIndexAccess")) );
+ mxEnumerationAccessClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.container.XEnumerationAccess")) );
+ mxInterfaceClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XInterface")) );
+ mxAggregationClass = mxCoreReflection->forName( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XAggregation")) );
+ mbDisposed = sal_False;
+}
+
+// XComponent
+void ImplIntrospection::dispose() throw(::com::sun::star::uno::RuntimeException)
+{
+ OComponentHelper::dispose();
+
+#ifdef USE_INTROSPECTION_CACHE
+ // Cache loeschen
+ delete mpCache;
+ mpCache = NULL;
+ delete mpTypeProviderCache;
+ mpTypeProviderCache = NULL;
+#endif
+
+ mxElementAccessClass = NULL;
+ mxNameContainerClass = NULL;
+ mxNameAccessClass = NULL;
+ mxIndexContainerClass = NULL;
+ mxIndexAccessClass = NULL;
+ mxEnumerationAccessClass = NULL;
+ mxInterfaceClass = NULL;
+ mxAggregationClass = NULL;
+ mbDisposed = sal_True;
+}
+
+
+//-----------------------------------------------------------------------------
+
+// XInterface
+Any ImplIntrospection::queryInterface( const Type & rType )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Any aRet( ::cppu::queryInterface(
+ rType,
+ static_cast< XIntrospection * >( this ),
+ static_cast< XServiceInfo * >( this ) ) );
+
+ return (aRet.hasValue() ? aRet : OComponentHelper::queryInterface( rType ));
+}
+
+// XTypeProvider
+Sequence< Type > ImplIntrospection::getTypes()
+ throw( RuntimeException )
+{
+ static OTypeCollection * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pTypes)
+ {
+ static OTypeCollection s_aTypes(
+ ::getCppuType( (const Reference< XIntrospection > *)0 ),
+ ::getCppuType( (const Reference< XServiceInfo > *)0 ),
+ OComponentHelper::getTypes() );
+ s_pTypes = &s_aTypes;
+ }
+ }
+ return s_pTypes->getTypes();
+}
+
+Sequence< sal_Int8 > ImplIntrospection::getImplementationId()
+ throw( RuntimeException )
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+
+// XServiceInfo
+OUString ImplIntrospection::getImplementationName() throw()
+{
+ return getImplementationName_Static();
+}
+
+// XServiceInfo
+sal_Bool ImplIntrospection::supportsService(const OUString& ServiceName) throw()
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > ImplIntrospection::getSupportedServiceNames(void) throw()
+{
+ return getSupportedServiceNames_Static();
+}
+
+//*************************************************************************
+// Helper XServiceInfo
+OUString ImplIntrospection::getImplementationName_Static( )
+{
+ return OUString::createFromAscii( IMPLEMENTATION_NAME );
+}
+
+// ORegistryServiceManager_Static
+Sequence< OUString > ImplIntrospection::getSupportedServiceNames_Static(void) throw()
+{
+ Sequence< OUString > aSNS( 1 );
+ aSNS.getArray()[0] = OUString::createFromAscii( SERVICE_NAME );
+ return aSNS;
+}
+
+//*************************************************************************
+
+// Methoden von XIntrospection
+Reference<XIntrospectionAccess> ImplIntrospection::inspect(const Any& aToInspectObj)
+ throw( RuntimeException )
+{
+ Reference<XIntrospectionAccess> xAccess;
+
+ if ( aToInspectObj.getValueType().getTypeClass() == TypeClass_TYPE )
+ {
+ Type aType;
+ aToInspectObj >>= aType;
+
+ Reference< XIdlClass > xIdlClass = mxCoreReflection->forName(((Type*)(aToInspectObj.getValue()))->getTypeName());
+
+ if ( xIdlClass.is() )
+ {
+ Any aRealInspectObj;
+ aRealInspectObj <<= xIdlClass;
+
+ IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aRealInspectObj );
+ if( pStaticImpl )
+ xAccess = new ImplIntrospectionAccess( aRealInspectObj, pStaticImpl );
+ }
+ }
+ else
+ {
+ IntrospectionAccessStatic_Impl* pStaticImpl = implInspect( aToInspectObj );
+ if( pStaticImpl )
+ xAccess = new ImplIntrospectionAccess( aToInspectObj, pStaticImpl );
+ }
+
+ return xAccess;
+}
+
+//-----------------------------------------------------------------------------
+
+// Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
+struct hashInterface_Impl
+{
+ size_t operator()(const void* p) const
+ {
+ return (size_t)p;
+ }
+};
+
+struct eqInterface_Impl
+{
+ bool operator()(const void* p1, const void* p2) const
+ {
+ return ( p1 == p2 );
+ }
+};
+
+typedef std::hash_map
+<
+ void*,
+ void*,
+ hashInterface_Impl,
+ eqInterface_Impl
+>
+CheckedInterfacesMap;
+
+
+
+// TODO: Spaeter auslagern
+Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XMultiServiceFactory > & xMgr )
+{
+ static Reference< XIdlReflection > xRefl;
+
+ // void als Default-Klasse eintragen
+ Reference<XIdlClass> xRetClass;
+ typelib_TypeDescription * pTD = 0;
+ rType.getDescription( &pTD );
+ if( pTD )
+ {
+ OUString sOWName( pTD->pTypeName );
+ if( !xRefl.is() )
+ {
+ xRefl = Reference< XIdlReflection >( xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")) ), UNO_QUERY );
+ OSL_ENSURE( xRefl.is(), "### no corereflection!" );
+ }
+ xRetClass = xRefl->forName( sOWName );
+ }
+ return xRetClass;
+}
+
+// Implementation der Introspection.
+IntrospectionAccessStatic_Impl* ImplIntrospection::implInspect(const Any& aToInspectObj)
+{
+ MutexGuard aGuard( m_mutex );
+
+ // Wenn die Introspection schon disposed ist, wird nur ein leeres Ergebnis geliefert
+ if( mbDisposed )
+ return NULL;
+
+ // Objekt untersuchen
+ TypeClass eType = aToInspectObj.getValueType().getTypeClass();
+ if( eType != TypeClass_INTERFACE && eType != TypeClass_STRUCT && eType != TypeClass_EXCEPTION )
+ return NULL;
+
+ Reference<XInterface> x;
+ if( eType == TypeClass_INTERFACE )
+ {
+ // Interface aus dem Any besorgen
+ x = *(Reference<XInterface>*)aToInspectObj.getValue();
+ if( !x.is() )
+ return NULL;
+ }
+
+#ifdef USE_INTROSPECTION_CACHE
+ // Haben wir schon eine Cache-Instanz
+ if( !mpCache )
+ mpCache = new IntrospectionAccessCacheMap;
+ if( !mpTypeProviderCache )
+ mpTypeProviderCache = new TypeProviderAccessCacheMap;
+ IntrospectionAccessCacheMap& aCache = *mpCache;
+ TypeProviderAccessCacheMap& aTPCache = *mpTypeProviderCache;
+
+ // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
+ IntrospectionAccessStatic_Impl* pAccess = NULL;
+#else
+ // Pointer auf ggf. noetige neue IntrospectionAccess-Instanz
+ IntrospectionAccessStatic_Impl* pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+#endif
+
+ // Pruefen: Ist schon ein passendes Access-Objekt gecached?
+ Sequence< Reference<XIdlClass> > SupportedClassSeq;
+ Sequence< Type > SupportedTypesSeq;
+ Reference<XIdlClassProvider> xClassProvider;
+ Reference<XTypeProvider> xTypeProvider;
+ Reference<XIdlClass> xImplClass;
+ Reference<XPropertySetInfo> xPropSetInfo;
+ Reference<XPropertySet> xPropSet;
+
+ // Bei Interfaces XTypeProvider / XIdlClassProvider- und PropertySet-Interface anfordern
+ if( eType == TypeClass_INTERFACE )
+ {
+ // XIdlClassProvider
+ xTypeProvider = Reference<XTypeProvider>::query( x );
+ if( xTypeProvider.is() )
+ {
+ SupportedTypesSeq = xTypeProvider->getTypes();
+ sal_Int32 nTypeCount = SupportedTypesSeq.getLength();
+ if( nTypeCount )
+ {
+ SupportedClassSeq.realloc( nTypeCount );
+ Reference<XIdlClass>* pClasses = SupportedClassSeq.getArray();
+
+ const Type* pTypes = SupportedTypesSeq.getConstArray();
+ for( sal_Int32 i = 0 ; i < nTypeCount ; i++ )
+ {
+ pClasses[ i ] = TypeToIdlClass( pTypes[ i ], m_xSMgr );
+ }
+ // TODO: Caching!
+ }
+ }
+ else
+ {
+ // XIdlClassProvider
+ xClassProvider = Reference<XIdlClassProvider>::query( x );
+ if( xClassProvider.is() )
+ {
+ SupportedClassSeq = xClassProvider->getIdlClasses();
+ if( SupportedClassSeq.getLength() )
+ xImplClass = SupportedClassSeq.getConstArray()[0];
+ }
+ }
+ // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne
+ // ClassProvider unterstuetzen
+ if( !xClassProvider.is() && !xTypeProvider.is() )
+ {
+ xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
+ SupportedClassSeq.realloc( 1 );
+ SupportedClassSeq.getArray()[ 0 ] = xImplClass;
+ }
+
+ xPropSet = Reference<XPropertySet>::query( x );
+ // Jetzt versuchen, das PropertySetInfo zu bekommen
+ if( xPropSet.is() )
+ xPropSetInfo = xPropSet->getPropertySetInfo();
+ }
+ else
+ {
+ xImplClass = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
+ }
+
+#ifdef USE_INTROSPECTION_CACHE
+ if( xTypeProvider.is() )
+ {
+ Sequence< sal_Int8 > aImpIdSeq = xTypeProvider->getImplementationId();
+ sal_Int32 nIdLen = aImpIdSeq.getLength();
+
+ if( nIdLen )
+ {
+ // cache only, if the descriptor class is set
+ hashTypeProviderKey_Impl aKeySeq( xPropSetInfo, aImpIdSeq );
+
+ TypeProviderAccessCacheMap::iterator aIt = aTPCache.find( aKeySeq );
+ if( aIt == aTPCache.end() )
+ {
+ // not found
+ // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
+ pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+
+ // RefCount von Hand erhoehen, muss beim Entfernen
+ // aus der Hashtable wieder released werden
+ pAccess->acquire();
+
+ // Groesse begrenzen, alten Eintrag wieder rausschmeissen
+ if( mnTPCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
+ {
+ // Access mit dem kleinsten HitCount suchen
+ TypeProviderAccessCacheMap::iterator iter = aTPCache.begin();
+ TypeProviderAccessCacheMap::iterator end = aTPCache.end();
+ TypeProviderAccessCacheMap::iterator toDelete = iter;
+ while( iter != end )
+ {
+ if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
+ toDelete = iter;
+ ++iter;
+ }
+
+ // Gefundenen Eintrag entfernen
+ if( (*toDelete).second )
+ (*toDelete).second->release();
+ (*toDelete).second = NULL;
+ aTPCache.erase( toDelete );
+ }
+ else
+ mnTPCacheEntryCount++;
+
+ // Neuer Eintrage rein in die Table
+ aKeySeq.nHitCount = 1;
+ aTPCache[ aKeySeq ] = pAccess;
+
+ }
+ else
+ {
+ // Hit-Count erhoehen
+ (*aIt).first.IncHitCount();
+ return (*aIt).second;
+ }
+ }
+ }
+ else if( xImplClass.is() )
+ {
+ // cache only, if the descriptor class is set
+ hashIntrospectionKey_Impl aKeySeq( SupportedClassSeq, xPropSetInfo, xImplClass );
+
+ IntrospectionAccessCacheMap::iterator aIt = aCache.find( aKeySeq );
+ if( aIt == aCache.end() )
+ {
+ // not found
+ // Neue Instanz anlegen und unter dem gegebenen Key einfuegen
+ pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+
+ // RefCount von Hand erhoehen, muss beim Entfernen
+ // aus der Hashtable wieder released werden
+ pAccess->acquire();
+
+ // Groesse begrenzen, alten Eintrag wieder rausschmeissen
+ if( mnCacheEntryCount > INTROSPECTION_CACHE_MAX_SIZE )
+ {
+ // Access mit dem kleinsten HitCount suchen
+ IntrospectionAccessCacheMap::iterator iter = aCache.begin();
+ IntrospectionAccessCacheMap::iterator end = aCache.end();
+ IntrospectionAccessCacheMap::iterator toDelete = iter;
+ while( iter != end )
+ {
+ if( (*iter).first.nHitCount < (*toDelete).first.nHitCount )
+ toDelete = iter;
+ ++iter;
+ }
+
+ // Gefundenen Eintrag entfernen
+ if( (*toDelete).second )
+ (*toDelete).second->release();
+ (*toDelete).second = NULL;
+ aCache.erase( toDelete );
+ }
+ else
+ mnCacheEntryCount++;
+
+ // Neuer Eintrage rein in die Table
+ aKeySeq.nHitCount = 1;
+ aCache[ aKeySeq ] = pAccess;
+
+ }
+ else
+ {
+ // Hit-Count erhoehen
+ (*aIt).first.IncHitCount();
+ return (*aIt).second;
+ }
+ }
+#endif
+
+ // Kein Access gecached -> neu anlegen
+ Property* pAllPropArray;
+ Reference<XInterface>* pInterfaces1;
+ Reference<XInterface>* pInterfaces2;
+ sal_Int16* pMapTypeArray;
+ sal_Int32* pPropertyConceptArray;
+ sal_Int32 i;
+
+ if( !pAccess )
+ pAccess = new IntrospectionAccessStatic_Impl( mxCoreReflection );
+
+ // Referenzen auf wichtige Daten von pAccess
+ sal_Int32& rPropCount = pAccess->mnPropCount;
+ IntrospectionNameMap& rPropNameMap = pAccess->maPropertyNameMap;
+ IntrospectionNameMap& rMethodNameMap = pAccess->maMethodNameMap;
+ LowerToExactNameMap& rLowerToExactNameMap = pAccess->maLowerToExactNameMap;
+
+ // Schon mal Pointer auf das eigene Property-Feld holen
+ pAllPropArray = pAccess->maAllPropertySeq.getArray();
+ pInterfaces1 = pAccess->aInterfaceSeq1.getArray();
+ pInterfaces2 = pAccess->aInterfaceSeq2.getArray();
+ pMapTypeArray = pAccess->maMapTypeSeq.getArray();
+ pPropertyConceptArray = pAccess->maPropertyConceptSeq.getArray();
+
+ //*************************
+ //*** Analyse vornehmen ***
+ //*************************
+ if( eType == TypeClass_INTERFACE )
+ {
+ // Zunaechst nach speziellen Interfaces suchen, die fuer
+ // die Introspection von besonderer Bedeutung sind.
+
+ // XPropertySet vorhanden?
+ if( xPropSet.is() && xPropSetInfo.is() )
+ {
+ // Gibt es auch ein FastPropertySet?
+ Reference<XFastPropertySet> xDummy = Reference<XFastPropertySet>::query( x );
+ sal_Bool bFast = pAccess->mbFastPropSet = xDummy.is();
+
+ Sequence<Property> aPropSeq = xPropSetInfo->getProperties();
+ const Property* pProps = aPropSeq.getConstArray();
+ sal_Int32 nLen = aPropSeq.getLength();
+
+ // Bei FastPropertySet muessen wir uns die Original-Handles merken
+ if( bFast )
+ pAccess->mpOrgPropertyHandleArray = new sal_Int32[ nLen ];
+
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ // Property in eigene Liste uebernehmen
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp = pProps[ i ];
+
+ if( bFast )
+ pAccess->mpOrgPropertyHandleArray[ i ] = rProp.Handle;
+
+ // PropCount als Handle fuer das eigene FastPropertySet eintragen
+ rProp.Handle = rPropCount;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_PROPERTY_SET;
+ pPropertyConceptArray[ rPropCount ] = PROPERTYSET;
+ pAccess->mnPropertySetPropCount++;
+
+ // Namen in Hashtable eintragen, wenn nicht schon bekannt
+ OUString aPropName = rProp.Name;
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( aIt == rPropNameMap.end() )
+ {
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ OString( "Introspection: Property \"" ) +
+ OUStringToOString( aPropName, RTL_TEXTENCODING_ASCII_US ) +
+ OString( "\" found more than once in PropertySet" ) );
+ }
+
+ // Count pflegen
+ rPropCount++;
+ }
+ }
+
+
+ // Jetzt alle weiteren implementierten Interfaces durchgehen
+ // Diese muessen durch das XIdlClassProvider-Interface geliefert werden.
+ // #70197, fuer InvocationAdapter: Interface-Typ im Any auch ohne
+ // ClassProvider unterstuetzen
+ //if( xClassProvider.is() )
+ {
+ // Indizes in die Export-Tabellen
+ sal_Int32 iAllExportedMethod = 0;
+ sal_Int32 iAllSupportedListener = 0;
+
+ // Hashtable fuer Pruefung auf mehrfache Beruecksichtigung von Interfaces
+ CheckedInterfacesMap aCheckedInterfacesMap;
+
+ // Flag, ob XInterface-Methoden erfasst werden sollen
+ // (das darf nur einmal erfolgen, initial zulassen)
+ sal_Bool bXInterfaceIsInvalid = sal_False;
+
+ // Flag, ob die XInterface-Methoden schon erfasst wurden. Wenn sal_True,
+ // wird bXInterfaceIsInvalid am Ende der Iface-Schleife aktiviert und
+ // XInterface-Methoden werden danach abgeklemmt.
+ sal_Bool bFoundXInterface = sal_False;
+
+ // Schleife ueber alle vom ClassProvider angegebenen Klassen
+ sal_Int32 nClassCount = SupportedClassSeq.getLength();
+ for( sal_Int32 nIdx = 0 ; nIdx < nClassCount; nIdx++ )
+ {
+ Reference<XIdlClass> xImplClass2 = SupportedClassSeq.getConstArray()[nIdx];
+ while( xImplClass2.is() )
+ {
+ // Interfaces der Implementation holen
+ Sequence< Reference<XIdlClass> > aClassSeq = xImplClass2->getInterfaces();
+ sal_Int32 nIfaceCount = aClassSeq.getLength();
+
+ aClassSeq.realloc( nIfaceCount + 1 );
+ aClassSeq.getArray()[ nIfaceCount ] = xImplClass2;
+ nIfaceCount++;
+
+ const Reference<XIdlClass>* pParamArray = aClassSeq.getConstArray();
+
+ for( sal_Int32 j = 0 ; j < nIfaceCount ; j++ )
+ {
+ const Reference<XIdlClass>& rxIfaceClass = pParamArray[j];
+
+ // Pruefen, ob das Interface schon beruecksichtigt wurde.
+ XInterface* pIface = SAL_STATIC_CAST( XInterface*, rxIfaceClass.get() );
+ if( aCheckedInterfacesMap.count( pIface ) > 0 )
+ {
+ // Kennen wir schon
+ continue;
+ }
+ else
+ {
+ // Sonst eintragen
+ aCheckedInterfacesMap[ pIface ] = pIface;
+ }
+
+ //********************************************************************
+
+ // 2. Fields als Properties registrieren
+
+ // Felder holen
+ Sequence< Reference<XIdlField> > fields = rxIfaceClass->getFields();
+ const Reference<XIdlField>* pFields = fields.getConstArray();
+ sal_Int32 nLen = fields.getLength();
+
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ Reference<XIdlField> xField = pFields[i];
+ Reference<XIdlClass> xPropType = xField->getType();
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ OUString aFieldName = xField->getName();
+ rProp.Name = aFieldName;
+ rProp.Handle = rPropCount;
+ Type aFieldType( xPropType->getTypeClass(), xPropType->getName() );
+ rProp.Type = aFieldType;
+ FieldAccessMode eAccessMode = xField->getAccessMode();
+ rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
+ eAccessMode == FieldAccessMode_CONST)
+ ? READONLY : 0;
+
+ // Namen in Hashtable eintragen
+ OUString aPropName = rProp.Name;
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( !( aIt == rPropNameMap.end() ) )
+ {
+ /* TODO
+ OSL_TRACE(
+ String( "Introspection: Property \"" ) +
+ OOUStringToString( aPropName, CHARSET_SYSTEM ) +
+ String( "\" found more than once" ) );
+ */
+ continue;
+ }
+
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // Field merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
+ pInterfaces1, rPropCount );
+ pInterfaces1[ rPropCount ] = xField;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_FIELD;
+ pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
+ pAccess->mnAttributePropCount++;
+
+ // Count pflegen
+ rPropCount++;
+ }
+
+ //********************************************************************
+
+ // 3. Methoden
+
+ // Zaehler fuer die gefundenen Listener
+ sal_Int32 nListenerCount = 0;
+
+ // Alle Methoden holen und merken
+ Sequence< Reference<XIdlMethod> > methods = rxIfaceClass->getMethods();
+ const Reference<XIdlMethod>* pSourceMethods = methods.getConstArray();
+ sal_Int32 nSourceMethodCount = methods.getLength();
+
+ // 3. a) get/set- und Listener-Methoden suchen
+
+ // Feld fuer Infos ueber die Methoden anlegen, damit spaeter leicht die Methoden
+ // gefunden werden koennen, die nicht im Zusammenhang mit Properties oder Listenern
+ // stehen. NEU: auch MethodConceptArray initialisieren
+ MethodType* pMethodTypes = new MethodType[ nSourceMethodCount ];
+ sal_Int32* pLocalMethodConcepts = new sal_Int32[ nSourceMethodCount ];
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ pMethodTypes[ i ] = STANDARD_METHOD;
+ pLocalMethodConcepts[ i ] = 0;
+ }
+
+ OUString aMethName;
+ OUString aPropName;
+ OUString aStartStr;
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
+ sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
+
+ // Namen besorgen
+ aMethName = rxMethod_i->getName();
+
+ // Methoden katalogisieren
+ // Alle (?) Methoden von XInterface filtern, damit z.B. nicht
+ // vom Scripting aus aquire oder release gerufen werden kann
+ if( rxMethod_i->getDeclaringClass()->equals( mxInterfaceClass ) )
+ {
+ // XInterface-Methoden sind hiermit einmal beruecksichtigt
+ bFoundXInterface = sal_True;
+
+ if( bXInterfaceIsInvalid )
+ {
+ pMethodTypes[ i ] = INVALID_METHOD;
+ continue;
+ }
+ else
+ {
+ if( aMethName != OUString( RTL_CONSTASCII_USTRINGPARAM("queryInterface")) )
+ {
+ rMethodConcept_i |= MethodConcept::DANGEROUS;
+ continue;
+ }
+ }
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxAggregationClass ) )
+ {
+ if( aMethName == OUString( RTL_CONSTASCII_USTRINGPARAM("setDelegator")) )
+ {
+ rMethodConcept_i |= MethodConcept::DANGEROUS;
+ continue;
+ }
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxElementAccessClass ) )
+ {
+ rMethodConcept_i |= ( NAMECONTAINER |
+ INDEXCONTAINER |
+ ENUMERATION );
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxNameContainerClass ) ||
+ rxMethod_i->getDeclaringClass()->equals( mxNameAccessClass ) )
+ {
+ rMethodConcept_i |= NAMECONTAINER;
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxIndexContainerClass ) ||
+ rxMethod_i->getDeclaringClass()->equals( mxIndexAccessClass ) )
+ {
+ rMethodConcept_i |= INDEXCONTAINER;
+ }
+ else if( rxMethod_i->getDeclaringClass()->equals( mxEnumerationAccessClass ) )
+ {
+ rMethodConcept_i |= ENUMERATION;
+ }
+
+ // Wenn der Name zu kurz ist, wird's sowieso nichts
+ if( aMethName.getLength() <= 3 )
+ continue;
+
+ // Ist es eine get-Methode?
+ aStartStr = aMethName.copy( 0, 3 );
+ if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("get")) )
+ {
+ // Namen der potentiellen Property
+ aPropName = aMethName.copy( 3 );
+
+ // get-Methode darf keinen Parameter haben
+ Sequence< Reference<XIdlClass> > getParams = rxMethod_i->getParameterTypes();
+ if( getParams.getLength() > 0 )
+ {
+ continue;
+ }
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( !( aIt == rPropNameMap.end() ) )
+ {
+ /* TODO
+ OSL_TRACE(
+ String( "Introspection: Property \"" ) +
+ OOUStringToString( aPropName, CHARSET_SYSTEM ) +
+ String( "\" found more than once" ) );
+ */
+ continue;
+ }
+
+ // Eine readonly-Property ist es jetzt mindestens schon
+ rMethodConcept_i |= PROPERTY;
+
+ pMethodTypes[i] = GETSET_METHOD;
+ Reference<XIdlClass> xGetRetType = rxMethod_i->getReturnType();
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp.Name = aPropName;
+ rProp.Handle = rPropCount;
+ rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
+ rProp.Attributes = READONLY;
+
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // get-Methode merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
+ pInterfaces1, rPropCount );
+ pInterfaces1[ rPropCount ] = rxMethod_i;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_GETSET;
+ pPropertyConceptArray[ rPropCount ] = METHODS;
+ pAccess->mnMethodPropCount++;
+
+ // Passende set-Methode suchen
+ sal_Int32 k;
+ for( k = 0 ; k < nSourceMethodCount ; k++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
+
+ // Nur Methoden nehmen, die nicht schon zugeordnet sind
+ if( k == i || pMethodTypes[k] != STANDARD_METHOD )
+ continue;
+
+ // Name holen und auswerten
+ OUString aMethName2 = rxMethod_k->getName();
+ OUString aStartStr2 = aMethName2.copy( 0, 3 );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aStartStr2 == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) ) )
+ continue;
+
+ // Ist es denn der gleiche Name?
+ OUString aPropName2 = aMethName2.copy( 3 );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aPropName == aPropName2 ) )
+ continue;
+
+ // set-Methode muss void returnen
+ Reference<XIdlClass> xSetRetType = rxMethod_k->getReturnType();
+ if( xSetRetType->getTypeClass() != TypeClass_VOID )
+ {
+ continue;
+ }
+
+ // set-Methode darf nur einen Parameter haben
+ Sequence< Reference<XIdlClass> > setParams = rxMethod_k->getParameterTypes();
+ sal_Int32 nParamCount = setParams.getLength();
+ if( nParamCount != 1 )
+ {
+ continue;
+ }
+
+ // Jetzt muss nur noch der return-Typ dem Parameter-Typ entsprechen
+ const Reference<XIdlClass>* pParamArray2 = setParams.getConstArray();
+ Reference<XIdlClass> xParamType = pParamArray2[ 0 ];
+ if( xParamType->equals( xGetRetType ) )
+ {
+ pLocalMethodConcepts[ k ] = PROPERTY;
+
+ pMethodTypes[k] = GETSET_METHOD;
+
+ // ReadOnly-Flag wieder loschen
+ rProp.Attributes &= ~READONLY;
+
+ // set-Methode merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
+ pInterfaces2, rPropCount );
+ pInterfaces2[ rPropCount ] = rxMethod_k;
+ }
+ }
+
+ // Count pflegen
+ rPropCount++;
+ }
+
+ // Ist es eine addListener-Methode?
+ else if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("add")) )
+ {
+ OUString aListenerStr( RTL_CONSTASCII_USTRINGPARAM("Listener" ) );
+
+ // Namen der potentiellen Property
+ sal_Int32 nStrLen = aMethName.getLength();
+ sal_Int32 nCopyLen = nStrLen - aListenerStr.getLength();
+ OUString aEndStr = aMethName.copy( nCopyLen > 0 ? nCopyLen : 0 );
+
+ // Endet das Teil auf Listener?
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aEndStr == aListenerStr ) )
+ continue;
+
+ // Welcher Listener?
+ OUString aListenerName = aMethName.copy( 3, nStrLen - aListenerStr.getLength() - 3 );
+
+ // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
+ // - Rueckgabe-Typ
+ // - Anzahl und Art der Parameter
+
+
+ // Passende remove-Methode suchen, sonst gilt's nicht
+ sal_Int32 k;
+ for( k = 0 ; k < nSourceMethodCount ; k++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_k = pSourceMethods[k];
+
+ // Nur Methoden nehmen, die nicht schon zugeordnet sind
+ if( k == i || pMethodTypes[k] != STANDARD_METHOD )
+ continue;
+
+ // Name holen und auswerten
+ OUString aMethName2 = rxMethod_k->getName();
+ sal_Int32 nNameLen = aMethName2.getLength();
+ sal_Int32 nCopyLen2 = (nNameLen < 6) ? nNameLen : 6;
+ OUString aStartStr2 = aMethName2.copy( 0, nCopyLen2 );
+ OUString aRemoveStr( RTL_CONSTASCII_USTRINGPARAM("remove" ) );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aStartStr2 == aRemoveStr ) )
+ continue;
+
+ // Ist es denn der gleiche Listener?
+ if( aMethName2.getLength() - aRemoveStr.getLength() <= aListenerStr.getLength() )
+ continue;
+ OUString aListenerName2 = aMethName2.copy
+ ( 6, aMethName2.getLength() - aRemoveStr.getLength() - aListenerStr.getLength() );
+ // ACHTUNG: Wegen SDL-Bug NICHT != bei OUString verwenden !!!
+ if( !( aListenerName == aListenerName2 ) )
+ continue;
+
+ // TODO: Hier koennten noch genauere Pruefungen vorgenommen werden
+ // - Rueckgabe-Typ
+ // - Anzahl und Art der Parameter
+
+
+ // Methoden sind als Listener-Schnittstelle erkannt
+ rMethodConcept_i |= LISTENER;
+ pLocalMethodConcepts[ k ] |= LISTENER;
+
+ pMethodTypes[i] = ADD_LISTENER_METHOD;
+ pMethodTypes[k] = REMOVE_LISTENER_METHOD;
+ nListenerCount++;
+ }
+ }
+ }
+
+
+ // Jetzt koennen noch SET-Methoden ohne zugehoerige GET-Methode existieren,
+ // diese muessen zu Write-Only-Properties gemachte werden.
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod_i = pSourceMethods[i];
+
+ // Nur Methoden nehmen, die nicht schon zugeordnet sind
+ if( pMethodTypes[i] != STANDARD_METHOD )
+ continue;
+
+ // Namen besorgen
+ aMethName = rxMethod_i->getName();
+
+ // Wenn der Name zu kurz ist, wird's sowieso nichts
+ if( aMethName.getLength() <= 3 )
+ continue;
+
+ // Ist es eine set-Methode ohne zugehoerige get-Methode?
+ aStartStr = aMethName.copy( 0, 3 );
+ if( aStartStr == OUString( RTL_CONSTASCII_USTRINGPARAM("set")) )
+ {
+ // Namen der potentiellen Property
+ aPropName = aMethName.copy( 3 );
+
+ // set-Methode muss void returnen
+ Reference<XIdlClass> xSetRetType = rxMethod_i->getReturnType();
+ if( xSetRetType->getTypeClass() != TypeClass_VOID )
+ {
+ continue;
+ }
+
+ // set-Methode darf nur einen Parameter haben
+ Sequence< Reference<XIdlClass> > setParams = rxMethod_i->getParameterTypes();
+ sal_Int32 nParamCount = setParams.getLength();
+ if( nParamCount != 1 )
+ {
+ continue;
+ }
+
+ // Haben wir den Namen schon?
+ IntrospectionNameMap::iterator aIt = rPropNameMap.find( aPropName );
+ if( !( aIt == rPropNameMap.end() ) )
+ {
+ /* TODO:
+ OSL_TRACE(
+ String( "Introspection: Property \"" ) +
+ OOUStringToString( aPropName, CHARSET_SYSTEM ) +
+ String( "\" found more than once" ) );
+ */
+ continue;
+ }
+
+ // Alles klar, es ist eine Write-Only-Property
+ pLocalMethodConcepts[ i ] = PROPERTY;
+
+ pMethodTypes[i] = GETSET_METHOD;
+ Reference<XIdlClass> xGetRetType = setParams.getConstArray()[0];
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp.Name = aPropName;
+ rProp.Handle = rPropCount;
+ rProp.Type = Type( xGetRetType->getTypeClass(), xGetRetType->getName() );
+ rProp.Attributes = 0; // PROPERTY_WRITEONLY ???
+
+ // Neuer Eintrag in die Hashtable
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // set-Methode merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq2,
+ pInterfaces2, rPropCount );
+ pInterfaces2[ rPropCount ] = rxMethod_i;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_SETONLY;
+ pPropertyConceptArray[ rPropCount ] = METHODS;
+ pAccess->mnMethodPropCount++;
+
+ // Count pflegen
+ rPropCount++;
+ }
+ }
+
+
+ //********************************************************************
+
+ // 4. Methoden in die Gesamt-Sequence uebernehmen
+
+ // Wieviele Methoden muessen in die Method-Sequence?
+ sal_Int32 nExportedMethodCount = 0;
+ sal_Int32 nSupportedListenerCount = 0;
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ if( pMethodTypes[ i ] != INVALID_METHOD )
+ {
+ nExportedMethodCount++;
+ }
+ if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
+ {
+ nSupportedListenerCount++;
+ }
+ }
+
+ // Sequences im Access-Objekt entsprechend aufbohren
+ pAccess->maAllMethodSeq.realloc( nExportedMethodCount + iAllExportedMethod );
+ pAccess->maMethodConceptSeq.realloc( nExportedMethodCount + iAllExportedMethod );
+ pAccess->maSupportedListenerSeq.realloc( nSupportedListenerCount + iAllSupportedListener );
+
+ // Methoden reinschreiben
+ Reference<XIdlMethod>* pDestMethods = pAccess->maAllMethodSeq.getArray();
+ sal_Int32* pMethodConceptArray = pAccess->maMethodConceptSeq.getArray();
+ Type* pListenerClassRefs = pAccess->maSupportedListenerSeq.getArray();
+ for( i = 0 ; i < nSourceMethodCount ; i++ )
+ {
+ if( pMethodTypes[ i ] != INVALID_METHOD )
+ {
+ // Methode ansprechen
+ const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
+
+ // Namen in Hashtable eintragen, wenn nicht schon bekannt
+ OUString aMethName2 = rxMethod->getName();
+ IntrospectionNameMap::iterator aIt = rMethodNameMap.find( aMethName2 );
+ if( aIt == rMethodNameMap.end() )
+ {
+ // Eintragen
+ rMethodNameMap[ aMethName2 ] = iAllExportedMethod;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aMethName2 ) ] = aMethName2;
+ }
+ else
+ {
+ sal_Int32 iHashResult = (*aIt).second;
+
+ Reference<XIdlMethod> xExistingMethod = pDestMethods[ iHashResult ];
+
+ Reference< XIdlClass > xExistingMethClass =
+ xExistingMethod->getDeclaringClass();
+ Reference< XIdlClass > xNewMethClass = rxMethod->getDeclaringClass();
+ if( xExistingMethClass->equals( xNewMethClass ) )
+ continue;
+ }
+
+ pDestMethods[ iAllExportedMethod ] = rxMethod;
+
+ // Wenn kein Concept gesetzt wurde, ist die Methode "normal"
+ sal_Int32& rMethodConcept_i = pLocalMethodConcepts[ i ];
+ if( !rMethodConcept_i )
+ rMethodConcept_i = MethodConcept_NORMAL_IMPL;
+ pMethodConceptArray[ iAllExportedMethod ] = rMethodConcept_i;
+ iAllExportedMethod++;
+ }
+ if( pMethodTypes[ i ] == ADD_LISTENER_METHOD )
+ {
+ // Klasse des Listeners ermitteln
+ const Reference<XIdlMethod>& rxMethod = pSourceMethods[i];
+
+ // void als Default-Klasse eintragen
+ Reference<XIdlClass> xListenerClass = TypeToIdlClass( getCppuVoidType(), m_xSMgr );
+ // ALT: Reference<XIdlClass> xListenerClass = Void_getReflection()->getIdlClass();
+
+ // 1. Moeglichkeit: Parameter nach einer Listener-Klasse durchsuchen
+ // Nachteil: Superklassen muessen rekursiv durchsucht werden
+ Sequence< Reference<XIdlClass> > aParams = rxMethod->getParameterTypes();
+ const Reference<XIdlClass>* pParamArray2 = aParams.getConstArray();
+
+ Reference<XIdlClass> xEventListenerClass = TypeToIdlClass( getCppuType( (Reference<XEventListener>*) NULL ), m_xSMgr );
+ // ALT: Reference<XIdlClass> xEventListenerClass = XEventListener_getReflection()->getIdlClass();
+ sal_Int32 nParamCount = aParams.getLength();
+ sal_Int32 k;
+ for( k = 0 ; k < nParamCount ; k++ )
+ {
+ const Reference<XIdlClass>& rxClass = pParamArray2[k];
+
+ // Sind wir von einem Listener abgeleitet?
+ if( rxClass->equals( xEventListenerClass ) ||
+ isDerivedFrom( rxClass, xEventListenerClass ) )
+ {
+ xListenerClass = rxClass;
+ break;
+ }
+ }
+
+ // 2. Moeglichkeit: Namen der Methode auswerden
+ // Nachteil: geht nicht bei Test-Listenern, die es nicht gibt
+ //aMethName = rxMethod->getName();
+ //aListenerName = aMethName.Copy( 3, aMethName.Len()-8-3 );
+ //Reference<XIdlClass> xListenerClass = reflection->forName( aListenerName );
+ Type aListenerType( TypeClass_INTERFACE, xListenerClass->getName() );
+ pListenerClassRefs[ iAllSupportedListener ] = aListenerType;
+ iAllSupportedListener++;
+ }
+ }
+
+ // Wenn in diesem Durchlauf XInterface-Methoden
+ // dabei waren, diese zukuenftig ignorieren
+ if( bFoundXInterface )
+ bXInterfaceIsInvalid = sal_True;
+
+ delete[] pMethodTypes;
+ delete[] pLocalMethodConcepts;
+ }
+
+ // Super-Klasse(n) vorhanden? Dann dort fortsetzen
+ Sequence< Reference<XIdlClass> > aSuperClassSeq = xImplClass2->getSuperclasses();
+
+ // Zur Zeit wird nur von einer Superklasse ausgegangen
+ if( aSuperClassSeq.getLength() >= 1 )
+ {
+ xImplClass2 = aSuperClassSeq.getConstArray()[0];
+ OSL_ENSURE( xImplClass2.is(), "super class null" );
+ }
+ else
+ {
+ xImplClass2 = NULL;
+ }
+ }
+ }
+
+ // Anzahl der exportierten Methoden uebernehmen und Sequences anpassen
+ // (kann abweichen, weil doppelte Methoden erst nach der Ermittlung
+ // von nExportedMethodCount herausgeworfen werden)
+ sal_Int32& rMethCount = pAccess->mnMethCount;
+ rMethCount = iAllExportedMethod;
+ pAccess->maAllMethodSeq.realloc( rMethCount );
+ pAccess->maMethodConceptSeq.realloc( rMethCount );
+
+ // Groesse der Property-Sequences anpassen
+ pAccess->maAllPropertySeq.realloc( rPropCount );
+ pAccess->maPropertyConceptSeq.realloc( rPropCount );
+ pAccess->maMapTypeSeq.realloc( rPropCount );
+
+ // Ende der Schleife ueber alle vom ClassProvider angegebenen Klassen
+ }
+ }
+ // Bei structs Fields als Properties registrieren
+ else //if( eType == TypeClass_STRUCT )
+ {
+ // Ist es ein Interface oder eine struct?
+ //Reference<XIdlClass> xClassRef = aToInspectObj.getReflection()->getIdlClass();
+ Reference<XIdlClass> xClassRef = TypeToIdlClass( aToInspectObj.getValueType(), m_xSMgr );
+ if( !xClassRef.is() )
+ {
+ OSL_ENSURE( sal_False, "Can't get XIdlClass from Reflection" );
+ return pAccess;
+ }
+
+ // Felder holen
+ Sequence< Reference<XIdlField> > fields = xClassRef->getFields();
+ const Reference<XIdlField>* pFields = fields.getConstArray();
+ sal_Int32 nLen = fields.getLength();
+
+ for( i = 0 ; i < nLen ; i++ )
+ {
+ Reference<XIdlField> xField = pFields[i];
+ Reference<XIdlClass> xPropType = xField->getType();
+ OUString aPropName = xField->getName();
+
+ // Ist die PropertySequence gross genug?
+ pAccess->checkPropertyArraysSize
+ ( pAllPropArray, pMapTypeArray, pPropertyConceptArray, rPropCount );
+
+ // In eigenes Property-Array eintragen
+ Property& rProp = pAllPropArray[ rPropCount ];
+ rProp.Name = aPropName;
+ rProp.Handle = rPropCount;
+ rProp.Type = Type( xPropType->getTypeClass(), xPropType->getName() );
+ FieldAccessMode eAccessMode = xField->getAccessMode();
+ rProp.Attributes = (eAccessMode == FieldAccessMode_READONLY ||
+ eAccessMode == FieldAccessMode_CONST)
+ ? READONLY : 0;
+
+ //FieldAccessMode eAccessMode = xField->getAccessMode();
+ //rProp.Attributes = (eAccessMode == FieldAccessMode::READONLY || eAccessMode == CONST)
+ //? PropertyAttribute::READONLY : 0;
+
+ // Namen in Hashtable eintragen
+ rPropNameMap[ aPropName ] = rPropCount;
+
+ // Tabelle fuer XExactName pflegen
+ rLowerToExactNameMap[ toLower( aPropName ) ] = aPropName;
+
+ // Field merken
+ pAccess->checkInterfaceArraySize( pAccess->aInterfaceSeq1,
+ pInterfaces1, rPropCount );
+ pInterfaces1[ rPropCount ] = xField;
+
+ // Art der Property merken
+ pMapTypeArray[ rPropCount ] = MAP_FIELD;
+ pPropertyConceptArray[ rPropCount ] = ATTRIBUTES;
+ pAccess->mnAttributePropCount++;
+
+ // Count pflegen
+ rPropCount++;
+ }
+ }
+
+ // Property-Sequence auf die richtige Laenge bringen
+ pAccess->maAllPropertySeq.realloc( pAccess->mnPropCount );
+
+ return pAccess;
+}
+
+//*************************************************************************
+Reference< XInterface > SAL_CALL ImplIntrospection_CreateInstance( const Reference< XMultiServiceFactory > & rSMgr )
+ throw( RuntimeException )
+{
+ Reference< XInterface > xService = (OWeakObject*)(OComponentHelper*)new ImplIntrospection( rSMgr );
+ return xService;
+}
+
+}
+
+extern "C"
+{
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * )
+{
+ void * pRet = 0;
+
+ if (pServiceManager && rtl_str_compare( pImplName, IMPLEMENTATION_NAME ) == 0)
+ {
+ Reference< XSingleServiceFactory > xFactory( createOneInstanceFactory(
+ reinterpret_cast< XMultiServiceFactory * >( pServiceManager ),
+ OUString::createFromAscii( pImplName ),
+ stoc_inspect::ImplIntrospection_CreateInstance,
+ stoc_inspect::ImplIntrospection::getSupportedServiceNames_Static() ) );
+
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pRet = xFactory.get();
+ }
+ }
+
+ return pRet;
+}
+}
+
+
diff --git a/stoc/source/inspect/makefile.mk b/stoc/source/inspect/makefile.mk
new file mode 100644
index 000000000000..60864eea2496
--- /dev/null
+++ b/stoc/source/inspect/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = introspection.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = insp
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/introspection.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+SHL1RPATH=URELIB
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/introspection.component
+
+$(MISC)/introspection.component .ERRREMOVE : \
+ $(SOLARENV)/bin/createcomponent.xslt introspection.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt introspection.component
diff --git a/stoc/source/invocation/inv.xml b/stoc/source/invocation/inv.xml
new file mode 100644
index 000000000000..a7b71d028f99
--- /dev/null
+++ b/stoc/source/invocation/inv.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> invocation.uno </module-name>
+ <component-description>
+ <author> Daniel Boelzle </author>
+ <name> com.sun.star.comp.stoc.Invocation </name>
+ <description>
+You can construct Invocation objects through this factory service.
+Invoke createInstanceWithArguments() of XSingleServiceFactory
+to create an Invocation adapter for your object;
+invoking createInstance() will fail.
+Instances implement XInvocation to invoke methods and set/get properties at an object
+which corresponds with the object which implements this interface.
+
+There are two ways to get information about this object. First you
+can get the implemented method with XInvocation::getMethodNames()
+and the properties with XInvocation::getPropertyNames().
+Second you can get, if provided, all information about the methods and the
+properties with XInvocation::getIntrospection().
+Container access is available through the XIndexContainer,
+XNameContainer and XEnumerationContainer
+(use XInterface::queryInterface).
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.script.Invocation </supported-service>
+ <service-dependency>com.sun.star.script.Converter</service-dependency>
+ <service-dependency>com.sun.star.beans.Introspection</service-dependency>
+ <service-dependency>com.sun.star.reflection.CoreReflection</service-dependency>
+ <type> com.sun.star.script.XInvocation </type>
+ <type> com.sun.star.script.XInvocation2 </type>
+ <type> com.sun.star.script.InvocationInfo </type>
+ <type> com.sun.star.script.MemberType </type>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com.sun.star.script.FailReason </type>
+ <type> com.sun.star.beans.XIntrospection </type>
+ <type> com.sun.star.beans.XIntrospectionAccess </type>
+ <type> com.sun.star.beans.XPropertySet </type>
+ <type> com.sun.star.beans.XFastPropertySet </type>
+ <type> com.sun.star.beans.XMaterialHolder </type>
+ <type> com.sun.star.beans.XExactName </type>
+ <type> com.sun.star.beans.PropertyAttribute </type>
+ <type> com.sun.star.beans.PropertyConcept </type>
+ <type> com.sun.star.beans.MethodConcept </type>
+ <type> com.sun.star.lang.XEventListener </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XMultiComponentFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.uno.DeploymentException </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.container.XEnumerationAccess </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.container.XIndexContainer </type>
+ <type> com.sun.star.reflection.XIdlReflection </type>
+ <type> com.sun.star.reflection.XIdlClassProvider </type>
+ <type> com.sun.star.reflection.XIdlClass </type>
+ <type> com.sun.star.reflection.XIdlArray </type>
+ <type> com.sun.star.reflection.FieldAccessMode </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/invocation/invocation.component b/stoc/source/invocation/invocation.component
new file mode 100644
index 000000000000..67178ef2e88d
--- /dev/null
+++ b/stoc/source/invocation/invocation.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.stoc.Invocation">
+ <service name="com.sun.star.script.Invocation"/>
+ </implementation>
+</component>
diff --git a/stoc/source/invocation/invocation.cxx b/stoc/source/invocation/invocation.cxx
new file mode 100644
index 000000000000..f66c3af742d7
--- /dev/null
+++ b/stoc/source/invocation/invocation.cxx
@@ -0,0 +1,1262 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/mutex.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#ifndef _CPPUHELER_WEAK_HXX_
+#include <cppuhelper/weak.hxx>
+#endif
+#include <cppuhelper/factory.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX__
+#include <cppuhelper/implementationentry.hxx>
+#endif
+#include <cppuhelper/typeprovider.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/script/FailReason.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/script/XInvocation2.hpp>
+#include <com/sun/star/reflection/XIdlReflection.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XIndexContainer.hpp>
+#include <com/sun/star/container/XEnumerationAccess.hpp>
+#include <com/sun/star/beans/XExactName.hpp>
+#include <com/sun/star/beans/XMaterialHolder.hpp>
+#include <com/sun/star/beans/XIntrospection.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/beans/MethodConcept.hpp>
+#include <com/sun/star/beans/PropertyConcept.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+#include <boost/scoped_array.hpp>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/strbuf.hxx>
+
+#define SERVICENAME "com.sun.star.script.Invocation"
+#define IMPLNAME "com.sun.star.comp.stoc.Invocation"
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::container;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+
+namespace stoc_inv
+{
+static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+static Sequence< OUString > inv_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+static OUString inv_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+
+// TODO: Zentral implementieren
+inline Reference<XIdlClass> TypeToIdlClass( const Type& rType, const Reference< XIdlReflection > & xRefl )
+{
+ return xRefl->forName( rType.getTypeName() );
+}
+
+
+//==================================================================================================
+class Invocation_Impl
+ : public OWeakObject
+ , public XInvocation2
+ , public XNameContainer
+ , public XIndexContainer
+ , public XEnumerationAccess
+ , public XExactName
+ , public XMaterialHolder
+ , public XTypeProvider
+{
+public:
+ Invocation_Impl( const Any & rAdapted, const Reference<XTypeConverter> &,
+ const Reference<XIntrospection> &,
+ const Reference<XIdlReflection> & );
+ virtual ~Invocation_Impl();
+
+ // XInterface
+ virtual Any SAL_CALL queryInterface( const Type & aType) throw( RuntimeException );
+ virtual void SAL_CALL acquire() throw() { OWeakObject::acquire(); }
+ virtual void SAL_CALL release() throw() { OWeakObject::release(); }
+
+
+ // XTypeProvider
+ virtual Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes( )
+ throw(RuntimeException);
+ virtual Sequence< sal_Int8 > SAL_CALL getImplementationId( )
+ throw( RuntimeException);
+
+ // Methoden von XMaterialHolder
+ virtual Any SAL_CALL getMaterial(void) throw(RuntimeException);
+
+ // ? XTool
+ virtual void SAL_CALL setMaterial( const Any& rMaterial );
+
+ // XInvocation
+ virtual Reference<XIntrospectionAccess> SAL_CALL getIntrospection(void) throw( RuntimeException );
+ virtual Any SAL_CALL invoke(const OUString& FunctionName, const Sequence< Any >& Params, Sequence< sal_Int16 >& OutParamIndex, Sequence< Any >& OutParam)
+ throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException );
+ virtual void SAL_CALL setValue(const OUString& PropertyName, const Any& Value)
+ throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException );
+ virtual Any SAL_CALL getValue(const OUString& PropertyName)
+ throw( UnknownPropertyException, RuntimeException );
+ virtual sal_Bool SAL_CALL hasMethod(const OUString& Name) throw( RuntimeException );
+ virtual sal_Bool SAL_CALL hasProperty(const OUString& Name) throw( RuntimeException );
+
+ // XInvocation2
+ virtual Sequence< OUString > SAL_CALL getMemberNames( )
+ throw( RuntimeException );
+ virtual Sequence< InvocationInfo > SAL_CALL getInfo( )
+ throw( RuntimeException );
+ virtual InvocationInfo SAL_CALL getInfoForName( const OUString& aName, sal_Bool bExact )
+ throw( IllegalArgumentException, RuntimeException );
+
+ // All Access and Container methods are not thread save
+ // XElementAccess
+ virtual Type SAL_CALL getElementType(void) throw( RuntimeException )
+ { return _xElementAccess->getElementType(); }
+
+ virtual sal_Bool SAL_CALL hasElements(void) throw( RuntimeException )
+ { return _xElementAccess->hasElements(); }
+
+ // XNameContainer
+ virtual void SAL_CALL insertByName( const OUString& Name, const Any& Element )
+ throw( IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException )
+ { _xNameContainer->insertByName( Name, Element ); }
+
+ virtual void SAL_CALL replaceByName( const OUString& Name, const Any& Element )
+ throw( IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException )
+ { _xNameContainer->replaceByName( Name, Element ); }
+
+ virtual void SAL_CALL removeByName( const OUString& Name )
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+ { _xNameContainer->removeByName( Name ); }
+
+ // XNameAccess
+ virtual Any SAL_CALL getByName( const OUString& Name )
+ throw( NoSuchElementException, WrappedTargetException, RuntimeException )
+ { return _xNameAccess->getByName( Name ); }
+
+ virtual Sequence<OUString> SAL_CALL getElementNames(void) throw( RuntimeException )
+ { return _xNameAccess->getElementNames(); }
+
+ virtual sal_Bool SAL_CALL hasByName( const OUString& Name ) throw( RuntimeException )
+ { return _xNameAccess->hasByName( Name ); }
+
+ // XIndexContainer
+ virtual void SAL_CALL insertByIndex( sal_Int32 Index, const Any& Element )
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+ { _xIndexContainer->insertByIndex( Index, Element ); }
+
+ virtual void SAL_CALL replaceByIndex( sal_Int32 Index, const Any& Element )
+ throw( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+ { _xIndexContainer->replaceByIndex( Index, Element ); }
+
+ virtual void SAL_CALL removeByIndex( sal_Int32 Index )
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+ { _xIndexContainer->removeByIndex( Index ); }
+
+ // XIndexAccess
+ virtual sal_Int32 SAL_CALL getCount(void) throw( RuntimeException )
+ { return _xIndexAccess->getCount(); }
+
+ virtual Any SAL_CALL getByIndex( sal_Int32 Index )
+ throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException )
+ { return _xIndexAccess->getByIndex( Index ); }
+
+ // XEnumerationAccess
+ virtual Reference<XEnumeration> SAL_CALL createEnumeration(void) throw( RuntimeException )
+ { return _xEnumerationAccess->createEnumeration(); }
+
+ // XExactName
+ virtual OUString SAL_CALL getExactName( const OUString& rApproximateName ) throw( RuntimeException );
+
+
+ //=====================================================================================================
+private:
+ void getInfoSequenceImpl( Sequence< OUString >* pStringSeq, Sequence< InvocationInfo >* pInfoSeq );
+ void fillInfoForNameAccess( InvocationInfo& rInfo, const OUString& aName );
+ void fillInfoForProperty( InvocationInfo& rInfo, const Property& rProp );
+ void fillInfoForMethod( InvocationInfo& rInfo, const Reference< XIdlMethod > xMethod );
+
+ Reference<XTypeConverter> xTypeConverter;
+ Reference<XIntrospection> xIntrospection;
+ Reference<XIdlReflection> xCoreReflection;
+
+ Any _aMaterial;
+ // _xDirect and (_xIntrospectionAccess, xPropertySet) are exclusive
+ Reference<XInvocation> _xDirect;
+ Reference<XInvocation2> _xDirect2;
+ Reference<XPropertySet> _xPropertySet;
+ Reference<XIntrospectionAccess> _xIntrospectionAccess;
+
+ // supplied Interfaces
+ Reference<XNameContainer> _xNameContainer;
+ Reference<XNameAccess> _xNameAccess;
+ Reference<XIndexContainer> _xIndexContainer;
+ Reference<XIndexAccess> _xIndexAccess;
+ Reference<XEnumerationAccess> _xEnumerationAccess;
+ Reference<XElementAccess> _xElementAccess;
+
+ //
+ Reference<XExactName> _xENDirect, _xENIntrospection, _xENNameAccess;
+};
+
+
+//==================================================================================================
+//==================================================================================================
+//==================================================================================================
+
+//--------------------------------------------------------------------------------------------------
+Invocation_Impl::Invocation_Impl
+(
+ const Any & rAdapted,
+ const Reference<XTypeConverter> & rTC,
+ const Reference<XIntrospection> & rI,
+ const Reference<XIdlReflection> & rCR
+)
+ : xTypeConverter( rTC )
+ , xIntrospection( rI )
+ , xCoreReflection( rCR )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ setMaterial( rAdapted );
+}
+
+Invocation_Impl::~Invocation_Impl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+//##################################################################################################
+//### INTERFACE IMPLEMENTATIONS ####################################################################
+//##################################################################################################
+
+
+Any SAL_CALL Invocation_Impl::queryInterface( const Type & aType )
+ throw( RuntimeException )
+{
+ // PropertySet-Implementation
+ Any a = ::cppu::queryInterface( aType,
+ SAL_STATIC_CAST(XInvocation*, this),
+ SAL_STATIC_CAST(XMaterialHolder*, this),
+ SAL_STATIC_CAST(XTypeProvider *,this) );
+ if( a.hasValue() )
+ {
+ return a;
+ }
+
+ if( aType == getCppuType( (Reference<XExactName>*) NULL ) )
+ {
+ // Ivocation does not support XExactName, if direct object supports
+ // XInvocation, but not XExactName.
+ if ((_xDirect.is() && _xENDirect.is()) ||
+ (!_xDirect.is() && (_xENIntrospection.is() || _xENNameAccess.is())))
+ {
+ return makeAny( Reference< XExactName >( SAL_STATIC_CAST(XExactName*, this) ) );
+ }
+ }
+ else if ( aType == getCppuType( (Reference<XNameContainer>*) NULL ) )
+ {
+ if( _xNameContainer.is() )
+ return makeAny( Reference< XNameContainer >( SAL_STATIC_CAST(XNameContainer*, this) ) );
+ }
+ else if ( aType == getCppuType( (Reference<XNameAccess>*) NULL ) )
+ {
+ if( _xNameAccess.is() )
+ return makeAny( Reference< XNameAccess >( SAL_STATIC_CAST(XNameAccess*, this) ) );
+ }
+ else if ( aType == getCppuType( (Reference<XIndexContainer>*) NULL ) )
+ {
+ if (_xIndexContainer.is())
+ return makeAny( Reference< XIndexContainer >( SAL_STATIC_CAST(XIndexContainer*, this) ) );
+ }
+ else if ( aType == getCppuType( (Reference<XIndexAccess>*) NULL ) )
+ {
+ if (_xIndexAccess.is())
+ return makeAny( Reference< XIndexAccess >( SAL_STATIC_CAST(XIndexAccess*, this) ) );
+ }
+ else if ( aType == getCppuType( (Reference<XEnumerationAccess>*) NULL ) )
+ {
+ if (_xEnumerationAccess.is())
+ return makeAny( Reference< XEnumerationAccess >( SAL_STATIC_CAST(XEnumerationAccess*, this) ) );
+ }
+ else if ( aType == getCppuType( (Reference<XElementAccess>*) NULL ) )
+ {
+ if (_xElementAccess.is())
+ {
+ return makeAny( Reference< XElementAccess >(
+ SAL_STATIC_CAST(XElementAccess*, SAL_STATIC_CAST(XNameContainer*, this) ) ) );
+ }
+ }
+ else if ( aType == getCppuType( (Reference<XInvocation2>*) NULL ) )
+ {
+ // Invocation does not support XInvocation2, if direct object supports
+ // XInvocation, but not XInvocation2.
+ if ( ( _xDirect.is() && _xDirect2.is()) ||
+ (!_xDirect.is() && _xIntrospectionAccess.is() ) )
+ {
+ return makeAny( Reference< XInvocation2 >( SAL_STATIC_CAST(XInvocation2*, this) ) );
+ }
+ }
+
+ return OWeakObject::queryInterface( aType );
+}
+
+
+//--------------------------------------------------------------------------------------------------
+Any Invocation_Impl::getMaterial(void) throw(RuntimeException)
+{
+ // AB, 12.2.1999 Sicherstellen, dass das Material wenn moeglich
+ // aus der direkten Invocation bzw. von der Introspection geholt
+ // wird, da sonst Structs nicht korrekt behandelt werden
+ Reference<XMaterialHolder> xMaterialHolder;
+ if( _xDirect.is() )
+ {
+ xMaterialHolder = Reference<XMaterialHolder>::query( _xDirect );
+ //_xDirect->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
+ }
+ else if( _xIntrospectionAccess.is() )
+ {
+ xMaterialHolder = Reference<XMaterialHolder>::query( _xIntrospectionAccess );
+ //_xIntrospectionAccess->queryInterface( XMaterialHolder::getSmartUik(), xMaterialHolder );
+ }
+ if( xMaterialHolder.is() )
+ {
+ return xMaterialHolder->getMaterial();
+ }
+ return _aMaterial;
+}
+
+//--------------------------------------------------------------------------------------------------
+void Invocation_Impl::setMaterial( const Any& rMaterial )
+{
+ // set the material first and only once
+ Reference<XInterface> xObj;
+
+ if (rMaterial.getValueType().getTypeClass() == TypeClass_INTERFACE)
+ xObj = *(Reference<XInterface>*)rMaterial.getValue();
+ _aMaterial = rMaterial;
+
+ // Ersteinmal alles ausserhalb des guards machen
+ _xDirect = Reference<XInvocation>::query( xObj );
+
+ if( _xDirect.is() )
+ {
+ // Objekt direkt befragen
+ _xElementAccess = Reference<XElementAccess>::query( _xDirect );
+ _xEnumerationAccess = Reference<XEnumerationAccess>::query( _xDirect );
+ _xIndexAccess = Reference<XIndexAccess>::query( _xDirect );
+ _xIndexContainer = Reference<XIndexContainer>::query( _xDirect );
+ _xNameAccess = Reference<XNameAccess>::query( _xDirect );
+ _xNameContainer = Reference<XNameContainer>::query( _xDirect );
+ _xENDirect = Reference<XExactName>::query( _xDirect );
+ _xDirect2 = Reference<XInvocation2>::query( _xDirect );
+
+ // only once!!!
+ //_xIntrospectionAccess = XIntrospectionAccessRef();
+ //_xPropertySet = XPropertySetRef();
+ }
+ else
+ {
+ // Invocation ueber die Introspection machen
+ if (xIntrospection.is())
+ {
+ _xIntrospectionAccess = xIntrospection->inspect( _aMaterial );
+ if( _xIntrospectionAccess.is() )
+ {
+
+ _xElementAccess = Reference<XElementAccess>::query(
+ _xIntrospectionAccess->queryAdapter(
+ getCppuType( (Reference<XElementAccess>*) NULL ) ) );
+
+ _xEnumerationAccess = Reference<XEnumerationAccess>::query(
+ _xIntrospectionAccess->queryAdapter(
+ getCppuType( (Reference<XEnumerationAccess>*) NULL )) );
+
+ _xIndexAccess = Reference<XIndexAccess>::query(
+ _xIntrospectionAccess->queryAdapter(
+ getCppuType( (Reference<XIndexAccess>*) NULL ) ) );
+
+ _xIndexContainer = Reference<XIndexContainer>::query(
+ _xIntrospectionAccess->queryAdapter(
+ getCppuType( (Reference<XIndexContainer>*) NULL ) ) );
+
+ _xNameAccess = Reference<XNameAccess>::query(
+ _xIntrospectionAccess->queryAdapter(
+ getCppuType( (Reference<XNameAccess>*) NULL ) ) );
+
+ _xNameContainer = Reference<XNameContainer>::query(
+ _xIntrospectionAccess->queryAdapter(
+ getCppuType( (Reference<XNameContainer>*) NULL ) ) );
+
+ _xPropertySet = Reference<XPropertySet>::query(
+ _xIntrospectionAccess->queryAdapter(
+ getCppuType( (Reference<XPropertySet>*) NULL )) );
+
+ _xENIntrospection = Reference<XExactName>::query( _xIntrospectionAccess );
+ if (_xNameAccess.is())
+ _xENNameAccess = Reference<XExactName>::query( _xNameAccess );
+ }
+ }
+ /* only once !!!
+ _xDirect = XInvocationRef();
+ if( !_xIntrospectionAccess.is() )
+ {
+ // reset
+ _xElementAccess = XElementAccessRef();
+ _xEnumerationAccess = XEnumerationAccessRef();
+ _xIndexAccess = XIndexAccessRef();
+ _xIndexContainer = XIndexContainerRef();
+ _xNameAccess = XNameAccessRef();
+ _xNameContainer = XNameContainerRef();
+ _xPropertySet = XPropertySetRef();
+ }
+ */
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+OUString Invocation_Impl::getExactName( const OUString& rApproximateName )
+ throw( RuntimeException )
+{
+ if (_xENDirect.is())
+ return _xENDirect->getExactName( rApproximateName );
+
+ OUString aRet;
+ if (_xENIntrospection.is())
+ aRet = _xENIntrospection->getExactName( rApproximateName );
+ if (!aRet.getLength() && _xENNameAccess.is())
+ aRet = _xENNameAccess->getExactName( rApproximateName );
+ return aRet;
+}
+
+//--------------------------------------------------------------------------------------------------
+Reference<XIntrospectionAccess> Invocation_Impl::getIntrospection(void)
+ throw( RuntimeException )
+{
+ if( _xDirect.is() )
+ return _xDirect->getIntrospection();
+ else
+ return _xIntrospectionAccess;
+}
+
+//--------------------------------------------------------------------------------------------------
+sal_Bool Invocation_Impl::hasMethod( const OUString& Name )
+ throw( RuntimeException )
+{
+ if (_xDirect.is())
+ return _xDirect->hasMethod( Name );
+ if( _xIntrospectionAccess.is() )
+ return _xIntrospectionAccess->hasMethod( Name, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
+ return sal_False;
+}
+
+//--------------------------------------------------------------------------------------------------
+sal_Bool Invocation_Impl::hasProperty( const OUString& Name )
+ throw( RuntimeException )
+{
+ if (_xDirect.is())
+ return _xDirect->hasProperty( Name );
+ // PropertySet
+ if( _xIntrospectionAccess.is()
+ && _xIntrospectionAccess->hasProperty( Name, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
+ return sal_True;
+ // NameAccess
+ if( _xNameAccess.is() )
+ return _xNameAccess->hasByName( Name );
+ return sal_False;
+}
+
+//--------------------------------------------------------------------------------------------------
+Any Invocation_Impl::getValue( const OUString& PropertyName )
+ throw( UnknownPropertyException, RuntimeException )
+{
+ if (_xDirect.is())
+ return _xDirect->getValue( PropertyName );
+ try
+ {
+ // PropertySet
+ if( _xIntrospectionAccess.is() && _xPropertySet.is()
+ && _xIntrospectionAccess->hasProperty
+ ( PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
+ {
+ return _xPropertySet->getPropertyValue( PropertyName );
+ }
+ // NameAccess
+ if( _xNameAccess.is() && _xNameAccess->hasByName( PropertyName ) )
+ return _xNameAccess->getByName( PropertyName );
+ }
+ catch (UnknownPropertyException &)
+ {
+ throw;
+ }
+ catch (RuntimeException &)
+ {
+ throw;
+ }
+ catch (Exception &)
+ {
+ }
+
+ throw UnknownPropertyException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("cannot get value ") ) + PropertyName,
+ Reference< XInterface >() );
+}
+
+//--------------------------------------------------------------------------------------------------
+void Invocation_Impl::setValue( const OUString& PropertyName, const Any& Value )
+ throw( UnknownPropertyException, CannotConvertException, InvocationTargetException, RuntimeException )
+{
+ if (_xDirect.is())
+ _xDirect->setValue( PropertyName, Value );
+ else
+ {
+ try
+ {
+ // Properties
+ if( _xIntrospectionAccess.is() && _xPropertySet.is()
+ && _xIntrospectionAccess->hasProperty(
+ PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
+ {
+ Property aProp = _xIntrospectionAccess->getProperty(
+ PropertyName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS );
+ Reference < XIdlClass > r = TypeToIdlClass( aProp.Type, xCoreReflection );
+ if( r->isAssignableFrom( TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) )
+ _xPropertySet->setPropertyValue( PropertyName, Value );
+ else if( xTypeConverter.is() )
+ _xPropertySet->setPropertyValue(
+ PropertyName, xTypeConverter->convertTo( Value, aProp.Type ) );
+ else
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no type converter service!") ),
+ Reference< XInterface >() );
+ }
+ // NameContainer
+ else if( _xNameContainer.is() )
+ {
+ Any aConv;
+ Reference < XIdlClass > r =
+ TypeToIdlClass( _xNameContainer->getElementType(), xCoreReflection );
+ if( r->isAssignableFrom(TypeToIdlClass( Value.getValueType(), xCoreReflection ) ) )
+ aConv = Value;
+ else if( xTypeConverter.is() )
+ aConv = xTypeConverter->convertTo( Value, _xNameContainer->getElementType() );
+ else
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no type converter service!") ),
+ Reference< XInterface >() );
+
+ // bei Vorhandensein ersetzen, ansonsten einfuegen
+ if (_xNameContainer->hasByName( PropertyName ))
+ _xNameContainer->replaceByName( PropertyName, aConv );
+ else
+ _xNameContainer->insertByName( PropertyName, aConv );
+ }
+ else
+ throw UnknownPropertyException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no introspection nor name container!") ),
+ Reference< XInterface >() );
+ }
+ catch (UnknownPropertyException &)
+ {
+ throw;
+ }
+ catch (CannotConvertException &)
+ {
+ throw;
+ }
+ catch (InvocationTargetException &)
+ {
+ throw;
+ }
+ catch (RuntimeException &)
+ {
+ throw;
+ }
+ catch (Exception & exc)
+ {
+ throw InvocationTargetException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("exception occured in setValue(): ") ) +
+ exc.Message, Reference< XInterface >(), makeAny( exc /* though sliced */ ) );
+ }
+ }
+}
+
+//--------------------------------------------------------------------------------------------------
+Any Invocation_Impl::invoke( const OUString& FunctionName, const Sequence<Any>& InParams,
+ Sequence<sal_Int16>& OutIndizes, Sequence<Any>& OutParams )
+ throw( IllegalArgumentException, CannotConvertException, InvocationTargetException, RuntimeException )
+{
+ if (_xDirect.is())
+ return _xDirect->invoke( FunctionName, InParams, OutIndizes, OutParams );
+
+ if (_xIntrospectionAccess.is())
+ {
+ // throw NoSuchMethodException if not exist
+ Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod(
+ FunctionName, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
+
+ // ParameterInfos
+ Sequence<ParamInfo> aFParams = xMethod->getParameterInfos();
+ const ParamInfo* pFParams = aFParams.getConstArray();
+ sal_Int32 nFParamsLen = aFParams.getLength();
+ if (nFParamsLen != InParams.getLength())
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("incorrect number of parameters passed invoking function ") ) + FunctionName,
+ (OWeakObject *) this, (sal_Int16) 1 );
+ }
+
+ // IN Parameter
+ const Any* pInParams = InParams.getConstArray();
+
+ // Introspection Invoke Parameter
+ Sequence<Any> aInvokeParams( nFParamsLen );
+ Any* pInvokeParams = aInvokeParams.getArray();
+
+ // OUT Indizes
+ OutIndizes.realloc( nFParamsLen );
+ sal_Int16* pOutIndizes = OutIndizes.getArray();
+ sal_uInt32 nOutIndex = 0;
+
+ for ( sal_Int32 nPos = 0; nPos < nFParamsLen; ++nPos )
+ {
+ try
+ {
+ const ParamInfo& rFParam = pFParams[nPos];
+ const Reference<XIdlClass>& rDestType = rFParam.aType;
+
+ // is IN/INOUT parameter?
+ if (rFParam.aMode != ParamMode_OUT)
+ {
+ if (rDestType->isAssignableFrom( TypeToIdlClass( pInParams[nPos].getValueType(), xCoreReflection ) ))
+ {
+ pInvokeParams[nPos] = pInParams[nPos];
+ }
+ else if (xTypeConverter.is())
+ {
+ Type aDestType( rDestType->getTypeClass(), rDestType->getName() );
+ pInvokeParams[nPos] = xTypeConverter->convertTo( pInParams[nPos], aDestType );
+ }
+ else
+ {
+ CannotConvertException aExc;
+ aExc.Context = *this;
+ aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("invocation type mismatch!") );
+ throw aExc;
+ }
+ }
+
+ // is OUT/INOUT parameter?
+ if (rFParam.aMode != ParamMode_IN)
+ {
+ pOutIndizes[nOutIndex] = (sal_Int16)nPos;
+ if (rFParam.aMode == ParamMode_OUT)
+ rDestType->createObject( pInvokeParams[nPos] ); // default init
+ ++nOutIndex;
+ }
+ }
+ catch( CannotConvertException& rExc )
+ {
+ rExc.ArgumentIndex = nPos; // optionalen Parameter Index hinzufuegen
+ throw rExc;
+ }
+ }
+
+ // execute Method
+ Any aRet = xMethod->invoke( _aMaterial, aInvokeParams );
+
+ // OUT Params
+ OutIndizes.realloc( nOutIndex );
+ pOutIndizes = OutIndizes.getArray();
+ OutParams.realloc( nOutIndex );
+ Any* pOutParams = OutParams.getArray();
+
+ while (nOutIndex--)
+ {
+ pOutParams[nOutIndex] = pInvokeParams[ pOutIndizes[nOutIndex] ];
+ }
+
+ return aRet;
+ }
+
+ RuntimeException aExc;
+ aExc.Context = *this;
+ aExc.Message = OUString( RTL_CONSTASCII_USTRINGPARAM("invocation lacking of introspection access!") );
+ throw aExc;
+}
+
+//--------------------------------------------------------------------------------------------------
+
+// Struct to optimize sorting
+struct MemberItem
+{
+ OUString aName;
+
+ // Defines where the member comes from
+ enum Mode { NAMEACCESS, PROPERTYSET, METHOD } eMode;
+
+ // Index to respective sequence
+ // (Index to NameAccess sequence for eMode==NAMEACCESS etc.)
+ sal_Int32 nIndex;
+};
+
+// Implementation of getting name or info
+// String sequence will be filled when pStringSeq != NULL
+// Info sequence will be filled when pInfoSeq != NULL
+void Invocation_Impl::getInfoSequenceImpl
+(
+ Sequence< OUString >* pStringSeq,
+ Sequence< InvocationInfo >* pInfoSeq
+)
+{
+ //Sequence< OUString > aStrSeq;
+ //if( !pStringSeq )
+ //pStringSeq = &aStrSeq;
+
+
+ // Get all needed sequences
+ Sequence<OUString> aNameAccessNames;
+ Sequence<Property> aPropertySeq;
+ Sequence< Reference< XIdlMethod > > aMethodSeq;
+
+ if( _xNameAccess.is() )
+ {
+ aNameAccessNames = _xNameAccess->getElementNames();
+ }
+
+ if( _xIntrospectionAccess.is() )
+ {
+ aPropertySeq = _xIntrospectionAccess->getProperties
+ ( PropertyConcept::ALL - PropertyConcept::DANGEROUS );
+
+ aMethodSeq = _xIntrospectionAccess->getMethods
+ ( MethodConcept::ALL - MethodConcept::DANGEROUS );
+ }
+
+ sal_Int32 nNameAccessCount = aNameAccessNames.getLength();
+ sal_Int32 nPropertyCount = aPropertySeq.getLength();
+ sal_Int32 nMethodCount = aMethodSeq.getLength();
+ sal_Int32 nTotalCount = nNameAccessCount + nPropertyCount + nMethodCount;
+
+ // Create and fill array of MemberItems
+ boost::scoped_array< MemberItem > pItems( new MemberItem[ nTotalCount ] );
+ const OUString* pStrings = aNameAccessNames.getConstArray();
+ const Property* pProps = aPropertySeq.getConstArray();
+ const Reference< XIdlMethod >* pMethods = aMethodSeq.getConstArray();
+
+ // Fill array of MemberItems
+ sal_Int32 i, iTotal = 0;
+
+ // Name Access
+ for( i = 0 ; i < nNameAccessCount ; i++, iTotal++ )
+ {
+ MemberItem& rItem = pItems[ iTotal ];
+ rItem.aName = pStrings[ i ];
+ rItem.eMode = MemberItem::NAMEACCESS;
+ rItem.nIndex = i;
+ }
+
+ // Property set
+ for( i = 0 ; i < nPropertyCount ; i++, iTotal++ )
+ {
+ MemberItem& rItem = pItems[ iTotal ];
+ rItem.aName = pProps[ i ].Name;
+ rItem.eMode = MemberItem::PROPERTYSET;
+ rItem.nIndex = i;
+ }
+
+ // Methods
+ for( i = 0 ; i < nMethodCount ; i++, iTotal++ )
+ {
+ MemberItem& rItem = pItems[ iTotal ];
+ Reference< XIdlMethod > xMethod = pMethods[ i ];
+ rItem.aName = xMethod->getName();
+ rItem.eMode = MemberItem::METHOD;
+ rItem.nIndex = i;
+ }
+
+ // Setting up result sequences
+ OUString* pRetStrings = NULL;
+ if( pStringSeq )
+ {
+ pStringSeq->realloc( nTotalCount );
+ pRetStrings = pStringSeq->getArray();
+ }
+
+ InvocationInfo* pRetInfos = NULL;
+ if( pInfoSeq )
+ {
+ pInfoSeq->realloc( nTotalCount );
+ pRetInfos = pInfoSeq->getArray();
+ }
+
+ // Fill result sequences in the correct order of members
+ for( iTotal = 0 ; iTotal < nTotalCount ; iTotal++ )
+ {
+ MemberItem& rItem = pItems[ iTotal ];
+ if( pRetStrings )
+ {
+ pRetStrings[ iTotal ] = rItem.aName;
+ }
+
+ if( pRetInfos )
+ {
+ if( rItem.eMode == MemberItem::NAMEACCESS )
+ {
+ fillInfoForNameAccess( pRetInfos[ iTotal ], rItem.aName );
+ }
+ else if( rItem.eMode == MemberItem::PROPERTYSET )
+ {
+ fillInfoForProperty( pRetInfos[ iTotal ], pProps[ rItem.nIndex ] );
+ }
+ else if( rItem.eMode == MemberItem::METHOD )
+ {
+ fillInfoForMethod( pRetInfos[ iTotal ], pMethods[ rItem.nIndex ] );
+ }
+ }
+ }
+}
+
+// XInvocation2
+Sequence< OUString > SAL_CALL Invocation_Impl::getMemberNames( )
+ throw( RuntimeException )
+{
+ if( _xDirect2.is() )
+ {
+ return _xDirect2->getMemberNames();
+ }
+ Sequence< OUString > aRetSeq;
+ getInfoSequenceImpl( &aRetSeq, NULL );
+ return aRetSeq;
+}
+
+Sequence< InvocationInfo > SAL_CALL Invocation_Impl::getInfo( )
+ throw( RuntimeException )
+{
+ if( _xDirect2.is() )
+ {
+ return _xDirect2->getInfo();
+ }
+ Sequence< InvocationInfo > aRetSeq;
+ getInfoSequenceImpl( NULL, &aRetSeq );
+ return aRetSeq;
+}
+
+InvocationInfo SAL_CALL Invocation_Impl::getInfoForName( const OUString& aName, sal_Bool bExact )
+ throw( IllegalArgumentException, RuntimeException )
+{
+ if( _xDirect2.is() )
+ {
+ return _xDirect2->getInfoForName( aName, bExact );
+ }
+
+ sal_Bool bFound = sal_False;
+ OUString aExactName = aName;
+ InvocationInfo aRetInfo;
+
+ if( bExact )
+ aExactName = getExactName( aName );
+ if( aExactName.getLength() > 0 )
+ {
+ if( _xIntrospectionAccess->hasMethod( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS ) )
+ {
+ Reference<XIdlMethod> xMethod = _xIntrospectionAccess->getMethod
+ ( aExactName, MethodConcept::ALL ^ MethodConcept::DANGEROUS );
+ fillInfoForMethod( aRetInfo, xMethod );
+ bFound = sal_True;
+ }
+ else
+ {
+ if( _xIntrospectionAccess.is() && _xIntrospectionAccess->hasProperty
+ ( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS ) )
+ {
+ Property aProp = _xIntrospectionAccess->getProperty
+ ( aExactName, PropertyConcept::ALL ^ PropertyConcept::DANGEROUS );
+ fillInfoForProperty( aRetInfo, aProp );
+ bFound = sal_True;
+ }
+ // NameAccess
+ else if( _xNameAccess.is() && _xNameAccess->hasByName( aExactName ) )
+ {
+ fillInfoForNameAccess( aRetInfo, aExactName );
+ bFound = sal_True;
+ }
+ }
+ }
+ if( !bFound )
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("Unknown name, getExactName() failed!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+ return aRetInfo;
+}
+
+// Helper functions to fill InvocationInfo for XNameAccess
+void Invocation_Impl::fillInfoForNameAccess
+(
+ InvocationInfo& rInfo,
+ const OUString& aName
+)
+{
+ rInfo.aName = aName;
+ rInfo.eMemberType = MemberType_PROPERTY;
+ rInfo.PropertyAttribute = 0;
+ if( !_xNameContainer.is() )
+ {
+ rInfo.PropertyAttribute = PropertyAttribute::READONLY;
+ }
+ rInfo.aType = _xNameAccess->getElementType();
+}
+
+void Invocation_Impl::fillInfoForProperty
+(
+ InvocationInfo& rInfo,
+ const Property& rProp
+)
+{
+ rInfo.aName = rProp.Name;
+ rInfo.eMemberType = MemberType_PROPERTY;
+ rInfo.PropertyAttribute = rProp.Attributes;
+ rInfo.aType = rProp.Type;
+}
+
+void Invocation_Impl::fillInfoForMethod
+(
+ InvocationInfo& rInfo,
+ const Reference< XIdlMethod > xMethod
+)
+{
+ rInfo.aName = xMethod->getName();
+ rInfo.eMemberType = MemberType_METHOD;
+ Reference< XIdlClass > xReturnClass = xMethod->getReturnType();
+ Type aReturnType( xReturnClass->getTypeClass(), xReturnClass->getName() );
+ rInfo.aType = aReturnType;
+ Sequence<ParamInfo> aParamInfos = xMethod->getParameterInfos();
+ sal_Int32 nParamCount = aParamInfos.getLength();
+ if( nParamCount > 0 )
+ {
+ const ParamInfo* pInfos = aParamInfos.getConstArray();
+
+ rInfo.aParamTypes.realloc( nParamCount );
+ Type* pParamTypes = rInfo.aParamTypes.getArray();
+ rInfo.aParamModes.realloc( nParamCount );
+ ParamMode* pParamModes = rInfo.aParamModes.getArray();
+
+ for( sal_Int32 i = 0 ; i < nParamCount ; i++ )
+ {
+ Reference< XIdlClass > xParamClass = pInfos[i].aType;
+ Type aParamType( xParamClass->getTypeClass(), xParamClass->getName() );
+ pParamTypes[ i ] = aParamType;
+ pParamModes[ i ] = pInfos[i].aMode;
+ }
+ }
+}
+
+
+// XTypeProvider
+Sequence< Type > SAL_CALL Invocation_Impl::getTypes(void) throw( RuntimeException )
+{
+ static Sequence< Type > const * s_pTypes = 0;
+ if (! s_pTypes)
+ {
+ Sequence< Type > types( 4 +8 );
+ Type * pTypes = types.getArray();
+ sal_Int32 n = 0;
+
+ pTypes[ n++ ] = ::getCppuType( (Reference< XTypeProvider > const *)0 );
+ pTypes[ n++ ] = ::getCppuType( (Reference< XWeak > const *)0 );
+ pTypes[ n++ ] = ::getCppuType( (Reference< XInvocation > const *)0 );
+ pTypes[ n++ ] = ::getCppuType( (Reference< XMaterialHolder > const *)0 );
+
+ // Ivocation does not support XExactName, if direct object supports
+ // XInvocation, but not XExactName.
+ if ((_xDirect.is() && _xENDirect.is()) ||
+ (!_xDirect.is() && (_xENIntrospection.is() || _xENNameAccess.is())))
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XExactName > const *)0 );
+ }
+ if( _xNameContainer.is() )
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XNameContainer > const *)0 );
+ }
+ if( _xNameAccess.is() )
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XNameAccess > const *)0 );
+ }
+ if (_xIndexContainer.is())
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XIndexContainer > const *)0 );
+ }
+ if (_xIndexAccess.is())
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XIndexAccess > const *)0 );
+ }
+ if (_xEnumerationAccess.is())
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XEnumerationAccess > const *)0 );
+ }
+ if (_xElementAccess.is())
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XElementAccess > const *)0 );
+ }
+ // Invocation does not support XInvocation2, if direct object supports
+ // XInvocation, but not XInvocation2.
+ if ( ( _xDirect.is() && _xDirect2.is()) ||
+ (!_xDirect.is() && _xIntrospectionAccess.is() ) )
+ {
+ pTypes[ n++ ] = ::getCppuType( (Reference< XInvocation2 > const *)0 );
+ }
+
+ types.realloc( n );
+
+ // store types
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_pTypes)
+ {
+ static Sequence< Type > s_types( types );
+ s_pTypes = &s_types;
+ }
+ }
+ return *s_pTypes;
+}
+
+Sequence< sal_Int8 > SAL_CALL Invocation_Impl::getImplementationId( ) throw( RuntimeException)
+{
+ static OImplementationId *pId = 0;
+ if( ! pId )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pId )
+ {
+ static OImplementationId id( sal_False );
+ pId = &id;
+ }
+ }
+ return pId->getImplementationId();
+}
+
+//==================================================================================================
+//==================================================================================================
+//==================================================================================================
+class InvocationService
+ : public WeakImplHelper2< XSingleServiceFactory, XServiceInfo >
+{
+public:
+ InvocationService( const Reference<XComponentContext> & xCtx );
+ virtual ~InvocationService();
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() throw( RuntimeException );
+ sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw( RuntimeException );
+ Sequence< OUString > SAL_CALL getSupportedServiceNames(void) throw( RuntimeException );
+
+ // XSingleServiceFactory
+ Reference<XInterface> SAL_CALL createInstance(void) throw( Exception, RuntimeException );
+ Reference<XInterface> SAL_CALL createInstanceWithArguments(
+ const Sequence<Any>& rArguments ) throw( Exception, RuntimeException );
+private:
+ Reference<XComponentContext> mxCtx;
+ Reference<XMultiComponentFactory> mxSMgr;
+ Reference<XTypeConverter> xTypeConverter;
+ Reference<XIntrospection> xIntrospection;
+ Reference<XIdlReflection> xCoreReflection;
+};
+
+InvocationService::InvocationService( const Reference<XComponentContext> & xCtx )
+ : mxCtx( xCtx )
+ , mxSMgr( xCtx->getServiceManager() )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ xTypeConverter = Reference<XTypeConverter>(
+ mxSMgr->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter")),
+ xCtx ),
+ UNO_QUERY );
+ xIntrospection = Reference<XIntrospection>(
+ mxSMgr->createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.beans.Introspection")),
+ xCtx),
+ UNO_QUERY);
+ mxCtx->getValueByName(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection")) )
+ >>= xCoreReflection;
+ OSL_ENSURE( xCoreReflection.is(), "### CoreReflection singleton not accessable!?" );
+ if (! xCoreReflection.is())
+ {
+ throw DeploymentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/singletons/com.sun.star.reflection.theCoreReflection singleton not accessable") ),
+ Reference< XInterface >() );
+ }
+// xCoreReflection = Reference<XIdlReflection>(
+// mxSMgr->createInstanceWithContext(
+// OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.reflection.CoreReflection")),
+// xCtx),
+// UNO_QUERY);
+}
+
+InvocationService::~InvocationService()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XServiceInfo
+OUString InvocationService::getImplementationName() throw( RuntimeException )
+{
+ return inv_getImplementationName();
+}
+
+// XServiceInfo
+sal_Bool InvocationService::supportsService(const OUString& ServiceName) throw( RuntimeException )
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > InvocationService::getSupportedServiceNames(void) throw( RuntimeException )
+{
+ return inv_getSupportedServiceNames();
+}
+
+//--------------------------------------------------------------------------------------------------
+Reference<XInterface> InvocationService::createInstance(void) throw( Exception, RuntimeException )
+{
+ //TODO:throw( Exception(OUString( RTL_CONSTASCII_USTRINGPARAM("no default construction of invocation adapter possible!")), *this) );
+ return Reference<XInterface>(); // dummy
+}
+
+//--------------------------------------------------------------------------------------------------
+Reference<XInterface> InvocationService::createInstanceWithArguments(
+ const Sequence<Any>& rArguments ) throw( Exception, RuntimeException )
+{
+ if (rArguments.getLength() == 1)
+ {
+ return Reference< XInterface >
+ ( *new Invocation_Impl( *rArguments.getConstArray(),
+ xTypeConverter, xIntrospection, xCoreReflection ) );
+ }
+ else
+ {
+ //TODO:throw( Exception(OUString( RTL_CONSTASCII_USTRINGPARAM("no default construction of invocation adapter possible!")), *this) );
+ return Reference<XInterface>();
+ }
+}
+
+
+//*************************************************************************
+Reference<XInterface> SAL_CALL InvocationService_CreateInstance( const Reference<XComponentContext> & xCtx )
+ throw( RuntimeException )
+{
+ Reference<XInterface> xService = Reference< XInterface > ( *new InvocationService( xCtx ) );
+ return xService;
+}
+
+}
+
+using namespace stoc_inv;
+static struct ImplementationEntry g_entries[] =
+{
+ {
+ InvocationService_CreateInstance, inv_getImplementationName,
+ inv_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+}
+
+
+
diff --git a/stoc/source/invocation/makefile.mk b/stoc/source/invocation/makefile.mk
new file mode 100644
index 000000000000..72eeea37c659
--- /dev/null
+++ b/stoc/source/invocation/makefile.mk
@@ -0,0 +1,71 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = invocation.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = inv
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/invocation.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1RPATH=URELIB
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/invocation.component
+
+$(MISC)/invocation.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ invocation.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt invocation.component
diff --git a/stoc/source/invocation_adapterfactory/iafactory.cxx b/stoc/source/invocation_adapterfactory/iafactory.cxx
new file mode 100644
index 000000000000..70d2562657ad
--- /dev/null
+++ b/stoc/source/invocation_adapterfactory/iafactory.cxx
@@ -0,0 +1,1025 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <hash_map>
+#include <hash_set>
+
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+
+#include <uno/dispatcher.h>
+#include <uno/data.h>
+#include <uno/any2.h>
+#include <uno/mapping.hxx>
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implbase3.hxx>
+#include <cppuhelper/implementationentry.hxx>
+
+#include <com/sun/star/uno/XAggregation.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/XInvocationAdapterFactory.hpp>
+#include <com/sun/star/script/XInvocationAdapterFactory2.hpp>
+#include <com/sun/star/script/XInvocation.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/reflection/InvocationTargetException.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+#define SERVICENAME "com.sun.star.script.InvocationAdapterFactory"
+#define IMPLNAME "com.sun.star.comp.stoc.InvocationAdapterFactory"
+
+
+using namespace ::std;
+using namespace ::rtl;
+using namespace ::osl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+namespace stoc_invadp
+{
+
+static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+static Sequence< OUString > invadp_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] =
+ OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+static OUString invadp_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+
+struct hash_ptr
+{
+ inline size_t operator() ( void * p ) const
+ { return (size_t)p; }
+};
+typedef hash_set< void *, hash_ptr, equal_to< void * > > t_ptr_set;
+typedef hash_map< void *, t_ptr_set, hash_ptr, equal_to< void * > > t_ptr_map;
+
+//==============================================================================
+class FactoryImpl
+ : public ::cppu::WeakImplHelper3< lang::XServiceInfo,
+ script::XInvocationAdapterFactory,
+ script::XInvocationAdapterFactory2 >
+{
+public:
+ Mapping m_aUno2Cpp;
+ Mapping m_aCpp2Uno;
+ uno_Interface * m_pConverter;
+
+ typelib_TypeDescription * m_pInvokMethodTD;
+ typelib_TypeDescription * m_pSetValueTD;
+ typelib_TypeDescription * m_pGetValueTD;
+ typelib_TypeDescription * m_pAnySeqTD;
+ typelib_TypeDescription * m_pShortSeqTD;
+ typelib_TypeDescription * m_pConvertToTD;
+
+ Mutex m_mutex;
+ t_ptr_map m_receiver2adapters;
+
+ FactoryImpl( Reference< XComponentContext > const & xContext )
+ SAL_THROW( (RuntimeException) );
+ virtual ~FactoryImpl() SAL_THROW( () );
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
+ throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+
+ // XInvocationAdapterFactory
+ virtual Reference< XInterface > SAL_CALL createAdapter(
+ const Reference< script::XInvocation > & xReceiver, const Type & rType )
+ throw (RuntimeException);
+ // XInvocationAdapterFactory2
+ virtual Reference< XInterface > SAL_CALL createAdapter(
+ const Reference< script::XInvocation > & xReceiver,
+ const Sequence< Type > & rTypes )
+ throw (RuntimeException);
+};
+struct AdapterImpl;
+//==============================================================================
+struct InterfaceAdapterImpl : public uno_Interface
+{
+ AdapterImpl * m_pAdapter;
+ typelib_InterfaceTypeDescription * m_pTypeDescr;
+};
+//==============================================================================
+struct AdapterImpl
+{
+ oslInterlockedCount m_nRef;
+ FactoryImpl * m_pFactory;
+ void * m_key; // map key
+ uno_Interface * m_pReceiver; // XInvocation receiver
+
+ sal_Int32 m_nInterfaces;
+ InterfaceAdapterImpl * m_pInterfaces;
+
+ // XInvocation calls
+ void getValue(
+ const typelib_TypeDescription * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException );
+ void setValue(
+ const typelib_TypeDescription * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException );
+ void invoke(
+ const typelib_TypeDescription * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException );
+
+ bool coerce_assign(
+ void * pDest, typelib_TypeDescriptionReference * pType,
+ uno_Any * pSource, uno_Any * pExc );
+ inline bool coerce_construct(
+ void * pDest, typelib_TypeDescriptionReference * pType,
+ uno_Any * pSource, uno_Any * pExc );
+
+ inline void acquire()
+ SAL_THROW( () );
+ inline void release()
+ SAL_THROW( () );
+ inline ~AdapterImpl()
+ SAL_THROW( () );
+ inline AdapterImpl(
+ void * key, Reference< script::XInvocation > const & xReceiver,
+ const Sequence< Type > & rTypes,
+ FactoryImpl * pFactory )
+ SAL_THROW( (RuntimeException) );
+};
+//______________________________________________________________________________
+inline AdapterImpl::~AdapterImpl()
+ SAL_THROW( () )
+{
+ for ( sal_Int32 nPos = m_nInterfaces; nPos--; )
+ {
+ ::typelib_typedescription_release(
+ (typelib_TypeDescription *)m_pInterfaces[ nPos ].m_pTypeDescr );
+ }
+ delete [] m_pInterfaces;
+ //
+ (*m_pReceiver->release)( m_pReceiver );
+ m_pFactory->release();
+}
+//______________________________________________________________________________
+inline void AdapterImpl::acquire()
+ SAL_THROW( () )
+{
+ ::osl_incrementInterlockedCount( &m_nRef );
+}
+//______________________________________________________________________________
+inline void AdapterImpl::release()
+ SAL_THROW( () )
+{
+ bool delete_this = false;
+ {
+ MutexGuard guard( m_pFactory->m_mutex );
+ if (! ::osl_decrementInterlockedCount( &m_nRef ))
+ {
+ t_ptr_map::iterator iFind(
+ m_pFactory->m_receiver2adapters.find( m_key ) );
+ OSL_ASSERT( m_pFactory->m_receiver2adapters.end() != iFind );
+ t_ptr_set & adapter_set = iFind->second;
+ if (adapter_set.erase( this ) != 1) {
+ OSL_ASSERT( false );
+ }
+ if (adapter_set.empty())
+ {
+ m_pFactory->m_receiver2adapters.erase( iFind );
+ }
+ delete_this = true;
+ }
+ }
+ if (delete_this)
+ delete this;
+}
+
+//------------------------------------------------------------------------------
+static inline void constructRuntimeException(
+ uno_Any * pExc, const OUString & rMsg )
+{
+ RuntimeException exc( rMsg, Reference< XInterface >() );
+ // no conversion neeeded due to binary compatibility + no convertable type
+ ::uno_type_any_construct(
+ pExc, &exc, ::getCppuType( &exc ).getTypeLibType(), 0 );
+}
+
+//------------------------------------------------------------------------------
+static inline sal_Bool type_equals(
+ typelib_TypeDescriptionReference * pType1,
+ typelib_TypeDescriptionReference * pType2 )
+ SAL_THROW( () )
+{
+ return (pType1 == pType2 ||
+ (pType1->pTypeName->length == pType2->pTypeName->length &&
+ 0 == ::rtl_ustr_compare(
+ pType1->pTypeName->buffer, pType2->pTypeName->buffer )));
+}
+
+//______________________________________________________________________________
+bool AdapterImpl::coerce_assign(
+ void * pDest, typelib_TypeDescriptionReference * pType, uno_Any * pSource,
+ uno_Any * pOutExc )
+{
+ if (typelib_TypeClass_ANY == pType->eTypeClass)
+ {
+ ::uno_type_any_assign(
+ (uno_Any *)pDest, pSource->pData, pSource->pType, 0, 0 );
+ return true;
+ }
+ if (::uno_type_assignData(
+ pDest, pType, pSource->pData, pSource->pType, 0, 0, 0 ))
+ {
+ return true;
+ }
+ else // try type converter
+ {
+ uno_Any ret;
+ void * args[ 2 ];
+ args[ 0 ] = pSource;
+ args[ 1 ] = &pType;
+ uno_Any exc;
+ uno_Any * p_exc = &exc;
+
+ // converTo()
+ (*m_pFactory->m_pConverter->pDispatcher)(
+ m_pFactory->m_pConverter,
+ m_pFactory->m_pConvertToTD, &ret, args, &p_exc );
+
+ if (p_exc) // exception occured
+ {
+ OSL_ASSERT(
+ p_exc->pType->eTypeClass == typelib_TypeClass_EXCEPTION );
+ if (typelib_typedescriptionreference_isAssignableFrom(
+ ::getCppuType(
+ (RuntimeException const *) 0 ).getTypeLibType(),
+ p_exc->pType ))
+ {
+ // is RuntimeException or derived: rethrow
+ uno_type_any_construct(
+ pOutExc, p_exc->pData, p_exc->pType, 0 );
+ }
+ else
+ {
+ // set runtime exception
+ constructRuntimeException(
+ pOutExc, OUSTR("type coercion failed: ") +
+ reinterpret_cast< Exception const * >(
+ p_exc->pData )->Message );
+ }
+ ::uno_any_destruct( p_exc, 0 );
+ // pOutExc constructed
+ return false;
+ }
+ else
+ {
+ bool succ = (sal_False != ::uno_type_assignData(
+ pDest, pType, ret.pData, ret.pType, 0, 0, 0 ));
+ ::uno_any_destruct( &ret, 0 );
+ OSL_ENSURE(
+ succ, "### conversion succeeded, but assignment failed!?" );
+ if (! succ)
+ {
+ // set runtime exception
+ constructRuntimeException(
+ pOutExc,
+ OUSTR("type coercion failed: "
+ "conversion succeeded, but assignment failed?!") );
+ }
+ return succ;
+ }
+ }
+}
+//______________________________________________________________________________
+inline bool AdapterImpl::coerce_construct(
+ void * pDest, typelib_TypeDescriptionReference * pType, uno_Any * pSource,
+ uno_Any * pExc )
+{
+ if (typelib_TypeClass_ANY == pType->eTypeClass)
+ {
+ ::uno_type_copyData( pDest, pSource, pType, 0 );
+ return true;
+ }
+ if (type_equals( pType, pSource->pType))
+ {
+ ::uno_type_copyData( pDest, pSource->pData, pType, 0 );
+ return true;
+ }
+ ::uno_type_constructData( pDest, pType );
+ return coerce_assign( pDest, pType, pSource, pExc );
+}
+
+//------------------------------------------------------------------------------
+static void handleInvokExc( uno_Any * pDest, uno_Any * pSource )
+{
+ OUString const & name =
+ *reinterpret_cast< OUString const * >( &pSource->pType->pTypeName );
+
+ if (name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM(
+ "com.sun.star.reflection.InvocationTargetException") ))
+ {
+ // unwrap invocation target exception
+ uno_Any * target_exc =
+ &reinterpret_cast< reflection::InvocationTargetException * >(
+ pSource->pData )->TargetException;
+ ::uno_type_any_construct(
+ pDest, target_exc->pData, target_exc->pType, 0 );
+ }
+ else // all other exceptions are wrapped to RuntimeException
+ {
+ if (typelib_TypeClass_EXCEPTION == pSource->pType->eTypeClass)
+ {
+ constructRuntimeException(
+ pDest, ((Exception const *)pSource->pData)->Message );
+ }
+ else
+ {
+ constructRuntimeException(
+ pDest, OUSTR("no exception has been thrown via invocation?!") );
+ }
+ }
+}
+//______________________________________________________________________________
+void AdapterImpl::getValue(
+ const typelib_TypeDescription * pMemberType,
+ void * pReturn, void * [], uno_Any ** ppException )
+{
+ uno_Any aInvokRet;
+ void * pInvokArgs[1];
+ pInvokArgs[0] =
+ &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName;
+ uno_Any aInvokExc;
+ uno_Any * pInvokExc = &aInvokExc;
+
+ // getValue()
+ (*m_pReceiver->pDispatcher)(
+ m_pReceiver, m_pFactory->m_pGetValueTD,
+ &aInvokRet, pInvokArgs, &pInvokExc );
+
+ if (pInvokExc) // getValue() call exception
+ {
+ handleInvokExc( *ppException, pInvokExc );
+ ::uno_any_destruct( pInvokExc, 0 ); // cleanup
+ }
+ else // invocation call succeeded
+ {
+ if (coerce_construct(
+ pReturn,
+ ((typelib_InterfaceAttributeTypeDescription *)
+ pMemberType)->pAttributeTypeRef,
+ &aInvokRet, *ppException ))
+ {
+ *ppException = 0; // no exceptions be thrown
+ }
+ ::uno_any_destruct( &aInvokRet, 0 );
+ }
+}
+//______________________________________________________________________________
+void AdapterImpl::setValue(
+ const typelib_TypeDescription * pMemberType,
+ void *, void * pArgs[], uno_Any ** ppException )
+{
+ uno_Any aInvokVal;
+ ::uno_type_any_construct(
+ &aInvokVal, pArgs[0],
+ ((typelib_InterfaceAttributeTypeDescription *)
+ pMemberType)->pAttributeTypeRef, 0 );
+
+ void * pInvokArgs[2];
+ pInvokArgs[0] =
+ &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName;
+ pInvokArgs[1] = &aInvokVal;
+ uno_Any aInvokExc;
+ uno_Any * pInvokExc = &aInvokExc;
+
+ // setValue()
+ (*m_pReceiver->pDispatcher)(
+ m_pReceiver, m_pFactory->m_pSetValueTD, 0, pInvokArgs, &pInvokExc );
+
+ if (pInvokExc) // setValue() call exception
+ {
+ handleInvokExc( *ppException, pInvokExc );
+ ::uno_any_destruct( pInvokExc, 0 ); // cleanup
+ }
+ else // invocation call succeeded
+ {
+ *ppException = 0; // no exceptions be thrown
+ }
+
+ ::uno_any_destruct( &aInvokVal, 0 ); // cleanup
+}
+//______________________________________________________________________________
+void AdapterImpl::invoke(
+ const typelib_TypeDescription * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ sal_Int32 nParams =
+ ((typelib_InterfaceMethodTypeDescription *)pMemberType)->nParams;
+ typelib_MethodParameter * pFormalParams =
+ ((typelib_InterfaceMethodTypeDescription *)pMemberType)->pParams;
+
+ // in params
+ uno_Sequence * pInParamsSeq = 0;
+ ::uno_sequence_construct(
+ &pInParamsSeq, m_pFactory->m_pAnySeqTD, 0, nParams, 0 );
+ uno_Any * pInAnys = (uno_Any *)pInParamsSeq->elements;
+ sal_Int32 nOutParams = 0;
+ sal_Int32 nPos;
+ for ( nPos = nParams; nPos--; )
+ {
+ typelib_MethodParameter const & rParam = pFormalParams[nPos];
+ if (rParam.bIn) // is in/inout param
+ {
+ ::uno_type_any_assign(
+ &pInAnys[nPos], pArgs[nPos], rParam.pTypeRef, 0, 0 );
+ }
+ // else: pure out is empty any
+
+ if (rParam.bOut)
+ ++nOutParams;
+ }
+
+ // out params, out indices
+ uno_Sequence * pOutIndices;
+ uno_Sequence * pOutParams;
+ // return value
+ uno_Any aInvokRet;
+ // perform call
+ void * pInvokArgs[4];
+ pInvokArgs[0] =
+ &((typelib_InterfaceMemberTypeDescription *)pMemberType)->pMemberName;
+ pInvokArgs[1] = &pInParamsSeq;
+ pInvokArgs[2] = &pOutIndices;
+ pInvokArgs[3] = &pOutParams;
+ uno_Any aInvokExc;
+ uno_Any * pInvokExc = &aInvokExc;
+
+ // invoke() call
+ (*m_pReceiver->pDispatcher)(
+ m_pReceiver, m_pFactory->m_pInvokMethodTD,
+ &aInvokRet, pInvokArgs, &pInvokExc );
+
+ if (pInvokExc)
+ {
+ handleInvokExc( *ppException, pInvokExc );
+ ::uno_any_destruct( pInvokExc, 0 ); // cleanup
+ }
+ else // no invocation exception
+ {
+ // write changed out params
+ OSL_ENSURE(
+ pOutParams->nElements == nOutParams &&
+ pOutIndices->nElements == nOutParams,
+ "### out params lens differ!" );
+ if (pOutParams->nElements == nOutParams &&
+ pOutIndices->nElements == nOutParams)
+ {
+ sal_Int16 * pIndices = (sal_Int16 *)pOutIndices->elements;
+ uno_Any * pOut = (uno_Any *)pOutParams->elements;
+ for ( nPos = 0; nPos < nOutParams; ++nPos )
+ {
+ sal_Int32 nIndex = pIndices[nPos];
+ OSL_ENSURE( nIndex < nParams, "### illegal index!" );
+ typelib_MethodParameter const & rParam = pFormalParams[nIndex];
+ bool succ;
+ if (rParam.bIn) // is in/inout param
+ {
+ succ = coerce_assign(
+ pArgs[nIndex], rParam.pTypeRef, &pOut[nPos],
+ *ppException );
+ }
+ else // pure out
+ {
+ succ = coerce_construct(
+ pArgs[nIndex], rParam.pTypeRef, &pOut[nPos],
+ *ppException );
+ }
+ if (! succ) // cleanup of out params
+ {
+ for ( sal_Int32 n = 0; n <= nPos; ++n )
+ {
+ sal_Int32 nIndex2 = pIndices[n];
+ OSL_ENSURE( nIndex2 < nParams, "### illegal index!" );
+ typelib_MethodParameter const & rParam2 =
+ pFormalParams[nIndex2];
+ if (! rParam2.bIn) // is pure out param
+ {
+ ::uno_type_destructData(
+ pArgs[nIndex2], rParam2.pTypeRef, 0 );
+ }
+ }
+ }
+ }
+ if (nPos == pOutIndices->nElements)
+ {
+ // out param copy ok; write return value
+ if (coerce_construct(
+ pReturn,
+ ((typelib_InterfaceMethodTypeDescription *)
+ pMemberType)->pReturnTypeRef,
+ &aInvokRet, *ppException ))
+ {
+ *ppException = 0; // no exception
+ }
+ }
+ }
+ else
+ {
+ // set runtime exception
+ constructRuntimeException(
+ *ppException,
+ OUSTR("out params lengths differ after invocation call!") );
+ }
+ // cleanup invok out params
+ ::uno_destructData( &pOutIndices, m_pFactory->m_pShortSeqTD, 0 );
+ ::uno_destructData( &pOutParams, m_pFactory->m_pAnySeqTD, 0 );
+ // cleanup invok return value
+ ::uno_any_destruct( &aInvokRet, 0 );
+ }
+ // cleanup constructed in params
+ ::uno_destructData( &pInParamsSeq, m_pFactory->m_pAnySeqTD, 0 );
+}
+
+extern "C"
+{
+//______________________________________________________________________________
+static void SAL_CALL adapter_acquire( uno_Interface * pUnoI )
+{
+ static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->acquire();
+}
+//______________________________________________________________________________
+static void SAL_CALL adapter_release( uno_Interface * pUnoI )
+{
+ static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter->release();
+}
+//______________________________________________________________________________
+static void SAL_CALL adapter_dispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType,
+ void * pReturn, void * pArgs[], uno_Any ** ppException )
+{
+ // query to emulated interface
+ switch (((typelib_InterfaceMemberTypeDescription *)pMemberType)->nPosition)
+ {
+ case 0: // queryInterface()
+ {
+ AdapterImpl * that =
+ static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter;
+ *ppException = 0; // no exc
+ typelib_TypeDescriptionReference * pDemanded =
+ *(typelib_TypeDescriptionReference **)pArgs[0];
+ // pInterfaces[0] is XInterface
+ for ( sal_Int32 nPos = 0; nPos < that->m_nInterfaces; ++nPos )
+ {
+ typelib_InterfaceTypeDescription * pTD =
+ that->m_pInterfaces[nPos].m_pTypeDescr;
+ while (pTD)
+ {
+ if (type_equals(
+ ((typelib_TypeDescription *)pTD)->pWeakRef, pDemanded ))
+ {
+ uno_Interface * pUnoI2 = &that->m_pInterfaces[nPos];
+ ::uno_any_construct(
+ (uno_Any *)pReturn, &pUnoI2,
+ (typelib_TypeDescription *)pTD, 0 );
+ return;
+ }
+ pTD = pTD->pBaseTypeDescription;
+ }
+ }
+ ::uno_any_construct( (uno_Any *)pReturn, 0, 0, 0 ); // clear()
+ break;
+ }
+ case 1: // acquire()
+ *ppException = 0; // no exc
+ adapter_acquire( pUnoI );
+ break;
+ case 2: // release()
+ *ppException = 0; // no exc
+ adapter_release( pUnoI );
+ break;
+
+ default:
+ {
+ AdapterImpl * that =
+ static_cast< InterfaceAdapterImpl * >( pUnoI )->m_pAdapter;
+ if (pMemberType->eTypeClass == typelib_TypeClass_INTERFACE_METHOD)
+ {
+ that->invoke( pMemberType, pReturn, pArgs, ppException );
+ }
+ else // attribute
+ {
+ if (pReturn)
+ that->getValue( pMemberType, pReturn, pArgs, ppException );
+ else
+ that->setValue( pMemberType, pReturn, pArgs, ppException );
+ }
+ }
+ }
+}
+}
+//______________________________________________________________________________
+AdapterImpl::AdapterImpl(
+ void * key, Reference< script::XInvocation > const & xReceiver,
+ const Sequence< Type > & rTypes,
+ FactoryImpl * pFactory )
+ SAL_THROW( (RuntimeException) )
+ : m_nRef( 1 ),
+ m_pFactory( pFactory ),
+ m_key( key )
+{
+ // init adapters
+ m_nInterfaces = rTypes.getLength();
+ m_pInterfaces = new InterfaceAdapterImpl[ rTypes.getLength() ];
+ const Type * pTypes = rTypes.getConstArray();
+ for ( sal_Int32 nPos = rTypes.getLength(); nPos--; )
+ {
+ InterfaceAdapterImpl * pInterface = &m_pInterfaces[nPos];
+ pInterface->acquire = adapter_acquire;
+ pInterface->release = adapter_release;
+ pInterface->pDispatcher = adapter_dispatch;
+ pInterface->m_pAdapter = this;
+ pInterface->m_pTypeDescr = 0;
+ pTypes[nPos].getDescription(
+ (typelib_TypeDescription **)&pInterface->m_pTypeDescr );
+ OSL_ASSERT( pInterface->m_pTypeDescr );
+ if (! pInterface->m_pTypeDescr)
+ {
+ for ( sal_Int32 n = 0; n < nPos; ++n )
+ {
+ ::typelib_typedescription_release(
+ (typelib_TypeDescription *)
+ m_pInterfaces[ n ].m_pTypeDescr );
+ }
+ delete [] m_pInterfaces;
+ throw RuntimeException(
+ OUSTR("cannot retrieve all interface type infos!"),
+ Reference< XInterface >() );
+ }
+ }
+
+ // map receiver
+ m_pReceiver = (uno_Interface *)m_pFactory->m_aCpp2Uno.mapInterface(
+ xReceiver.get(), ::getCppuType( &xReceiver ) );
+ OSL_ASSERT( 0 != m_pReceiver );
+ if (! m_pReceiver)
+ {
+ throw RuntimeException(
+ OUSTR("cannot map receiver!"), Reference< XInterface >() );
+ }
+
+ m_pFactory->acquire();
+}
+
+//______________________________________________________________________________
+FactoryImpl::FactoryImpl( Reference< XComponentContext > const & xContext )
+ SAL_THROW( (RuntimeException) )
+ : m_pInvokMethodTD( 0 ),
+ m_pSetValueTD( 0 ),
+ m_pGetValueTD( 0 ),
+ m_pAnySeqTD( 0 ),
+ m_pShortSeqTD( 0 ),
+ m_pConvertToTD( 0 )
+{
+ // C++/UNO bridge
+ OUString aCppEnvTypeName = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
+ OUString aUnoEnvTypeName = OUSTR(UNO_LB_UNO);
+ m_aUno2Cpp = Mapping( aUnoEnvTypeName, aCppEnvTypeName );
+ m_aCpp2Uno = Mapping( aCppEnvTypeName, aUnoEnvTypeName );
+ OSL_ENSURE(
+ m_aUno2Cpp.is() && m_aCpp2Uno.is(), "### no uno / C++ mappings!" );
+
+ // type converter
+ Reference< script::XTypeConverter > xConverter(
+ xContext->getServiceManager()->createInstanceWithContext(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.script.Converter") ),
+ xContext ),
+ UNO_QUERY_THROW );
+ m_pConverter = (uno_Interface *)m_aCpp2Uno.mapInterface(
+ xConverter.get(), ::getCppuType( &xConverter ) );
+ OSL_ASSERT( 0 != m_pConverter );
+
+ // some type info:
+ // sequence< any >
+ Type const & rAnySeqType = ::getCppuType( (const Sequence< Any > *)0 );
+ rAnySeqType.getDescription( &m_pAnySeqTD );
+ // sequence< short >
+ const Type & rShortSeqType =
+ ::getCppuType( (const Sequence< sal_Int16 > *)0 );
+ rShortSeqType.getDescription( &m_pShortSeqTD );
+ // script.XInvocation
+ typelib_TypeDescription * pTD = 0;
+ const Type & rInvType = ::getCppuType(
+ (const Reference< script::XInvocation > *)0 );
+ TYPELIB_DANGER_GET( &pTD, rInvType.getTypeLibType() );
+ typelib_InterfaceTypeDescription * pITD;
+ pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD);
+ if( ! pITD->aBase.bComplete )
+ typelib_typedescription_complete( &pTD );
+ ::typelib_typedescriptionreference_getDescription(
+ &m_pInvokMethodTD, pITD->ppMembers[ 1 ] ); // invoke()
+ ::typelib_typedescriptionreference_getDescription(
+ &m_pSetValueTD, pITD->ppMembers[ 2 ] ); // setValue()
+ ::typelib_typedescriptionreference_getDescription(
+ &m_pGetValueTD, pITD->ppMembers[ 3 ] ); // getValue()
+ // script.XTypeConverter
+ const Type & rTCType =
+ ::getCppuType( (const Reference< script::XTypeConverter > *)0 );
+ TYPELIB_DANGER_GET( &pTD, rTCType.getTypeLibType() );
+ pITD = reinterpret_cast<typelib_InterfaceTypeDescription*>(pTD);
+ ::typelib_typedescriptionreference_getDescription(
+ &m_pConvertToTD, pITD->ppMembers[ 0 ] ); // convertTo()
+ TYPELIB_DANGER_RELEASE( pTD );
+
+ if (!m_pInvokMethodTD || !m_pSetValueTD || !m_pGetValueTD ||
+ !m_pConvertToTD ||
+ !m_pAnySeqTD || !m_pShortSeqTD)
+ {
+ throw RuntimeException(
+ OUSTR("missing type descriptions!"), Reference< XInterface >() );
+ }
+
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+//______________________________________________________________________________
+FactoryImpl::~FactoryImpl() SAL_THROW( () )
+{
+ ::typelib_typedescription_release( m_pInvokMethodTD );
+ ::typelib_typedescription_release( m_pSetValueTD );
+ ::typelib_typedescription_release( m_pGetValueTD );
+ ::typelib_typedescription_release( m_pAnySeqTD );
+ ::typelib_typedescription_release( m_pShortSeqTD );
+ ::typelib_typedescription_release( m_pConvertToTD );
+
+ (*m_pConverter->release)( m_pConverter );
+
+#if OSL_DEBUG_LEVEL > 1
+ OSL_ENSURE( m_receiver2adapters.empty(), "### still adapters out there!?" );
+#endif
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+//------------------------------------------------------------------------------
+static inline AdapterImpl * lookup_adapter(
+ t_ptr_set ** pp_adapter_set,
+ t_ptr_map & map, void * key, Sequence< Type > const & rTypes )
+ SAL_THROW( () )
+{
+ t_ptr_set & adapters_set = map[ key ];
+ *pp_adapter_set = &adapters_set;
+ if (adapters_set.empty())
+ return 0; // shortcut
+ // find matching adapter
+ Type const * pTypes = rTypes.getConstArray();
+ sal_Int32 nTypes = rTypes.getLength();
+ t_ptr_set::const_iterator iPos( adapters_set.begin() );
+ t_ptr_set::const_iterator const iEnd( adapters_set.end() );
+ while (iEnd != iPos)
+ {
+ AdapterImpl * that = reinterpret_cast< AdapterImpl * >( *iPos );
+ // iterate thru all types if that is a matching adapter
+ sal_Int32 nPosTypes;
+ for ( nPosTypes = nTypes; nPosTypes--; )
+ {
+ Type const & rType = pTypes[ nPosTypes ];
+ // find in adapter's type list
+ sal_Int32 nPos;
+ for ( nPos = that->m_nInterfaces; nPos--; )
+ {
+ if (::typelib_typedescriptionreference_isAssignableFrom(
+ rType.getTypeLibType(),
+ ((typelib_TypeDescription *)that->
+ m_pInterfaces[ nPos ].m_pTypeDescr)->pWeakRef ))
+ {
+ // found
+ break;
+ }
+ }
+ if (nPos < 0) // type not found => next adapter
+ break;
+ }
+ if (nPosTypes < 0) // all types found
+ return that;
+ ++iPos;
+ }
+ return 0;
+}
+
+// XInvocationAdapterFactory2 impl
+//______________________________________________________________________________
+Reference< XInterface > FactoryImpl::createAdapter(
+ const Reference< script::XInvocation > & xReceiver,
+ const Sequence< Type > & rTypes )
+ throw (RuntimeException)
+{
+ Reference< XInterface > xRet;
+ if (xReceiver.is() && rTypes.getLength())
+ {
+ t_ptr_set * adapter_set;
+ AdapterImpl * that;
+ Reference< XInterface > xKey( xReceiver, UNO_QUERY );
+ {
+ ClearableMutexGuard guard( m_mutex );
+ that = lookup_adapter(
+ &adapter_set, m_receiver2adapters, xKey.get(), rTypes );
+ if (0 == that) // no entry
+ {
+ guard.clear();
+ // create adapter; already acquired: m_nRef == 1
+ AdapterImpl * pNew =
+ new AdapterImpl( xKey.get(), xReceiver, rTypes, this );
+ // lookup again
+ ClearableMutexGuard guard2( m_mutex );
+ that = lookup_adapter(
+ &adapter_set, m_receiver2adapters, xKey.get(), rTypes );
+ if (0 == that) // again no entry
+ {
+ pair< t_ptr_set::iterator, bool > insertion(
+ adapter_set->insert( pNew ) );
+ OSL_ASSERT( insertion.second );
+ that = pNew;
+ }
+ else
+ {
+ that->acquire();
+ guard2.clear();
+ delete pNew; // has never been inserted
+ }
+ }
+ else // found adapter
+ {
+ that->acquire();
+ }
+ }
+ // map one interface to C++
+ uno_Interface * pUnoI = &that->m_pInterfaces[ 0 ];
+ m_aUno2Cpp.mapInterface(
+ (void **)&xRet, pUnoI, ::getCppuType( &xRet ) );
+ that->release();
+ OSL_ASSERT( xRet.is() );
+ if (! xRet.is())
+ {
+ throw RuntimeException(
+ OUSTR("mapping UNO to C++ failed!"),
+ Reference< XInterface >() );
+ }
+ }
+ return xRet;
+}
+// XInvocationAdapterFactory impl
+//______________________________________________________________________________
+Reference< XInterface > FactoryImpl::createAdapter(
+ const Reference< script::XInvocation > & xReceiver, const Type & rType )
+ throw (RuntimeException)
+{
+ return createAdapter( xReceiver, Sequence< Type >( &rType, 1 ) );
+}
+
+// XServiceInfo
+//______________________________________________________________________________
+OUString FactoryImpl::getImplementationName()
+ throw (RuntimeException)
+{
+ return invadp_getImplementationName();
+}
+//______________________________________________________________________________
+sal_Bool FactoryImpl::supportsService( const OUString & rServiceName )
+ throw (RuntimeException)
+{
+ const Sequence< OUString > & rSNL = getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (pArray[nPos].equals( rServiceName ))
+ return sal_True;
+ }
+ return sal_False;
+}
+//______________________________________________________________________________
+Sequence< OUString > FactoryImpl::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return invadp_getSupportedServiceNames();
+}
+
+//==============================================================================
+static Reference< XInterface > SAL_CALL FactoryImpl_create(
+ const Reference< XComponentContext > & xContext )
+ throw (Exception)
+{
+ Reference< XInterface > rRet;
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ static WeakReference < XInterface > rwInstance;
+ rRet = rwInstance;
+
+ if( ! rRet.is() )
+ {
+ rRet = (::cppu::OWeakObject *)new FactoryImpl( xContext );
+ rwInstance = rRet;
+ }
+ }
+ return rRet;
+}
+
+}
+
+
+//##############################################################################
+//##############################################################################
+//##############################################################################
+
+static struct ::cppu::ImplementationEntry g_entries[] =
+{
+ {
+ ::stoc_invadp::FactoryImpl_create,
+ ::stoc_invadp::invadp_getImplementationName,
+ ::stoc_invadp::invadp_getSupportedServiceNames,
+ ::cppu::createSingleComponentFactory,
+ &::stoc_invadp::g_moduleCount.modCnt , 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+sal_Bool SAL_CALL component_canUnload(
+ TimeValue *pTime )
+{
+ return ::stoc_invadp::g_moduleCount.canUnload(
+ &::stoc_invadp::g_moduleCount, pTime );
+}
+
+//==============================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+//==============================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+}
diff --git a/stoc/source/invocation_adapterfactory/invadp.xml b/stoc/source/invocation_adapterfactory/invadp.xml
new file mode 100644
index 000000000000..e0585b88efe4
--- /dev/null
+++ b/stoc/source/invocation_adapterfactory/invadp.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> invocadapt.uno </module-name>
+ <component-description>
+ <author> Daniel Boelzle </author>
+ <name> com.sun.star.comp.stoc.InvocationAdapterFactory </name>
+ <description>
+You can create adapter interfaces of any given type for an invocation
+interface by using an adapter factory instance.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.script.InvocationAdapterFactory </supported-service>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com.sun.star.script.XInvocationAdapterFactory </type>
+ <type> com.sun.star.script.XInvocationAdapterFactory2 </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.container.XEnumerationAccess </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.container.XIndexContainer </type>
+ <type> com.sun.star.reflection.InvocationTargetException </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/invocation_adapterfactory/invocadapt.component b/stoc/source/invocation_adapterfactory/invocadapt.component
new file mode 100644
index 000000000000..64f7b2b3691a
--- /dev/null
+++ b/stoc/source/invocation_adapterfactory/invocadapt.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.stoc.InvocationAdapterFactory">
+ <service name="com.sun.star.script.InvocationAdapterFactory"/>
+ </implementation>
+</component>
diff --git a/stoc/source/invocation_adapterfactory/makefile.mk b/stoc/source/invocation_adapterfactory/makefile.mk
new file mode 100644
index 000000000000..4c3450ac8c8d
--- /dev/null
+++ b/stoc/source/invocation_adapterfactory/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=stoc
+TARGET = invocadapt.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = invadp
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/iafactory.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map
+SHL1RPATH=URELIB
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/invocadapt.component
+
+$(MISC)/invocadapt.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ invocadapt.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt invocadapt.component
diff --git a/stoc/source/javaloader/javaloader.component b/stoc/source/javaloader/javaloader.component
new file mode 100644
index 000000000000..bdd3b82d5125
--- /dev/null
+++ b/stoc/source/javaloader/javaloader.component
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.stoc.JavaComponentLoader">
+ <service name="com.sun.star.loader.Java"/>
+ <service name="com.sun.star.loader.Java2"/>
+ </implementation>
+</component>
diff --git a/stoc/source/javaloader/javaloader.cxx b/stoc/source/javaloader/javaloader.cxx
new file mode 100644
index 000000000000..396ff48ec310
--- /dev/null
+++ b/stoc/source/javaloader/javaloader.cxx
@@ -0,0 +1,480 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+
+#include <cstdarg>
+#include <osl/diagnose.h>
+#include <osl/process.h>
+
+#include <rtl/process.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <uno/environment.h>
+#include <uno/mapping.hxx>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include <cppuhelper/servicefactory.hxx>
+
+#ifdef LINUX
+#undef minor
+#undef major
+#endif
+
+#include <com/sun/star/java/XJavaVM.hpp>
+
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+
+#include "jni.h"
+
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+
+#include <cppuhelper/implbase2.hxx>
+
+#include <com/sun/star/loader/XImplementationLoader.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "jvmaccess/virtualmachine.hxx"
+
+namespace css = com::sun::star;
+
+using namespace ::com::sun::star::java;
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::loader;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::registry;
+
+using namespace ::cppu;
+using namespace ::rtl;
+using namespace ::osl;
+
+namespace stoc_javaloader {
+
+static Mutex & getInitMutex();
+
+static Sequence< OUString > loader_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(2);
+ seqNames.getArray()[0] = OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Java") );
+ seqNames.getArray()[1] = OUString(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.loader.Java2") );
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+static OUString loader_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.JavaComponentLoader" ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+
+class JavaComponentLoader : public WeakImplHelper2<XImplementationLoader, XServiceInfo>
+{
+ css::uno::Reference<XComponentContext> m_xComponentContext;
+ /** Do not use m_javaLoader directly. Instead use getJavaLoader.
+ */
+ css::uno::Reference<XImplementationLoader> m_javaLoader;
+ /** The retured Reference contains a null pointer if the office is not configured
+ to run java.
+
+ @exception com::sun::star::uno::RuntimeException
+ If the Java implementation of the loader could not be obtained, for reasons other
+ then that java was not configured the RuntimeException is thrown.
+ */
+ const css::uno::Reference<XImplementationLoader> & getJavaLoader();
+
+
+public:
+ JavaComponentLoader(const css::uno::Reference<XComponentContext> & xCtx)
+ throw(RuntimeException);
+ virtual ~JavaComponentLoader() throw();
+
+public:
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
+ throw(RuntimeException);
+ virtual Sequence<OUString> SAL_CALL getSupportedServiceNames()
+ throw(RuntimeException);
+
+ // XImplementationLoader
+ virtual css::uno::Reference<XInterface> SAL_CALL activate(
+ const OUString& implementationName, const OUString& implementationLoaderUrl,
+ const OUString& locationUrl, const css::uno::Reference<XRegistryKey>& xKey)
+ throw(CannotActivateFactoryException, RuntimeException);
+ virtual sal_Bool SAL_CALL writeRegistryInfo(
+ const css::uno::Reference<XRegistryKey>& xKey,
+ const OUString& implementationLoaderUrl, const OUString& locationUrl)
+ throw(CannotRegisterImplementationException, RuntimeException);
+};
+
+const css::uno::Reference<XImplementationLoader> & JavaComponentLoader::getJavaLoader()
+{
+ MutexGuard aGuard(getInitMutex());
+
+ if (m_javaLoader.is())
+ return m_javaLoader;
+
+ uno_Environment * pJava_environment = NULL;
+ uno_Environment * pUno_environment = NULL;
+ typelib_InterfaceTypeDescription * pType_XImplementationLoader = 0;
+
+ try {
+ // get a java vm, where we can create a loader
+ css::uno::Reference<XJavaVM> javaVM_xJavaVM(
+ m_xComponentContext->getValueByName(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/"
+ "com.sun.star.java.theJavaVirtualMachine"))),
+ UNO_QUERY_THROW);
+
+ // Use the special protocol of XJavaVM.getJavaVM: If the passed in
+ // process ID has an extra 17th byte of value one, the returned any
+ // contains a pointer to a jvmaccess::UnoVirtualMachine, instead of the
+ // underlying JavaVM pointer:
+ Sequence<sal_Int8> processID(17);
+ rtl_getGlobalProcessId(reinterpret_cast<sal_uInt8 *>(processID.getArray()));
+ processID[16] = 1;
+
+ // We get a non-refcounted pointer to a jvmaccess::UnoVirtualMachine
+ // from the XJavaVM service (the pointer is guaranteed to be valid
+ // as long as our reference to the XJavaVM service lasts), and
+ // convert the non-refcounted pointer into a refcounted one
+ // immediately:
+ OSL_ENSURE(sizeof (sal_Int64)
+ >= sizeof (jvmaccess::UnoVirtualMachine *),
+ "Pointer cannot be represented as sal_Int64");
+ sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
+ static_cast< jvmaccess::UnoVirtualMachine * >(0));
+ javaVM_xJavaVM->getJavaVM(processID) >>= nPointer;
+ rtl::Reference< jvmaccess::UnoVirtualMachine > xVirtualMachine(
+ reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer));
+ if (!xVirtualMachine.is())
+ //throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ // "javaloader error - JavaVirtualMachine service could not provide a VM")),
+ // css::uno::Reference<XInterface>());
+ // We must not throw a RuntimeException, because this might end the applications.
+ // It is ok if java components
+ // are not working because the office can be installed without Java support.
+ return m_javaLoader; // null-ref
+
+ try
+ {
+ jvmaccess::VirtualMachine::AttachGuard aGuard2(
+ xVirtualMachine->getVirtualMachine());
+ JNIEnv * pJNIEnv = aGuard2.getEnvironment();
+
+ // instantiate the java JavaLoader
+ jclass jcClassLoader = pJNIEnv->FindClass("java/lang/ClassLoader");
+ if(pJNIEnv->ExceptionOccurred())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - could not find class java/lang/ClassLoader")),
+ css::uno::Reference<XInterface>());
+ jmethodID jmLoadClass = pJNIEnv->GetMethodID(
+ jcClassLoader, "loadClass",
+ "(Ljava/lang/String;)Ljava/lang/Class;");
+ if(pJNIEnv->ExceptionOccurred())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - could not find method java/lang/ClassLoader.loadClass")),
+ css::uno::Reference<XInterface>());
+ jvalue arg;
+ arg.l = pJNIEnv->NewStringUTF(
+ "com.sun.star.comp.loader.JavaLoader");
+ if(pJNIEnv->ExceptionOccurred())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - could not create string")),
+ css::uno::Reference<XInterface>());
+ jclass jcJavaLoader = static_cast< jclass >(
+ pJNIEnv->CallObjectMethodA(
+ static_cast< jobject >(xVirtualMachine->getClassLoader()),
+ jmLoadClass, &arg));
+ if(pJNIEnv->ExceptionOccurred())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - could not find class com/sun/star/comp/loader/JavaLoader")),
+ css::uno::Reference<XInterface>());
+ jmethodID jmJavaLoader_init = pJNIEnv->GetMethodID(jcJavaLoader, "<init>", "()V");
+ if(pJNIEnv->ExceptionOccurred())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed")),
+ css::uno::Reference<XInterface>());
+ jobject joJavaLoader = pJNIEnv->NewObject(jcJavaLoader, jmJavaLoader_init);
+ if(pJNIEnv->ExceptionOccurred())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - instantiation of com.sun.star.comp.loader.JavaLoader failed")),
+ css::uno::Reference<XInterface>());
+
+ // map the java JavaLoader to this environment
+ OUString sJava(RTL_CONSTASCII_USTRINGPARAM("java"));
+ uno_getEnvironment(&pJava_environment, sJava.pData,
+ xVirtualMachine.get());
+ if(!pJava_environment)
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - no Java environment available")), css::uno::Reference<XInterface>());
+
+ // why is there no convinient contructor?
+ OUString sCppu_current_lb_name(RTL_CONSTASCII_USTRINGPARAM(CPPU_CURRENT_LANGUAGE_BINDING_NAME));
+ uno_getEnvironment(&pUno_environment, sCppu_current_lb_name.pData, NULL);
+ if(!pUno_environment)
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - no C++ environment available")), css::uno::Reference<XInterface>());
+
+ Mapping java_curr(pJava_environment, pUno_environment);
+ if(!java_curr.is())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - no mapping from java to C++ ")), css::uno::Reference<XInterface>());
+
+ // release java environment
+ pJava_environment->release(pJava_environment);
+ pJava_environment = NULL;
+
+ // release uno environment
+ pUno_environment->release(pUno_environment);
+ pUno_environment = NULL;
+
+ getCppuType((css::uno::Reference<XImplementationLoader> *) 0).
+ getDescription((typelib_TypeDescription **) & pType_XImplementationLoader);
+ if(!pType_XImplementationLoader)
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - no type information for XImplementationLoader")),
+ css::uno::Reference<XInterface>());
+
+ m_javaLoader = css::uno::Reference<XImplementationLoader>(reinterpret_cast<XImplementationLoader *>(
+ java_curr.mapInterface(joJavaLoader, pType_XImplementationLoader)));
+ pJNIEnv->DeleteLocalRef( joJavaLoader );
+ if(!m_javaLoader.is())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - mapping of java XImplementationLoader to c++ failed")),
+ css::uno::Reference<XInterface>());
+
+ typelib_typedescription_release(reinterpret_cast<typelib_TypeDescription *>(pType_XImplementationLoader));
+ pType_XImplementationLoader = NULL;
+ }
+ catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ throw RuntimeException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "jvmaccess::VirtualMachine::AttachGuard"
+ "::CreationException")),0);
+ }
+
+ // set the service manager at the javaloader
+ css::uno::Reference<XInitialization> javaLoader_XInitialization(m_javaLoader, UNO_QUERY);
+ if(!javaLoader_XInitialization.is())
+ throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "javaloader error - initialization of java javaloader failed, no XInitialization")),
+ css::uno::Reference<XInterface>());
+
+ Any any;
+ any <<= css::uno::Reference<XMultiComponentFactory>(
+ m_xComponentContext->getServiceManager());
+
+ javaLoader_XInitialization->initialize(Sequence<Any>(&any, 1));
+ }
+ catch(RuntimeException &) {
+ if(pJava_environment)
+ pJava_environment->release(pJava_environment);
+
+ if(pUno_environment)
+ pUno_environment->release(pUno_environment);
+
+ if(pType_XImplementationLoader)
+ typelib_typedescription_release(
+ reinterpret_cast<typelib_TypeDescription *>(pType_XImplementationLoader));
+ throw;
+ }
+ OSL_TRACE("javaloader.cxx: mapped javaloader - 0x%x", m_javaLoader.get());
+ return m_javaLoader;
+}
+
+JavaComponentLoader::JavaComponentLoader(const css::uno::Reference<XComponentContext> & xCtx) throw(RuntimeException) :
+ m_xComponentContext(xCtx)
+
+{
+
+}
+
+JavaComponentLoader::~JavaComponentLoader() throw()
+{
+}
+
+// XServiceInfo
+OUString SAL_CALL JavaComponentLoader::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return loader_getImplementationName();
+}
+
+sal_Bool SAL_CALL JavaComponentLoader::supportsService(const OUString & ServiceName)
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ sal_Bool bSupport = sal_False;
+
+ Sequence<OUString> aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getArray();
+ for(sal_Int32 i = 0; i < aSNL.getLength() && !bSupport; ++ i)
+ bSupport = pArray[i] == ServiceName;
+
+ return bSupport;
+}
+
+Sequence<OUString> SAL_CALL JavaComponentLoader::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return loader_getSupportedServiceNames();
+}
+
+
+
+// XImplementationLoader
+sal_Bool SAL_CALL JavaComponentLoader::writeRegistryInfo(
+ const css::uno::Reference<XRegistryKey> & xKey, const OUString & blabla,
+ const OUString & rLibName)
+ throw(CannotRegisterImplementationException, RuntimeException)
+{
+ const css::uno::Reference<XImplementationLoader> & loader = getJavaLoader();
+ if (loader.is())
+ return loader->writeRegistryInfo(xKey, blabla, rLibName);
+ else
+ throw CannotRegisterImplementationException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Could not create Java implementation loader")), NULL);
+}
+
+
+css::uno::Reference<XInterface> SAL_CALL JavaComponentLoader::activate(
+ const OUString & rImplName, const OUString & blabla, const OUString & rLibName,
+ const css::uno::Reference<XRegistryKey> & xKey)
+ throw(CannotActivateFactoryException, RuntimeException)
+{
+ const css::uno::Reference<XImplementationLoader> & loader = getJavaLoader();
+ if (loader.is())
+ return loader->activate(rImplName, blabla, rLibName, xKey);
+ else
+ throw CannotActivateFactoryException(
+ OUString(RTL_CONSTASCII_USTRINGPARAM("Could not create Java implementation loader")), NULL);
+}
+
+static Mutex & getInitMutex()
+{
+ static Mutex * pMutex = 0;
+ if( ! pMutex )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pMutex )
+ {
+ static Mutex mutex;
+ pMutex = &mutex;
+ }
+ }
+ return *pMutex;
+}
+
+css::uno::Reference<XInterface> SAL_CALL JavaComponentLoader_CreateInstance(const css::uno::Reference<XComponentContext> & xCtx) throw(Exception)
+{
+ css::uno::Reference<XInterface> xRet;
+
+ try {
+ MutexGuard guard( getInitMutex() );
+ // The javaloader is never destroyed and there can be only one!
+ // Note that the first context wins ....
+ static css::uno::Reference< XInterface > *pStaticRef = 0;
+ if( pStaticRef )
+ {
+ xRet = *pStaticRef;
+ }
+ else
+ {
+ xRet = *new JavaComponentLoader(xCtx);
+ pStaticRef = new css::uno::Reference< XInterface > ( xRet );
+ }
+ }
+ catch(RuntimeException & runtimeException) {
+ OString message = OUStringToOString(runtimeException.Message, RTL_TEXTENCODING_ASCII_US);
+ osl_trace("javaloader - could not init javaloader cause of %s", message.getStr());
+ throw;
+ }
+
+ return xRet;
+}
+
+} //end namespace
+
+
+using namespace stoc_javaloader;
+
+static struct ImplementationEntry g_entries[] =
+{
+ {
+ JavaComponentLoader_CreateInstance, loader_getImplementationName,
+ loader_getSupportedServiceNames, createSingleComponentFactory,
+ 0 , 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+// NOTE: component_canUnload is not exported, as the library cannot be unloaded.
+
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+}
diff --git a/stoc/source/javaloader/javaloader.xml b/stoc/source/javaloader/javaloader.xml
new file mode 100644
index 000000000000..fffddb4459c4
--- /dev/null
+++ b/stoc/source/javaloader/javaloader.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> javaloader.uno </module-name>
+ <component-description>
+ <author> Kay Ramme </author>
+ <name> com.sun.star.comp.stoc.JavaComponentLoader </name>
+ <description> ... </description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.loader.Java </supported-service>
+ <supported-service> com.sun.star.loader.Java2 </supported-service>
+ <service-dependency> ... </service-dependency>
+
+ <type> com.sun.star.java.XJavaVM </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XMultiComponentFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.loader.XImplementationLoader </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> jvmaccess </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> jvmaccess3$(COM) </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/javaloader/makefile.mk b/stoc/source/javaloader/makefile.mk
new file mode 100644
index 000000000000..e53b90d5e6e7
--- /dev/null
+++ b/stoc/source/javaloader/makefile.mk
@@ -0,0 +1,79 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=stoc
+TARGET = javaloader.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = javaloader
+
+.IF "$(SOLAR_JAVA)" == "TRUE"
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= $(SLO)$/javaloader.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS=\
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(JVMACCESSLIB)
+
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1RPATH= URELIB
+
+DEF1NAME= $(SHL1TARGET)
+
+.ELSE # SOLAR_JAVA
+all:
+ @echo Nothing to do: SOLAR_JAVA not set
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/javaloader.component
+
+$(MISC)/javaloader.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ javaloader.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt javaloader.component
diff --git a/stoc/source/javavm/interact.cxx b/stoc/source/javavm/interact.cxx
new file mode 100644
index 000000000000..024d34acf12e
--- /dev/null
+++ b/stoc/source/javavm/interact.cxx
@@ -0,0 +1,125 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "interact.hxx"
+
+#include "com/sun/star/java/JavaDisabledException.hpp"
+#include "com/sun/star/java/JavaVMCreationFailureException.hpp"
+#include "com/sun/star/task/XInteractionAbort.hpp"
+#include "com/sun/star/task/XInteractionRetry.hpp"
+#include "com/sun/star/task/XInteractionContinuation.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "osl/mutex.hxx"
+
+namespace css = com::sun::star;
+
+using stoc_javavm::InteractionRequest;
+
+namespace {
+
+class AbortContinuation:
+ public cppu::WeakImplHelper1< css::task::XInteractionAbort >
+{
+public:
+ inline AbortContinuation() {}
+
+ virtual inline void SAL_CALL select() throw (css::uno::RuntimeException) {}
+
+private:
+ AbortContinuation(AbortContinuation &); // not implemented
+ void operator =(AbortContinuation); // not implemented
+
+ virtual inline ~AbortContinuation() {}
+};
+
+}
+
+class InteractionRequest::RetryContinuation:
+ public cppu::WeakImplHelper1< css::task::XInteractionRetry >
+{
+public:
+ inline RetryContinuation(): m_bSelected(false) {}
+
+ virtual void SAL_CALL select() throw (css::uno::RuntimeException);
+
+ bool isSelected() const;
+
+private:
+ RetryContinuation(RetryContinuation &); // not implemented
+ void operator =(RetryContinuation); // not implemented
+
+ virtual inline ~RetryContinuation() {}
+
+ mutable osl::Mutex m_aMutex;
+ bool m_bSelected;
+};
+
+void SAL_CALL InteractionRequest::RetryContinuation::select()
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ m_bSelected = true;
+}
+
+bool InteractionRequest::RetryContinuation::isSelected() const
+{
+ osl::MutexGuard aGuard(m_aMutex);
+ return m_bSelected;
+}
+
+InteractionRequest::InteractionRequest(css::uno::Any const & rRequest):
+ m_aRequest(rRequest)
+{
+ m_aContinuations.realloc(2);
+ m_xRetryContinuation = new RetryContinuation;
+ m_aContinuations[0] = new AbortContinuation;
+ m_aContinuations[1] = m_xRetryContinuation.get();
+}
+
+css::uno::Any SAL_CALL InteractionRequest::getRequest()
+ throw (css::uno::RuntimeException)
+{
+ return m_aRequest;
+}
+
+css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > >
+SAL_CALL InteractionRequest::getContinuations()
+ throw (css::uno::RuntimeException)
+{
+ return m_aContinuations;
+}
+
+bool InteractionRequest::retry() const
+{
+ return m_xRetryContinuation.is() && m_xRetryContinuation->isSelected();
+}
+
+InteractionRequest::~InteractionRequest()
+{}
diff --git a/stoc/source/javavm/interact.hxx b/stoc/source/javavm/interact.hxx
new file mode 100644
index 000000000000..7db3fd949b68
--- /dev/null
+++ b/stoc/source/javavm/interact.hxx
@@ -0,0 +1,75 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if !defined INCLUDED_STOC_JAVAVM_INTERACT_HXX
+#define INCLUDED_STOC_JAVAVM_INTERACT_HXX
+
+#include "com/sun/star/task/XInteractionRequest.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "rtl/ref.hxx"
+
+namespace com { namespace sun { namespace star { namespace task {
+ class XInteractionContinuation;
+} } } }
+
+namespace stoc_javavm {
+
+class InteractionRequest:
+ public cppu::WeakImplHelper1< com::sun::star::task::XInteractionRequest >
+{
+public:
+ explicit InteractionRequest(com::sun::star::uno::Any const & rRequest);
+
+ virtual com::sun::star::uno::Any SAL_CALL getRequest()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Sequence< com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionContinuation > > SAL_CALL
+ getContinuations() throw (com::sun::star::uno::RuntimeException);
+
+ bool retry() const;
+
+private:
+ class RetryContinuation;
+
+ InteractionRequest(InteractionRequest &); // not implemented
+ void operator =(InteractionRequest); // not implemented
+
+ virtual ~InteractionRequest();
+
+ com::sun::star::uno::Any m_aRequest;
+ com::sun::star::uno::Sequence< com::sun::star::uno::Reference<
+ com::sun::star::task::XInteractionContinuation > > m_aContinuations;
+ rtl::Reference< RetryContinuation > m_xRetryContinuation;
+};
+
+}
+
+#endif // INCLUDED_STOC_JAVAVM_INTERACT_HXX
diff --git a/stoc/source/javavm/javavm.component b/stoc/source/javavm/javavm.component
new file mode 100644
index 000000000000..f78d8af3ac29
--- /dev/null
+++ b/stoc/source/javavm/javavm.component
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.stoc.JavaVirtualMachine">
+ <service name="com.sun.star.java.JavaVirtualMachine"/>
+ <singleton name="com.sun.star.java.theJavaVirtualMachine"/>
+ </implementation>
+</component>
diff --git a/stoc/source/javavm/javavm.cxx b/stoc/source/javavm/javavm.cxx
new file mode 100644
index 000000000000..1ea792270861
--- /dev/null
+++ b/stoc/source/javavm/javavm.cxx
@@ -0,0 +1,1776 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "javavm.hxx"
+
+#include "interact.hxx"
+#include "jvmargs.hxx"
+
+#include "com/sun/star/beans/NamedValue.hpp"
+#include "com/sun/star/beans/PropertyState.hpp"
+#include "com/sun/star/beans/PropertyValue.hpp"
+#include "com/sun/star/container/XContainer.hpp"
+#include "com/sun/star/java/JavaNotFoundException.hpp"
+#include "com/sun/star/java/InvalidJavaSettingsException.hpp"
+#include "com/sun/star/java/RestartRequiredException.hpp"
+#include "com/sun/star/java/JavaDisabledException.hpp"
+#include "com/sun/star/java/JavaVMCreationFailureException.hpp"
+#include "com/sun/star/lang/DisposedException.hpp"
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/XEventListener.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XSingleComponentFactory.hpp"
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/task/XInteractionHandler.hpp"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XCurrentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "com/sun/star/container/XNameAccess.hpp"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "jvmaccess/classpath.hxx"
+#include "jvmaccess/unovirtualmachine.hxx"
+#include "jvmaccess/virtualmachine.hxx"
+#include "osl/file.hxx"
+#include "osl/thread.h"
+#include "rtl/bootstrap.hxx"
+#include "rtl/process.h"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "rtl/uri.hxx"
+#include "sal/types.h"
+#include "uno/current_context.hxx"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+#include "jvmfwk/framework.h"
+#include "jni.h"
+
+#include <stack>
+#include <string.h>
+#include <time.h>
+#include <memory>
+#include <vector>
+#include "boost/scoped_array.hpp"
+#define OUSTR(x) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
+
+// Properties of the javavm can be put
+// as a komma separated list in this
+// environment variable
+#define PROPERTIES_ENV "OO_JAVA_PROPERTIES"
+#ifdef UNIX
+#define INI_FILE "javarc"
+#ifdef MACOSX
+#define DEF_JAVALIB "JavaVM.framework"
+#else
+#define DEF_JAVALIB "libjvm.so"
+#endif
+#define TIMEZONE "MEZ"
+#else
+#define INI_FILE "java.ini"
+#define DEF_JAVALIB "jvm.dll"
+#define TIMEZONE "MET"
+#endif
+
+/* Within this implementation of the com.sun.star.java.JavaVirtualMachine
+ * service and com.sun.star.java.theJavaVirtualMachine singleton, the method
+ * com.sun.star.java.XJavaVM.getJavaVM relies on the following:
+ * 1 The string "$URE_INTERNAL_JAVA_DIR/" is expanded via the
+ * com.sun.star.util.theMacroExpander singleton into an internal (see the
+ * com.sun.star.uri.ExternalUriReferenceTranslator service), hierarchical URI
+ * reference relative to which the URE JAR files can be addressed.
+ * 2 The string "$URE_INTERNAL_JAVA_CLASSPATH" is either not expandable via the
+ * com.sun.star.util.theMacroExpander singleton
+ * (com.sun.star.lang.IllegalArgumentException), or is expanded via the
+ * com.sun.star.util.theMacroExpander singleton into a list of zero or more
+ * internal (see the com.sun.star.uri.ExternalUriReferenceTranslator service)
+ * URIs, where any space characters (U+0020) are ignored (and, in particular,
+ * separate adjacent URIs).
+ * If either of these requirements is not met, getJavaVM raises a
+ * com.sun.star.uno.RuntimeException.
+ */
+
+namespace css = com::sun::star;
+
+using stoc_javavm::JavaVirtualMachine;
+
+namespace {
+
+
+
+class NoJavaIniException: public css::uno::Exception
+{
+};
+
+class SingletonFactory:
+ private cppu::WeakImplHelper1< css::lang::XEventListener >
+{
+public:
+ static css::uno::Reference< css::uno::XInterface > getSingleton(
+ css::uno::Reference< css::uno::XComponentContext > const & rContext);
+
+private:
+ SingletonFactory(SingletonFactory &); // not implemented
+ void operator =(SingletonFactory); // not implemented
+
+ inline SingletonFactory() {}
+
+ virtual inline ~SingletonFactory() {}
+
+ virtual void SAL_CALL disposing(css::lang::EventObject const &)
+ throw (css::uno::RuntimeException);
+
+ static void dispose();
+
+ // TODO ok to keep these static?
+ static osl::Mutex m_aMutex;
+ static css::uno::Reference< css::uno::XInterface > m_xSingleton;
+ static bool m_bDisposed;
+};
+
+css::uno::Reference< css::uno::XInterface > SingletonFactory::getSingleton(
+ css::uno::Reference< css::uno::XComponentContext > const & rContext)
+{
+ css::uno::Reference< css::uno::XInterface > xSingleton;
+ css::uno::Reference< css::lang::XComponent > xComponent;
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ if (!m_xSingleton.is())
+ {
+ if (m_bDisposed)
+ throw css::lang::DisposedException();
+ xComponent = css::uno::Reference< css::lang::XComponent >(
+ rContext, css::uno::UNO_QUERY_THROW);
+ m_xSingleton = static_cast< cppu::OWeakObject * >(
+ new JavaVirtualMachine(rContext));
+ }
+ xSingleton = m_xSingleton;
+ }
+ if (xComponent.is())
+ try
+ {
+ xComponent->addEventListener(new SingletonFactory);
+ }
+ catch (...)
+ {
+ dispose();
+ throw;
+ }
+ return xSingleton;
+}
+
+void SAL_CALL SingletonFactory::disposing(css::lang::EventObject const &)
+ throw (css::uno::RuntimeException)
+{
+ dispose();
+}
+
+void SingletonFactory::dispose()
+{
+ css::uno::Reference< css::lang::XComponent > xComponent;
+ {
+ osl::MutexGuard aGuard(m_aMutex);
+ xComponent = css::uno::Reference< css::lang::XComponent >(
+ m_xSingleton, css::uno::UNO_QUERY);
+ m_xSingleton.clear();
+ m_bDisposed = true;
+ }
+ if (xComponent.is())
+ xComponent->dispose();
+}
+
+osl::Mutex SingletonFactory::m_aMutex;
+css::uno::Reference< css::uno::XInterface > SingletonFactory::m_xSingleton;
+bool SingletonFactory::m_bDisposed = false;
+
+rtl::OUString serviceGetImplementationName()
+{
+ return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.stoc.JavaVirtualMachine"));
+}
+
+css::uno::Sequence< rtl::OUString > serviceGetSupportedServiceNames()
+{
+ rtl::OUString aServiceName(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.java.JavaVirtualMachine"));
+ return css::uno::Sequence< rtl::OUString >(&aServiceName, 1);
+}
+
+css::uno::Reference< css::uno::XInterface > SAL_CALL serviceCreateInstance(
+ css::uno::Reference< css::uno::XComponentContext > const & rContext)
+ SAL_THROW((css::uno::Exception))
+{
+ // Only one single instance of this service is ever constructed, and is
+ // available until the component context used to create this instance is
+ // disposed. Afterwards, this function throws a DisposedException (as do
+ // all relevant methods on the single service instance).
+ return SingletonFactory::getSingleton(rContext);
+}
+
+cppu::ImplementationEntry const aServiceImplementation[]
+ = { { serviceCreateInstance,
+ serviceGetImplementationName,
+ serviceGetSupportedServiceNames,
+ cppu::createSingleComponentFactory,
+ 0, 0 },
+ { 0, 0, 0, 0, 0, 0 } };
+
+typedef std::stack< jvmaccess::VirtualMachine::AttachGuard * > GuardStack;
+
+extern "C" {
+
+static void destroyAttachGuards(void * pData)
+{
+ GuardStack * pStack = static_cast< GuardStack * >(pData);
+ if (pStack != 0)
+ {
+ while (!pStack->empty())
+ {
+ delete pStack->top();
+ pStack->pop();
+ }
+ delete pStack;
+ }
+}
+
+}
+
+bool askForRetry(css::uno::Any const & rException)
+{
+ css::uno::Reference< css::uno::XCurrentContext > xContext(
+ css::uno::getCurrentContext());
+ if (xContext.is())
+ {
+ css::uno::Reference< css::task::XInteractionHandler > xHandler;
+ xContext->getValueByName(rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "java-vm.interaction-handler")))
+ >>= xHandler;
+ if (xHandler.is())
+ {
+ rtl::Reference< stoc_javavm::InteractionRequest > xRequest(
+ new stoc_javavm::InteractionRequest(rException));
+ xHandler->handle(xRequest.get());
+ return xRequest->retry();
+ }
+ }
+ return false;
+}
+
+// Only gets the properties if the "Proxy Server" entry in the option dialog is
+// set to manual (i.e. not to none)
+void getINetPropsFromConfig(stoc_javavm::JVM * pjvm,
+ const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
+ const css::uno::Reference<css::uno::XComponentContext> &xCtx ) throw (css::uno::Exception)
+{
+ css::uno::Reference<css::uno::XInterface> xConfRegistry = xSMgr->createInstanceWithContext(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationRegistry")),
+ xCtx );
+ if(!xConfRegistry.is()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
+
+ css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(xConfRegistry, css::uno::UNO_QUERY);
+ if(!xConfRegistry_simple.is()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
+
+ xConfRegistry_simple->open(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Inet")), sal_True, sal_False);
+ css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
+
+// if ooInetProxyType is not 0 then read the settings
+ css::uno::Reference<css::registry::XRegistryKey> proxyEnable= xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetProxyType")));
+ if( proxyEnable.is() && 0 != proxyEnable->getLongValue())
+ {
+ // read ftp proxy name
+ css::uno::Reference<css::registry::XRegistryKey> ftpProxy_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetFTPProxyName")));
+ if(ftpProxy_name.is() && ftpProxy_name->getStringValue().getLength()) {
+ rtl::OUString ftpHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyHost="));
+ ftpHost += ftpProxy_name->getStringValue();
+
+ // read ftp proxy port
+ css::uno::Reference<css::registry::XRegistryKey> ftpProxy_port = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetFTPProxyPort")));
+ if(ftpProxy_port.is() && ftpProxy_port->getLongValue()) {
+ rtl::OUString ftpPort = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyPort="));
+ ftpPort += rtl::OUString::valueOf(ftpProxy_port->getLongValue());
+
+ pjvm->pushProp(ftpHost);
+ pjvm->pushProp(ftpPort);
+ }
+ }
+
+ // read http proxy name
+ css::uno::Reference<css::registry::XRegistryKey> httpProxy_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPProxyName")));
+ if(httpProxy_name.is() && httpProxy_name->getStringValue().getLength()) {
+ rtl::OUString httpHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyHost="));
+ httpHost += httpProxy_name->getStringValue();
+
+ // read http proxy port
+ css::uno::Reference<css::registry::XRegistryKey> httpProxy_port = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPProxyPort")));
+ if(httpProxy_port.is() && httpProxy_port->getLongValue()) {
+ rtl::OUString httpPort = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort="));
+ httpPort += rtl::OUString::valueOf(httpProxy_port->getLongValue());
+
+ pjvm->pushProp(httpHost);
+ pjvm->pushProp(httpPort);
+ }
+ }
+
+ // read https proxy name
+ css::uno::Reference<css::registry::XRegistryKey> httpsProxy_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPSProxyName")));
+ if(httpsProxy_name.is() && httpsProxy_name->getStringValue().getLength()) {
+ rtl::OUString httpsHost = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https.proxyHost="));
+ httpsHost += httpsProxy_name->getStringValue();
+
+ // read https proxy port
+ css::uno::Reference<css::registry::XRegistryKey> httpsProxy_port = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetHTTPSProxyPort")));
+ if(httpsProxy_port.is() && httpsProxy_port->getLongValue()) {
+ rtl::OUString httpsPort = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https.proxyPort="));
+ httpsPort += rtl::OUString::valueOf(httpsProxy_port->getLongValue());
+
+ pjvm->pushProp(httpsHost);
+ pjvm->pushProp(httpsPort);
+ }
+ }
+
+ // read nonProxyHosts
+ css::uno::Reference<css::registry::XRegistryKey> nonProxies_name = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Settings/ooInetNoProxy")));
+ if(nonProxies_name.is() && nonProxies_name->getStringValue().getLength()) {
+ rtl::OUString httpNonProxyHosts = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.nonProxyHosts="));
+ rtl::OUString ftpNonProxyHosts= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.nonProxyHosts="));
+ rtl::OUString value= nonProxies_name->getStringValue();
+ // replace the separator ";" by "|"
+ value= value.replace((sal_Unicode)';', (sal_Unicode)'|');
+
+ httpNonProxyHosts += value;
+ ftpNonProxyHosts += value;
+
+ pjvm->pushProp(httpNonProxyHosts);
+ pjvm->pushProp(ftpNonProxyHosts);
+ }
+
+ // read socks settings
+/* Reference<XRegistryKey> socksProxy_name = xRegistryRootKey->openKey(OUSTR("Settings/ooInetSOCKSProxyName"));
+ if (socksProxy_name.is() && httpProxy_name->getStringValue().getLength()) {
+ OUString socksHost = OUSTR("socksProxyHost=");
+ socksHost += socksProxy_name->getStringValue();
+
+ // read http proxy port
+ Reference<XRegistryKey> socksProxy_port = xRegistryRootKey->openKey(OUSTR("Settings/ooInetSOCKSProxyPort"));
+ if (socksProxy_port.is() && socksProxy_port->getLongValue()) {
+ OUString socksPort = OUSTR("socksProxyPort=");
+ socksPort += OUString::valueOf(socksProxy_port->getLongValue());
+
+ pjvm->pushProp(socksHost);
+ pjvm->pushProp(socksPort);
+ }
+ }
+*/ }
+ xConfRegistry_simple->close();
+}
+
+void getDefaultLocaleFromConfig(
+ stoc_javavm::JVM * pjvm,
+ const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
+ const css::uno::Reference<css::uno::XComponentContext> &xCtx ) throw(css::uno::Exception)
+{
+ css::uno::Reference<css::uno::XInterface> xConfRegistry =
+ xSMgr->createInstanceWithContext(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationRegistry")), xCtx );
+ if(!xConfRegistry.is())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
+
+ css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
+ xConfRegistry, css::uno::UNO_QUERY);
+ if(!xConfRegistry_simple.is())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
+
+ xConfRegistry_simple->open(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Setup")), sal_True, sal_False);
+ css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey = xConfRegistry_simple->getRootKey();
+
+ // read locale
+ css::uno::Reference<css::registry::XRegistryKey> locale = xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("L10N/ooLocale")));
+ if(locale.is() && locale->getStringValue().getLength()) {
+ rtl::OUString language;
+ rtl::OUString country;
+
+ sal_Int32 index = locale->getStringValue().indexOf((sal_Unicode) '-');
+
+ if(index >= 0) {
+ language = locale->getStringValue().copy(0, index);
+ country = locale->getStringValue().copy(index + 1);
+
+ if(language.getLength()) {
+ rtl::OUString prop(RTL_CONSTASCII_USTRINGPARAM("user.language="));
+ prop += language;
+
+ pjvm->pushProp(prop);
+ }
+
+ if(country.getLength()) {
+ rtl::OUString prop(RTL_CONSTASCII_USTRINGPARAM("user.country="));
+ prop += country;
+
+ pjvm->pushProp(prop);
+ }
+ }
+ }
+
+ xConfRegistry_simple->close();
+}
+
+
+
+void getJavaPropsFromSafetySettings(
+ stoc_javavm::JVM * pjvm,
+ const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
+ const css::uno::Reference<css::uno::XComponentContext> &xCtx) throw(css::uno::Exception)
+{
+ css::uno::Reference<css::uno::XInterface> xConfRegistry =
+ xSMgr->createInstanceWithContext(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationRegistry")),
+ xCtx);
+ if(!xConfRegistry.is())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
+
+ css::uno::Reference<css::registry::XSimpleRegistry> xConfRegistry_simple(
+ xConfRegistry, css::uno::UNO_QUERY);
+ if(!xConfRegistry_simple.is())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("javavm.cxx: couldn't get ConfigurationRegistry")), 0);
+
+ xConfRegistry_simple->open(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Java")),
+ sal_True, sal_False);
+ css::uno::Reference<css::registry::XRegistryKey> xRegistryRootKey =
+ xConfRegistry_simple->getRootKey();
+
+ if (xRegistryRootKey.is())
+ {
+ css::uno::Reference<css::registry::XRegistryKey> key_NetAccess= xRegistryRootKey->openKey(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VirtualMachine/NetAccess")));
+ if (key_NetAccess.is())
+ {
+ sal_Int32 val= key_NetAccess->getLongValue();
+ rtl::OUString sVal;
+ switch( val)
+ {
+ case 0: sVal= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("host"));
+ break;
+ case 1: sVal= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unrestricted"));
+ break;
+ case 3: sVal= rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("none"));
+ break;
+ }
+ rtl::OUString sProperty( RTL_CONSTASCII_USTRINGPARAM("appletviewer.security.mode="));
+ sProperty= sProperty + sVal;
+ pjvm->pushProp(sProperty);
+ }
+ css::uno::Reference<css::registry::XRegistryKey> key_CheckSecurity= xRegistryRootKey->openKey(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("VirtualMachine/Security")));
+ if( key_CheckSecurity.is())
+ {
+ sal_Bool val= (sal_Bool) key_CheckSecurity->getLongValue();
+ rtl::OUString sProperty(RTL_CONSTASCII_USTRINGPARAM("stardiv.security.disableSecurity="));
+ if( val)
+ sProperty= sProperty + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("false"));
+ else
+ sProperty= sProperty + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("true"));
+ pjvm->pushProp( sProperty);
+ }
+ }
+ xConfRegistry_simple->close();
+}
+
+static void setTimeZone(stoc_javavm::JVM * pjvm) throw() {
+ /* A Bug in the Java function
+ ** struct Hjava_util_Properties * java_lang_System_initProperties(
+ ** struct Hjava_lang_System *this,
+ ** struct Hjava_util_Properties *props);
+ ** This function doesn't detect MEZ, MET or "W. Europe Standard Time"
+ */
+ struct tm *tmData;
+ time_t clock = time(NULL);
+ tzset();
+ tmData = localtime(&clock);
+#ifdef MACOSX
+ char * p = tmData->tm_zone;
+#else
+ char * p = tzname[0];
+#endif
+
+ if (!strcmp(TIMEZONE, p))
+ pjvm->pushProp(rtl::OUString::createFromAscii("user.timezone=ECT"));
+}
+
+void initVMConfiguration(
+ stoc_javavm::JVM * pjvm,
+ const css::uno::Reference<css::lang::XMultiComponentFactory> & xSMgr,
+ const css::uno::Reference<css::uno::XComponentContext > &xCtx) throw(css::uno::Exception)
+{
+ stoc_javavm::JVM jvm;
+ try {
+ getINetPropsFromConfig(&jvm, xSMgr, xCtx);
+ }
+ catch(css::uno::Exception & exception) {
+#if OSL_DEBUG_LEVEL > 1
+ rtl::OString message = rtl::OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_TRACE("javavm.cxx: can not get INetProps cause of >%s<", message.getStr());
+#else
+ (void) exception; // unused
+#endif
+ }
+
+ try {
+ getDefaultLocaleFromConfig(&jvm, xSMgr,xCtx);
+ }
+ catch(css::uno::Exception & exception) {
+#if OSL_DEBUG_LEVEL > 1
+ rtl::OString message = rtl::OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_TRACE("javavm.cxx: can not get locale cause of >%s<", message.getStr());
+#else
+ (void) exception; // unused
+#endif
+ }
+
+ try
+ {
+ getJavaPropsFromSafetySettings(&jvm, xSMgr, xCtx);
+ }
+ catch(css::uno::Exception & exception) {
+#if OSL_DEBUG_LEVEL > 1
+ rtl::OString message = rtl::OUStringToOString(exception.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_TRACE("javavm.cxx: couldn't get safety settings because of >%s<", message.getStr());
+#else
+ (void) exception; // unused
+#endif
+ }
+
+ *pjvm= jvm;
+ setTimeZone(pjvm);
+
+}
+
+class DetachCurrentThread {
+public:
+ explicit DetachCurrentThread(JavaVM * jvm): m_jvm(jvm) {}
+
+ ~DetachCurrentThread() {
+ if (m_jvm->DetachCurrentThread() != 0) {
+ OSL_ASSERT(false);
+ }
+ }
+
+private:
+ DetachCurrentThread(DetachCurrentThread &); // not defined
+ void operator =(DetachCurrentThread &); // not defined
+
+ JavaVM * m_jvm;
+};
+
+}
+
+extern "C" void SAL_CALL
+component_getImplementationEnvironment(sal_Char const ** pEnvTypeName,
+ uno_Environment **)
+{
+ *pEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+extern "C" void * SAL_CALL component_getFactory(sal_Char const * pImplName,
+ void * pServiceManager,
+ void * pRegistryKey)
+{
+ return cppu::component_getFactoryHelper(pImplName, pServiceManager,
+ pRegistryKey,
+ aServiceImplementation);
+}
+
+// There is no component_canUnload, as the library cannot be unloaded.
+
+JavaVirtualMachine::JavaVirtualMachine(
+ css::uno::Reference< css::uno::XComponentContext > const & rContext):
+ JavaVirtualMachine_Impl(*static_cast< osl::Mutex * >(this)),
+ m_xContext(rContext),
+ m_bDisposed(false),
+ m_pJavaVm(0),
+ m_bDontCreateJvm(false),
+ m_aAttachGuards(destroyAttachGuards) // TODO check for validity
+{}
+
+void SAL_CALL
+JavaVirtualMachine::initialize(css::uno::Sequence< css::uno::Any > const &
+ rArguments)
+ throw (css::uno::Exception)
+{
+ osl::MutexGuard aGuard(*this);
+ if (m_bDisposed)
+ throw css::lang::DisposedException(
+ rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
+ if (m_xUnoVirtualMachine.is())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "bad call to initialize")),
+ static_cast< cppu::OWeakObject * >(this));
+ css::beans::NamedValue val;
+ if (rArguments.getLength() == 1 && (rArguments[0] >>= val)
+ && val.Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM( "UnoVirtualMachine")))
+ {
+ OSL_ENSURE(
+ sizeof (sal_Int64) >= sizeof (jvmaccess::UnoVirtualMachine *),
+ "Pointer cannot be represented as sal_Int64");
+ sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
+ static_cast< jvmaccess::UnoVirtualMachine * >(0));
+ val.Value >>= nPointer;
+ m_xUnoVirtualMachine =
+ reinterpret_cast< jvmaccess::UnoVirtualMachine * >(nPointer);
+ } else {
+ OSL_ENSURE(
+ sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *),
+ "Pointer cannot be represented as sal_Int64");
+ sal_Int64 nPointer = reinterpret_cast< sal_Int64 >(
+ static_cast< jvmaccess::VirtualMachine * >(0));
+ if (rArguments.getLength() == 1)
+ rArguments[0] >>= nPointer;
+ rtl::Reference< jvmaccess::VirtualMachine > vm(
+ reinterpret_cast< jvmaccess::VirtualMachine * >(nPointer));
+ if (vm.is()) {
+ try {
+ m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(vm, 0);
+ } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "jvmaccess::UnoVirtualMachine::CreationException")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ }
+ }
+ if (!m_xUnoVirtualMachine.is()) {
+ throw css::lang::IllegalArgumentException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "sequence of exactly one any containing either (a) a"
+ " com.sun.star.beans.NamedValue with Name"
+ " \"UnoVirtualMachine\" and Value a hyper representing a"
+ " non-null pointer to a jvmaccess:UnoVirtualMachine, or (b)"
+ " a hyper representing a non-null pointer to a"
+ " jvmaccess::VirtualMachine required")),
+ static_cast< cppu::OWeakObject * >(this), 0);
+ }
+ m_xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
+}
+
+rtl::OUString SAL_CALL JavaVirtualMachine::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return serviceGetImplementationName();
+}
+
+sal_Bool SAL_CALL
+JavaVirtualMachine::supportsService(rtl::OUString const & rServiceName)
+ throw (css::uno::RuntimeException)
+{
+ css::uno::Sequence< rtl::OUString > aNames(getSupportedServiceNames());
+ for (sal_Int32 i = 0; i < aNames.getLength(); ++i)
+ if (aNames[i] == rServiceName)
+ return true;
+ return false;
+}
+
+css::uno::Sequence< rtl::OUString > SAL_CALL
+JavaVirtualMachine::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return serviceGetSupportedServiceNames();
+}
+
+css::uno::Any SAL_CALL
+JavaVirtualMachine::getJavaVM(css::uno::Sequence< sal_Int8 > const & rProcessId)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(*this);
+ if (m_bDisposed)
+ throw css::lang::DisposedException(
+ rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
+ css::uno::Sequence< sal_Int8 > aId(16);
+ rtl_getGlobalProcessId(reinterpret_cast< sal_uInt8 * >(aId.getArray()));
+ enum ReturnType {
+ RETURN_JAVAVM, RETURN_VIRTUALMACHINE, RETURN_UNOVIRTUALMACHINE };
+ ReturnType returnType =
+ rProcessId.getLength() == 17 && rProcessId[16] == 0
+ ? RETURN_VIRTUALMACHINE
+ : rProcessId.getLength() == 17 && rProcessId[16] == 1
+ ? RETURN_UNOVIRTUALMACHINE
+ : RETURN_JAVAVM;
+ css::uno::Sequence< sal_Int8 > aProcessId(rProcessId);
+ if (returnType != RETURN_JAVAVM)
+ aProcessId.realloc(16);
+ if (aId != aProcessId)
+ return css::uno::Any();
+
+ while (!m_xVirtualMachine.is()) // retry until successful
+ {
+ // This is the second attempt to create Java. m_bDontCreateJvm is
+ // set which means instantiating the JVM might crash.
+ if (m_bDontCreateJvm)
+ //throw css::uno::RuntimeException();
+ return css::uno::Any();
+
+ stoc_javavm::JVM aJvm;
+ initVMConfiguration(&aJvm, m_xContext->getServiceManager(),
+ m_xContext);
+ //Create the JavaVMOption array
+ const std::vector<rtl::OUString> & props = aJvm.getProperties();
+ boost::scoped_array<JavaVMOption> sarOptions(
+ new JavaVMOption[props.size()]);
+ JavaVMOption * arOptions = sarOptions.get();
+ //Create an array that contains the strings which are passed
+ //into the options
+ boost::scoped_array<rtl::OString> sarPropStrings(
+ new rtl::OString[props.size()]);
+ rtl::OString * arPropStrings = sarPropStrings.get();
+
+ rtl::OString sJavaOption("-");
+ typedef std::vector<rtl::OUString>::const_iterator cit;
+ int index = 0;
+ for (cit i = props.begin(); i != props.end(); i++)
+ {
+ rtl::OString sOption = rtl::OUStringToOString(
+ *i, osl_getThreadTextEncoding());
+
+ if (!sOption.matchIgnoreAsciiCase(sJavaOption, 0))
+ arPropStrings[index]= rtl::OString("-D") + sOption;
+ else
+ arPropStrings[index] = sOption;
+
+ arOptions[index].optionString = (sal_Char*)arPropStrings[index].getStr();
+ arOptions[index].extraInfo = 0;
+ index ++;
+ }
+
+ JNIEnv * pMainThreadEnv = 0;
+ javaFrameworkError errcode = JFW_E_NONE;
+ errcode = jfw_startVM(arOptions, index, & m_pJavaVm,
+ & pMainThreadEnv);
+
+ bool bStarted = false;
+ switch (errcode)
+ {
+ case JFW_E_NONE: bStarted = true; break;
+ case JFW_E_NO_SELECT:
+ {
+ // No Java configured. We silenty run the java configuration
+ // Java.
+ javaFrameworkError errFind = jfw_findAndSelectJRE( NULL );
+ if (errFind == JFW_E_NONE)
+ {
+ continue;
+ }
+ else if (errFind == JFW_E_NO_JAVA_FOUND)
+ {
+
+ //Warning MessageBox:
+ //%PRODUCTNAME requires a Java runtime environment (JRE) to perform this task.
+ //Please install a JRE and restart %PRODUCTNAME.
+ css::java::JavaNotFoundException exc(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::getJavaVM failed because"
+ " No suitable JRE found!")),
+ static_cast< cppu::OWeakObject * >(this));
+ askForRetry(css::uno::makeAny(exc));
+ return css::uno::Any();
+ }
+ else
+ {
+ //An unexpected error occurred
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "[JavaVirtualMachine]:An unexpected error occurred"
+ " while searching for a Java!")), 0);
+ }
+ }
+ case JFW_E_INVALID_SETTINGS:
+ {
+ //Warning MessageBox:
+ // The %PRODUCTNAME configuration has been changed. Under Tools
+ // - Options - %PRODUCTNAME - Java, select the Java runtime environment
+ // you want to have used by %PRODUCTNAME.
+ css::java::InvalidJavaSettingsException exc(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::getJavaVM failed because"
+ " Java settings have changed!")),
+ static_cast< cppu::OWeakObject * >(this));
+ askForRetry(css::uno::makeAny(exc));
+ return css::uno::Any();
+ }
+ case JFW_E_JAVA_DISABLED:
+ {
+ //QueryBox:
+ //%PRODUCTNAME requires a Java runtime environment (JRE) to perform
+ //this task. However, use of a JRE has been disabled. Do you want to
+ //enable the use of a JRE now?
+ css::java::JavaDisabledException exc(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::getJavaVM failed because"
+ " Java is disabled!")),
+ static_cast< cppu::OWeakObject * >(this));
+ if( ! askForRetry(css::uno::makeAny(exc)))
+ return css::uno::Any();
+ continue;
+ }
+ case JFW_E_VM_CREATION_FAILED:
+ {
+ //If the creation failed because the JRE has been uninstalled then
+ //we search another one. As long as there is a javaldx, we should
+ //never come into this situation. javaldx checks alway if the JRE
+ //still exist.
+ JavaInfo * pJavaInfo = NULL;
+ if (JFW_E_NONE == jfw_getSelectedJRE(&pJavaInfo))
+ {
+ sal_Bool bExist = sal_False;
+ if (JFW_E_NONE == jfw_existJRE(pJavaInfo, &bExist))
+ {
+ if (bExist == sal_False
+ && ! (pJavaInfo->nRequirements & JFW_REQUIRE_NEEDRESTART))
+ {
+ javaFrameworkError errFind = jfw_findAndSelectJRE( NULL );
+ if (errFind == JFW_E_NONE)
+ {
+ continue;
+ }
+ }
+ }
+ }
+
+ jfw_freeJavaInfo(pJavaInfo);
+ //
+ //Error: %PRODUCTNAME requires a Java
+ //runtime environment (JRE) to perform this task. The selected JRE
+ //is defective. Please select another version or install a new JRE
+ //and select it under Tools - Options - %PRODUCTNAME - Java.
+ css::java::JavaVMCreationFailureException exc(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::getJavaVM failed because"
+ " Java is defective!")),
+ static_cast< cppu::OWeakObject * >(this), 0);
+ askForRetry(css::uno::makeAny(exc));
+ return css::uno::Any();
+ }
+ case JFW_E_RUNNING_JVM:
+ {
+ //This service should make sure that we do not start java twice.
+ OSL_ASSERT(0);
+ break;
+ }
+ case JFW_E_NEED_RESTART:
+ {
+ //Error:
+ //For the selected Java runtime environment to work properly,
+ //%PRODUCTNAME must be restarted. Please restart %PRODUCTNAME now.
+ css::java::RestartRequiredException exc(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::getJavaVM failed because"
+ "Office must be restarted before Java can be used!")),
+ static_cast< cppu::OWeakObject * >(this));
+ askForRetry(css::uno::makeAny(exc));
+ return css::uno::Any();
+ }
+ default:
+ //RuntimeException: error is somewhere in the java framework.
+ //An unexpected error occurred
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "[JavaVirtualMachine]:An unexpected error occurred"
+ " while starting Java!")), 0);
+ }
+
+ if (bStarted)
+ {
+ {
+ DetachCurrentThread detach(m_pJavaVm);
+ // necessary to make debugging work; this thread will be
+ // suspended when the destructor of detach returns
+ m_xVirtualMachine = new jvmaccess::VirtualMachine(
+ m_pJavaVm, JNI_VERSION_1_2, true, pMainThreadEnv);
+ setUpUnoVirtualMachine(pMainThreadEnv);
+ }
+ // Listen for changes in the configuration (e.g. proxy settings):
+ // TODO this is done too late; changes to the configuration done
+ // after the above call to initVMConfiguration are lost
+ registerConfigChangesListener();
+
+ break;
+ }
+ }
+ if (!m_xUnoVirtualMachine.is()) {
+ try {
+ jvmaccess::VirtualMachine::AttachGuard guard(m_xVirtualMachine);
+ setUpUnoVirtualMachine(guard.getEnvironment());
+ } catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "jvmaccess::VirtualMachine::AttachGuard::"
+ "CreationException occurred")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ }
+ switch (returnType) {
+ default: // RETURN_JAVAVM
+ if (m_pJavaVm == 0) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine service was initialized in a way"
+ " that the requested JavaVM pointer is not available")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ return css::uno::makeAny(reinterpret_cast< sal_IntPtr >(m_pJavaVm));
+ case RETURN_VIRTUALMACHINE:
+ OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
+ return css::uno::makeAny(
+ reinterpret_cast< sal_Int64 >(
+ m_xUnoVirtualMachine->getVirtualMachine().get()));
+ case RETURN_UNOVIRTUALMACHINE:
+ OSL_ASSERT(sizeof (sal_Int64) >= sizeof (jvmaccess::VirtualMachine *));
+ return css::uno::makeAny(
+ reinterpret_cast< sal_Int64 >(m_xUnoVirtualMachine.get()));
+ }
+}
+
+sal_Bool SAL_CALL JavaVirtualMachine::isVMStarted()
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(*this);
+ if (m_bDisposed)
+ throw css::lang::DisposedException(
+ rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
+ return m_xUnoVirtualMachine.is();
+}
+
+sal_Bool SAL_CALL JavaVirtualMachine::isVMEnabled()
+ throw (css::uno::RuntimeException)
+{
+ {
+ osl::MutexGuard aGuard(*this);
+ if (m_bDisposed)
+ throw css::lang::DisposedException(
+ rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
+ }
+// stoc_javavm::JVM aJvm;
+// initVMConfiguration(&aJvm, m_xContext->getServiceManager(), m_xContext);
+// return aJvm.isEnabled();
+ //ToDo
+ sal_Bool bEnabled = sal_False;
+ if (jfw_getEnabled( & bEnabled) != JFW_E_NONE)
+ throw css::uno::RuntimeException();
+ return bEnabled;
+}
+
+sal_Bool SAL_CALL JavaVirtualMachine::isThreadAttached()
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(*this);
+ if (m_bDisposed)
+ throw css::lang::DisposedException(
+ rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
+ // TODO isThreadAttached only returns true if the thread was attached via
+ // registerThread:
+ GuardStack * pStack
+ = static_cast< GuardStack * >(m_aAttachGuards.getData());
+ return pStack != 0 && !pStack->empty();
+}
+
+void SAL_CALL JavaVirtualMachine::registerThread()
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(*this);
+ if (m_bDisposed)
+ throw css::lang::DisposedException(
+ rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
+ if (!m_xUnoVirtualMachine.is())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::registerThread:"
+ " null VirtualMachine")),
+ static_cast< cppu::OWeakObject * >(this));
+ GuardStack * pStack
+ = static_cast< GuardStack * >(m_aAttachGuards.getData());
+ if (pStack == 0)
+ {
+ pStack = new GuardStack;
+ m_aAttachGuards.setData(pStack);
+ }
+ try
+ {
+ pStack->push(
+ new jvmaccess::VirtualMachine::AttachGuard(
+ m_xUnoVirtualMachine->getVirtualMachine()));
+ }
+ catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::registerThread: jvmaccess::"
+ "VirtualMachine::AttachGuard::CreationException")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+}
+
+void SAL_CALL JavaVirtualMachine::revokeThread()
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(*this);
+ if (m_bDisposed)
+ throw css::lang::DisposedException(
+ rtl::OUString(), static_cast< cppu::OWeakObject * >(this));
+ if (!m_xUnoVirtualMachine.is())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::revokeThread:"
+ " null VirtualMachine")),
+ static_cast< cppu::OWeakObject * >(this));
+ GuardStack * pStack
+ = static_cast< GuardStack * >(m_aAttachGuards.getData());
+ if (pStack == 0 || pStack->empty())
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "JavaVirtualMachine::revokeThread:"
+ " no matching registerThread")),
+ static_cast< cppu::OWeakObject * >(this));
+ delete pStack->top();
+ pStack->pop();
+}
+
+void SAL_CALL
+JavaVirtualMachine::disposing(css::lang::EventObject const & rSource)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard aGuard(*this);
+ if (rSource.Source == m_xInetConfiguration)
+ m_xInetConfiguration.clear();
+ if (rSource.Source == m_xJavaConfiguration)
+ m_xJavaConfiguration.clear();
+}
+
+void SAL_CALL JavaVirtualMachine::elementInserted(
+ css::container::ContainerEvent const &)
+ throw (css::uno::RuntimeException)
+{}
+
+void SAL_CALL JavaVirtualMachine::elementRemoved(
+ css::container::ContainerEvent const &)
+ throw (css::uno::RuntimeException)
+{}
+
+// If a user changes the setting, for example for proxy settings, then this
+// function will be called from the configuration manager. Even if the .xml
+// file does not contain an entry yet and that entry has to be inserted, this
+// function will be called. We call java.lang.System.setProperty for the new
+// values.
+void SAL_CALL JavaVirtualMachine::elementReplaced(
+ css::container::ContainerEvent const & rEvent)
+ throw (css::uno::RuntimeException)
+{
+ // TODO Using the new value stored in rEvent is wrong here. If two threads
+ // receive different elementReplaced calls in quick succession, it is
+ // unspecified which changes the JVM's system properties last. A correct
+ // solution must atomically (i.e., protected by a mutex) read the latest
+ // value from the configuration and set it as a system property at the JVM.
+
+ rtl::OUString aAccessor;
+ rEvent.Accessor >>= aAccessor;
+ rtl::OUString aPropertyName;
+ rtl::OUString aPropertyName2;
+ rtl::OUString aPropertyValue;
+ bool bSecurityChanged = false;
+ if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("ooInetProxyType")))
+ {
+ // Proxy none, manually
+ sal_Int32 value = 0;
+ rEvent.Element >>= value;
+ setINetSettingsInVM(value != 0);
+ return;
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "ooInetHTTPProxyName")))
+ {
+ aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "http.proxyHost"));
+ rEvent.Element >>= aPropertyValue;
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "ooInetHTTPProxyPort")))
+ {
+ aPropertyName
+ = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort"));
+ sal_Int32 n = 0;
+ rEvent.Element >>= n;
+ aPropertyValue = rtl::OUString::valueOf(n);
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "ooInetHTTPSProxyName")))
+ {
+ aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "https.proxyHost"));
+ rEvent.Element >>= aPropertyValue;
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "ooInetHTTPSProxyPort")))
+ {
+ aPropertyName
+ = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("https.proxyPort"));
+ sal_Int32 n = 0;
+ rEvent.Element >>= n;
+ aPropertyValue = rtl::OUString::valueOf(n);
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "ooInetFTPProxyName")))
+ {
+ aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ftp.proxyHost"));
+ rEvent.Element >>= aPropertyValue;
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "ooInetFTPProxyPort")))
+ {
+ aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ftp.proxyPort"));
+ sal_Int32 n = 0;
+ rEvent.Element >>= n;
+ aPropertyValue = rtl::OUString::valueOf(n);
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(
+ "ooInetNoProxy")))
+ {
+ aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "http.nonProxyHosts"));
+ aPropertyName2 = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "ftp.nonProxyHosts"));
+ rEvent.Element >>= aPropertyValue;
+ aPropertyValue = aPropertyValue.replace(';', '|');
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("NetAccess")))
+ {
+ aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "appletviewer.security.mode"));
+ sal_Int32 n = 0;
+ if (rEvent.Element >>= n)
+ switch (n)
+ {
+ case 0:
+ aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "host"));
+ break;
+ case 1:
+ aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "unrestricted"));
+ break;
+ case 3:
+ aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "none"));
+ break;
+ }
+ else
+ return;
+ bSecurityChanged = true;
+ }
+ else if (aAccessor.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("Security")))
+ {
+ aPropertyName = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "stardiv.security.disableSecurity"));
+ sal_Bool b = sal_Bool();
+ if (rEvent.Element >>= b)
+ if (b)
+ aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "false"));
+ else
+ aPropertyValue = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "true"));
+ else
+ return;
+ bSecurityChanged = true;
+ }
+ else
+ return;
+
+ rtl::Reference< jvmaccess::VirtualMachine > xVirtualMachine;
+ {
+ osl::MutexGuard aGuard(*this);
+ if (m_xUnoVirtualMachine.is()) {
+ xVirtualMachine = m_xUnoVirtualMachine->getVirtualMachine();
+ }
+ }
+ if (xVirtualMachine.is())
+ {
+ try
+ {
+ jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
+ xVirtualMachine);
+ JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
+
+ // call java.lang.System.setProperty
+ // String setProperty( String key, String value)
+ jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/lang/System")), 0);
+ jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.setProperty")), 0);
+
+ jstring jsPropName= pJNIEnv->NewString( aPropertyName.getStr(), aPropertyName.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+
+ // remove the property if it does not have a value ( user left the dialog field empty)
+ // or if the port is set to 0
+ aPropertyValue= aPropertyValue.trim();
+ if(
+ aPropertyValue.getLength() == 0 ||
+ (
+ (
+ aPropertyName.equals( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyPort"))) ||
+ aPropertyName.equals( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort"))) /*||
+ aPropertyName.equals( OUString( RTL_CONSTASCII_USTRINGPARAM("socksProxyPort")))*/
+ ) &&
+ aPropertyValue.equals(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("0")))
+ )
+ )
+ {
+ // call java.lang.System.getProperties
+ jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.getProperties")), 0);
+ jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.getProperties")), 0);
+ // call java.util.Properties.remove
+ jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/util/Properties")), 0);
+ jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID java.util.Properties.remove")), 0);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName);
+
+ // special calse for ftp.nonProxyHosts and http.nonProxyHosts. The office only
+ // has a value for two java properties
+ if (aPropertyName2.getLength() > 0)
+ {
+ jstring jsPropName2= pJNIEnv->NewString( aPropertyName2.getStr(), aPropertyName2.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsPropName2);
+ }
+ }
+ else
+ {
+ // Change the Value of the property
+ jstring jsPropValue= pJNIEnv->NewString( aPropertyValue.getStr(), aPropertyValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName, jsPropValue);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+
+ // special calse for ftp.nonProxyHosts and http.nonProxyHosts. The office only
+ // has a value for two java properties
+ if (aPropertyName2.getLength() > 0)
+ {
+ jstring jsPropName2= pJNIEnv->NewString( aPropertyName2.getStr(), aPropertyName2.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ jsPropValue= pJNIEnv->NewString( aPropertyValue.getStr(), aPropertyValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsPropName2, jsPropValue);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+ }
+ }
+
+ // If the settings for Security and NetAccess changed then we have to notify the SandboxSecurity
+ // SecurityManager
+ // call System.getSecurityManager()
+ if (bSecurityChanged)
+ {
+ jmethodID jmGetSecur= pJNIEnv->GetStaticMethodID( jcSystem,"getSecurityManager","()Ljava/lang/SecurityManager;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.getSecurityManager")), 0);
+ jobject joSecur= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetSecur);
+ if (joSecur != 0)
+ {
+ // Make sure the SecurityManager is our SandboxSecurity
+ // FindClass("com.sun.star.lib.sandbox.SandboxSecurityManager" only worked at the first time
+ // this code was executed. Maybe it is a security feature. However, all attempts to debug the
+ // SandboxSecurity class (maybe the VM invokes checkPackageAccess) failed.
+// jclass jcSandboxSec= pJNIEnv->FindClass("com.sun.star.lib.sandbox.SandboxSecurity");
+// if(pJNIEnv->ExceptionOccurred()) throw RuntimeException(OUSTR("JNI:FindClass com.sun.star.lib.sandbox.SandboxSecurity"), Reference<XInterface>());
+// jboolean bIsSand= pJNIEnv->IsInstanceOf( joSecur, jcSandboxSec);
+ // The SecurityManagers class Name must be com.sun.star.lib.sandbox.SandboxSecurity
+ jclass jcSec= pJNIEnv->GetObjectClass( joSecur);
+ jclass jcClass= pJNIEnv->FindClass("java/lang/Class");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java.lang.Class")), 0);
+ jmethodID jmName= pJNIEnv->GetMethodID( jcClass,"getName","()Ljava/lang/String;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID java.lang.Class.getName")), 0);
+ jstring jsClass= (jstring) pJNIEnv->CallObjectMethod( jcSec, jmName);
+ const jchar* jcharName= pJNIEnv->GetStringChars( jsClass, NULL);
+ rtl::OUString sName( jcharName);
+ jboolean bIsSandbox;
+ if (sName == rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lib.sandbox.SandboxSecurity")))
+ bIsSandbox= JNI_TRUE;
+ else
+ bIsSandbox= JNI_FALSE;
+ pJNIEnv->ReleaseStringChars( jsClass, jcharName);
+
+ if (bIsSandbox == JNI_TRUE)
+ {
+ // call SandboxSecurity.reset
+ jmethodID jmReset= pJNIEnv->GetMethodID( jcSec,"reset","()V");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID com.sun.star.lib.sandbox.SandboxSecurity.reset")), 0);
+ pJNIEnv->CallVoidMethod( joSecur, jmReset);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallVoidMethod com.sun.star.lib.sandbox.SandboxSecurity.reset")), 0);
+ }
+ }
+ }
+ }
+ catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "jvmaccess::VirtualMachine::AttachGuard::"
+ "CreationException")),
+ 0);
+ }
+ }
+}
+
+JavaVirtualMachine::~JavaVirtualMachine()
+{
+ if (m_xInetConfiguration.is())
+ // We should never get here, but just in case...
+ try
+ {
+ m_xInetConfiguration->removeContainerListener(this);
+ }
+ catch (css::uno::Exception &)
+ {
+ OSL_ENSURE(false, "com.sun.star.uno.Exception caught");
+ }
+ if (m_xJavaConfiguration.is())
+ // We should never get here, but just in case...
+ try
+ {
+ m_xJavaConfiguration->removeContainerListener(this);
+ }
+ catch (css::uno::Exception &)
+ {
+ OSL_ENSURE(false, "com.sun.star.uno.Exception caught");
+ }
+}
+
+void SAL_CALL JavaVirtualMachine::disposing()
+{
+ css::uno::Reference< css::container::XContainer > xContainer1;
+ css::uno::Reference< css::container::XContainer > xContainer2;
+ {
+ osl::MutexGuard aGuard(*this);
+ m_bDisposed = true;
+ xContainer1 = m_xInetConfiguration;
+ m_xInetConfiguration.clear();
+ xContainer2 = m_xJavaConfiguration;
+ m_xJavaConfiguration.clear();
+ }
+ if (xContainer1.is())
+ xContainer1->removeContainerListener(this);
+ if (xContainer2.is())
+ xContainer2->removeContainerListener(this);
+}
+
+/*We listen to changes in the configuration. For example, the user changes the proxy
+ settings in the options dialog (menu tools). Then we are notified of this change and
+ if the java vm is already running we change the properties (System.lang.System.setProperties)
+ through JNI.
+ To receive notifications this class implements XContainerListener.
+*/
+void JavaVirtualMachine::registerConfigChangesListener()
+{
+ try
+ {
+ css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(
+ m_xContext->getServiceManager()->createInstanceWithContext( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider")), m_xContext), css::uno::UNO_QUERY);
+
+ if (xConfigProvider.is())
+ {
+ // We register this instance as listener to changes in org.openoffice.Inet/Settings
+ // arguments for ConfigurationAccess
+ css::uno::Sequence< css::uno::Any > aArguments(2);
+ aArguments[0] <<= css::beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")),
+ 0,
+ css::uno::makeAny(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Inet/Settings"))),
+ css::beans::PropertyState_DIRECT_VALUE);
+ // depth: -1 means unlimited
+ aArguments[1] <<= css::beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("depth")),
+ 0,
+ css::uno::makeAny( (sal_Int32)-1),
+ css::beans::PropertyState_DIRECT_VALUE);
+
+ m_xInetConfiguration
+ = css::uno::Reference< css::container::XContainer >(
+ xConfigProvider->createInstanceWithArguments(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess")),
+ aArguments),
+ css::uno::UNO_QUERY);
+
+ if (m_xInetConfiguration.is())
+ m_xInetConfiguration->addContainerListener(this);
+
+ // now register as listener to changes in org.openoffice.Java/VirtualMachine
+ css::uno::Sequence< css::uno::Any > aArguments2(2);
+ aArguments2[0] <<= css::beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("nodepath")),
+ 0,
+ css::uno::makeAny(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Java/VirtualMachine"))),
+ css::beans::PropertyState_DIRECT_VALUE);
+ // depth: -1 means unlimited
+ aArguments2[1] <<= css::beans::PropertyValue(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("depth")),
+ 0,
+ css::uno::makeAny( (sal_Int32)-1),
+ css::beans::PropertyState_DIRECT_VALUE);
+
+ m_xJavaConfiguration
+ = css::uno::Reference< css::container::XContainer >(
+ xConfigProvider->createInstanceWithArguments(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationAccess")),
+ aArguments2),
+ css::uno::UNO_QUERY);
+
+ if (m_xJavaConfiguration.is())
+ m_xJavaConfiguration->addContainerListener(this);
+ }
+ }catch( css::uno::Exception & e)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ rtl::OString message = rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_ASCII_US);
+ OSL_TRACE("javavm.cxx: could not set up listener for Configuration because of >%s<", message.getStr());
+#else
+ (void) e; // unused
+#endif
+ }
+}
+
+// param true: all Inet setting are set as Java Properties on a live VM.
+// false: the Java net properties are set to empty value.
+void JavaVirtualMachine::setINetSettingsInVM(bool set_reset)
+{
+ osl::MutexGuard aGuard(*this);
+ try
+ {
+ if (m_xUnoVirtualMachine.is())
+ {
+ jvmaccess::VirtualMachine::AttachGuard aAttachGuard(
+ m_xUnoVirtualMachine->getVirtualMachine());
+ JNIEnv * pJNIEnv = aAttachGuard.getEnvironment();
+
+ // The Java Properties
+ rtl::OUString sFtpProxyHost(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyHost") );
+ rtl::OUString sFtpProxyPort(RTL_CONSTASCII_USTRINGPARAM("ftp.proxyPort") );
+ rtl::OUString sFtpNonProxyHosts (RTL_CONSTASCII_USTRINGPARAM("ftp.nonProxyHosts"));
+ rtl::OUString sHttpProxyHost(RTL_CONSTASCII_USTRINGPARAM("http.proxyHost") );
+ rtl::OUString sHttpProxyPort(RTL_CONSTASCII_USTRINGPARAM("http.proxyPort") );
+ rtl::OUString sHttpNonProxyHosts(RTL_CONSTASCII_USTRINGPARAM("http.nonProxyHosts"));
+
+ // creat Java Properties as JNI strings
+ jstring jsFtpProxyHost= pJNIEnv->NewString( sFtpProxyHost.getStr(), sFtpProxyHost.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ jstring jsFtpProxyPort= pJNIEnv->NewString( sFtpProxyPort.getStr(), sFtpProxyPort.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ jstring jsFtpNonProxyHosts= pJNIEnv->NewString( sFtpNonProxyHosts.getStr(), sFtpNonProxyHosts.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ jstring jsHttpProxyHost= pJNIEnv->NewString( sHttpProxyHost.getStr(), sHttpProxyHost.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ jstring jsHttpProxyPort= pJNIEnv->NewString( sHttpProxyPort.getStr(), sHttpProxyPort.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ jstring jsHttpNonProxyHosts= pJNIEnv->NewString( sHttpNonProxyHosts.getStr(), sHttpNonProxyHosts.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+
+ // prepare java.lang.System.setProperty
+ jclass jcSystem= pJNIEnv->FindClass("java/lang/System");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/lang/System")), 0);
+ jmethodID jmSetProps= pJNIEnv->GetStaticMethodID( jcSystem, "setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.setProperty")), 0);
+
+ // call java.lang.System.getProperties
+ jmethodID jmGetProps= pJNIEnv->GetStaticMethodID( jcSystem, "getProperties","()Ljava/util/Properties;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetStaticMethodID java.lang.System.getProperties")), 0);
+ jobject joProperties= pJNIEnv->CallStaticObjectMethod( jcSystem, jmGetProps);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.getProperties")), 0);
+ // prepare java.util.Properties.remove
+ jclass jcProperties= pJNIEnv->FindClass("java/util/Properties");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:FindClass java/util/Properties")), 0);
+
+ if (set_reset)
+ {
+ // Set all network properties with the VM
+ JVM jvm;
+ getINetPropsFromConfig( &jvm, m_xContext->getServiceManager(), m_xContext);
+ const ::std::vector< rtl::OUString> & Props = jvm.getProperties();
+ typedef ::std::vector< rtl::OUString >::const_iterator C_IT;
+
+ for( C_IT i= Props.begin(); i != Props.end(); i++)
+ {
+ rtl::OUString prop= *i;
+ sal_Int32 index= prop.indexOf( (sal_Unicode)'=');
+ rtl::OUString propName= prop.copy( 0, index);
+ rtl::OUString propValue= prop.copy( index + 1);
+
+ if( propName.equals( sFtpProxyHost))
+ {
+ jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyHost, jsVal);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+ }
+ else if( propName.equals( sFtpProxyPort))
+ {
+ jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpProxyPort, jsVal);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+ }
+ else if( propName.equals( sFtpNonProxyHosts))
+ {
+ jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsFtpNonProxyHosts, jsVal);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+ }
+ else if( propName.equals( sHttpProxyHost))
+ {
+ jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyHost, jsVal);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+ }
+ else if( propName.equals( sHttpProxyPort))
+ {
+ jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpProxyPort, jsVal);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+ }
+ else if( propName.equals( sHttpNonProxyHosts))
+ {
+ jstring jsVal= pJNIEnv->NewString( propValue.getStr(), propValue.getLength());
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:NewString")), 0);
+ pJNIEnv->CallStaticObjectMethod( jcSystem, jmSetProps, jsHttpNonProxyHosts, jsVal);
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:CallStaticObjectMethod java.lang.System.setProperty")), 0);
+ }
+ }
+ }
+ else
+ {
+ // call java.util.Properties.remove
+ jmethodID jmRemove= pJNIEnv->GetMethodID( jcProperties, "remove", "(Ljava/lang/Object;)Ljava/lang/Object;");
+ if(pJNIEnv->ExceptionOccurred()) throw css::uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("JNI:GetMethodID java.util.Property.remove")), 0);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyHost);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpProxyPort);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsFtpNonProxyHosts);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyHost);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpProxyPort);
+ pJNIEnv->CallObjectMethod( joProperties, jmRemove, jsHttpNonProxyHosts);
+ }
+ }
+ }
+ catch (css::uno::RuntimeException &)
+ {
+ OSL_ENSURE(false, "RuntimeException");
+ }
+ catch (jvmaccess::VirtualMachine::AttachGuard::CreationException &)
+ {
+ OSL_ENSURE(false,
+ "jvmaccess::VirtualMachine::AttachGuard::CreationException");
+ }
+}
+
+void JavaVirtualMachine::setUpUnoVirtualMachine(JNIEnv * environment) {
+ css::uno::Reference< css::util::XMacroExpander > exp;
+ if (!(m_xContext->getValueByName(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.util.theMacroExpander")))
+ >>= exp)
+ || !exp.is())
+ {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "component context fails to supply singleton"
+ " com.sun.star.util.theMacroExpander of type"
+ " com.sun.star.util.XMacroExpander")),
+ m_xContext);
+ }
+ rtl::OUString baseUrl;
+ try {
+ baseUrl = exp->expandMacros(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("$URE_INTERNAL_JAVA_DIR/")));
+ } catch (css::lang::IllegalArgumentException &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com::sun::star::lang::IllegalArgumentException")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ rtl::OUString classPath;
+ try {
+ classPath = exp->expandMacros(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("$URE_INTERNAL_JAVA_CLASSPATH")));
+ } catch (css::lang::IllegalArgumentException &) {}
+ jclass class_URLClassLoader = environment->FindClass(
+ "java/net/URLClassLoader");
+ if (class_URLClassLoader == 0) {
+ handleJniException(environment);
+ }
+ jmethodID ctor_URLClassLoader = environment->GetMethodID(
+ class_URLClassLoader, "<init>", "([Ljava/net/URL;)V");
+ if (ctor_URLClassLoader == 0) {
+ handleJniException(environment);
+ }
+ jclass class_URL = environment->FindClass("java/net/URL");
+ if (class_URL == 0) {
+ handleJniException(environment);
+ }
+ jmethodID ctor_URL_1 = environment->GetMethodID(
+ class_URL, "<init>", "(Ljava/lang/String;)V");
+ if (ctor_URL_1 == 0) {
+ handleJniException(environment);
+ }
+ jvalue args[3];
+ args[0].l = environment->NewString(
+ static_cast< jchar const * >(baseUrl.getStr()),
+ static_cast< jsize >(baseUrl.getLength()));
+ if (args[0].l == 0) {
+ handleJniException(environment);
+ }
+ jobject base = environment->NewObjectA(class_URL, ctor_URL_1, args);
+ if (base == 0) {
+ handleJniException(environment);
+ }
+ jmethodID ctor_URL_2 = environment->GetMethodID(
+ class_URL, "<init>", "(Ljava/net/URL;Ljava/lang/String;)V");
+ if (ctor_URL_2 == 0) {
+ handleJniException(environment);
+ }
+ jobjectArray classpath = jvmaccess::ClassPath::translateToUrls(
+ m_xContext, environment, classPath);
+ if (classpath == 0) {
+ handleJniException(environment);
+ }
+ args[0].l = base;
+ args[1].l = environment->NewStringUTF("unoloader.jar");
+ if (args[1].l == 0) {
+ handleJniException(environment);
+ }
+ args[0].l = environment->NewObjectA(class_URL, ctor_URL_2, args);
+ if (args[0].l == 0) {
+ handleJniException(environment);
+ }
+ args[0].l = environment->NewObjectArray(1, class_URL, args[0].l);
+ if (args[0].l == 0) {
+ handleJniException(environment);
+ }
+ jobject cl1 = environment->NewObjectA(
+ class_URLClassLoader, ctor_URLClassLoader, args);
+ if (cl1 == 0) {
+ handleJniException(environment);
+ }
+ jmethodID method_loadClass = environment->GetMethodID(
+ class_URLClassLoader, "loadClass",
+ "(Ljava/lang/String;)Ljava/lang/Class;");
+ if (method_loadClass == 0) {
+ handleJniException(environment);
+ }
+ args[0].l = environment->NewStringUTF(
+ "com.sun.star.lib.unoloader.UnoClassLoader");
+ if (args[0].l == 0) {
+ handleJniException(environment);
+ }
+ jclass class_UnoClassLoader = static_cast< jclass >(
+ environment->CallObjectMethodA(cl1, method_loadClass, args));
+ if (class_UnoClassLoader == 0) {
+ handleJniException(environment);
+ }
+ jmethodID ctor_UnoClassLoader = environment->GetMethodID(
+ class_UnoClassLoader, "<init>",
+ "(Ljava/net/URL;[Ljava/net/URL;Ljava/lang/ClassLoader;)V");
+ if (ctor_UnoClassLoader == 0) {
+ handleJniException(environment);
+ }
+ args[0].l = base;
+ args[1].l = classpath;
+ args[2].l = cl1;
+ jobject cl2 = environment->NewObjectA(
+ class_UnoClassLoader, ctor_UnoClassLoader, args);
+ if (cl2 == 0) {
+ handleJniException(environment);
+ }
+ try {
+ m_xUnoVirtualMachine = new jvmaccess::UnoVirtualMachine(
+ m_xVirtualMachine, cl2);
+ } catch (jvmaccess::UnoVirtualMachine::CreationException &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "jvmaccess::UnoVirtualMachine::CreationException")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+}
+
+void JavaVirtualMachine::handleJniException(JNIEnv * environment) {
+ environment->ExceptionClear();
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("JNI exception occurred")),
+ static_cast< cppu::OWeakObject * >(this));
+}
diff --git a/stoc/source/javavm/javavm.hxx b/stoc/source/javavm/javavm.hxx
new file mode 100644
index 000000000000..d04ed4a2805c
--- /dev/null
+++ b/stoc/source/javavm/javavm.hxx
@@ -0,0 +1,172 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#if !defined INCLUDED_STOC_JAVAVM_JAVAVM_HXX
+#define INCLUDED_STOC_JAVAVM_JAVAVM_HXX
+
+#include "jvmargs.hxx"
+
+#include "com/sun/star/container/XContainerListener.hpp"
+#include "com/sun/star/lang/XInitialization.hpp"
+#include "com/sun/star/java/XJavaThreadRegister_11.hpp"
+#include "com/sun/star/java/XJavaVM.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "cppuhelper/compbase5.hxx"
+#include "osl/thread.hxx"
+#include "rtl/ref.hxx"
+#include <osl/mutex.hxx>
+#include <rtl/ustring.hxx>
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XContainer; }
+ namespace uno { class XComponentContext; }
+} } }
+namespace jvmaccess {
+ class UnoVirtualMachine;
+ class VirtualMachine;
+}
+
+namespace stoc_javavm {
+
+bool configureJava(const com::sun::star::uno::Reference<
+ com::sun::star::uno::XComponentContext>& xContext);
+// The MS compiler needs a typedef here, so the JavaVirtualMachine ctor can call
+// its base class ctor:
+typedef
+cppu::WeakComponentImplHelper5< com::sun::star::lang::XInitialization,
+ com::sun::star::lang::XServiceInfo,
+ com::sun::star::java::XJavaVM,
+ com::sun::star::java::XJavaThreadRegister_11,
+ com::sun::star::container::XContainerListener >
+JavaVirtualMachine_Impl;
+
+class JavaVirtualMachine: private osl::Mutex, public JavaVirtualMachine_Impl
+{
+public:
+ explicit JavaVirtualMachine(
+ com::sun::star::uno::Reference<
+ com::sun::star::uno::XComponentContext > const & rContext);
+
+ // XInitialization
+ virtual void SAL_CALL
+ initialize(com::sun::star::uno::Sequence< com::sun::star::uno::Any > const &
+ rArguments)
+ throw (com::sun::star::uno::Exception);
+
+ // XServiceInfo
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL
+ supportsService(rtl::OUString const & rServiceName)
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (com::sun::star::uno::RuntimeException);
+
+ // XJavaVM
+ virtual com::sun::star::uno::Any SAL_CALL
+ getJavaVM(com::sun::star::uno::Sequence< sal_Int8 > const & rProcessId)
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isVMStarted()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isVMEnabled()
+ throw (com::sun::star::uno::RuntimeException);
+
+ // XJavaThreadRegister_11
+ virtual sal_Bool SAL_CALL isThreadAttached()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL registerThread()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL revokeThread()
+ throw (com::sun::star::uno::RuntimeException);
+
+ // XContainerListener
+ virtual void SAL_CALL
+ disposing(com::sun::star::lang::EventObject const & rSource)
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ elementInserted(com::sun::star::container::ContainerEvent const & rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ elementRemoved(com::sun::star::container::ContainerEvent const & rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual void SAL_CALL
+ elementReplaced(com::sun::star::container::ContainerEvent const & rEvent)
+ throw (com::sun::star::uno::RuntimeException);
+
+private:
+ JavaVirtualMachine(JavaVirtualMachine &); // not implemented
+ void operator =(JavaVirtualMachine); // not implemented
+
+ virtual ~JavaVirtualMachine();
+
+ virtual void SAL_CALL disposing();
+
+ JavaVM * createJavaVM(JVM const & jvm, JNIEnv ** pMainThreadEnv);
+ // throws com::sun::star::uno::RuntimeException
+
+ void registerConfigChangesListener();
+
+ void setINetSettingsInVM(bool set_reset);
+
+ void setUpUnoVirtualMachine(JNIEnv * environment);
+
+ void handleJniException(JNIEnv * environment);
+
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ m_xContext;
+
+ // the following are controlled by the 'this' mutex:
+ bool m_bDisposed;
+ rtl::Reference< jvmaccess::VirtualMachine > m_xVirtualMachine;
+ rtl::Reference< jvmaccess::UnoVirtualMachine > m_xUnoVirtualMachine;
+ JavaVM * m_pJavaVm;
+ // stored as an instance member for backwards compatibility in getJavaVM
+ bool m_bDontCreateJvm;
+ // If the first creation of Java failed and this flag is set then the
+ // next call to getJavaVM throws a RuntimException. This is useful when
+ // the second attempt to create Java might cause a crash.
+ com::sun::star::uno::Reference< com::sun::star::container::XContainer >
+ m_xInetConfiguration;
+ com::sun::star::uno::Reference< com::sun::star::container::XContainer >
+ m_xJavaConfiguration; // for Java settings
+
+ osl::ThreadData m_aAttachGuards;
+};
+
+}
+
+#endif // INCLUDED_STOC_JAVAVM_JAVAVM_HXX
diff --git a/stoc/source/javavm/jen.xml b/stoc/source/javavm/jen.xml
new file mode 100644
index 000000000000..29ceb09db110
--- /dev/null
+++ b/stoc/source/javavm/jen.xml
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> javavm.uno </module-name>
+ <component-description>
+ <author> Kay Ramme </author>
+ <name> com.sun.star.comp.stoc.JavaVirtualMachine </name>
+ <description>
+The Java VM service manages the creation of java vms.
+It takes a look at the UNO runtime and tries to find a java environment.
+If an java environment already exists, no new vm is created, instead
+the existing vm given back.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.java.JavaVirtualMachine </supported-service>
+ <service-dependency> ... </service-dependency>
+ <type>com.sun.star.beans.NamedValue</type>
+ <type>com.sun.star.java.XJavaThreadRegister_11</type>
+ <type>com.sun.star.uri/ExternalUriReferenceTranslator</type>
+ <type>com.sun.star.util.XMacroExpander</type>
+ <type> com.sun.star.java.XJavaVM </type>
+ <type> com.sun.star.java.XJavaVM </type>
+ <type> com.sun.star.container.XNameAccess </type>
+ <type> com.sun.star.container.XContainer </type>
+ <type> com.sun.star.container.XContainerListener </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.WrappedTargetRuntimeException </type>
+ <type> com.sun.star.lang.DisposedException </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XCurrentContext </type>
+ <type> com.sun.star.beans.PropertyValue </type>
+ <type> com.sun.star.task.XInteractionHandler </type>
+ <type> com.sun.star.task.XInteractionRequest </type>
+ <type> com.sun.star.task.XInteractionContinuation </type>
+ <type> com.sun.star.task.XInteractionAbort </type>
+ <type> com.sun.star.task.XInteractionRetry </type>
+ <type> com.sun.star.java.JavaInitializationException </type>
+ <type> com.sun.star.java.JavaDisabledException </type>
+ <type> com.sun.star.java.JavaNotFoundException </type>
+ <type> com.sun.star.java.InvalidJavaSettingsException </type>
+ <type> com.sun.star.java.RestartRequiredException </type>
+ <type> com.sun.star.java.JavaVMCreationFailureException </type>
+ <type> com.sun.star.container.XNameAccess </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> tools </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <project-build-dependency> jvmaccess </project-build-dependency>
+ <project-build-dependency> salhelper </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> tl(COM) </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+ <runtime-module-dependency> jvmaccess3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> salhelper3$(COM) </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/javavm/jvmargs.cxx b/stoc/source/javavm/jvmargs.cxx
new file mode 100644
index 000000000000..8563b46a41f9
--- /dev/null
+++ b/stoc/source/javavm/jvmargs.cxx
@@ -0,0 +1,66 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "jvmargs.hxx"
+#include <rtl/ustring.hxx>
+
+
+#define OUSTR(x) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( x ))
+
+using namespace rtl;
+
+namespace stoc_javavm {
+
+JVM::JVM() throw()//: _enabled(sal_False)
+{
+}
+
+void JVM::pushProp(const OUString & property)
+{
+ sal_Int32 index = property.indexOf((sal_Unicode)'=');
+ if(index > 0)
+ {
+ OUString left = property.copy(0, index).trim();
+ OUString right(property.copy(index + 1).trim());
+ _props.push_back(property);
+ }
+ else
+ { // no '=', could be -X
+ _props.push_back(property);
+ }
+}
+
+
+const ::std::vector< ::rtl::OUString > & JVM::getProperties() const
+{
+ return _props;
+}
+
+}
diff --git a/stoc/source/javavm/jvmargs.hxx b/stoc/source/javavm/jvmargs.hxx
new file mode 100644
index 000000000000..5eae66da9d07
--- /dev/null
+++ b/stoc/source/javavm/jvmargs.hxx
@@ -0,0 +1,58 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+
+#ifndef __JVM_HXX
+#define __JVM_HXX
+
+
+#include <vector>
+#include <rtl/ustring.hxx>
+
+#include "jni.h"
+
+
+extern "C" {
+ typedef jint JNICALL JNI_InitArgs_Type(void *);
+ typedef jint JNICALL JNI_CreateVM_Type(JavaVM **, JNIEnv **, void *);
+
+}
+
+namespace stoc_javavm {
+
+ class JVM {
+ ::std::vector<rtl::OUString> _props;
+
+ public:
+ JVM() throw();
+
+ void pushProp(const ::rtl::OUString & uString);
+ const ::std::vector< ::rtl::OUString> & getProperties() const;
+ };
+}
+
+#endif
diff --git a/stoc/source/javavm/makefile.mk b/stoc/source/javavm/makefile.mk
new file mode 100644
index 000000000000..bcd36e69681e
--- /dev/null
+++ b/stoc/source/javavm/makefile.mk
@@ -0,0 +1,94 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=stoc
+TARGET = javavm.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = jen
+
+.IF "$(SOLAR_JAVA)" == "TRUE"
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# --- Files --------------------------------------------------------
+
+# Kollision zwischen bool.h aus Java und bool.h aus der STL.
+# Das Problem tritt fuer alle Plattformen auf, aber anscheinend stolpert nur der
+# GCC darueber
+.IF "$(COM)" == "GCC"
+CDEFS += -D__SGI_STL_BOOL_H
+.ENDIF
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/javavm.obj \
+ $(SLO)$/jvmargs.obj \
+ $(SLO)$/interact.obj
+
+SHL1TARGET= $(TARGET)
+SHL1VERSIONMAP = $(SOLARENV)/src/component.map
+SHL1STDLIBS= \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB) \
+ $(JVMACCESSLIB) \
+ $(SALHELPERLIB) \
+ $(JVMFWKLIB)
+
+.IF "$(GUI)"=="WNT"
+SHL1STDLIBS += $(ADVAPI32LIB)
+.ENDIF
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1RPATH= URELIB
+
+DEF1NAME= $(SHL1TARGET)
+
+.ELSE # SOLAR_JAVA
+all:
+ @echo Nothing to do: SOLAR_JAVA not set
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/javavm.component
+
+$(MISC)/javavm.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ javavm.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt javavm.component
diff --git a/stoc/source/loader/dllcomponentloader.cxx b/stoc/source/loader/dllcomponentloader.cxx
new file mode 100644
index 000000000000..d50f209718ed
--- /dev/null
+++ b/stoc/source/loader/dllcomponentloader.cxx
@@ -0,0 +1,261 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <stdlib.h>
+#include <osl/file.h>
+#include <vector>
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+#include <osl/module.h>
+#include <rtl/ustring.hxx>
+#include <uno/environment.h>
+#include <uno/mapping.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/shlib.hxx>
+#include <cppuhelper/implbase3.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX__
+#include <cppuhelper/implementationentry.hxx>
+#endif
+#include <cppuhelper/bootstrap.hxx>
+
+#include <com/sun/star/loader/XImplementationLoader.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+#define SERVICENAME "com.sun.star.loader.SharedLibrary"
+#define IMPLNAME "com.sun.star.comp.stoc.DLLComponentLoader"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::loader;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_bootstrap
+{
+Sequence< OUString > loader_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString loader_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+}
+
+namespace stoc_loader
+{
+//*************************************************************************
+// DllComponentLoader
+//*************************************************************************
+class DllComponentLoader
+ : public WeakImplHelper3< XImplementationLoader,
+ XInitialization,
+ XServiceInfo >
+{
+public:
+ DllComponentLoader( const Reference<XComponentContext> & xCtx );
+ ~DllComponentLoader();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& aArguments ) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XImplementationLoader
+ virtual Reference<XInterface> SAL_CALL activate( const OUString& implementationName, const OUString& implementationLoaderUrl, const OUString& locationUrl, const Reference<XRegistryKey>& xKey ) throw(CannotActivateFactoryException, RuntimeException);
+ virtual sal_Bool SAL_CALL writeRegistryInfo( const Reference<XRegistryKey>& xKey, const OUString& implementationLoaderUrl, const OUString& locationUrl ) throw(CannotRegisterImplementationException, RuntimeException);
+
+private:
+ OUString expand_url( OUString const & url )
+ SAL_THROW( (RuntimeException) );
+
+ Reference<XMultiServiceFactory> m_xSMgr;
+};
+
+//*************************************************************************
+DllComponentLoader::DllComponentLoader( const Reference<XComponentContext> & xCtx )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ m_xSMgr.set( xCtx->getServiceManager(), UNO_QUERY );
+}
+
+//*************************************************************************
+DllComponentLoader::~DllComponentLoader()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+//*************************************************************************
+OUString SAL_CALL DllComponentLoader::getImplementationName( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::loader_getImplementationName();
+}
+
+//*************************************************************************
+sal_Bool SAL_CALL DllComponentLoader::supportsService( const OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+//*************************************************************************
+Sequence<OUString> SAL_CALL DllComponentLoader::getSupportedServiceNames( )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::loader_getSupportedServiceNames();
+}
+
+//*************************************************************************
+void DllComponentLoader::initialize( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any >& )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ OSL_ENSURE( 0, "dllcomponentloader::initialize should not be called !" );
+// if( aArgs.getLength() != 1 )
+// {
+// throw IllegalArgumentException();
+// }
+
+// Reference< XMultiServiceFactory > rServiceManager;
+
+// if( aArgs.getConstArray()[0].getValueType().getTypeClass() == TypeClass_INTERFACE )
+// {
+// aArgs.getConstArray()[0] >>= rServiceManager;
+// }
+
+// if( !rServiceManager.is() )
+// {
+// throw IllegalArgumentException();
+// }
+
+// m_xSMgr = rServiceManager;
+}
+
+//==================================================================================================
+OUString DllComponentLoader::expand_url( OUString const & url )
+ SAL_THROW( (RuntimeException) )
+{
+ try
+ {
+ return cppu::bootstrap_expandUri( url );
+ }
+ catch ( IllegalArgumentException & e )
+ {
+ throw RuntimeException( e.Message, e.Context );
+ }
+}
+
+//*************************************************************************
+Reference<XInterface> SAL_CALL DllComponentLoader::activate(
+ const OUString & rImplName, const OUString &, const OUString & rLibName,
+ const Reference< XRegistryKey > & xKey )
+
+ throw(CannotActivateFactoryException, RuntimeException)
+{
+ return loadSharedLibComponentFactory(
+ expand_url( rLibName ), OUString(), rImplName, m_xSMgr, xKey );
+}
+
+
+//*************************************************************************
+sal_Bool SAL_CALL DllComponentLoader::writeRegistryInfo(
+ const Reference< XRegistryKey > & xKey, const OUString &, const OUString & rLibName )
+
+ throw(CannotRegisterImplementationException, RuntimeException)
+{
+ writeSharedLibComponentInfo(
+ expand_url( rLibName ), OUString(), m_xSMgr, xKey );
+ return sal_True;
+}
+}
+
+namespace stoc_bootstrap
+{
+//*************************************************************************
+Reference<XInterface> SAL_CALL DllComponentLoader_CreateInstance( const Reference<XComponentContext> & xCtx ) throw(Exception)
+{
+ Reference<XInterface> xRet;
+
+ XImplementationLoader *pXLoader = (XImplementationLoader *)new stoc_loader::DllComponentLoader(xCtx);
+
+ if (pXLoader)
+ {
+ xRet = Reference<XInterface>::query(pXLoader);
+ }
+
+ return xRet;
+}
+
+}
+
diff --git a/stoc/source/loader/makefile.mk b/stoc/source/loader/makefile.mk
new file mode 100644
index 000000000000..24a39597a8cd
--- /dev/null
+++ b/stoc/source/loader/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = shlibloader
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT= $(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/dllcomponentloader.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/stoc/source/module-description.dtd b/stoc/source/module-description.dtd
new file mode 100644
index 000000000000..279f721de1da
--- /dev/null
+++ b/stoc/source/module-description.dtd
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+
+ Copyright 2000, 2010 Oracle and/or its affiliates.
+
+ OpenOffice.org - a multi-platform office productivity suite
+
+ This file is part of OpenOffice.org.
+
+ OpenOffice.org is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License version 3
+ only, as published by the Free Software Foundation.
+
+ OpenOffice.org is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License version 3 for more details
+ (a copy is included in the LICENSE file that accompanied this code).
+
+ You should have received a copy of the GNU Lesser General Public License
+ version 3 along with OpenOffice.org. If not, see
+ <http://www.openoffice.org/license.html>
+ for a copy of the LGPLv3 License.
+
+-->
+
+<!ENTITY % component-description-optional "reference-docu|service-dependency|type">
+<!ENTITY % module-description-optional "project-build-dependency|runtime-module-dependency|(%component-description-optional;)">
+<!ELEMENT module-description (module-name, component-description*,(%module-description-optional;)* )>
+<!ELEMENT component-description (author,name,description,loader-name,language,status, supported-service+, (%component-description-optional;)* )>
+
+<!ELEMENT author (#PCDATA)>
+<!ELEMENT name (#PCDATA)>
+<!ELEMENT description (#PCDATA)>
+<!ELEMENT reference-docu EMPTY >
+<!ATTLIST reference-docu
+ xmlns:xlink CDATA #FIXED "http://www.w3.org/1999/xlink/Namespace"
+ xlink:type (simple) #FIXED "simple"
+ xlink:href CDATA #REQUIRED
+ xlink:role NMTOKEN #IMPLIED
+ xlink:title CDATA #IMPLIED >
+
+<!ELEMENT module-name (#PCDATA)>
+<!ELEMENT loader-name (#PCDATA)>
+<!ELEMENT supported-service (#PCDATA)>
+<!ELEMENT service-dependency (#PCDATA)>
+<!ELEMENT project-build-dependency (#PCDATA)>
+<!ELEMENT runtime-module-dependency (#PCDATA)>
+<!ELEMENT language (#PCDATA)>
+<!ELEMENT status EMPTY >
+<!ATTLIST status value (under_construction | alpha | beta | final) #REQUIRED>
+<!ELEMENT type (#PCDATA)>
diff --git a/stoc/source/namingservice/makefile.mk b/stoc/source/namingservice/makefile.mk
new file mode 100644
index 000000000000..cc98cdfc3571
--- /dev/null
+++ b/stoc/source/namingservice/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = namingservice.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = namingservice
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/namingservice.obj
+
+SHL1TARGET= $(TARGET)
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map
+
+SHL1DEPN=
+SHL1IMPLIB= i$(TARGET)
+SHL1LIBS= $(SLB)$/$(TARGET).lib
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+SHL1RPATH= URELIB
+
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/namingservice.component
+
+$(MISC)/namingservice.component .ERRREMOVE : \
+ $(SOLARENV)/bin/createcomponent.xslt namingservice.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt namingservice.component
diff --git a/stoc/source/namingservice/namingservice.component b/stoc/source/namingservice/namingservice.component
new file mode 100644
index 000000000000..8450cdee6d7e
--- /dev/null
+++ b/stoc/source/namingservice/namingservice.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.stoc.NamingService">
+ <service name="com.sun.star.uno.NamingService"/>
+ </implementation>
+</component>
diff --git a/stoc/source/namingservice/namingservice.cxx b/stoc/source/namingservice/namingservice.cxx
new file mode 100644
index 000000000000..a2ea1d361202
--- /dev/null
+++ b/stoc/source/namingservice/namingservice.cxx
@@ -0,0 +1,246 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <hash_map>
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+#include <uno/dispatcher.h>
+#include <uno/mapping.hxx>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/component.hxx>
+#include <cppuhelper/implbase2.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+
+#include <com/sun/star/uno/XNamingService.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+using namespace std;
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::registry;
+
+#define SERVICENAME "com.sun.star.uno.NamingService"
+#define IMPLNAME "com.sun.star.comp.stoc.NamingService"
+
+namespace stoc_namingservice
+{
+static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+static Sequence< OUString > ns_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+static OUString ns_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+
+struct equalOWString_Impl
+{
+ sal_Bool operator()(const OUString & s1, const OUString & s2) const
+ { return s1 == s2; }
+};
+
+struct hashOWString_Impl
+{
+ size_t operator()(const OUString & rName) const
+ { return rName.hashCode(); }
+};
+
+typedef hash_map
+<
+ OUString,
+ Reference<XInterface >,
+ hashOWString_Impl,
+ equalOWString_Impl
+> HashMap_OWString_Interface;
+
+//==================================================================================================
+class NamingService_Impl
+ : public WeakImplHelper2 < XServiceInfo, XNamingService >
+{
+ Mutex aMutex;
+ HashMap_OWString_Interface aMap;
+public:
+ NamingService_Impl();
+ ~NamingService_Impl();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName )
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException);
+ static Sequence< OUString > SAL_CALL getSupportedServiceNames_Static()
+ {
+ OUString aStr( OUString::createFromAscii( SERVICENAME ) );
+ return Sequence< OUString >( &aStr, 1 );
+ }
+
+ virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL getRegisteredObject( const ::rtl::OUString& Name ) throw(Exception, RuntimeException);
+ virtual void SAL_CALL registerObject( const ::rtl::OUString& Name, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& Object ) throw(Exception, RuntimeException);
+ virtual void SAL_CALL revokeObject( const ::rtl::OUString& Name ) throw(Exception, RuntimeException);
+};
+
+//==================================================================================================
+static Reference<XInterface> SAL_CALL NamingService_Impl_create( const Reference<XComponentContext> & )
+{
+ return *new NamingService_Impl();
+}
+
+//==================================================================================================
+NamingService_Impl::NamingService_Impl()
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+
+//==================================================================================================
+NamingService_Impl::~NamingService_Impl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XServiceInfo
+OUString NamingService_Impl::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return ns_getImplementationName();
+}
+
+// XServiceInfo
+sal_Bool NamingService_Impl::supportsService( const OUString & rServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ const Sequence< OUString > & rSNL = getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (pArray[nPos] == rServiceName)
+ return sal_True;
+ }
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > NamingService_Impl::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return ns_getSupportedServiceNames();
+}
+
+// XServiceInfo
+Reference< XInterface > NamingService_Impl::getRegisteredObject( const OUString& Name ) throw(Exception, RuntimeException)
+{
+ Guard< Mutex > aGuard( aMutex );
+ Reference< XInterface > xRet;
+ HashMap_OWString_Interface::iterator aIt = aMap.find( Name );
+ if( aIt != aMap.end() )
+ xRet = (*aIt).second;
+ return xRet;
+}
+
+// XServiceInfo
+void NamingService_Impl::registerObject( const OUString& Name, const Reference< XInterface >& Object ) throw(Exception, RuntimeException)
+{
+ Guard< Mutex > aGuard( aMutex );
+ aMap[ Name ] = Object;
+}
+
+// XServiceInfo
+void NamingService_Impl::revokeObject( const OUString& Name ) throw(Exception, RuntimeException)
+{
+ Guard< Mutex > aGuard( aMutex );
+ aMap.erase( Name );
+}
+
+}
+
+using namespace stoc_namingservice;
+static struct ImplementationEntry g_entries[] =
+{
+ {
+ NamingService_Impl_create, ns_getImplementationName,
+ ns_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+}
diff --git a/stoc/source/namingservice/namingservice.xml b/stoc/source/namingservice/namingservice.xml
new file mode 100644
index 000000000000..2b9d9365ea62
--- /dev/null
+++ b/stoc/source/namingservice/namingservice.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> namingservice.uno </module-name>
+ <component-description>
+ <author> Juergen Schmidt </author>
+ <name> com.sun.star.comp.stoc.NamingService </name>
+ <description>
+The naming service allows the registration and retrieval of objects.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> c++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.uno.NamingService </supported-service>
+ <type>com.sun.star.lang.DisposedException</type>
+ <type> com.sun.star.lang.XComponent </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.lang.XInitialization </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XNamingService </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper3$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu3 </runtime-module-dependency>
+ <runtime-module-dependency> sal3 </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/proxy_factory/makefile.mk b/stoc/source/proxy_factory/makefile.mk
new file mode 100644
index 000000000000..23146e678f5a
--- /dev/null
+++ b/stoc/source/proxy_factory/makefile.mk
@@ -0,0 +1,73 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+
+PRJNAME=stoc
+TARGET = proxyfac.uno
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = proxyfac
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/proxyfac.obj
+
+SHL1TARGET=$(TARGET)
+SHL1VERSIONMAP = $(SOLARENV)/src/unloadablecomponent.map
+
+SHL1STDLIBS= \
+ $(CPPULIB) \
+ $(CPPUHELPERLIB) \
+ $(SALLIB)
+
+SHL1DEPN=
+SHL1IMPLIB=i$(TARGET)
+SHL1LIBS=$(SLB)$/$(TARGET).lib
+SHL1DEF=$(MISC)$/$(SHL1TARGET).def
+SHL1RPATH=URELIB
+
+DEF1NAME=$(SHL1TARGET)
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
+ALLTAR : $(MISC)/proxyfac.component
+
+$(MISC)/proxyfac.component .ERRREMOVE : $(SOLARENV)/bin/createcomponent.xslt \
+ proxyfac.component
+ $(XSLTPROC) --nonet --stringparam uri \
+ '$(COMPONENTPREFIX_URE_NATIVE)$(SHL1TARGETN:f)' -o $@ \
+ $(SOLARENV)/bin/createcomponent.xslt proxyfac.component
diff --git a/stoc/source/proxy_factory/proxyfac.component b/stoc/source/proxy_factory/proxyfac.component
new file mode 100644
index 000000000000..bfe2c9c4268a
--- /dev/null
+++ b/stoc/source/proxy_factory/proxyfac.component
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--**********************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+**********************************************************************-->
+
+<component loader="com.sun.star.loader.SharedLibrary"
+ xmlns="http://openoffice.org/2010/uno-components">
+ <implementation name="com.sun.star.comp.reflection.ProxyFactory">
+ <service name="com.sun.star.reflection.ProxyFactory"/>
+ </implementation>
+</component>
diff --git a/stoc/source/proxy_factory/proxyfac.cxx b/stoc/source/proxy_factory/proxyfac.cxx
new file mode 100644
index 000000000000..644f8ecb624c
--- /dev/null
+++ b/stoc/source/proxy_factory/proxyfac.cxx
@@ -0,0 +1,537 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "osl/diagnose.h"
+#include "osl/interlck.h"
+#include "osl/doublecheckedlocking.h"
+#include "osl/mutex.hxx"
+#include "rtl/ref.hxx"
+#include "uno/dispatcher.hxx"
+#include "uno/data.h"
+#include "uno/mapping.hxx"
+#include "uno/environment.hxx"
+#include "typelib/typedescription.hxx"
+#include "cppuhelper/exc_hlp.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "cppuhelper/factory.hxx"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/reflection/XProxyFactory.hpp"
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define SERVICE_NAME "com.sun.star.reflection.ProxyFactory"
+#define IMPL_NAME "com.sun.star.comp.reflection.ProxyFactory"
+
+
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+
+
+namespace
+{
+
+static rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+static OUString proxyfac_getImplementationName()
+{
+ return OUSTR(IMPL_NAME);
+}
+
+static Sequence< OUString > proxyfac_getSupportedServiceNames()
+{
+ OUString str_name = OUSTR(SERVICE_NAME);
+ return Sequence< OUString >( &str_name, 1 );
+}
+
+//==============================================================================
+struct FactoryImpl : public ::cppu::WeakImplHelper2< lang::XServiceInfo,
+ reflection::XProxyFactory >
+{
+ Environment m_uno_env;
+ Environment m_cpp_env;
+ Mapping m_uno2cpp;
+ Mapping m_cpp2uno;
+
+ UnoInterfaceReference binuno_queryInterface(
+ UnoInterfaceReference const & unoI,
+ typelib_InterfaceTypeDescription * pTypeDescr );
+
+ FactoryImpl();
+ virtual ~FactoryImpl();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName )
+ throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+
+ // XProxyFactory
+ virtual Reference< XAggregation > SAL_CALL createProxy(
+ Reference< XInterface > const & xTarget )
+ throw (RuntimeException);
+};
+
+//______________________________________________________________________________
+UnoInterfaceReference FactoryImpl::binuno_queryInterface(
+ UnoInterfaceReference const & unoI,
+ typelib_InterfaceTypeDescription * pTypeDescr )
+{
+ // init queryInterface() td
+ static typelib_TypeDescription * s_pQITD = 0;
+ if (s_pQITD == 0)
+ {
+ ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
+ if (s_pQITD == 0)
+ {
+ typelib_TypeDescription * pTXInterfaceDescr = 0;
+ TYPELIB_DANGER_GET(
+ &pTXInterfaceDescr,
+ ::getCppuType( reinterpret_cast< Reference< XInterface >
+ const * >(0) ).getTypeLibType() );
+ typelib_TypeDescription * pQITD = 0;
+ typelib_typedescriptionreference_getDescription(
+ &pQITD, reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ pTXInterfaceDescr )->ppAllMembers[ 0 ] );
+ TYPELIB_DANGER_RELEASE( pTXInterfaceDescr );
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ s_pQITD = pQITD;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+
+ void * args[ 1 ];
+ args[ 0 ] = &reinterpret_cast< typelib_TypeDescription * >(
+ pTypeDescr )->pWeakRef;
+ uno_Any ret_val, exc_space;
+ uno_Any * exc = &exc_space;
+
+ unoI.dispatch( s_pQITD, &ret_val, args, &exc );
+
+ if (exc == 0)
+ {
+ UnoInterfaceReference ret;
+ if (ret_val.pType->eTypeClass == typelib_TypeClass_INTERFACE)
+ {
+ ret.set( *reinterpret_cast< uno_Interface ** >(ret_val.pData),
+ SAL_NO_ACQUIRE );
+ typelib_typedescriptionreference_release( ret_val.pType );
+ }
+ else
+ {
+ uno_any_destruct( &ret_val, 0 );
+ }
+ return ret;
+ }
+ else
+ {
+ // exception occured:
+ OSL_ENSURE(
+ typelib_typedescriptionreference_isAssignableFrom(
+ ::getCppuType( reinterpret_cast<
+ RuntimeException const * >(0) ).getTypeLibType(),
+ exc->pType ),
+ "### RuntimeException expected!" );
+ Any cpp_exc;
+ uno_type_copyAndConvertData(
+ &cpp_exc, exc, ::getCppuType( &cpp_exc ).getTypeLibType(),
+ m_uno2cpp.get() );
+ uno_any_destruct( exc, 0 );
+ ::cppu::throwException( cpp_exc );
+ OSL_ASSERT( 0 ); // way of no return
+ return UnoInterfaceReference(); // for dummy
+ }
+}
+
+//==============================================================================
+struct ProxyRoot : public ::cppu::OWeakAggObject
+{
+ // XAggregation
+ virtual Any SAL_CALL queryAggregation( Type const & rType )
+ throw (RuntimeException);
+
+ virtual ~ProxyRoot();
+ inline ProxyRoot( ::rtl::Reference< FactoryImpl > const & factory,
+ Reference< XInterface > const & xTarget );
+
+ ::rtl::Reference< FactoryImpl > m_factory;
+
+private:
+ UnoInterfaceReference m_target;
+};
+
+//==============================================================================
+struct binuno_Proxy : public uno_Interface
+{
+ oslInterlockedCount m_nRefCount;
+ ::rtl::Reference< ProxyRoot > m_root;
+ UnoInterfaceReference m_target;
+ OUString m_oid;
+ TypeDescription m_typeDescr;
+
+ inline binuno_Proxy(
+ ::rtl::Reference< ProxyRoot > const & root,
+ UnoInterfaceReference const & target,
+ OUString const & oid, TypeDescription const & typeDescr );
+};
+
+extern "C"
+{
+
+//------------------------------------------------------------------------------
+static void SAL_CALL binuno_proxy_free(
+ uno_ExtEnvironment * pEnv, void * pProxy )
+{
+ (void) pEnv; // avoid warning about unused parameter
+ binuno_Proxy * proxy = static_cast< binuno_Proxy * >(
+ reinterpret_cast< uno_Interface * >( pProxy ) );
+ OSL_ASSERT( proxy->m_root->m_factory->m_uno_env.get()->pExtEnv == pEnv );
+ delete proxy;
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL binuno_proxy_acquire( uno_Interface * pUnoI )
+{
+ binuno_Proxy * that = static_cast< binuno_Proxy * >( pUnoI );
+ if (osl_incrementInterlockedCount( &that->m_nRefCount ) == 1)
+ {
+ // rebirth of zombie
+ uno_ExtEnvironment * uno_env =
+ that->m_root->m_factory->m_uno_env.get()->pExtEnv;
+ OSL_ASSERT( uno_env != 0 );
+ (*uno_env->registerProxyInterface)(
+ uno_env, reinterpret_cast< void ** >( &pUnoI ), binuno_proxy_free,
+ that->m_oid.pData,
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ that->m_typeDescr.get() ) );
+ OSL_ASSERT( that == static_cast< binuno_Proxy * >( pUnoI ) );
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL binuno_proxy_release( uno_Interface * pUnoI )
+{
+ binuno_Proxy * that = static_cast< binuno_Proxy * >( pUnoI );
+ if (osl_decrementInterlockedCount( &that->m_nRefCount ) == 0)
+ {
+ uno_ExtEnvironment * uno_env =
+ that->m_root->m_factory->m_uno_env.get()->pExtEnv;
+ OSL_ASSERT( uno_env != 0 );
+ (*uno_env->revokeInterface)( uno_env, pUnoI );
+ }
+}
+
+//------------------------------------------------------------------------------
+static void SAL_CALL binuno_proxy_dispatch(
+ uno_Interface * pUnoI, const typelib_TypeDescription * pMemberType,
+ void * pReturn, void * pArgs [], uno_Any ** ppException )
+{
+ binuno_Proxy * that = static_cast< binuno_Proxy * >( pUnoI );
+ switch (reinterpret_cast< typelib_InterfaceMemberTypeDescription const * >(
+ pMemberType )->nPosition)
+ {
+ case 0: // queryInterface()
+ {
+ try
+ {
+ Type const & rType =
+ *reinterpret_cast< Type const * >( pArgs[ 0 ] );
+ Any ret( that->m_root->queryInterface( rType ) );
+ uno_type_copyAndConvertData(
+ pReturn, &ret, ::getCppuType( &ret ).getTypeLibType(),
+ that->m_root->m_factory->m_cpp2uno.get() );
+ *ppException = 0; // no exc
+ }
+ catch (RuntimeException &)
+ {
+ Any exc( ::cppu::getCaughtException() );
+ uno_type_any_constructAndConvert(
+ *ppException, const_cast< void * >(exc.getValue()),
+ exc.getValueTypeRef(),
+ that->m_root->m_factory->m_cpp2uno.get() );
+ }
+ break;
+ }
+ case 1: // acquire()
+ binuno_proxy_acquire( pUnoI );
+ *ppException = 0; // no exc
+ break;
+ case 2: // release()
+ binuno_proxy_release( pUnoI );
+ *ppException = 0; // no exc
+ break;
+ default:
+ that->m_target.dispatch( pMemberType, pReturn, pArgs, ppException );
+ break;
+ }
+}
+
+}
+
+//______________________________________________________________________________
+inline binuno_Proxy::binuno_Proxy(
+ ::rtl::Reference< ProxyRoot > const & root,
+ UnoInterfaceReference const & target,
+ OUString const & oid, TypeDescription const & typeDescr )
+ : m_nRefCount( 1 ),
+ m_root( root ),
+ m_target( target ),
+ m_oid( oid ),
+ m_typeDescr( typeDescr )
+{
+ uno_Interface::acquire = binuno_proxy_acquire;
+ uno_Interface::release = binuno_proxy_release;
+ uno_Interface::pDispatcher = binuno_proxy_dispatch;
+}
+
+//______________________________________________________________________________
+ProxyRoot::~ProxyRoot()
+{
+}
+
+//______________________________________________________________________________
+inline ProxyRoot::ProxyRoot(
+ ::rtl::Reference< FactoryImpl > const & factory,
+ Reference< XInterface > const & xTarget )
+ : m_factory( factory )
+{
+ m_factory->m_cpp2uno.mapInterface(
+ reinterpret_cast< void ** >( &m_target.m_pUnoI ), xTarget.get(),
+ ::getCppuType( &xTarget ) );
+ OSL_ENSURE( m_target.is(), "### mapping interface failed!" );
+}
+
+//______________________________________________________________________________
+Any ProxyRoot::queryAggregation( Type const & rType )
+ throw (RuntimeException)
+{
+ Any ret( OWeakAggObject::queryAggregation( rType ) );
+ if (! ret.hasValue())
+ {
+ typelib_TypeDescription * pTypeDescr = 0;
+ TYPELIB_DANGER_GET( &pTypeDescr, rType.getTypeLibType() );
+ try
+ {
+ Reference< XInterface > xProxy;
+ uno_ExtEnvironment * cpp_env = m_factory->m_cpp_env.get()->pExtEnv;
+ OSL_ASSERT( cpp_env != 0 );
+
+ // mind a new delegator, calculate current root:
+ Reference< XInterface > xRoot(
+ static_cast< OWeakObject * >(this), UNO_QUERY_THROW );
+ OUString oid;
+ (*cpp_env->getObjectIdentifier)( cpp_env, &oid.pData, xRoot.get() );
+ OSL_ASSERT( oid.getLength() > 0 );
+
+ (*cpp_env->getRegisteredInterface)(
+ cpp_env, reinterpret_cast< void ** >( &xProxy ),
+ oid.pData, reinterpret_cast<
+ typelib_InterfaceTypeDescription * >(pTypeDescr) );
+ if (! xProxy.is())
+ {
+ // perform query on target:
+ UnoInterfaceReference proxy_target(
+ m_factory->binuno_queryInterface(
+ m_target, reinterpret_cast<
+ typelib_InterfaceTypeDescription * >(pTypeDescr) ) );
+ if (proxy_target.is())
+ {
+ // ensure root's object entries:
+ UnoInterfaceReference root;
+ m_factory->m_cpp2uno.mapInterface(
+ reinterpret_cast< void ** >( &root.m_pUnoI ),
+ xRoot.get(), ::getCppuType( &xRoot ) );
+
+ UnoInterfaceReference proxy(
+ // ref count initially 1:
+ new binuno_Proxy( this, proxy_target, oid, pTypeDescr ),
+ SAL_NO_ACQUIRE );
+ uno_ExtEnvironment * uno_env =
+ m_factory->m_uno_env.get()->pExtEnv;
+ OSL_ASSERT( uno_env != 0 );
+ (*uno_env->registerProxyInterface)(
+ uno_env, reinterpret_cast< void ** >( &proxy.m_pUnoI ),
+ binuno_proxy_free, oid.pData,
+ reinterpret_cast< typelib_InterfaceTypeDescription * >(
+ pTypeDescr ) );
+
+ m_factory->m_uno2cpp.mapInterface(
+ reinterpret_cast< void ** >( &xProxy ),
+ proxy.get(), pTypeDescr );
+ }
+ }
+ if (xProxy.is())
+ ret.setValue( &xProxy, pTypeDescr );
+ }
+ catch (...) // finally
+ {
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ throw;
+ }
+ TYPELIB_DANGER_RELEASE( pTypeDescr );
+ }
+ return ret;
+}
+
+//##############################################################################
+
+//______________________________________________________________________________
+FactoryImpl::FactoryImpl()
+{
+ OUString uno = OUSTR(UNO_LB_UNO);
+ OUString cpp = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
+
+ uno_getEnvironment(
+ reinterpret_cast< uno_Environment ** >( &m_uno_env ), uno.pData, 0 );
+ OSL_ENSURE( m_uno_env.is(), "### cannot get binary uno env!" );
+
+ uno_getEnvironment(
+ reinterpret_cast< uno_Environment ** >( &m_cpp_env ), cpp.pData, 0 );
+ OSL_ENSURE( m_cpp_env.is(), "### cannot get C++ uno env!" );
+
+ uno_getMapping(
+ reinterpret_cast< uno_Mapping ** >( &m_uno2cpp ),
+ m_uno_env.get(), m_cpp_env.get(), 0 );
+ OSL_ENSURE( m_uno2cpp.is(), "### cannot get bridge uno <-> C++!" );
+
+ uno_getMapping(
+ reinterpret_cast< uno_Mapping ** >( &m_cpp2uno ),
+ m_cpp_env.get(), m_uno_env.get(), 0 );
+ OSL_ENSURE( m_cpp2uno.is(), "### cannot get bridge C++ <-> uno!" );
+
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+
+//______________________________________________________________________________
+FactoryImpl::~FactoryImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XProxyFactory
+//______________________________________________________________________________
+Reference< XAggregation > FactoryImpl::createProxy(
+ Reference< XInterface > const & xTarget )
+ throw (RuntimeException)
+{
+ return new ProxyRoot( this, xTarget );
+}
+
+// XServiceInfo
+//______________________________________________________________________________
+OUString FactoryImpl::getImplementationName()
+ throw (RuntimeException)
+{
+ return proxyfac_getImplementationName();;
+}
+
+//______________________________________________________________________________
+sal_Bool FactoryImpl::supportsService( const OUString & rServiceName )
+ throw (RuntimeException)
+{
+ Sequence< OUString > const & rSNL = getSupportedServiceNames();
+ OUString const * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (rServiceName.equals( pArray[ nPos ] ))
+ return true;
+ }
+ return false;
+}
+
+//______________________________________________________________________________
+Sequence< OUString > FactoryImpl::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return proxyfac_getSupportedServiceNames();
+}
+
+//==============================================================================
+static Reference< XInterface > SAL_CALL proxyfac_create(
+ Reference< XComponentContext > const & )
+ throw (Exception)
+{
+ Reference< XInterface > xRet;
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ static WeakReference < XInterface > rwInstance;
+ xRet = rwInstance;
+
+ if (! xRet.is())
+ {
+ xRet = static_cast< ::cppu::OWeakObject * >(new FactoryImpl);
+ rwInstance = xRet;
+ }
+ }
+ return xRet;
+}
+
+static ::cppu::ImplementationEntry g_entries [] =
+{
+ {
+ proxyfac_create, proxyfac_getImplementationName,
+ proxyfac_getSupportedServiceNames, ::cppu::createSingleComponentFactory,
+ &g_moduleCount.modCnt, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+}
+
+extern "C"
+{
+
+sal_Bool SAL_CALL component_canUnload( TimeValue * pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount, pTime );
+}
+
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return ::cppu::component_getFactoryHelper(
+ pImplName, pServiceManager, pRegistryKey, g_entries );
+}
+
+}
+
diff --git a/stoc/source/proxy_factory/proxyfac.xml b/stoc/source/proxy_factory/proxyfac.xml
new file mode 100644
index 000000000000..57f175b70d34
--- /dev/null
+++ b/stoc/source/proxy_factory/proxyfac.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> proxyfac.uno </module-name>
+ <component-description>
+ <author> Daniel Boelzle </author>
+ <name> com.sun.star.comp.stoc.ProxyFactory </name>
+ <description>
+Specifies a factory object to create proxy objects.
+These proxy object represent a given target object and can be
+be aggregated. The proxy objects act UNO conform and do NOT provide
+original target interfaces on queryInterface() calls.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.reflection.ProxyFactory </supported-service>
+ <service-dependency> ... </service-dependency>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XSimpleRegistry </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.reflection.XProxyFactory </type>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper2$(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu2 </runtime-module-dependency>
+ <runtime-module-dependency> sal2 </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/registry_tdprovider/base.hxx b/stoc/source/registry_tdprovider/base.hxx
new file mode 100644
index 000000000000..0e2deed76919
--- /dev/null
+++ b/stoc/source/registry_tdprovider/base.hxx
@@ -0,0 +1,647 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STOC_RDBTDP_BASE_HXX
+#define _STOC_RDBTDP_BASE_HXX
+
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <cppuhelper/weak.hxx>
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/implbase2.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+
+#include "registry/refltype.hxx"
+
+#include <list>
+#include <memory>
+#include <vector>
+
+#include <com/sun/star/reflection/XTypeDescription.hpp>
+#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
+#include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
+#include <com/sun/star/reflection/XInterfaceTypeDescription2.hpp>
+#include <com/sun/star/reflection/XCompoundTypeDescription.hpp>
+#include <com/sun/star/reflection/XConstantTypeDescription.hpp>
+#include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
+#include <com/sun/star/reflection/XEnumTypeDescription.hpp>
+#include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
+#include <com/sun/star/reflection/XServiceConstructorDescription.hpp>
+#include <com/sun/star/reflection/XServiceTypeDescription.hpp>
+#include <com/sun/star/reflection/XServiceTypeDescription2.hpp>
+#include <com/sun/star/reflection/XSingletonTypeDescription2.hpp>
+#include <com/sun/star/reflection/XModuleTypeDescription.hpp>
+#include <com/sun/star/reflection/XPublished.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+using namespace std;
+using namespace rtl;
+using namespace osl;
+using namespace cppu;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace com::sun::star::reflection;
+
+//--------------------------------------------------------------------------------------------------
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_rdbtdp
+{
+
+com::sun::star::uno::Reference< XTypeDescription > resolveTypedefs(
+ com::sun::star::uno::Reference< XTypeDescription > const & type);
+
+
+::osl::Mutex & getMutex();
+
+//--------------------------------------------------------------------------------------------------
+
+typedef ::std::list< ::com::sun::star::uno::Reference<
+ ::com::sun::star::registry::XRegistryKey > > RegistryKeyList;
+
+//--------------------------------------------------------------------------------------------------
+
+class RegistryKeyCloser
+{
+public:
+ RegistryKeyCloser( const ::com::sun::star::uno::Reference<
+ ::com::sun::star::registry::XRegistryKey > & xKey )
+ : m_xKey( xKey ) {}
+ ~RegistryKeyCloser()
+ { if ( m_xKey.is() ) { try { if ( m_xKey->isValid() ) m_xKey->closeKey(); } catch (...) {} } }
+
+ void reset() { m_xKey.clear(); }
+private:
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::registry::XRegistryKey > m_xKey;
+};
+
+//--------------------------------------------------------------------------------------------------
+
+// helper to create XTypeDescription instances using typereg::Reader
+// (used from Type Provider and Type Description Enumeration implementation)
+::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescription >
+createTypeDescription(
+ const ::com::sun::star::uno::Sequence< sal_Int8 > & rData,
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess > & xNameAccess,
+ bool bReturnEmptyRefForUnknownType );
+
+
+//--------------------------------------------------------------------------------------------------
+inline sal_Int32 getRTValueAsInt32( const RTConstValue & rVal )
+{
+ switch (rVal.m_type)
+ {
+ case RT_TYPE_BYTE:
+ return rVal.m_value.aByte;
+ case RT_TYPE_INT16:
+ return rVal.m_value.aShort;
+ case RT_TYPE_UINT16:
+ return rVal.m_value.aUShort;
+ case RT_TYPE_INT32:
+ return rVal.m_value.aLong;
+ case RT_TYPE_UINT32:
+ return rVal.m_value.aULong;
+ default:
+ OSL_ENSURE( sal_False, "### unexpected value type!" );
+ return 0;
+ }
+}
+//--------------------------------------------------------------------------------------------------
+inline Any getRTValue( const RTConstValue & rVal )
+{
+ switch (rVal.m_type)
+ {
+ case RT_TYPE_BOOL:
+ return Any( &rVal.m_value.aBool, ::getCppuBooleanType() );
+ case RT_TYPE_BYTE:
+ return Any( &rVal.m_value.aByte, ::getCppuType( (const sal_Int8 *)0 ) );
+ case RT_TYPE_INT16:
+ return Any( &rVal.m_value.aShort, ::getCppuType( (const sal_Int16 *)0 ) );
+ case RT_TYPE_UINT16:
+ return Any( &rVal.m_value.aUShort, ::getCppuType( (const sal_uInt16 *)0 ) );
+ case RT_TYPE_INT32:
+ return Any( &rVal.m_value.aLong, ::getCppuType( (const sal_Int32 *)0 ) );
+ case RT_TYPE_UINT32:
+ return Any( &rVal.m_value.aULong, ::getCppuType( (const sal_uInt32 *)0 ) );
+ case RT_TYPE_INT64:
+ return Any( &rVal.m_value.aHyper, ::getCppuType( (const sal_Int64 *)0 ) );
+ case RT_TYPE_UINT64:
+ return Any( &rVal.m_value.aUHyper, ::getCppuType( (const sal_uInt64 *)0 ) );
+ case RT_TYPE_FLOAT:
+ return Any( &rVal.m_value.aFloat, ::getCppuType( (const float *)0 ) );
+ case RT_TYPE_DOUBLE:
+ return Any( &rVal.m_value.aDouble, ::getCppuType( (const double *)0 ) );
+ case RT_TYPE_STRING:
+ {
+ OUString aStr( rVal.m_value.aString );
+ return Any( &aStr, ::getCppuType( (const OUString *)0 ) );
+ }
+ default:
+ OSL_ENSURE( sal_False, "### unexpected RTValue!" );
+ return Any();
+ }
+}
+
+//==================================================================================================
+class TypeDescriptionImpl : public WeakImplHelper1< XTypeDescription >
+{
+ TypeClass _eTypeClass;
+ OUString _aName;
+
+public:
+ TypeDescriptionImpl( TypeClass eTypeClass, const OUString & rName )
+ : _eTypeClass( eTypeClass )
+ , _aName( rName )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~TypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class InterfaceTypeDescriptionImpl:
+ public WeakImplHelper2< XInterfaceTypeDescription2, XPublished >
+{
+ com::sun::star::uno::Reference< XHierarchicalNameAccess > _xTDMgr;
+ Sequence< sal_Int8 > _aBytes;
+
+ OUString _aName;
+
+ Sequence< OUString > _aBaseTypes;
+ Sequence< com::sun::star::uno::Reference< XTypeDescription > > _xBaseTDs;
+ Sequence< OUString > _aOptionalBaseTypes;
+ Sequence< com::sun::star::uno::Reference< XTypeDescription > >
+ _xOptionalBaseTDs;
+
+ sal_Int32 _nBaseOffset;
+ Sequence<
+ com::sun::star::uno::Reference< XInterfaceMemberTypeDescription > >
+ _members;
+ bool _membersInit;
+
+ bool _published;
+
+ void checkInterfaceType(
+ com::sun::star::uno::Reference< XTypeDescription > const & type);
+
+public:
+ InterfaceTypeDescriptionImpl(
+ const com::sun::star::uno::Reference< XHierarchicalNameAccess > &
+ xTDMgr,
+ const OUString & rName, const Sequence< OUString > & rBaseTypes,
+ const Sequence< OUString > & rOptionalBaseTypes,
+ const Sequence< sal_Int8 > & rBytes, bool published );
+ virtual ~InterfaceTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XInterfaceTypeDescription2
+ virtual Uik SAL_CALL getUik() throw(::com::sun::star::uno::RuntimeException);
+ virtual com::sun::star::uno::Reference< XTypeDescription > SAL_CALL
+ getBaseType() throw(::com::sun::star::uno::RuntimeException);
+ virtual
+ Sequence<
+ com::sun::star::uno::Reference< XInterfaceMemberTypeDescription > >
+ SAL_CALL getMembers() throw(::com::sun::star::uno::RuntimeException);
+
+ virtual Sequence< com::sun::star::uno::Reference< XTypeDescription > >
+ SAL_CALL getBaseTypes() throw (RuntimeException);
+
+ virtual Sequence< com::sun::star::uno::Reference< XTypeDescription > >
+ SAL_CALL getOptionalBaseTypes() throw (RuntimeException);
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return _published; }
+};
+
+//==================================================================================================
+class CompoundTypeDescriptionImpl:
+ public WeakImplHelper2< XCompoundTypeDescription, XPublished >
+{
+ com::sun::star::uno::Reference< XHierarchicalNameAccess > _xTDMgr;
+ TypeClass _eTypeClass;
+ Sequence< sal_Int8 > _aBytes;
+ OUString _aName;
+
+ OUString _aBaseType;
+ com::sun::star::uno::Reference< XTypeDescription > _xBaseTD;
+
+ Sequence< com::sun::star::uno::Reference< XTypeDescription > > * _pMembers;
+ Sequence< OUString > * _pMemberNames;
+
+ bool _published;
+
+public:
+ CompoundTypeDescriptionImpl(
+ const com::sun::star::uno::Reference< XHierarchicalNameAccess > &
+ xTDMgr,
+ TypeClass eTypeClass,
+ const OUString & rName, const OUString & rBaseName,
+ const Sequence< sal_Int8 > & rBytes,
+ bool published )
+ : _xTDMgr( xTDMgr )
+ , _eTypeClass( eTypeClass )
+ , _aBytes( rBytes )
+ , _aName( rName )
+ , _aBaseType( rBaseName )
+ , _pMembers( 0 )
+ , _pMemberNames( 0 )
+ , _published( published )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~CompoundTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XCompoundTypeDescription
+ virtual com::sun::star::uno::Reference< XTypeDescription > SAL_CALL
+ getBaseType() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< com::sun::star::uno::Reference< XTypeDescription > >
+ SAL_CALL getMemberTypes() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getMemberNames() throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return _published; }
+};
+
+//==================================================================================================
+class EnumTypeDescriptionImpl:
+ public WeakImplHelper2< XEnumTypeDescription, XPublished >
+{
+ com::sun::star::uno::Reference< XHierarchicalNameAccess > _xTDMgr;
+ Sequence< sal_Int8 > _aBytes;
+
+ OUString _aName;
+ sal_Int32 _nDefaultValue;
+
+ Sequence< OUString > * _pEnumNames;
+ Sequence< sal_Int32 > * _pEnumValues;
+
+ bool _published;
+
+public:
+ EnumTypeDescriptionImpl(
+ const com::sun::star::uno::Reference< XHierarchicalNameAccess > &
+ xTDMgr,
+ const OUString & rName, sal_Int32 nDefaultValue,
+ const Sequence< sal_Int8 > & rBytes, bool published )
+ : _xTDMgr( xTDMgr )
+ , _aBytes( rBytes )
+ , _aName( rName )
+ , _nDefaultValue( nDefaultValue )
+ , _pEnumNames( 0 )
+ , _pEnumValues( 0 )
+ , _published( published )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~EnumTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XEnumTypeDescription
+ virtual sal_Int32 SAL_CALL getDefaultEnumValue() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getEnumNames() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int32 > SAL_CALL getEnumValues() throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return _published; }
+};
+
+//==================================================================================================
+class TypedefTypeDescriptionImpl:
+ public WeakImplHelper2< XIndirectTypeDescription, XPublished >
+{
+ com::sun::star::uno::Reference< XHierarchicalNameAccess > _xTDMgr;
+ OUString _aName;
+
+ OUString _aRefName;
+ com::sun::star::uno::Reference< XTypeDescription > _xRefTD;
+
+ bool _published;
+
+public:
+ TypedefTypeDescriptionImpl(
+ const com::sun::star::uno::Reference< XHierarchicalNameAccess > &
+ xTDMgr,
+ const OUString & rName, const OUString & rRefName, bool published )
+ : _xTDMgr( xTDMgr )
+ , _aName( rName )
+ , _aRefName( rRefName )
+ , _published( published )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~TypedefTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XIndirectTypeDescription
+ virtual com::sun::star::uno::Reference< XTypeDescription > SAL_CALL
+ getReferencedType() throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return _published; }
+};
+
+//==================================================================================================
+class ServiceTypeDescriptionImpl:
+ public WeakImplHelper2< XServiceTypeDescription2, XPublished >
+{
+ OUString _aName;
+ Sequence< sal_Int8 > _aBytes;
+ com::sun::star::uno::Reference< XHierarchicalNameAccess > _xTDMgr;
+ bool _bInitReferences;
+
+ com::sun::star::uno::Reference< XTypeDescription > _xInterfaceTD;
+ std::auto_ptr<
+ Sequence<
+ com::sun::star::uno::Reference< XServiceConstructorDescription > > >
+ _pCtors;
+ Sequence< com::sun::star::uno::Reference< XServiceTypeDescription > >
+ _aMandatoryServices;
+ Sequence< com::sun::star::uno::Reference< XServiceTypeDescription > >
+ _aOptionalServices;
+ Sequence< com::sun::star::uno::Reference< XInterfaceTypeDescription > >
+ _aMandatoryInterfaces;
+ Sequence< com::sun::star::uno::Reference< XInterfaceTypeDescription > >
+ _aOptionalInterfaces;
+ std::auto_ptr<
+ Sequence< com::sun::star::uno::Reference< XPropertyTypeDescription > > >
+ _pProps;
+
+ bool _published;
+
+public:
+ ServiceTypeDescriptionImpl(
+ const com::sun::star::uno::Reference< XHierarchicalNameAccess > &
+ xTDMgr,
+ const OUString & rName, const Sequence< sal_Int8 > & rBytes,
+ bool published)
+ : _aName( rName ), _aBytes( rBytes ), _xTDMgr( xTDMgr ),
+ _bInitReferences( false ), _published( published )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~ServiceTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL
+ getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL
+ getName()
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XServiceTypeDescription
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XServiceTypeDescription > > SAL_CALL
+ getMandatoryServices()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XServiceTypeDescription > > SAL_CALL
+ getOptionalServices()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XInterfaceTypeDescription > > SAL_CALL
+ getMandatoryInterfaces()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XInterfaceTypeDescription > > SAL_CALL
+ getOptionalInterfaces()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XPropertyTypeDescription > > SAL_CALL
+ getProperties()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ // XServiceTypeDescription2
+ virtual sal_Bool SAL_CALL isSingleInterfaceBased()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Reference< XTypeDescription > SAL_CALL
+ getInterface() throw (::com::sun::star::uno::RuntimeException);
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XServiceConstructorDescription > >
+ SAL_CALL getConstructors()
+ throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return _published; }
+
+private:
+ void getReferences()
+ throw (::com::sun::star::uno::RuntimeException);
+};
+
+//==================================================================================================
+class ModuleTypeDescriptionImpl : public WeakImplHelper1< XModuleTypeDescription >
+{
+ OUString _aName;
+ com::sun::star::uno::Reference< XTypeDescriptionEnumerationAccess > _xTDMgr;
+
+ Sequence< com::sun::star::uno::Reference< XTypeDescription > > * _pMembers;
+
+public:
+ ModuleTypeDescriptionImpl(
+ const com::sun::star::uno::Reference<
+ XTypeDescriptionEnumerationAccess > & xTDMgr,
+ const OUString & rName )
+ : _aName( rName ), _xTDMgr( xTDMgr ), _pMembers( 0 )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~ModuleTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL
+ getTypeClass()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual OUString SAL_CALL
+ getName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XModuleTypeDescription
+ virtual ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescription > > SAL_CALL
+ getMembers()
+ throw ( ::com::sun::star::uno::RuntimeException );
+};
+
+//==================================================================================================
+class ConstantTypeDescriptionImpl : public WeakImplHelper1< XConstantTypeDescription >
+{
+ OUString _aName;
+ Any _aValue;
+
+public:
+ ConstantTypeDescriptionImpl( const OUString & rName,
+ const Any & rValue )
+ : _aName( rName ), _aValue( rValue )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~ConstantTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL
+ getTypeClass()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual OUString SAL_CALL
+ getName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XConstantTypeDescription
+ virtual ::com::sun::star::uno::Any SAL_CALL
+ getConstantValue()
+ throw ( ::com::sun::star::uno::RuntimeException );
+};
+
+//==================================================================================================
+class ConstantsTypeDescriptionImpl:
+ public WeakImplHelper2< XConstantsTypeDescription, XPublished >
+{
+ OUString _aName;
+ Sequence< sal_Int8 > _aBytes;
+ Sequence< com::sun::star::uno::Reference< XConstantTypeDescription > > *
+ _pMembers;
+
+ bool _published;
+
+public:
+ ConstantsTypeDescriptionImpl( const OUString & rName,
+ const Sequence< sal_Int8 > & rBytes,
+ bool published )
+ : _aName( rName ), _aBytes( rBytes), _pMembers( 0 ), _published( published )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~ConstantsTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL
+ getTypeClass()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual OUString SAL_CALL
+ getName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XConstantsTypeDescription
+ virtual
+ Sequence< com::sun::star::uno::Reference< XConstantTypeDescription > >
+ SAL_CALL getConstants() throw ( RuntimeException );
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return _published; }
+};
+
+//==================================================================================================
+class SingletonTypeDescriptionImpl:
+ public WeakImplHelper2< XSingletonTypeDescription2, XPublished >
+{
+ OUString _aName;
+ OUString _aBaseName;
+ com::sun::star::uno::Reference< XHierarchicalNameAccess > _xTDMgr;
+ com::sun::star::uno::Reference< XTypeDescription > _xInterfaceTD;
+ com::sun::star::uno::Reference< XServiceTypeDescription > _xServiceTD;
+
+ bool _published;
+
+ void init();
+
+public:
+ SingletonTypeDescriptionImpl(
+ const com::sun::star::uno::Reference< XHierarchicalNameAccess > &
+ xTDMgr,
+ const OUString & rName, const OUString & rBaseName, bool published )
+ : _aName( rName ), _aBaseName( rBaseName), _xTDMgr( xTDMgr ),
+ _published( published )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~SingletonTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL
+ getTypeClass()
+ throw( ::com::sun::star::uno::RuntimeException );
+ virtual OUString SAL_CALL
+ getName()
+ throw( ::com::sun::star::uno::RuntimeException );
+
+ // XSingletonTypeDescription
+ virtual com::sun::star::uno::Reference< XServiceTypeDescription > SAL_CALL
+ getService() throw ( ::com::sun::star::uno::RuntimeException );
+
+ // XSingletonTypeDescription2
+ virtual sal_Bool SAL_CALL isInterfaceBased()
+ throw (::com::sun::star::uno::RuntimeException);
+ virtual com::sun::star::uno::Reference< XTypeDescription > SAL_CALL
+ getInterface() throw (::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return _published; }
+};
+
+}
+
+#endif /* _STOC_RDBTDP_BASE_HXX */
diff --git a/stoc/source/registry_tdprovider/functiondescription.cxx b/stoc/source/registry_tdprovider/functiondescription.cxx
new file mode 100644
index 000000000000..b771d0843151
--- /dev/null
+++ b/stoc/source/registry_tdprovider/functiondescription.cxx
@@ -0,0 +1,115 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "functiondescription.hxx"
+
+#include "com/sun/star/container/NoSuchElementException.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/reflection/XCompoundTypeDescription.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/TypeClass.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "registry/reader.hxx"
+#include "registry/version.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace css = com::sun::star;
+
+using stoc::registry_tdprovider::FunctionDescription;
+
+FunctionDescription::FunctionDescription(
+ css::uno::Reference< css::container::XHierarchicalNameAccess > const &
+ manager,
+ com::sun::star::uno::Sequence< sal_Int8 > const & bytes,
+ sal_uInt16 index):
+ m_manager(manager), m_bytes(bytes), m_index(index), m_exceptionsInit(false)
+{}
+
+FunctionDescription::~FunctionDescription() {}
+
+css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+FunctionDescription::getExceptions() const {
+ {
+ osl::MutexGuard guard(m_mutex);
+ if (m_exceptionsInit) {
+ return m_exceptions;
+ }
+ }
+ typereg::Reader reader(getReader());
+ sal_uInt16 n = reader.getMethodExceptionCount(m_index);
+ css::uno::Sequence<
+ css::uno::Reference< css::reflection::XCompoundTypeDescription > >
+ exceptions(n);
+ for (sal_uInt16 i = 0; i < n; ++i) {
+ rtl::OUString name(
+ reader.getMethodExceptionTypeName(m_index, i).replace('/', '.'));
+ css::uno::Any any;
+ try {
+ any = m_manager->getByHierarchicalName(name);
+ } catch (css::container::NoSuchElementException & e) {
+ throw new css::uno::RuntimeException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container.NoSuchElementException: "))
+ + e.Message),
+ css::uno::Reference< css::uno::XInterface >()); //TODO
+ }
+ if (!(any >>= exceptions[i])
+ || exceptions[i]->getTypeClass() != css::uno::TypeClass_EXCEPTION)
+ {
+ throw new css::uno::RuntimeException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("not an exception type: "))
+ + name),
+ css::uno::Reference< css::uno::XInterface >()); //TODO
+ }
+ OSL_ASSERT(exceptions[i].is());
+ }
+ osl::MutexGuard guard(m_mutex);
+ if (!m_exceptionsInit) {
+ m_exceptions = exceptions;
+ m_exceptionsInit = true;
+ }
+ return m_exceptions;
+}
+
+typereg::Reader FunctionDescription::getReader() const {
+ return typereg::Reader(
+ m_bytes.getConstArray(), m_bytes.getLength(), false, TYPEREG_VERSION_1);
+}
diff --git a/stoc/source/registry_tdprovider/functiondescription.hxx b/stoc/source/registry_tdprovider/functiondescription.hxx
new file mode 100644
index 000000000000..d61af71b970f
--- /dev/null
+++ b/stoc/source/registry_tdprovider/functiondescription.hxx
@@ -0,0 +1,86 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_registry_tdprovider_functiondescription_hxx
+#define INCLUDED_stoc_source_registry_tdprovider_functiondescription_hxx
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "osl/mutex.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XHierarchicalNameAccess;
+ }
+ namespace reflection {
+ class XCompoundTypeDescription;
+ }
+} } }
+namespace typereg { class Reader; }
+
+namespace stoc { namespace registry_tdprovider {
+
+class FunctionDescription {
+public:
+ FunctionDescription(
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > const &
+ manager,
+ com::sun::star::uno::Sequence< sal_Int8 > const & bytes,
+ sal_uInt16 index);
+
+ ~FunctionDescription();
+
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XCompoundTypeDescription > >
+ getExceptions() const;
+
+protected:
+ typereg::Reader getReader() const;
+
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > m_manager;
+ com::sun::star::uno::Sequence< sal_Int8 > m_bytes;
+ sal_uInt16 m_index;
+
+ mutable osl::Mutex m_mutex;
+ mutable com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XCompoundTypeDescription > >
+ m_exceptions;
+ mutable bool m_exceptionsInit;
+
+private:
+ FunctionDescription(FunctionDescription &); // not implemented
+ void operator =(FunctionDescription); // not implemented
+};
+
+} }
+
+#endif
diff --git a/stoc/source/registry_tdprovider/makefile.mk b/stoc/source/registry_tdprovider/makefile.mk
new file mode 100644
index 000000000000..6b59701541bb
--- /dev/null
+++ b/stoc/source/registry_tdprovider/makefile.mk
@@ -0,0 +1,61 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = regtypeprov
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT= $(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/tdprovider.obj \
+ $(SLO)$/td.obj \
+ $(SLO)$/tdef.obj \
+ $(SLO)$/tdenum.obj \
+ $(SLO)$/tdcomp.obj \
+ $(SLO)$/tdconsts.obj \
+ $(SLO)$/tdiface.obj \
+ $(SLO)$/tdmodule.obj \
+ $(SLO)$/tdprop.obj \
+ $(SLO)$/tdservice.obj \
+ $(SLO)$/tdsingleton.obj \
+ $(SLO)$/rdbtdp_tdenumeration.obj \
+ $(SLO)$/functiondescription.obj \
+ $(SLO)$/methoddescription.obj \
+ $(SLO)$/structtypedescription.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/stoc/source/registry_tdprovider/methoddescription.cxx b/stoc/source/registry_tdprovider/methoddescription.cxx
new file mode 100644
index 000000000000..7301f84248c5
--- /dev/null
+++ b/stoc/source/registry_tdprovider/methoddescription.cxx
@@ -0,0 +1,144 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "methoddescription.hxx"
+
+#include "com/sun/star/container/NoSuchElementException.hpp"
+#include "com/sun/star/container/XHierarchicalNameAccess.hpp"
+#include "com/sun/star/reflection/XParameter.hpp"
+#include "com/sun/star/reflection/XTypeDescription.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/mutex.hxx"
+#include "registry/reader.hxx"
+#include "registry/types.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace css = com::sun::star;
+
+using stoc::registry_tdprovider::MethodDescription;
+
+namespace {
+
+class Parameter: public cppu::WeakImplHelper1< css::reflection::XParameter > {
+public:
+ Parameter(
+ css::uno::Reference< css::container::XHierarchicalNameAccess > const &
+ manager,
+ rtl::OUString const & name, rtl::OUString const & typeName,
+ RTParamMode mode, sal_Int32 position):
+ m_manager(manager), m_name(name),
+ m_typeName(typeName.replace('/', '.')), m_mode(mode),
+ m_position(position) {}
+
+ virtual ~Parameter() {}
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException)
+ { return m_name; }
+
+ virtual css::uno::Reference< css::reflection::XTypeDescription > SAL_CALL
+ getType() throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isIn() throw (css::uno::RuntimeException)
+ { return (m_mode & RT_PARAM_IN) != 0; }
+
+ virtual sal_Bool SAL_CALL isOut() throw (css::uno::RuntimeException)
+ { return (m_mode & RT_PARAM_OUT) != 0; }
+
+ virtual sal_Int32 SAL_CALL getPosition() throw (css::uno::RuntimeException)
+ { return m_position; }
+
+ virtual sal_Bool SAL_CALL isRestParameter()
+ throw (css::uno::RuntimeException)
+ { return (m_mode & RT_PARAM_REST) != 0; }
+
+private:
+ Parameter(Parameter &); // not implemented
+ void operator =(Parameter); // not implemented
+
+ css::uno::Reference< css::container::XHierarchicalNameAccess > m_manager;
+ rtl::OUString m_name;
+ rtl::OUString m_typeName;
+ RTParamMode m_mode;
+ sal_Int32 m_position;
+};
+
+css::uno::Reference< css::reflection::XTypeDescription > Parameter::getType()
+ throw (css::uno::RuntimeException)
+{
+ try {
+ return css::uno::Reference< css::reflection::XTypeDescription >(
+ m_manager->getByHierarchicalName(m_typeName),
+ css::uno::UNO_QUERY_THROW);
+ } catch (css::container::NoSuchElementException & e) {
+ throw new css::uno::RuntimeException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container.NoSuchElementException: "))
+ + e.Message),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+}
+
+}
+
+MethodDescription::MethodDescription(
+ css::uno::Reference< css::container::XHierarchicalNameAccess > const &
+ manager,
+ rtl::OUString const & name,
+ com::sun::star::uno::Sequence< sal_Int8 > const & bytes,
+ sal_uInt16 index):
+ FunctionDescription(manager, bytes, index), m_name(name),
+ m_parametersInit(false)
+{}
+
+MethodDescription::~MethodDescription() {}
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XParameter > >
+MethodDescription::getParameters() const {
+ osl::MutexGuard guard(m_mutex);
+ if (!m_parametersInit) {
+ typereg::Reader reader(getReader());
+ sal_uInt16 n = reader.getMethodParameterCount(m_index);
+ m_parameters.realloc(n);
+ for (sal_uInt16 i = 0; i < n; ++i) {
+ m_parameters[i] = new Parameter(
+ m_manager, reader.getMethodParameterName(m_index, i),
+ reader.getMethodParameterTypeName(m_index, i),
+ reader.getMethodParameterFlags(m_index, i), i);
+ }
+ m_parametersInit = true;
+ }
+ return m_parameters;
+}
diff --git a/stoc/source/registry_tdprovider/methoddescription.hxx b/stoc/source/registry_tdprovider/methoddescription.hxx
new file mode 100644
index 000000000000..8d46eced73ac
--- /dev/null
+++ b/stoc/source/registry_tdprovider/methoddescription.hxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_registry_tdprovider_methoddescription_hxx
+#define INCLUDED_stoc_source_registry_tdprovider_methoddescription_hxx
+
+#include "functiondescription.hxx"
+
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star {
+ namespace container {
+ class XHierarchicalNameAccess;
+ }
+ namespace reflection {
+ class XParameter;
+ }
+} } }
+namespace typereg { class Reader; }
+
+namespace stoc { namespace registry_tdprovider {
+
+class MethodDescription: public FunctionDescription {
+public:
+ MethodDescription(
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > const &
+ manager,
+ rtl::OUString const & name,
+ com::sun::star::uno::Sequence< sal_Int8 > const & bytes,
+ sal_uInt16 index);
+
+ ~MethodDescription();
+
+ rtl::OUString getName() const { return m_name; }
+
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XParameter > >
+ getParameters() const;
+
+private:
+ MethodDescription(MethodDescription &); // not implemented
+ void operator =(MethodDescription); // not implemented
+
+ rtl::OUString m_name;
+ mutable com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XParameter > > m_parameters;
+ mutable bool m_parametersInit;
+};
+
+} }
+
+#endif
diff --git a/stoc/source/registry_tdprovider/rdbtdp_tdenumeration.cxx b/stoc/source/registry_tdprovider/rdbtdp_tdenumeration.cxx
new file mode 100644
index 000000000000..7104fbf57d92
--- /dev/null
+++ b/stoc/source/registry_tdprovider/rdbtdp_tdenumeration.cxx
@@ -0,0 +1,643 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+//=========================================================================
+// Todo:
+//
+// - closeKey() calls (according to JSC not really needed because XRegistry
+// implementation closes key in it's dtor.
+//
+//=========================================================================
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include "com/sun/star/reflection/XPublished.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "registry/reader.hxx"
+#include "registry/version.h"
+#include "base.hxx"
+#include "rdbtdp_tdenumeration.hxx"
+
+using namespace com::sun::star;
+
+namespace {
+
+class IndividualConstantTypeDescriptionImpl:
+ public cppu::ImplInheritanceHelper1<
+ stoc_rdbtdp::ConstantTypeDescriptionImpl,
+ com::sun::star::reflection::XPublished >
+{
+public:
+ IndividualConstantTypeDescriptionImpl(
+ rtl::OUString const & name, com::sun::star::uno::Any const & value,
+ bool published):
+ cppu::ImplInheritanceHelper1<
+ stoc_rdbtdp::ConstantTypeDescriptionImpl,
+ com::sun::star::reflection::XPublished >(name, value),
+ m_published(published) {}
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (::com::sun::star::uno::RuntimeException)
+ { return m_published; }
+
+private:
+ bool m_published;
+};
+
+}
+
+namespace stoc_rdbtdp
+{
+
+//=========================================================================
+//=========================================================================
+//
+// TypeDescriptionEnumerationImpl Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+// static
+rtl::Reference< TypeDescriptionEnumerationImpl >
+TypeDescriptionEnumerationImpl::createInstance(
+ const uno::Reference< container::XHierarchicalNameAccess > & xTDMgr,
+ const rtl::OUString & rModuleName,
+ const uno::Sequence< uno::TypeClass > & rTypes,
+ reflection::TypeDescriptionSearchDepth eDepth,
+ const RegistryKeyList & rBaseKeys )
+ throw ( reflection::NoSuchTypeNameException,
+ reflection::InvalidTypeNameException,
+ uno::RuntimeException )
+{
+ if ( rModuleName.getLength() == 0 )
+ {
+ // Enumeration for root requested.
+ return rtl::Reference< TypeDescriptionEnumerationImpl >(
+ new TypeDescriptionEnumerationImpl(
+ xTDMgr, rBaseKeys, rTypes, eDepth ) );
+ }
+
+ RegistryKeyList aModuleKeys;
+
+ rtl::OUString aKey( rModuleName.replace( '.', '/' ) );
+
+ bool bOpenKeySucceeded = false;
+
+ const RegistryKeyList::const_iterator end = rBaseKeys.end();
+ RegistryKeyList::const_iterator it = rBaseKeys.begin();
+
+ while ( it != end )
+ {
+ uno::Reference< registry::XRegistryKey > xKey;
+ try
+ {
+ xKey = (*it)->openKey( aKey );
+ if ( xKey.is() )
+ {
+ // closes key in it's dtor (which is
+ // called even in case of exceptions).
+ RegistryKeyCloser aCloser( xKey );
+
+ if ( xKey->isValid() )
+ {
+ bOpenKeySucceeded = true;
+
+ if ( xKey->getValueType()
+ == registry::RegistryValueType_BINARY )
+ {
+ uno::Sequence< sal_Int8 > aBytes(
+ xKey->getBinaryValue() );
+
+ typereg::Reader aReader(
+ aBytes.getConstArray(), aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+
+ rtl::OUString aName(
+ aReader.getTypeName().replace( '/', '.' ) );
+
+ if ( aReader.getTypeClass() == RT_TYPE_MODULE )
+ {
+ // Do not close xKey!
+ aCloser.reset();
+
+ aModuleKeys.push_back( xKey );
+ }
+ }
+ }
+ else
+ {
+ OSL_ENSURE(
+ sal_False,
+ "TypeDescriptionEnumerationImpl::createInstance "
+ "- Invalid registry key!" );
+ }
+ }
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ // openKey, getValueType, getBinaryValue
+
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::createInstance "
+ "- Caught InvalidRegistryException!" );
+ }
+
+ it++;
+ }
+
+ if ( !bOpenKeySucceeded )
+ throw reflection::NoSuchTypeNameException();
+
+ if ( aModuleKeys.size() == 0 )
+ throw reflection::InvalidTypeNameException();
+
+ return rtl::Reference< TypeDescriptionEnumerationImpl >(
+ new TypeDescriptionEnumerationImpl(
+ xTDMgr, aModuleKeys, rTypes, eDepth ) );
+}
+
+//=========================================================================
+TypeDescriptionEnumerationImpl::TypeDescriptionEnumerationImpl(
+ const uno::Reference< container::XHierarchicalNameAccess > & xTDMgr,
+ const RegistryKeyList & rModuleKeys,
+ const uno::Sequence< uno::TypeClass > & rTypes,
+ reflection::TypeDescriptionSearchDepth eDepth )
+: m_aModuleKeys( rModuleKeys ),
+ m_aTypes( rTypes ),
+ m_eDepth( eDepth ),
+ m_xTDMgr( xTDMgr )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+
+//=========================================================================
+// virtual
+TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl()
+{
+ RegistryKeyList::const_iterator it = m_aModuleKeys.begin();
+ RegistryKeyList::const_iterator end = m_aModuleKeys.end();
+/*
+ @@@ in case we enumerate root and queryMore was never called, then
+ m_aModuleKeys contains open root keys which where passed from
+ tdprov and must not be closed by us.
+
+ while ( it != end )
+ {
+ try
+ {
+ if ( (*it)->isValid() )
+ (*it)->closeKey();
+ }
+ catch (...)
+ {
+ // No exceptions from dtors, please!
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl "
+ "- Caught exception!" );
+ }
+
+ it++;
+ }
+*/
+ it = m_aCurrentModuleSubKeys.begin();
+ end = m_aCurrentModuleSubKeys.end();
+ while ( it != end )
+ {
+ try
+ {
+ if ( (*it)->isValid() )
+ (*it)->closeKey();
+ }
+ catch (Exception &)
+ {
+ // No exceptions from dtors, please!
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl "
+ "- Caught exception!" );
+ }
+
+ it++;
+ }
+
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+//=========================================================================
+//
+// XEnumeration (base of XTypeDescriptionEnumeration) methods
+//
+//=========================================================================
+
+// virtual
+sal_Bool SAL_CALL TypeDescriptionEnumerationImpl::hasMoreElements()
+ throw ( uno::RuntimeException )
+{
+ return queryMore();
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL TypeDescriptionEnumerationImpl::nextElement()
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ return uno::Any( uno::makeAny( nextTypeDescription() ) );
+}
+
+//=========================================================================
+//
+// XTypeDescriptionEnumeration methods
+//
+//=========================================================================
+
+// virtual
+uno::Reference< reflection::XTypeDescription > SAL_CALL
+TypeDescriptionEnumerationImpl::nextTypeDescription()
+ throw ( container::NoSuchElementException,
+ uno::RuntimeException )
+{
+ uno::Reference< reflection::XTypeDescription > xTD( queryNext() );
+
+ if ( xTD.is() )
+ return xTD;
+
+ throw container::NoSuchElementException(
+ rtl::OUString::createFromAscii(
+ "No further elements in enumeration!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+}
+
+//=========================================================================
+bool TypeDescriptionEnumerationImpl::match(
+ RTTypeClass eType1, uno::TypeClass eType2 )
+{
+ switch ( eType1 )
+ {
+ case RT_TYPE_INTERFACE:
+ return eType2 == uno::TypeClass_INTERFACE;
+
+ case RT_TYPE_MODULE:
+ return eType2 == uno::TypeClass_MODULE;
+
+ case RT_TYPE_STRUCT:
+ return eType2 == uno::TypeClass_STRUCT;
+
+ case RT_TYPE_ENUM:
+ return eType2 == uno::TypeClass_ENUM;
+
+ case RT_TYPE_EXCEPTION:
+ return eType2 == uno::TypeClass_EXCEPTION;
+
+ case RT_TYPE_TYPEDEF:
+ return eType2 == uno::TypeClass_TYPEDEF;
+
+ case RT_TYPE_SERVICE:
+ return eType2 == uno::TypeClass_SERVICE;
+
+ case RT_TYPE_SINGLETON:
+ return eType2 == uno::TypeClass_SINGLETON;
+
+ case RT_TYPE_CONSTANTS:
+ return eType2 == uno::TypeClass_CONSTANTS;
+
+ case RT_TYPE_UNION:
+ return eType2 == uno::TypeClass_UNION;
+
+ default:
+ return false;
+ }
+}
+
+//=========================================================================
+bool TypeDescriptionEnumerationImpl::queryMore()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ for (;;)
+ {
+ if ( !m_aCurrentModuleSubKeys.empty() || !m_aTypeDescs.empty() )
+ {
+ // Okay, there is at least one more element.
+ return true;
+ }
+
+ if ( m_aModuleKeys.empty() )
+ {
+ // No module keys (therefore no elements) left.
+ return false;
+ }
+
+ // Note: m_aCurrentModuleSubKeys is always empty AND m_aModuleKeys is
+ // never empty when ariving here.
+ // ==> select new module key, fill m_aCurrentModuleSubKeys
+
+ uno::Sequence< uno::Reference< registry::XRegistryKey > > aKeys;
+ try
+ {
+ aKeys = m_aModuleKeys.front()->openKeys();
+ for ( sal_Int32 n = 0; n < aKeys.getLength(); ++n )
+ {
+ uno::Reference< registry::XRegistryKey > xKey = aKeys[ n ];
+
+ // closes key in it's dtor (which is
+ // called even in case of exceptions).
+ RegistryKeyCloser aCloser( xKey );
+
+ try
+ {
+ if ( xKey->isValid() )
+ {
+ if ( xKey->getValueType()
+ == registry::RegistryValueType_BINARY )
+ {
+ bool bIncludeIt = (m_aTypes.getLength() == 0);
+ bool bNeedTypeClass =
+ ((m_aTypes.getLength() > 0) ||
+ (m_eDepth
+ == reflection::TypeDescriptionSearchDepth_INFINITE));
+ if ( bNeedTypeClass )
+ {
+ uno::Sequence< sal_Int8 > aBytes(
+ xKey->getBinaryValue() );
+
+ typereg::Reader aReader(
+ aBytes.getConstArray(), aBytes.getLength(),
+ false, TYPEREG_VERSION_1);
+
+ RTTypeClass eTypeClass = aReader.getTypeClass();
+
+ // Does key match requested types? Empty
+ // sequence means include all.
+ if ( m_aTypes.getLength() > 0 )
+ {
+ for ( sal_Int32 m = 0;
+ m < m_aTypes.getLength();
+ ++m )
+ {
+ if ( match(eTypeClass, m_aTypes[ m ]) )
+ {
+ bIncludeIt = true;
+ break;
+ }
+ }
+ }
+
+ if ( m_eDepth ==
+ reflection::TypeDescriptionSearchDepth_INFINITE )
+ {
+ if ( eTypeClass == RT_TYPE_MODULE )
+ {
+ // Do not close xKey!
+ aCloser.reset();
+
+ // Remember new module key.
+ m_aModuleKeys.push_back( xKey );
+ }
+ }
+ }
+
+ if ( bIncludeIt )
+ {
+ // Do not close xKey!
+ aCloser.reset();
+
+ m_aCurrentModuleSubKeys.push_back( xKey );
+ }
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryMore "
+ "- Invalid registry key!" );
+ }
+
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ // getValueType, getBinaryValue
+
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryMore "
+ "- Caught InvalidRegistryException!" );
+
+ // Don't stop iterating!
+ }
+ }
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ // openKeys
+
+ for ( sal_Int32 n = 0; n < aKeys.getLength(); ++n )
+ {
+ try
+ {
+ aKeys[ n ]->closeKey();
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryMore "
+ "- Caught InvalidRegistryException!" );
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+ // Special handling for constants contained directly in module.
+ /////////////////////////////////////////////////////////////////////
+
+ // Constants requested?
+ bool bIncludeConstants = ( m_aTypes.getLength() == 0 );
+ if ( !bIncludeConstants )
+ {
+ for ( sal_Int32 m = 0; m < m_aTypes.getLength(); ++m )
+ {
+ if ( m_aTypes[ m ] == uno::TypeClass_CONSTANT )
+ {
+ bIncludeConstants = true;
+ break;
+ }
+ }
+
+ }
+
+ if ( bIncludeConstants )
+ {
+ if ( m_aModuleKeys.front()->getValueType()
+ == registry::RegistryValueType_BINARY )
+ {
+ try
+ {
+ uno::Sequence< sal_Int8 > aBytes(
+ m_aModuleKeys.front()->getBinaryValue() );
+
+ typereg::Reader aReader(
+ aBytes.getConstArray(), aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+
+ if ( aReader.getTypeClass() == RT_TYPE_MODULE )
+ {
+ sal_uInt16 nFields = aReader.getFieldCount();
+ while ( nFields-- )
+ {
+ rtl::OUStringBuffer aName(
+ aReader.getTypeName().replace( '/', '.' ) );
+ aName.appendAscii( "." );
+ aName.append( aReader.getFieldName( nFields ) );
+
+ uno::Any aValue(
+ getRTValue(
+ aReader.getFieldValue( nFields ) ) );
+
+ m_aTypeDescs.push_back(
+ new IndividualConstantTypeDescriptionImpl(
+ aName.makeStringAndClear(), aValue,
+ ( ( aReader.getFieldFlags( nFields )
+ & RT_ACCESS_PUBLISHED )
+ != 0 ) ) );
+ }
+ }
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ // getBinaryValue
+
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryMore "
+ "- Caught InvalidRegistryException!" );
+ }
+ }
+ }
+
+ /////////////////////////////////////////////////////////////////////
+
+/*
+ @@@ m_aModuleKeys.front() may have open sub keys (may be contained in
+ both m_aModuleKeys and m_aCurrentModuleSubKeys)!
+
+ try
+ {
+ m_aModuleKeys.front()->closeKey();
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryMore "
+ "- Caught InvalidRegistryException!" );
+ }
+*/
+ // We're done with this module key, even if there were errors.
+ m_aModuleKeys.pop_front();
+ }
+
+ // unreachable
+}
+
+//=========================================================================
+uno::Reference< reflection::XTypeDescription >
+TypeDescriptionEnumerationImpl::queryNext()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ for (;;)
+ {
+ if ( !queryMore() )
+ return uno::Reference< reflection::XTypeDescription >();
+
+ uno::Reference< reflection::XTypeDescription > xTD;
+
+ if ( !m_aTypeDescs.empty() )
+ {
+ xTD = m_aTypeDescs.front();
+ m_aTypeDescs.pop_front();
+ return xTD;
+ }
+
+ // Note: xKey is already opened.
+ uno::Reference< registry::XRegistryKey >
+ xKey( m_aCurrentModuleSubKeys.front() );
+/*
+ @@@ xKey may still be contained in m_aModuleKeys, too
+
+ // closes key in it's dtor (which is
+ // called even in case of exceptions).
+ RegistryKeyCloser aCloser( xKey );
+*/
+ try
+ {
+ {
+ if ( xKey->isValid() )
+ {
+ if ( xKey->getValueType()
+ == registry::RegistryValueType_BINARY )
+ {
+ uno::Sequence< sal_Int8 > aBytes(
+ xKey->getBinaryValue() );
+
+ xTD = createTypeDescription( aBytes,
+ m_xTDMgr,
+ false );
+ OSL_ENSURE( xTD.is(),
+ "TypeDescriptionEnumerationImpl::queryNext "
+ "- No XTypeDescription created!" );
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryNext "
+ "- Invalid registry key!" );
+ }
+ }
+ }
+ catch ( registry::InvalidRegistryException const & )
+ {
+ // getValueType, getBinaryValue
+
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryNext "
+ "- Caught InvalidRegistryException!" );
+ }
+
+ // We're done with this key, even if there were errors.
+ m_aCurrentModuleSubKeys.pop_front();
+
+ if ( xTD.is() )
+ return xTD;
+
+ // next try...
+
+ } // for (;;)
+}
+
+} // namespace stoc_rdbtdp
+
diff --git a/stoc/source/registry_tdprovider/rdbtdp_tdenumeration.hxx b/stoc/source/registry_tdprovider/rdbtdp_tdenumeration.hxx
new file mode 100644
index 000000000000..7e2c84840aae
--- /dev/null
+++ b/stoc/source/registry_tdprovider/rdbtdp_tdenumeration.hxx
@@ -0,0 +1,116 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STOC_RDBTDP_TDENUMERATION_HXX
+#define _STOC_RDBTDP_TDENUMERATION_HXX
+
+#include <list>
+#include <osl/mutex.hxx>
+#include <rtl/ref.hxx>
+#include <registry/refltype.hxx>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/reflection/InvalidTypeNameException.hpp>
+#include <com/sun/star/reflection/NoSuchTypeNameException.hpp>
+#include <com/sun/star/reflection/TypeDescriptionSearchDepth.hpp>
+#include <com/sun/star/reflection/XTypeDescriptionEnumeration.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/TypeClass.hpp>
+#include <cppuhelper/implbase1.hxx>
+#include "base.hxx"
+
+namespace stoc_rdbtdp
+{
+
+typedef ::std::list< ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescription > > TypeDescriptionList;
+
+class TypeDescriptionEnumerationImpl
+ : public cppu::WeakImplHelper1<
+ com::sun::star::reflection::XTypeDescriptionEnumeration >
+{
+public:
+ static rtl::Reference< TypeDescriptionEnumerationImpl > createInstance(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess > & xTDMgr,
+ const rtl::OUString & rModuleName,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::TypeClass > & rTypes,
+ ::com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
+ const RegistryKeyList & rBaseKeys )
+ throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
+ ::com::sun::star::reflection::InvalidTypeNameException,
+ ::com::sun::star::uno::RuntimeException );
+
+ virtual ~TypeDescriptionEnumerationImpl();
+
+ // XEnumeration (base of XTypeDescriptionEnumeration)
+ virtual sal_Bool SAL_CALL hasMoreElements()
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Any SAL_CALL nextElement()
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XTypeDescriptionEnumeration
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescription > SAL_CALL
+ nextTypeDescription()
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException );
+
+private:
+ // Note: keys must be open (XRegistryKey->openKey(...)).
+ TypeDescriptionEnumerationImpl(
+ const ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess > & xTDMgr,
+ const RegistryKeyList & rModuleKeys,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::TypeClass > & rTypes,
+ ::com::sun::star::reflection::TypeDescriptionSearchDepth eDepth );
+
+ static bool match( ::RTTypeClass eType1,
+ ::com::sun::star::uno::TypeClass eType2 );
+ bool queryMore();
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescription > queryNext();
+
+ // members
+ osl::Mutex m_aMutex;
+ RegistryKeyList m_aModuleKeys;
+ RegistryKeyList m_aCurrentModuleSubKeys;
+ TypeDescriptionList m_aTypeDescs;
+ ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::TypeClass > m_aTypes;
+ ::com::sun::star::reflection::TypeDescriptionSearchDepth m_eDepth;
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::container::XHierarchicalNameAccess > m_xTDMgr;
+};
+
+} // namespace stoc_rdbtdp
+
+#endif /* _STOC_RDBTDP_TDENUMERATION_HXX */
+
diff --git a/stoc/source/registry_tdprovider/structtypedescription.cxx b/stoc/source/registry_tdprovider/structtypedescription.cxx
new file mode 100644
index 000000000000..52cc247fae2e
--- /dev/null
+++ b/stoc/source/registry_tdprovider/structtypedescription.cxx
@@ -0,0 +1,139 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "structtypedescription.hxx"
+
+#include "base.hxx"
+
+#include "com/sun/star/reflection/XTypeDescription.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/TypeClass.hpp"
+#include "cppuhelper/weak.hxx"
+#include "osl/diagnose.h"
+#include "registry/reader.hxx"
+#include "registry/types.h"
+#include "registry/version.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+
+#include <new>
+
+namespace css = com::sun::star;
+using stoc::registry_tdprovider::StructTypeDescription;
+
+StructTypeDescription::StructTypeDescription(
+ css::uno::Reference< css::container::XHierarchicalNameAccess > const &
+ manager,
+ rtl::OUString const & name, rtl::OUString const & baseTypeName,
+ css::uno::Sequence< sal_Int8 > const & data, bool published):
+ m_data(data),
+ m_base(
+ new stoc_rdbtdp::CompoundTypeDescriptionImpl(
+ manager, css::uno::TypeClass_STRUCT, name, baseTypeName, data,
+ published))
+{}
+
+StructTypeDescription::~StructTypeDescription()
+{}
+
+css::uno::TypeClass StructTypeDescription::getTypeClass()
+ throw (css::uno::RuntimeException)
+{
+ return m_base->getTypeClass();
+}
+
+rtl::OUString StructTypeDescription::getName()
+ throw (css::uno::RuntimeException)
+{
+ return m_base->getName();
+}
+
+css::uno::Reference< css::reflection::XTypeDescription >
+StructTypeDescription::getBaseType() throw (css::uno::RuntimeException)
+{
+ return m_base->getBaseType();
+}
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+StructTypeDescription::getMemberTypes() throw (css::uno::RuntimeException)
+{
+ return m_base->getMemberTypes();
+}
+
+css::uno::Sequence< rtl::OUString > StructTypeDescription::getMemberNames()
+ throw (css::uno::RuntimeException)
+{
+ return m_base->getMemberNames();
+}
+
+css::uno::Sequence< rtl::OUString > StructTypeDescription::getTypeParameters()
+ throw (css::uno::RuntimeException)
+{
+ try {
+ typereg::Reader reader(
+ m_data.getConstArray(), m_data.getLength(), false,
+ TYPEREG_VERSION_1);
+ OSL_ASSERT(reader.isValid());
+ sal_uInt16 n = reader.getReferenceCount();
+ css::uno::Sequence< rtl::OUString > parameters(n);
+ for (sal_uInt16 i = 0; i < n; ++i) {
+ if (reader.getReferenceFlags(i) != RT_ACCESS_INVALID
+ || reader.getReferenceSort(i) != RT_REF_TYPE_PARAMETER)
+ {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "type parameter of polymorphic struct type template"
+ " not RT_ACCESS_INVALID/RT_REF_TYPE_PARAMETER")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ parameters[i] = reader.getReferenceTypeName(i);
+ }
+ return parameters;
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("std::bad_alloc")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+}
+
+css::uno::Sequence< css::uno::Reference< css::reflection::XTypeDescription > >
+StructTypeDescription::getTypeArguments() throw (css::uno::RuntimeException)
+{
+ return css::uno::Sequence<
+ css::uno::Reference< css::reflection::XTypeDescription > >();
+}
+
+sal_Bool StructTypeDescription::isPublished() throw (css::uno::RuntimeException)
+{
+ return m_base->isPublished();
+}
diff --git a/stoc/source/registry_tdprovider/structtypedescription.hxx b/stoc/source/registry_tdprovider/structtypedescription.hxx
new file mode 100644
index 000000000000..ba2ce701992e
--- /dev/null
+++ b/stoc/source/registry_tdprovider/structtypedescription.hxx
@@ -0,0 +1,105 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_registry_tdprovider_structtypedescription_hxx
+#define INCLUDED_stoc_source_registry_tdprovider_structtypedescription_hxx
+
+#include "com/sun/star/reflection/XPublished.hpp"
+#include "com/sun/star/reflection/XStructTypeDescription.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "rtl/ref.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star {
+ namespace container { class XHierarchicalNameAccess; }
+ namespace reflection { class XCompoundTypeDescription; }
+} } }
+namespace rtl { class OUString; }
+namespace stoc_rdbtdp { class CompoundTypeDescriptionImpl; }
+
+namespace stoc { namespace registry_tdprovider {
+
+class StructTypeDescription:
+ public cppu::WeakImplHelper2<
+ com::sun::star::reflection::XStructTypeDescription,
+ com::sun::star::reflection::XPublished >
+{
+public:
+ StructTypeDescription(
+ com::sun::star::uno::Reference<
+ com::sun::star::container::XHierarchicalNameAccess > const &
+ manager,
+ rtl::OUString const & name, rtl::OUString const & baseTypeName,
+ com::sun::star::uno::Sequence< sal_Int8 > const & data, bool published);
+
+ virtual ~StructTypeDescription();
+
+ virtual com::sun::star::uno::TypeClass SAL_CALL getTypeClass()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getName()
+ throw (com::sun::star::uno::RuntimeException);
+
+ virtual
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescription >
+ SAL_CALL getBaseType() throw (com::sun::star::uno::RuntimeException);
+
+ virtual
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescription > >
+ SAL_CALL getMemberTypes() throw (com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getMemberNames() throw (com::sun::star::uno::RuntimeException);
+
+ virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getTypeParameters() throw (com::sun::star::uno::RuntimeException);
+
+ virtual
+ com::sun::star::uno::Sequence<
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescription > >
+ SAL_CALL getTypeArguments() throw (com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isPublished()
+ throw (com::sun::star::uno::RuntimeException);
+
+private:
+ StructTypeDescription(StructTypeDescription &); // not implemented
+ void operator =(StructTypeDescription); // not implemented
+
+ com::sun::star::uno::Sequence< sal_Int8 > m_data;
+ rtl::Reference< stoc_rdbtdp::CompoundTypeDescriptionImpl > m_base;
+};
+
+} }
+
+#endif
diff --git a/stoc/source/registry_tdprovider/td.cxx b/stoc/source/registry_tdprovider/td.cxx
new file mode 100644
index 000000000000..27a5a936d54b
--- /dev/null
+++ b/stoc/source/registry_tdprovider/td.cxx
@@ -0,0 +1,80 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "osl/doublecheckedlocking.h"
+#include "base.hxx"
+
+namespace stoc_rdbtdp
+{
+
+//------------------------------------------------------------------------------
+::osl::Mutex & getMutex()
+{
+ static ::osl::Mutex * s_pmutex = 0;
+ if (s_pmutex == 0)
+ {
+ ::osl::MutexGuard guard( ::osl::Mutex::getGlobalMutex() );
+ if (s_pmutex == 0)
+ {
+ static ::osl::Mutex s_mutex;
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ s_pmutex = &s_mutex;
+ }
+ }
+ else
+ {
+ OSL_DOUBLE_CHECKED_LOCKING_MEMORY_BARRIER();
+ }
+ return *s_pmutex;
+}
+
+
+TypeDescriptionImpl::~TypeDescriptionImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass TypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _eTypeClass;
+}
+//__________________________________________________________________________________________________
+OUString TypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+}
+
+
diff --git a/stoc/source/registry_tdprovider/tdcomp.cxx b/stoc/source/registry_tdprovider/tdcomp.cxx
new file mode 100644
index 000000000000..d7ca4887ee7c
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdcomp.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include "base.hxx"
+
+#include "registry/reader.hxx"
+#include "registry/version.h"
+
+namespace stoc_rdbtdp
+{
+
+//__________________________________________________________________________________________________
+CompoundTypeDescriptionImpl::~CompoundTypeDescriptionImpl()
+{
+ delete _pMembers;
+ delete _pMemberNames;
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass CompoundTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _eTypeClass;
+}
+//__________________________________________________________________________________________________
+OUString CompoundTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+// XCompoundTypeDescription
+//__________________________________________________________________________________________________
+Reference< XTypeDescription > CompoundTypeDescriptionImpl::getBaseType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (!_xBaseTD.is() && _aBaseType.getLength())
+ {
+ try
+ {
+ Reference< XTypeDescription > xBaseTD;
+ if (_xTDMgr->getByHierarchicalName( _aBaseType ) >>= xBaseTD)
+ {
+ MutexGuard aGuard( getMutex() );
+ if (! _xBaseTD.is())
+ _xBaseTD = xBaseTD;
+ return _xBaseTD;
+ }
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ // never try again, if no base td was found
+ _aBaseType = OUString();
+ }
+ return _xBaseTD;
+}
+//__________________________________________________________________________________________________
+
+namespace {
+
+class TypeParameter: public WeakImplHelper1< XTypeDescription > {
+public:
+ explicit TypeParameter(OUString const & name): m_name(name) {}
+
+ virtual TypeClass SAL_CALL getTypeClass() throw (RuntimeException)
+ { return TypeClass_UNKNOWN; }
+
+ virtual OUString SAL_CALL getName() throw (RuntimeException)
+ { return m_name; }
+
+private:
+ OUString m_name;
+};
+
+}
+
+Sequence< Reference< XTypeDescription > > CompoundTypeDescriptionImpl::getMemberTypes()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pMembers)
+ {
+ typereg::Reader aReader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+
+ sal_uInt16 nFields = aReader.getFieldCount();
+ Sequence< Reference< XTypeDescription > > * pTempMembers =
+ new Sequence< Reference< XTypeDescription > >( nFields );
+ Reference< XTypeDescription > * pMembers = pTempMembers->getArray();
+
+ while (nFields--)
+ {
+ if ((aReader.getFieldFlags(nFields) & RT_ACCESS_PARAMETERIZED_TYPE)
+ != 0)
+ {
+ pMembers[nFields] = new TypeParameter(
+ aReader.getFieldTypeName(nFields));
+ } else {
+ try {
+ _xTDMgr->getByHierarchicalName(
+ aReader.getFieldTypeName(nFields).replace('/', '.'))
+ >>= pMembers[nFields];
+ } catch (NoSuchElementException &) {}
+ OSL_ENSURE(
+ pMembers[nFields].is(), "### compound member unknown!");
+ }
+ }
+
+ ClearableMutexGuard aGuard( getMutex() );
+ if (_pMembers)
+ {
+ aGuard.clear();
+ delete pTempMembers;
+ }
+ else
+ {
+ _pMembers = pTempMembers;
+ }
+ }
+
+ return *_pMembers;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > CompoundTypeDescriptionImpl::getMemberNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pMemberNames)
+ {
+ typereg::Reader aReader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+
+ sal_uInt16 nFields = aReader.getFieldCount();
+ Sequence< OUString > * pTempMemberNames = new Sequence< OUString >( nFields );
+ OUString * pMemberNames = pTempMemberNames->getArray();
+
+ while (nFields--)
+ {
+ pMemberNames[nFields] = aReader.getFieldName( nFields );
+ }
+
+ ClearableMutexGuard aGuard( getMutex() );
+ if (_pMemberNames)
+ {
+ aGuard.clear();
+ delete pTempMemberNames;
+ }
+ else
+ {
+ _pMemberNames = pTempMemberNames;
+ }
+ }
+ return *_pMemberNames;
+}
+
+}
+
+
diff --git a/stoc/source/registry_tdprovider/tdconsts.cxx b/stoc/source/registry_tdprovider/tdconsts.cxx
new file mode 100644
index 000000000000..fe98f010a3a9
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdconsts.cxx
@@ -0,0 +1,110 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include "registry/reader.hxx"
+#include "registry/version.h"
+#include "base.hxx"
+
+namespace stoc_rdbtdp
+{
+
+//__________________________________________________________________________________________________
+// virtual
+ConstantsTypeDescriptionImpl::~ConstantsTypeDescriptionImpl()
+{
+ delete _pMembers;
+
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+TypeClass ConstantsTypeDescriptionImpl::getTypeClass()
+ throw( RuntimeException )
+{
+ return TypeClass_CONSTANTS;
+}
+//__________________________________________________________________________________________________
+// virtual
+OUString ConstantsTypeDescriptionImpl::getName()
+ throw( RuntimeException )
+{
+ return _aName;
+}
+
+// XConstantsTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+Sequence< Reference< XConstantTypeDescription > > SAL_CALL
+ConstantsTypeDescriptionImpl::getConstants()
+ throw ( RuntimeException )
+{
+ if ( !_pMembers )
+ {
+ typereg::Reader aReader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+
+ sal_uInt16 nFields = aReader.getFieldCount();
+ Sequence< Reference< XConstantTypeDescription > > * pTempConsts
+ = new Sequence< Reference< XConstantTypeDescription > >( nFields );
+ Reference< XConstantTypeDescription > * pConsts
+ = pTempConsts->getArray();
+
+ while ( nFields-- )
+ {
+ rtl::OUStringBuffer aName( _aName );
+ aName.appendAscii( "." );
+ aName.append( aReader.getFieldName( nFields ) );
+
+ Any aValue( getRTValue( aReader.getFieldValue( nFields ) ) );
+
+ pConsts[ nFields ]
+ = new ConstantTypeDescriptionImpl( aName.makeStringAndClear(),
+ aValue );
+ }
+
+ ClearableMutexGuard aGuard( getMutex() );
+ if ( _pMembers )
+ {
+ aGuard.clear();
+ delete pTempConsts;
+ }
+ else
+ {
+ _pMembers = pTempConsts;
+ }
+ }
+ return *_pMembers;
+}
+
+}
diff --git a/stoc/source/registry_tdprovider/tdef.cxx b/stoc/source/registry_tdprovider/tdef.cxx
new file mode 100644
index 000000000000..91b182697122
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdef.cxx
@@ -0,0 +1,82 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include "base.hxx"
+
+namespace stoc_rdbtdp
+{
+TypedefTypeDescriptionImpl::~TypedefTypeDescriptionImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass TypedefTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_TYPEDEF;
+}
+//__________________________________________________________________________________________________
+OUString TypedefTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+// XIndirectTypeDescription
+//__________________________________________________________________________________________________
+Reference< XTypeDescription > TypedefTypeDescriptionImpl::getReferencedType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (!_xRefTD.is() && _aRefName.getLength())
+ {
+ try
+ {
+ Reference< XTypeDescription > xRefTD;
+ if (_xTDMgr->getByHierarchicalName( _aRefName ) >>= xRefTD)
+ {
+ MutexGuard aGuard( getMutex() );
+ if (! _xRefTD.is())
+ _xRefTD = xRefTD;
+ return _xRefTD;
+ }
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ // never try again, if no base td was found
+ _aRefName = OUString();
+ }
+ return _xRefTD;
+}
+
+}
+
+
diff --git a/stoc/source/registry_tdprovider/tdenum.cxx b/stoc/source/registry_tdprovider/tdenum.cxx
new file mode 100644
index 000000000000..d6922ce4226a
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdenum.cxx
@@ -0,0 +1,135 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include "base.hxx"
+
+#include "registry/reader.hxx"
+#include "registry/version.h"
+
+namespace stoc_rdbtdp
+{
+
+//__________________________________________________________________________________________________
+EnumTypeDescriptionImpl::~EnumTypeDescriptionImpl()
+{
+ delete _pEnumNames;
+ delete _pEnumValues;
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass EnumTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_ENUM;
+}
+//__________________________________________________________________________________________________
+OUString EnumTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+// XEnumTypeDescription
+//__________________________________________________________________________________________________
+sal_Int32 EnumTypeDescriptionImpl::getDefaultEnumValue()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _nDefaultValue;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > EnumTypeDescriptionImpl::getEnumNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pEnumNames)
+ {
+ typereg::Reader aReader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+
+ sal_uInt16 nFields = aReader.getFieldCount();
+ Sequence< OUString > * pTempEnumNames = new Sequence< OUString >( nFields );
+ OUString * pEnumNames = pTempEnumNames->getArray();
+
+ while (nFields--)
+ {
+ pEnumNames[nFields] = aReader.getFieldName( nFields );
+ }
+
+ ClearableMutexGuard aGuard( getMutex() );
+ if (_pEnumNames)
+ {
+ aGuard.clear();
+ delete pTempEnumNames;
+ }
+ else
+ {
+ _pEnumNames = pTempEnumNames;
+ }
+ }
+ return *_pEnumNames;
+}
+//__________________________________________________________________________________________________
+Sequence< sal_Int32 > EnumTypeDescriptionImpl::getEnumValues()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (! _pEnumValues)
+ {
+ typereg::Reader aReader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+
+ sal_uInt16 nFields = aReader.getFieldCount();
+ Sequence< sal_Int32 > * pTempEnumValues = new Sequence< sal_Int32 >( nFields );
+ sal_Int32 * pEnumValues = pTempEnumValues->getArray();
+
+ while (nFields--)
+ {
+ pEnumValues[nFields] = getRTValueAsInt32(
+ aReader.getFieldValue( nFields ) );
+ }
+
+ ClearableMutexGuard aGuard( getMutex() );
+ if (_pEnumValues)
+ {
+ aGuard.clear();
+ delete pTempEnumValues;
+ }
+ else
+ {
+ _pEnumValues = pTempEnumValues;
+ }
+ }
+ return *_pEnumValues;
+}
+
+}
+
+
diff --git a/stoc/source/registry_tdprovider/tdiface.cxx b/stoc/source/registry_tdprovider/tdiface.cxx
new file mode 100644
index 000000000000..abee4540773a
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdiface.cxx
@@ -0,0 +1,585 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include "registry/reader.hxx"
+#include "registry/version.h"
+
+#include <com/sun/star/reflection/XInterfaceMemberTypeDescription.hpp>
+#include <com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp>
+#include <com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp>
+#include <com/sun/star/reflection/XMethodParameter.hpp>
+#include <com/sun/star/reflection/XParameter.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "base.hxx"
+#include "functiondescription.hxx"
+#include "methoddescription.hxx"
+
+#include <memory>
+#include <set>
+
+namespace stoc_rdbtdp
+{
+
+//==================================================================================================
+class InterfaceMethodImpl : public WeakImplHelper1< XInterfaceMethodTypeDescription >
+{
+ stoc::registry_tdprovider::MethodDescription _desc;
+
+ Reference< XHierarchicalNameAccess > _xTDMgr;
+
+ OUString _aTypeName;
+
+ OUString _aReturnType;
+ Reference< XTypeDescription > _xReturnTD;
+
+ sal_Bool _bIsOneWay;
+ sal_Int32 _nPosition;
+
+public:
+ InterfaceMethodImpl( const Reference< XHierarchicalNameAccess > & xTDMgr,
+ const OUString & rTypeName,
+ const OUString & rMemberName,
+ const OUString & rReturnType,
+ const Sequence< sal_Int8 > & rBytes,
+ sal_uInt16 nMethodIndex,
+ sal_Bool bIsOneWay,
+ sal_Int32 nPosition )
+ : _desc(xTDMgr, rMemberName, rBytes, nMethodIndex)
+ , _xTDMgr( xTDMgr )
+ , _aTypeName( rTypeName )
+ , _aReturnType( rReturnType )
+ , _bIsOneWay( bIsOneWay )
+ , _nPosition( nPosition )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~InterfaceMethodImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XInterfaceMemberTypeDescription
+ virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException)
+ { return _desc.getName(); }
+ virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException);
+
+ // XInterfaceMethodTypeDescription
+ virtual Reference< XTypeDescription > SAL_CALL getReturnType() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL isOneway() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XMethodParameter > > SAL_CALL getParameters() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< Reference< XTypeDescription > > SAL_CALL getExceptions() throw(::com::sun::star::uno::RuntimeException);
+};
+//__________________________________________________________________________________________________
+InterfaceMethodImpl::~InterfaceMethodImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass InterfaceMethodImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_INTERFACE_METHOD;
+}
+//__________________________________________________________________________________________________
+OUString InterfaceMethodImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aTypeName;
+}
+
+// XInterfaceMemberTypeDescription
+//__________________________________________________________________________________________________
+sal_Int32 InterfaceMethodImpl::getPosition()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _nPosition;
+}
+
+// XInterfaceMethodTypeDescription
+//__________________________________________________________________________________________________
+Reference<XTypeDescription > InterfaceMethodImpl::getReturnType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (!_xReturnTD.is() && _aReturnType.getLength())
+ {
+ try
+ {
+ Reference< XTypeDescription > xReturnTD;
+ if (_xTDMgr->getByHierarchicalName( _aReturnType ) >>= xReturnTD)
+ {
+ MutexGuard aGuard( getMutex() );
+ if (! _xReturnTD.is())
+ _xReturnTD = xReturnTD;
+ return _xReturnTD;
+ }
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ // never try again, if no td was found
+ _aReturnType = OUString();
+ }
+ return _xReturnTD;
+}
+//__________________________________________________________________________________________________
+sal_Bool InterfaceMethodImpl::isOneway()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _bIsOneWay;
+}
+//__________________________________________________________________________________________________
+Sequence<Reference<XMethodParameter > > InterfaceMethodImpl::getParameters()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Sequence< Reference< XParameter > > s1(_desc.getParameters());
+ Sequence< Reference< XMethodParameter > > s2(s1.getLength());
+ for (sal_Int32 i = 0; i < s1.getLength(); ++i) {
+ s2[i] = s1[i].get();
+ }
+ return s2;
+}
+//__________________________________________________________________________________________________
+Sequence<Reference<XTypeDescription > > InterfaceMethodImpl::getExceptions()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Sequence< Reference< XCompoundTypeDescription > > s1(
+ _desc.getExceptions());
+ Sequence< Reference< XTypeDescription > > s2(s1.getLength());
+ for (sal_Int32 i = 0; i < s1.getLength(); ++i) {
+ s2[i] = s1[i].get();
+ }
+ return s2;
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+class InterfaceAttributeImpl : public WeakImplHelper1< XInterfaceAttributeTypeDescription2 >
+{
+ Reference< XHierarchicalNameAccess > _xTDMgr;
+
+ OUString _aTypeName;
+ OUString _aMemberName;
+
+ OUString _aMemberTypeName;
+ Reference< XTypeDescription > _xMemberTD;
+
+ sal_Bool _bReadOnly;
+ sal_Bool _bBound;
+ sal_Int32 _nPosition;
+
+ std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _getter;
+ std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > _setter;
+
+public:
+ InterfaceAttributeImpl(
+ const Reference< XHierarchicalNameAccess > & xTDMgr,
+ const OUString & rTypeName,
+ const OUString & rMemberName,
+ const OUString & rMemberTypeName,
+ sal_Bool bReadOnly,
+ sal_Bool bBound,
+ std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
+ getter,
+ std::auto_ptr< stoc::registry_tdprovider::FunctionDescription > &
+ setter,
+ sal_Int32 nPosition )
+ : _xTDMgr( xTDMgr )
+ , _aTypeName( rTypeName )
+ , _aMemberName( rMemberName )
+ , _aMemberTypeName( rMemberTypeName )
+ , _bReadOnly( bReadOnly )
+ , _bBound( bBound )
+ , _nPosition( nPosition )
+ , _getter( getter )
+ , _setter( setter )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~InterfaceAttributeImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XInterfaceMemberTypeDescription
+ virtual OUString SAL_CALL getMemberName() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getPosition() throw(::com::sun::star::uno::RuntimeException);
+
+ // XInterfaceAttributeTypeDescription2
+ virtual sal_Bool SAL_CALL isReadOnly() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isBound() throw (RuntimeException)
+ { return _bBound; }
+
+ virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL
+ getGetExceptions() throw (RuntimeException)
+ {
+ if (_getter.get() != 0) {
+ return _getter->getExceptions();
+ } else {
+ return Sequence< Reference< XCompoundTypeDescription > >();
+ }
+ }
+
+ virtual Sequence< Reference< XCompoundTypeDescription > > SAL_CALL
+ getSetExceptions() throw (RuntimeException)
+ {
+ if (_setter.get() != 0) {
+ return _setter->getExceptions();
+ } else {
+ return Sequence< Reference< XCompoundTypeDescription > >();
+ }
+ }
+};
+
+InterfaceAttributeImpl::~InterfaceAttributeImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass InterfaceAttributeImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_INTERFACE_ATTRIBUTE;
+}
+//__________________________________________________________________________________________________
+OUString InterfaceAttributeImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aTypeName;
+}
+
+// XInterfaceMemberTypeDescription
+//__________________________________________________________________________________________________
+OUString InterfaceAttributeImpl::getMemberName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aMemberName;
+}
+//__________________________________________________________________________________________________
+sal_Int32 InterfaceAttributeImpl::getPosition()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _nPosition;
+}
+
+// XInterfaceAttributeTypeDescription2
+//__________________________________________________________________________________________________
+sal_Bool InterfaceAttributeImpl::isReadOnly()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _bReadOnly;
+}
+//__________________________________________________________________________________________________
+Reference<XTypeDescription > InterfaceAttributeImpl::getType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (!_xMemberTD.is() && _aMemberTypeName.getLength())
+ {
+ try
+ {
+ Reference< XTypeDescription > xMemberTD;
+ if (_xTDMgr->getByHierarchicalName( _aMemberTypeName ) >>= xMemberTD)
+ {
+ MutexGuard aGuard( getMutex() );
+ if (! _xMemberTD.is())
+ _xMemberTD = xMemberTD;
+ return _xMemberTD;
+ }
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ // never try again, if no td was found
+ _aMemberTypeName = OUString();
+ }
+ return _xMemberTD;
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+void InterfaceTypeDescriptionImpl::checkInterfaceType(
+ Reference< XTypeDescription > const & type)
+{
+ if (resolveTypedefs(type)->getTypeClass() != TypeClass_INTERFACE) {
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Interface base is not an interface type")),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+namespace {
+
+class BaseOffset {
+public:
+ BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc);
+
+ sal_Int32 get() const { return offset; }
+
+private:
+ void calculateBases(Reference< XInterfaceTypeDescription2 > const & desc);
+
+ void calculate(Reference< XInterfaceTypeDescription2 > const & desc);
+
+ std::set< rtl::OUString > set;
+ sal_Int32 offset;
+};
+
+BaseOffset::BaseOffset(Reference< XInterfaceTypeDescription2 > const & desc) {
+ offset = 0;
+ calculateBases(desc);
+}
+
+void BaseOffset::calculateBases(
+ Reference< XInterfaceTypeDescription2 > const & desc)
+{
+ Sequence< Reference < XTypeDescription > > bases(desc->getBaseTypes());
+ for (sal_Int32 i = 0; i < bases.getLength(); ++i) {
+ calculate(
+ Reference< XInterfaceTypeDescription2 >(
+ resolveTypedefs(bases[i]), UNO_QUERY_THROW));
+ }
+}
+
+void BaseOffset::calculate(Reference< XInterfaceTypeDescription2 > const & desc)
+{
+ if (set.insert(desc->getName()).second) {
+ calculateBases(desc);
+ offset += desc->getMembers().getLength();
+ }
+}
+
+}
+
+//__________________________________________________________________________________________________
+InterfaceTypeDescriptionImpl::InterfaceTypeDescriptionImpl(
+ const Reference< XHierarchicalNameAccess > & xTDMgr,
+ const OUString & rName, const Sequence< OUString > & rBaseTypes,
+ const Sequence< OUString > & rOptionalBaseTypes,
+ const Sequence< sal_Int8 > & rBytes, bool published )
+ : _xTDMgr( xTDMgr )
+ , _aBytes( rBytes )
+ , _aName( rName )
+ , _aBaseTypes( rBaseTypes )
+ , _aOptionalBaseTypes( rOptionalBaseTypes )
+ , _membersInit( false )
+ , _published( published )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+InterfaceTypeDescriptionImpl::~InterfaceTypeDescriptionImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass InterfaceTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_INTERFACE;
+}
+//__________________________________________________________________________________________________
+OUString InterfaceTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+// XInterfaceTypeDescription2
+//__________________________________________________________________________________________________
+Reference< XTypeDescription > InterfaceTypeDescriptionImpl::getBaseType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Sequence< Reference< XTypeDescription > > aBaseTypes(getBaseTypes());
+ return aBaseTypes.getLength() >= 1 ? aBaseTypes[0] : 0;
+}
+//__________________________________________________________________________________________________
+Uik SAL_CALL InterfaceTypeDescriptionImpl::getUik()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return Uik();
+}
+//__________________________________________________________________________________________________
+Sequence< Reference< XInterfaceMemberTypeDescription > > InterfaceTypeDescriptionImpl::getMembers()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ osl::MutexGuard guard(getMutex());
+ if (!_membersInit) {
+ _nBaseOffset = BaseOffset(this).get();
+ typereg::Reader reader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+ sal_Int32 count = 0;
+ sal_uInt16 methodCount = reader.getMethodCount();
+ {for (sal_uInt16 i = 0; i < methodCount; ++i) {
+ RTMethodMode flags = reader.getMethodFlags(i);
+ if (flags != RT_MODE_ATTRIBUTE_GET
+ && flags != RT_MODE_ATTRIBUTE_SET)
+ {
+ ++count;
+ }
+ }}
+ sal_uInt16 fieldCount = reader.getFieldCount();
+ count += fieldCount;
+ _members.realloc(count);
+ sal_Int32 index = 0;
+ {for (sal_uInt16 i = 0; i < fieldCount; ++i) {
+ rtl::OUString name(reader.getFieldName(i));
+ rtl::OUStringBuffer typeName(getName());
+ typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
+ typeName.append(name);
+ RTFieldAccess flags = reader.getFieldFlags(i);
+ std::auto_ptr< stoc::registry_tdprovider::FunctionDescription >
+ getter;
+ std::auto_ptr< stoc::registry_tdprovider::FunctionDescription >
+ setter;
+ for (sal_uInt16 j = 0; j < methodCount; ++j) {
+ if (reader.getMethodName(j) == name) {
+ switch (reader.getMethodFlags(j)) {
+ case RT_MODE_ATTRIBUTE_GET:
+ OSL_ASSERT(getter.get() == 0);
+ getter.reset(
+ new stoc::registry_tdprovider::FunctionDescription(
+ _xTDMgr, _aBytes, j));
+ break;
+
+ case RT_MODE_ATTRIBUTE_SET:
+ OSL_ASSERT(setter.get() == 0);
+ setter.reset(
+ new stoc::registry_tdprovider::FunctionDescription(
+ _xTDMgr, _aBytes, j));
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+ }
+ _members[index] = new InterfaceAttributeImpl(
+ _xTDMgr, typeName.makeStringAndClear(), name,
+ reader.getFieldTypeName(i).replace('/', '.'),
+ (flags & RT_ACCESS_READONLY) != 0,
+ (flags & RT_ACCESS_BOUND) != 0, getter, setter,
+ _nBaseOffset + index);
+ ++index;
+ }}
+ {for (sal_uInt16 i = 0; i < methodCount; ++i) {
+ RTMethodMode flags = reader.getMethodFlags(i);
+ if (flags != RT_MODE_ATTRIBUTE_GET
+ && flags != RT_MODE_ATTRIBUTE_SET)
+ {
+ rtl::OUString name(reader.getMethodName(i));
+ rtl::OUStringBuffer typeName(getName());
+ typeName.appendAscii(RTL_CONSTASCII_STRINGPARAM("::"));
+ typeName.append(name);
+ _members[index] = new InterfaceMethodImpl(
+ _xTDMgr, typeName.makeStringAndClear(), name,
+ reader.getMethodReturnTypeName(i).replace('/', '.'),
+ _aBytes, i, flags == RT_MODE_ONEWAY, _nBaseOffset + index);
+ ++index;
+ }
+ }}
+ _membersInit = true;
+ }
+ return _members;
+}
+
+Sequence< Reference< XTypeDescription > >
+InterfaceTypeDescriptionImpl::getBaseTypes() throw (RuntimeException) {
+ MutexGuard guard(getMutex());
+ if (_xBaseTDs.getLength() == 0 && _aBaseTypes.getLength() != 0) {
+ Sequence< Reference< XTypeDescription > > tds(_aBaseTypes.getLength());
+ for (sal_Int32 i = 0; i < _aBaseTypes.getLength(); ++i) {
+ try {
+ _xTDMgr->getByHierarchicalName(_aBaseTypes[i]) >>= tds[i];
+ } catch (NoSuchElementException & e) {
+ throw RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container.NoSuchElementException: "))
+ + e.Message),
+ static_cast< OWeakObject * >(this));
+ }
+ OSL_ASSERT(tds[i].is());
+ checkInterfaceType(tds[i]);
+ }
+ _xBaseTDs = tds;
+ }
+ return _xBaseTDs;
+}
+
+Sequence< Reference< XTypeDescription > >
+InterfaceTypeDescriptionImpl::getOptionalBaseTypes() throw (RuntimeException) {
+ MutexGuard guard(getMutex());
+ if (_xOptionalBaseTDs.getLength() == 0
+ && _aOptionalBaseTypes.getLength() != 0)
+ {
+ Sequence< Reference< XTypeDescription > > tds(
+ _aOptionalBaseTypes.getLength());
+ for (sal_Int32 i = 0; i < _aOptionalBaseTypes.getLength(); ++i) {
+ try {
+ _xTDMgr->getByHierarchicalName(_aOptionalBaseTypes[i])
+ >>= tds[i];
+ } catch (NoSuchElementException & e) {
+ throw RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container.NoSuchElementException: "))
+ + e.Message),
+ static_cast< OWeakObject * >(this));
+ }
+ OSL_ASSERT(tds[i].is());
+ checkInterfaceType(tds[i]);
+ }
+ _xOptionalBaseTDs = tds;
+ }
+ return _xOptionalBaseTDs;
+}
+
+}
diff --git a/stoc/source/registry_tdprovider/tdmodule.cxx b/stoc/source/registry_tdprovider/tdmodule.cxx
new file mode 100644
index 000000000000..50d0a2cfaca3
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdmodule.cxx
@@ -0,0 +1,126 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <vector>
+#include <osl/diagnose.h>
+#include "base.hxx"
+
+namespace stoc_rdbtdp
+{
+
+//__________________________________________________________________________________________________
+// virtual
+ModuleTypeDescriptionImpl::~ModuleTypeDescriptionImpl()
+{
+ delete _pMembers;
+
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+TypeClass ModuleTypeDescriptionImpl::getTypeClass()
+ throw( RuntimeException )
+{
+ return TypeClass_MODULE;
+}
+//__________________________________________________________________________________________________
+// virtual
+OUString ModuleTypeDescriptionImpl::getName()
+ throw( RuntimeException )
+{
+ return _aName;
+}
+
+// XModuleTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+Sequence< Reference< XTypeDescription > > SAL_CALL
+ModuleTypeDescriptionImpl::getMembers()
+ throw ( RuntimeException )
+{
+ if ( !_pMembers )
+ {
+ Reference< XTypeDescriptionEnumeration > xEnum;
+ try
+ {
+ xEnum = _xTDMgr->createTypeDescriptionEnumeration(
+ _aName,
+ Sequence< TypeClass >(),
+ TypeDescriptionSearchDepth_ONE );
+ }
+ catch ( NoSuchTypeNameException const & )
+ {
+ }
+ catch ( InvalidTypeNameException const & )
+ {
+ }
+
+ OSL_ENSURE( xEnum.is(),
+ "ModuleTypeDescriptionImpl::getMembers - No enumeration!" );
+
+ std::vector< Reference< XTypeDescription > > aTDs;
+ while ( xEnum->hasMoreElements() )
+ {
+ try
+ {
+ Reference< XTypeDescription > xTD(
+ xEnum->nextTypeDescription() );
+ aTDs.push_back( xTD );
+ }
+ catch ( NoSuchElementException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "ModuleTypeDescriptionImpl::getMembers - "
+ " Caught NoSuchElementException!" );
+ }
+ }
+
+ Sequence< Reference< XTypeDescription > > * pMembers
+ = new Sequence< Reference< XTypeDescription > >( aTDs.size() );
+ for ( sal_Int32 n = 0; n < pMembers->getLength(); n++ )
+ (*pMembers)[ n ] = aTDs[ n ];
+
+ ClearableMutexGuard aGuard( getMutex() );
+ if ( _pMembers )
+ {
+ aGuard.clear();
+ delete pMembers;
+ }
+ else
+ {
+ _pMembers = pMembers;
+ }
+ }
+ return *_pMembers;
+}
+
+}
diff --git a/stoc/source/registry_tdprovider/tdprop.cxx b/stoc/source/registry_tdprovider/tdprop.cxx
new file mode 100644
index 000000000000..b103b5f06192
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdprop.cxx
@@ -0,0 +1,68 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include "base.hxx"
+
+namespace stoc_rdbtdp
+{
+
+//__________________________________________________________________________________________________
+// virtual
+ConstantTypeDescriptionImpl::~ConstantTypeDescriptionImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+TypeClass ConstantTypeDescriptionImpl::getTypeClass()
+ throw( RuntimeException )
+{
+ return TypeClass_CONSTANT;
+}
+//__________________________________________________________________________________________________
+// virtual
+OUString ConstantTypeDescriptionImpl::getName()
+ throw( RuntimeException )
+{
+ return _aName;
+}
+
+// XConstantTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+Any SAL_CALL ConstantTypeDescriptionImpl::getConstantValue()
+ throw( RuntimeException )
+{
+ return _aValue;
+}
+
+}
diff --git a/stoc/source/registry_tdprovider/tdprovider.cxx b/stoc/source/registry_tdprovider/tdprovider.cxx
new file mode 100644
index 000000000000..2cf26706993c
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdprovider.cxx
@@ -0,0 +1,629 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include <uno/dispatcher.h>
+#include <uno/mapping.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/compbase4.hxx>
+#include <cppuhelper/implbase2.hxx>
+#include <cppuhelper/typeprovider.hxx>
+
+#include <cppuhelper/weakref.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "registry/reader.hxx"
+#include "registry/version.h"
+#include "base.hxx"
+#include "rdbtdp_tdenumeration.hxx"
+#include "structtypedescription.hxx"
+
+#define SERVICENAME "com.sun.star.reflection.TypeDescriptionProvider"
+#define IMPLNAME "com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"
+
+using namespace com::sun::star;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::registry;
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_bootstrap
+{
+uno::Sequence< OUString > rdbtdp_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString rdbtdp_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+}
+
+namespace stoc_rdbtdp
+{
+struct MutexHolder
+{
+ Mutex _aComponentMutex;
+};
+//==================================================================================================
+class ProviderImpl
+ : public MutexHolder
+ , public WeakComponentImplHelper4< XServiceInfo,
+ XHierarchicalNameAccess,
+ XTypeDescriptionEnumerationAccess,
+ XInitialization >
+{
+ // XHierarchicalNameAccess + XTypeDescriptionEnumerationAccess wrapper
+ // first asking the tdmgr instance, then looking up locally
+ class TypeDescriptionManagerWrapper
+ : public ::cppu::WeakImplHelper2<
+ container::XHierarchicalNameAccess,
+ reflection::XTypeDescriptionEnumerationAccess>
+ {
+ com::sun::star::uno::Reference<container::XHierarchicalNameAccess>
+ m_xTDMgr;
+ com::sun::star::uno::Reference<container::XHierarchicalNameAccess>
+ m_xThisProvider;
+ public:
+ TypeDescriptionManagerWrapper( ProviderImpl * pProvider )
+ : m_xTDMgr( pProvider->_xContext->getValueByName(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "/singletons/com.sun.star.reflection."
+ "theTypeDescriptionManager") ) ),
+ UNO_QUERY_THROW ),
+ m_xThisProvider( pProvider )
+ {}
+ // XHierarchicalNameAccess
+ virtual Any SAL_CALL getByHierarchicalName( OUString const & name )
+ throw (container::NoSuchElementException, RuntimeException);
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( OUString const & name )
+ throw (RuntimeException);
+
+ // XTypeDescriptionEnumerationAccess
+ virtual uno::Reference<
+ reflection::XTypeDescriptionEnumeration > SAL_CALL
+ createTypeDescriptionEnumeration(
+ const ::rtl::OUString& moduleName,
+ const uno::Sequence< uno::TypeClass >& types,
+ reflection::TypeDescriptionSearchDepth depth )
+ throw ( reflection::NoSuchTypeNameException,
+ reflection::InvalidTypeNameException,
+ uno::RuntimeException );
+ };
+ friend class TypeDescriptionManagerWrapper;
+
+ com::sun::star::uno::Reference< XComponentContext > _xContext;
+ com::sun::star::uno::WeakReference<XHierarchicalNameAccess> _xTDMgr;
+ com::sun::star::uno::Reference< XHierarchicalNameAccess > getTDMgr() SAL_THROW( () );
+
+ RegistryKeyList _aBaseKeys;
+
+protected:
+ virtual void SAL_CALL disposing();
+
+public:
+ ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext );
+ virtual ~ProviderImpl();
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalNameAccess
+ Any getByHierarchicalNameImpl( const OUString & rName );
+
+ virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeDescriptionEnumerationAccess
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL
+ createTypeDescriptionEnumeration(
+ const ::rtl::OUString& moduleName,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::TypeClass >& types,
+ ::com::sun::star::reflection::TypeDescriptionSearchDepth depth )
+ throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
+ ::com::sun::star::reflection::InvalidTypeNameException,
+ ::com::sun::star::uno::RuntimeException );
+};
+//__________________________________________________________________________________________________
+ProviderImpl::ProviderImpl( const com::sun::star::uno::Reference< XComponentContext > & xContext )
+ : WeakComponentImplHelper4<
+ XServiceInfo, XHierarchicalNameAccess,
+ XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex )
+ , _xContext( xContext )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+ProviderImpl::~ProviderImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+//______________________________________________________________________________
+Any ProviderImpl::TypeDescriptionManagerWrapper::getByHierarchicalName(
+ OUString const & name ) throw (container::NoSuchElementException,
+ RuntimeException)
+{
+ try
+ {
+ // first try tdmgr:
+ return m_xTDMgr->getByHierarchicalName( name );
+ }
+ catch (container::NoSuchElementException &)
+ {
+ // then lookup locally:
+ return m_xThisProvider->getByHierarchicalName( name );
+ }
+}
+
+//______________________________________________________________________________
+sal_Bool ProviderImpl::TypeDescriptionManagerWrapper::hasByHierarchicalName(
+ OUString const & name ) throw (RuntimeException)
+{
+ return m_xTDMgr->hasByHierarchicalName( name ) || m_xThisProvider->hasByHierarchicalName( name );
+}
+
+//______________________________________________________________________________
+uno::Reference< reflection::XTypeDescriptionEnumeration > SAL_CALL
+ProviderImpl::TypeDescriptionManagerWrapper::createTypeDescriptionEnumeration(
+ const ::rtl::OUString& moduleName,
+ const uno::Sequence< uno::TypeClass >& types,
+ reflection::TypeDescriptionSearchDepth depth )
+ throw ( reflection::NoSuchTypeNameException,
+ reflection::InvalidTypeNameException,
+ uno::RuntimeException )
+{
+ try
+ {
+ // first try tdmgr:
+ uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA(
+ m_xTDMgr, uno::UNO_QUERY_THROW );
+ return
+ xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth );
+ }
+ catch (reflection::NoSuchTypeNameException &)
+ {
+ // then lookup locally:
+ uno::Reference< reflection::XTypeDescriptionEnumerationAccess > xTDEA(
+ m_xThisProvider, uno::UNO_QUERY_THROW );
+ return
+ xTDEA->createTypeDescriptionEnumeration( moduleName, types, depth );
+ }
+}
+
+//__________________________________________________________________________________________________
+com::sun::star::uno::Reference< XHierarchicalNameAccess > ProviderImpl::getTDMgr()
+ SAL_THROW( () )
+{
+ // harden weak reference:
+ com::sun::star::uno::Reference<container::XHierarchicalNameAccess> xTDMgr(
+ _xTDMgr );
+ if (! xTDMgr.is())
+ {
+ xTDMgr.set( new TypeDescriptionManagerWrapper(this) );
+ {
+ MutexGuard guard( _aComponentMutex );
+ _xTDMgr = xTDMgr;
+ }
+ }
+ return xTDMgr;
+}
+
+//__________________________________________________________________________________________________
+void ProviderImpl::disposing()
+{
+ _xContext.clear();
+
+ for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() );
+ iPos != _aBaseKeys.end(); ++iPos )
+ {
+ (*iPos)->closeKey();
+ }
+ _aBaseKeys.clear();
+}
+
+// XInitialization
+//__________________________________________________________________________________________________
+void ProviderImpl::initialize(
+ const Sequence< Any > & args )
+ throw (Exception, RuntimeException)
+{
+ // registries to read from
+ Any const * pRegistries = args.getConstArray();
+ for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos )
+ {
+ com::sun::star::uno::Reference< XSimpleRegistry > xRegistry( pRegistries[ nPos ], UNO_QUERY );
+ if (xRegistry.is() && xRegistry->isValid())
+ {
+ com::sun::star::uno::Reference< XRegistryKey > xKey( xRegistry->getRootKey()->openKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("/UCR") ) ) );
+ if (xKey.is() && xKey->isValid())
+ {
+ _aBaseKeys.push_back( xKey );
+ }
+ }
+ }
+}
+
+// XServiceInfo
+//__________________________________________________________________________________________________
+OUString ProviderImpl::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::rdbtdp_getImplementationName();
+}
+//__________________________________________________________________________________________________
+sal_Bool ProviderImpl::supportsService( const OUString & rServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ const Sequence< OUString > & rSNL = getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (pArray[nPos] == rServiceName)
+ return sal_True;
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > ProviderImpl::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::rdbtdp_getSupportedServiceNames();
+}
+
+// XHierarchicalNameAccess
+//__________________________________________________________________________________________________
+Any ProviderImpl::getByHierarchicalNameImpl( const OUString & rName )
+{
+ Any aRet;
+
+ // read from registry
+ OUString aKey( rName.replace( '.', '/' ) );
+ for ( RegistryKeyList::const_iterator iPos( _aBaseKeys.begin() );
+ !aRet.hasValue() && iPos != _aBaseKeys.end(); ++iPos )
+ {
+ try
+ {
+ com::sun::star::uno::Reference< XRegistryKey > xBaseKey( *iPos );
+ com::sun::star::uno::Reference< XRegistryKey > xKey( xBaseKey->openKey( aKey ) );
+ if (xKey.is())
+ {
+ // closes key in it's dtor (which is
+ // called even in case of exceptions).
+ RegistryKeyCloser aCloser( xKey );
+
+ if ( xKey->isValid() )
+ {
+ if (xKey->getValueType() == RegistryValueType_BINARY)
+ {
+ Sequence< sal_Int8 > aBytes( xKey->getBinaryValue() );
+ com::sun::star::uno::Reference< XTypeDescription > xTD(
+ createTypeDescription( aBytes,
+ getTDMgr(),
+ true ) );
+ if ( xTD.is() )
+ aRet <<= xTD;
+ }
+ }
+ }
+ else // might be a constant
+ {
+ sal_Int32 nIndex = aKey.lastIndexOf( '/' );
+ if (nIndex > 0)
+ {
+ // open module
+ com::sun::star::uno::Reference< XRegistryKey > xKey2( xBaseKey->openKey( aKey.copy( 0, nIndex ) ) );
+ if (xKey2.is())
+ {
+ // closes key in it's dtor (which is
+ // called even in case of exceptions).
+ RegistryKeyCloser aCloser( xKey2 );
+
+ if ( xKey2->isValid() )
+ {
+ if (xKey2->getValueType() == RegistryValueType_BINARY)
+ {
+ Sequence< sal_Int8 > aBytes( xKey2->getBinaryValue() );
+ typereg::Reader aReader(
+ aBytes.getConstArray(), aBytes.getLength(),
+ false, TYPEREG_VERSION_1);
+
+ if (aReader.getTypeClass() == RT_TYPE_MODULE ||
+ aReader.getTypeClass() == RT_TYPE_CONSTANTS ||
+ aReader.getTypeClass() == RT_TYPE_ENUM)
+ {
+ OUString aFieldName( aKey.copy( nIndex+1, aKey.getLength() - nIndex -1 ) );
+ sal_Int16 nPos = aReader.getFieldCount();
+ while (nPos--)
+ {
+ if (aFieldName.equals(
+ aReader.getFieldName(nPos)))
+ break;
+ }
+ if (nPos >= 0)
+ aRet = getRTValue(
+ aReader.getFieldValue(nPos));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ catch ( InvalidRegistryException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "ProviderImpl::getByHierarchicalName "
+ "- Caught InvalidRegistryException!" );
+
+ // openKey, closeKey, getValueType, getBinaryValue, isValid
+
+ // Don't stop iteration in this case.
+ }
+ catch ( NoSuchElementException const & )
+ {
+ }
+ }
+ return aRet;
+}
+
+Any SAL_CALL ProviderImpl::getByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException, com::sun::star::container::NoSuchElementException)
+{
+ Any aRet( getByHierarchicalNameImpl( rName ) );
+
+ if ( !aRet.hasValue() )
+ throw NoSuchElementException(
+ rName, static_cast< cppu::OWeakObject * >( this ) );
+
+ return aRet;
+}
+
+//__________________________________________________________________________________________________
+sal_Bool ProviderImpl::hasByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return getByHierarchicalNameImpl( rName ).hasValue();
+}
+
+// XTypeDescriptionEnumerationAccess
+//__________________________________________________________________________________________________
+// virtual
+com::sun::star::uno::Reference< XTypeDescriptionEnumeration > SAL_CALL
+ProviderImpl::createTypeDescriptionEnumeration(
+ const OUString & moduleName,
+ const Sequence< TypeClass > & types,
+ TypeDescriptionSearchDepth depth )
+ throw ( NoSuchTypeNameException,
+ InvalidTypeNameException,
+ RuntimeException )
+{
+ return com::sun::star::uno::Reference< XTypeDescriptionEnumeration >(
+ TypeDescriptionEnumerationImpl::createInstance( getTDMgr(),
+ moduleName,
+ types,
+ depth,
+ _aBaseKeys ).get() );
+}
+
+//__________________________________________________________________________________________________
+// global helper function
+
+com::sun::star::uno::Reference< XTypeDescription > resolveTypedefs(
+ com::sun::star::uno::Reference< XTypeDescription > const & type)
+{
+ com::sun::star::uno::Reference< XTypeDescription > resolved(type);
+ while (resolved->getTypeClass() == TypeClass_TYPEDEF) {
+ resolved = com::sun::star::uno::Reference< XIndirectTypeDescription >(
+ resolved, UNO_QUERY_THROW)->getReferencedType();
+ }
+ return resolved;
+}
+
+com::sun::star::uno::Reference< XTypeDescription > createTypeDescription(
+ const Sequence< sal_Int8 > & rData,
+ const com::sun::star::uno::Reference< XHierarchicalNameAccess > & xNameAccess,
+ bool bReturnEmptyRefForUnknownType )
+{
+ typereg::Reader aReader(
+ rData.getConstArray(), rData.getLength(), false, TYPEREG_VERSION_1);
+
+ OUString aName( aReader.getTypeName().replace( '/', '.' ) );
+
+ switch (aReader.getTypeClass())
+ {
+ case RT_TYPE_INTERFACE:
+ {
+ sal_uInt16 n = aReader.getSuperTypeCount();
+ com::sun::star::uno::Sequence< rtl::OUString > aBaseTypeNames(n);
+ {for (sal_uInt16 i = 0; i < n; ++i) {
+ aBaseTypeNames[i] = aReader.getSuperTypeName(i).replace(
+ '/', '.');
+ }}
+ sal_uInt16 n2 = aReader.getReferenceCount();
+ com::sun::star::uno::Sequence< rtl::OUString >
+ aOptionalBaseTypeNames(n2);
+ {for (sal_uInt16 i = 0; i < n2; ++i) {
+ OSL_ASSERT(
+ aReader.getReferenceSort(i) == RT_REF_SUPPORTS
+ && aReader.getReferenceFlags(i) == RT_ACCESS_OPTIONAL);
+ aOptionalBaseTypeNames[i] = aReader.getReferenceTypeName(i);
+ }}
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new InterfaceTypeDescriptionImpl( xNameAccess,
+ aName,
+ aBaseTypeNames,
+ aOptionalBaseTypeNames,
+ rData,
+ aReader.isPublished() ) );
+ }
+
+ case RT_TYPE_MODULE:
+ {
+ com::sun::star::uno::Reference<
+ XTypeDescriptionEnumerationAccess > xTDEA(
+ xNameAccess, UNO_QUERY );
+
+ OSL_ENSURE( xTDEA.is(),
+ "No XTypeDescriptionEnumerationAccess!" );
+
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new ModuleTypeDescriptionImpl( xTDEA, aName ) );
+ }
+
+ case RT_TYPE_STRUCT:
+ {
+ rtl::OUString superTypeName;
+ if (aReader.getSuperTypeCount() == 1) {
+ superTypeName = aReader.getSuperTypeName(0).replace(
+ '/', '.');
+ }
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new stoc::registry_tdprovider::StructTypeDescription(
+ xNameAccess, aName, superTypeName, rData,
+ aReader.isPublished()));
+ }
+
+ case RT_TYPE_ENUM:
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new EnumTypeDescriptionImpl( xNameAccess,
+ aName,
+ getRTValueAsInt32(
+ aReader.getFieldValue( 0 ) ),
+ rData, aReader.isPublished() ) );
+
+ case RT_TYPE_EXCEPTION:
+ {
+ rtl::OUString superTypeName;
+ if (aReader.getSuperTypeCount() == 1) {
+ superTypeName = aReader.getSuperTypeName(0).replace(
+ '/', '.');
+ }
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new CompoundTypeDescriptionImpl(
+ xNameAccess, TypeClass_EXCEPTION, aName, superTypeName,
+ rData, aReader.isPublished()));
+ }
+
+ case RT_TYPE_TYPEDEF:
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new TypedefTypeDescriptionImpl( xNameAccess,
+ aName,
+ aReader.getSuperTypeName(0)
+ .replace( '/', '.' ),
+ aReader.isPublished() ) );
+ case RT_TYPE_SERVICE:
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new ServiceTypeDescriptionImpl(
+ xNameAccess, aName, rData, aReader.isPublished() ) );
+
+ case RT_TYPE_CONSTANTS:
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new ConstantsTypeDescriptionImpl(
+ aName, rData, aReader.isPublished() ) );
+
+ case RT_TYPE_SINGLETON:
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new SingletonTypeDescriptionImpl( xNameAccess,
+ aName,
+ aReader.getSuperTypeName(0)
+ .replace( '/', '.' ),
+ aReader.isPublished() ) );
+ case RT_TYPE_INVALID:
+ case RT_TYPE_OBJECT: // deprecated and not used
+ case RT_TYPE_UNION: // deprecated and not used
+ OSL_ENSURE( sal_False, "createTypeDescription - Unsupported Type!" );
+ break;
+
+ default:
+ OSL_ENSURE( sal_False, "createTypeDescription - Unknown Type!" );
+ break;
+ }
+
+ // Unknown type.
+
+ if ( bReturnEmptyRefForUnknownType )
+ return com::sun::star::uno::Reference< XTypeDescription >();
+
+ return com::sun::star::uno::Reference< XTypeDescription >(
+ new TypeDescriptionImpl( TypeClass_UNKNOWN, aName ) );
+}
+
+}
+
+namespace stoc_bootstrap
+{
+//==================================================================================================
+com::sun::star::uno::Reference< XInterface > SAL_CALL ProviderImpl_create(
+ com::sun::star::uno::Reference< XComponentContext > const & xContext )
+ throw(::com::sun::star::uno::Exception)
+{
+ return com::sun::star::uno::Reference< XInterface >( *new stoc_rdbtdp::ProviderImpl( xContext ) );
+}
+}
diff --git a/stoc/source/registry_tdprovider/tdservice.cxx b/stoc/source/registry_tdprovider/tdservice.cxx
new file mode 100644
index 000000000000..b8a1de58b1aa
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdservice.cxx
@@ -0,0 +1,565 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include "registry/reader.hxx"
+#include "registry/version.h"
+#include "base.hxx"
+#include "methoddescription.hxx"
+
+#include <memory>
+
+using namespace com::sun::star;
+
+namespace {
+
+class Constructor:
+ public cppu::WeakImplHelper1< XServiceConstructorDescription >
+{
+public:
+ Constructor(
+ Reference< XHierarchicalNameAccess > const & manager,
+ rtl::OUString const & name, Sequence< sal_Int8 > const & bytes,
+ sal_uInt16 index):
+ m_desc(manager, name, bytes, index) {}
+
+ virtual ~Constructor() {}
+
+ virtual sal_Bool SAL_CALL isDefaultConstructor() throw (RuntimeException)
+ { return m_desc.getName().getLength() == 0; }
+
+ virtual rtl::OUString SAL_CALL getName() throw (RuntimeException)
+ { return m_desc.getName(); }
+
+ virtual Sequence< Reference< XParameter > > SAL_CALL getParameters()
+ throw (RuntimeException)
+ { return m_desc.getParameters(); }
+
+ virtual Sequence< Reference<XCompoundTypeDescription > > SAL_CALL
+ getExceptions() throw (RuntimeException)
+ { return m_desc.getExceptions(); }
+
+private:
+ Constructor(Constructor &); // not implemented
+ void operator =(Constructor); // not implemented
+
+ stoc::registry_tdprovider::MethodDescription m_desc;
+};
+
+}
+
+namespace stoc_rdbtdp
+{
+
+//==================================================================================================
+//
+// class PropertyTypeDescriptionImpl
+//
+//==================================================================================================
+class PropertyTypeDescriptionImpl : public WeakImplHelper1< XPropertyTypeDescription >
+{
+ OUString _aName;
+ Reference< XTypeDescription > _xTD;
+ sal_Int16 _nFlags;
+
+public:
+ PropertyTypeDescriptionImpl( const OUString & rName,
+ const Reference< XTypeDescription > & xTD,
+ sal_Int16 nFlags )
+ : _aName( rName ), _xTD( xTD ), _nFlags( nFlags )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~PropertyTypeDescriptionImpl();
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass()
+ throw( RuntimeException );
+ virtual OUString SAL_CALL getName()
+ throw( RuntimeException );
+
+ // XPropertyTypeDescription
+ virtual sal_Int16 SAL_CALL getPropertyFlags()
+ throw ( RuntimeException );
+ virtual Reference< XTypeDescription > SAL_CALL getPropertyTypeDescription()
+ throw ( RuntimeException );
+};
+
+//__________________________________________________________________________________________________
+// virtual
+PropertyTypeDescriptionImpl::~PropertyTypeDescriptionImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+TypeClass PropertyTypeDescriptionImpl::getTypeClass()
+ throw ( RuntimeException )
+{
+ return TypeClass_PROPERTY;
+}
+//__________________________________________________________________________________________________
+// virtual
+OUString PropertyTypeDescriptionImpl::getName()
+ throw ( RuntimeException )
+{
+ return _aName;
+}
+
+// XPropertyTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+sal_Int16 SAL_CALL PropertyTypeDescriptionImpl::getPropertyFlags()
+ throw ( RuntimeException )
+{
+ return _nFlags;
+}
+
+//__________________________________________________________________________________________________
+// virtual
+Reference< XTypeDescription > SAL_CALL
+PropertyTypeDescriptionImpl::getPropertyTypeDescription()
+ throw ( RuntimeException )
+{
+ return _xTD;
+}
+
+//==================================================================================================
+//
+// ServiceTypeDescriptionImpl implementation
+//
+//==================================================================================================
+
+//__________________________________________________________________________________________________
+// virtual
+ServiceTypeDescriptionImpl::~ServiceTypeDescriptionImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+TypeClass ServiceTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_SERVICE;
+}
+//__________________________________________________________________________________________________
+// virtual
+OUString ServiceTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+// XServiceTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+Sequence< Reference< XServiceTypeDescription > > SAL_CALL
+ServiceTypeDescriptionImpl::getMandatoryServices()
+ throw ( RuntimeException )
+{
+ getReferences();
+ return _aMandatoryServices;
+}
+
+//__________________________________________________________________________________________________
+// virtual
+Sequence< Reference< XServiceTypeDescription > > SAL_CALL
+ServiceTypeDescriptionImpl::getOptionalServices()
+ throw ( RuntimeException )
+{
+ getReferences();
+ return _aOptionalServices;
+}
+
+//__________________________________________________________________________________________________
+// virtual
+Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL
+ServiceTypeDescriptionImpl::getMandatoryInterfaces()
+ throw ( RuntimeException )
+{
+ getReferences();
+ return _aMandatoryInterfaces;
+}
+
+//__________________________________________________________________________________________________
+// virtual
+Sequence< Reference< XInterfaceTypeDescription > > SAL_CALL
+ServiceTypeDescriptionImpl::getOptionalInterfaces()
+ throw ( RuntimeException )
+{
+ getReferences();
+ return _aOptionalInterfaces;
+}
+
+//__________________________________________________________________________________________________
+// virtual
+Sequence< Reference< XPropertyTypeDescription > > SAL_CALL
+ServiceTypeDescriptionImpl::getProperties()
+ throw ( RuntimeException )
+{
+ {
+ MutexGuard guard(getMutex());
+ if (_pProps.get() != 0) {
+ return *_pProps;
+ }
+ }
+
+ typereg::Reader aReader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1);
+
+ sal_uInt16 nFields = (sal_uInt16)aReader.getFieldCount();
+ std::auto_ptr< Sequence< Reference< XPropertyTypeDescription > > >
+ pTempProps(
+ new Sequence< Reference< XPropertyTypeDescription > >(nFields));
+ Reference< XPropertyTypeDescription > * pProps = pTempProps->getArray();
+
+ while ( nFields-- )
+ {
+ // name
+ OUStringBuffer aName( _aName );
+ aName.appendAscii( "." );
+ aName.append( aReader.getFieldName( nFields ) );
+
+ // type description
+ Reference< XTypeDescription > xTD;
+ try
+ {
+ _xTDMgr->getByHierarchicalName(
+ aReader.getFieldTypeName( nFields ).replace( '/', '.' ) )
+ >>= xTD;
+ }
+ catch ( NoSuchElementException const & )
+ {
+ }
+ OSL_ENSURE( xTD.is(), "### no type description for property!" );
+
+ // flags
+ RTFieldAccess nFlags = aReader.getFieldFlags( nFields );
+
+ sal_Int16 nAttribs = 0;
+ if ( nFlags & RT_ACCESS_READONLY )
+ nAttribs |= beans::PropertyAttribute::READONLY;
+ if ( nFlags & RT_ACCESS_OPTIONAL )
+ nAttribs |= beans::PropertyAttribute::OPTIONAL;
+ if ( nFlags & RT_ACCESS_MAYBEVOID )
+ nAttribs |= beans::PropertyAttribute::MAYBEVOID;
+ if ( nFlags & RT_ACCESS_BOUND )
+ nAttribs |= beans::PropertyAttribute::BOUND;
+ if ( nFlags & RT_ACCESS_CONSTRAINED )
+ nAttribs |= beans::PropertyAttribute::CONSTRAINED;
+ if ( nFlags & RT_ACCESS_TRANSIENT )
+ nAttribs |= beans::PropertyAttribute::TRANSIENT;
+ if ( nFlags & RT_ACCESS_MAYBEAMBIGUOUS )
+ nAttribs |= beans::PropertyAttribute::MAYBEAMBIGUOUS;
+ if ( nFlags & RT_ACCESS_MAYBEDEFAULT )
+ nAttribs |= beans::PropertyAttribute::MAYBEDEFAULT;
+ if ( nFlags & RT_ACCESS_REMOVEABLE )
+ nAttribs |= beans::PropertyAttribute::REMOVEABLE;
+
+ OSL_ENSURE( !(nFlags & RT_ACCESS_PROPERTY),
+ "### RT_ACCESS_PROPERTY is unexpected here!" );
+ OSL_ENSURE( !(nFlags & RT_ACCESS_ATTRIBUTE),
+ "### RT_ACCESS_ATTRIBUTE is unexpected here!" );
+ OSL_ENSURE( !(nFlags & RT_ACCESS_CONST),
+ "### RT_ACCESS_CONST is unexpected here!" );
+ // always set, unless RT_ACCESS_READONLY is set.
+ //OSL_ENSURE( !(nFlags & RT_ACCESS_READWRITE),
+ // "### RT_ACCESS_READWRITE is unexpected here" );
+ OSL_ENSURE( !(nFlags & RT_ACCESS_DEFAULT),
+ "### RT_ACCESS_DEAFAULT is unexpected here" );
+
+ pProps[ nFields ]
+ = new PropertyTypeDescriptionImpl( aName.makeStringAndClear(),
+ xTD,
+ nAttribs );
+ }
+
+ MutexGuard guard(getMutex());
+ if (_pProps.get() == 0) {
+ _pProps = pTempProps;
+ }
+ return *_pProps;
+}
+
+sal_Bool ServiceTypeDescriptionImpl::isSingleInterfaceBased()
+ throw (RuntimeException)
+{
+ getReferences();
+ return _xInterfaceTD.is();
+}
+
+Reference< XTypeDescription > ServiceTypeDescriptionImpl::getInterface()
+ throw (RuntimeException)
+{
+ getReferences();
+ return _xInterfaceTD;
+}
+
+Sequence< Reference< XServiceConstructorDescription > >
+ServiceTypeDescriptionImpl::getConstructors() throw (RuntimeException) {
+ MutexGuard guard(getMutex());
+ if (_pCtors.get() == 0) {
+ typereg::Reader reader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false,
+ TYPEREG_VERSION_1);
+ sal_uInt16 ctorCount = reader.getMethodCount();
+ std::auto_ptr< Sequence< Reference< XServiceConstructorDescription > > >
+ ctors(
+ new Sequence< Reference< XServiceConstructorDescription > >(
+ ctorCount));
+ for (sal_uInt16 i = 0; i < ctorCount; ++i) {
+ rtl::OUString name(reader.getMethodName(i));
+ if (reader.getMethodFlags(i) != RT_MODE_TWOWAY
+ || (!reader.getMethodReturnTypeName(i).equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("void")))
+ || (name.getLength() == 0
+ && (ctorCount != 1 || reader.getMethodParameterCount(i) != 0
+ || reader.getMethodExceptionCount(i) != 0)))
+ {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Service has bad constructors")),
+ static_cast< OWeakObject * >(this));
+ }
+ (*ctors)[i] = new Constructor(
+ _xTDMgr, reader.getMethodName(i), _aBytes, i);
+ }
+ _pCtors = ctors;
+ }
+ return *_pCtors;
+}
+
+//__________________________________________________________________________________________________
+void ServiceTypeDescriptionImpl::getReferences()
+ throw ( RuntimeException )
+{
+ {
+ MutexGuard guard(getMutex());
+ if (_bInitReferences) {
+ return;
+ }
+ }
+ typereg::Reader aReader(
+ _aBytes.getConstArray(), _aBytes.getLength(), false, TYPEREG_VERSION_1);
+ sal_uInt16 superTypes = aReader.getSuperTypeCount();
+ if (superTypes > 1) {
+ throw RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Service has more than one supertype")),
+ static_cast< OWeakObject * >(this));
+ }
+ if (superTypes == 1) {
+ OUString aBaseName( aReader.getSuperTypeName(0).replace( '/', '.' ) );
+ if ( aReader.getReferenceCount() != 0
+ || aReader.getFieldCount() != 0 )
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Service is single-interface--based but also has"
+ " references and/or properties" ) ),
+ static_cast< OWeakObject * >( this ) );
+ Reference< XTypeDescription > ifc;
+ try
+ {
+ _xTDMgr->getByHierarchicalName( aBaseName ) >>= ifc;
+ }
+ catch ( NoSuchElementException const & e )
+ {
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container.NoSuchElementException: " ) )
+ + e.Message,
+ static_cast< OWeakObject * >( this ) );
+ }
+ OSL_ASSERT(ifc.is());
+ if (resolveTypedefs(ifc)->getTypeClass() != TypeClass_INTERFACE) {
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Single-interface--based service is not based on"
+ " interface type" ) ),
+ static_cast< OWeakObject * >( this ) );
+ }
+ MutexGuard guard(getMutex());
+ if (!_bInitReferences) {
+ _xInterfaceTD = ifc;
+ _bInitReferences = true;
+ }
+ }
+ else
+ {
+ sal_uInt16 nRefs = aReader.getReferenceCount();
+ Sequence< Reference< XServiceTypeDescription > > aMandatoryServices(
+ nRefs);
+ Sequence< Reference< XServiceTypeDescription > > aOptionalServices(
+ nRefs);
+ Sequence< Reference< XInterfaceTypeDescription > > aMandatoryInterfaces(
+ nRefs);
+ Sequence< Reference< XInterfaceTypeDescription > > aOptionalInterfaces(
+ nRefs);
+ sal_uInt32 nMS = 0;
+ sal_uInt32 nOS = 0;
+ sal_uInt32 nMI = 0;
+ sal_uInt32 nOI = 0;
+
+ for ( sal_uInt16 nPos = 0; nPos < nRefs; ++nPos )
+ {
+ RTReferenceType eType = aReader.getReferenceSort( nPos );
+ switch ( eType )
+ {
+ case RT_REF_EXPORTS: // service
+ {
+ uno::Any aTypeDesc;
+ try
+ {
+ aTypeDesc = _xTDMgr->getByHierarchicalName(
+ aReader.getReferenceTypeName( nPos ).replace(
+ '/', '.' ) );
+ }
+ catch ( NoSuchElementException const & e )
+ {
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container."
+ "NoSuchElementException: " ) )
+ + e.Message,
+ static_cast< OWeakObject * >( this ) );
+ }
+
+ RTFieldAccess nAccess = aReader.getReferenceFlags( nPos );
+ if ( nAccess & RT_ACCESS_OPTIONAL )
+ {
+ // optional service
+ if ( !( aTypeDesc >>= aOptionalServices[ nOS ] ) )
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Service 'export' is not a service" ) ),
+ static_cast< OWeakObject * >( this ) );
+ nOS++;
+ }
+ else
+ {
+ // mandatory service
+ if ( !( aTypeDesc >>= aMandatoryServices[ nMS ] ) )
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Service 'export' is not a service" ) ),
+ static_cast< OWeakObject * >( this ) );
+ nMS++;
+ }
+ break;
+ }
+ case RT_REF_SUPPORTS: // interface
+ {
+ uno::Any aTypeDesc;
+ try
+ {
+ aTypeDesc = _xTDMgr->getByHierarchicalName(
+ aReader.getReferenceTypeName( nPos ).replace(
+ '/', '.' ) );
+ }
+ catch ( NoSuchElementException const & e )
+ {
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container."
+ "NoSuchElementException: " ) )
+ + e.Message,
+ static_cast< OWeakObject * >( this ) );
+ }
+
+ RTFieldAccess nAccess = aReader.getReferenceFlags( nPos );
+ if ( nAccess & RT_ACCESS_OPTIONAL )
+ {
+ // optional interface
+ if ( !( aTypeDesc >>= aOptionalInterfaces[ nOI ] ) )
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Service 'supports' is not an"
+ " interface" ) ),
+ static_cast< OWeakObject * >( this ) );
+ nOI++;
+ }
+ else
+ {
+ // mandatory interface
+ if ( !( aTypeDesc >>= aMandatoryInterfaces[ nMI ] ) )
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Service 'supports' is not an"
+ " interface" ) ),
+ static_cast< OWeakObject * >( this ) );
+ nMI++;
+ }
+ break;
+ }
+ case RT_REF_OBSERVES:
+ case RT_REF_NEEDS:
+ break;
+ default:
+ OSL_ENSURE( sal_False, "### unsupported reference type!" );
+ break;
+ }
+ }
+ aMandatoryServices.realloc( nMS );
+ aOptionalServices.realloc( nOS );
+ aMandatoryInterfaces.realloc( nMI );
+ aOptionalInterfaces.realloc( nOI );
+
+ MutexGuard guard(getMutex());
+ if (!_bInitReferences) {
+ _aMandatoryServices = aMandatoryServices;
+ _aOptionalServices = aOptionalServices;
+ _aMandatoryInterfaces = aMandatoryInterfaces;
+ _aOptionalInterfaces = aOptionalInterfaces;
+ _bInitReferences = true;
+ }
+ }
+}
+
+
+}
diff --git a/stoc/source/registry_tdprovider/tdsingleton.cxx b/stoc/source/registry_tdprovider/tdsingleton.cxx
new file mode 100644
index 000000000000..ef38dacb657e
--- /dev/null
+++ b/stoc/source/registry_tdprovider/tdsingleton.cxx
@@ -0,0 +1,132 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include "base.hxx"
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+using namespace com::sun::star;
+
+namespace stoc_rdbtdp
+{
+
+void SingletonTypeDescriptionImpl::init() {
+ {
+ MutexGuard guard(getMutex());
+ if (_xInterfaceTD.is() || _xServiceTD.is()) {
+ return;
+ }
+ }
+ Reference< XTypeDescription > base;
+ try {
+ base = Reference< XTypeDescription >(
+ _xTDMgr->getByHierarchicalName(_aBaseName), UNO_QUERY_THROW);
+ } catch (NoSuchElementException const & e) {
+ throw RuntimeException(
+ (OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.container.NoSuchElementException: "))
+ + e.Message),
+ static_cast< OWeakObject * >(this));
+ }
+ MutexGuard guard(getMutex());
+ if (!_xInterfaceTD.is() && !_xServiceTD.is()) {
+ if (resolveTypedefs(base)->getTypeClass() == TypeClass_INTERFACE) {
+ _xInterfaceTD = base;
+ } else if (base->getTypeClass() == TypeClass_SERVICE) {
+ _xServiceTD = Reference< XServiceTypeDescription >(
+ base, UNO_QUERY_THROW);
+ } else {
+ throw RuntimeException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "Singleton is based on neither interface nor service")),
+ static_cast< OWeakObject * >(this));
+ }
+ }
+ OSL_ASSERT(_xInterfaceTD.is() ^ _xServiceTD.is());
+}
+
+//__________________________________________________________________________________________________
+// virtual
+SingletonTypeDescriptionImpl::~SingletonTypeDescriptionImpl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+TypeClass SingletonTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_SINGLETON;
+}
+//__________________________________________________________________________________________________
+// virtual
+OUString SingletonTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+// XSingletonTypeDescription
+//__________________________________________________________________________________________________
+// virtual
+Reference< XServiceTypeDescription > SAL_CALL
+SingletonTypeDescriptionImpl::getService()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ init();
+ return _xServiceTD;
+}
+
+// XSingletonTypeDescription2
+//______________________________________________________________________________
+// virtual
+sal_Bool SAL_CALL
+SingletonTypeDescriptionImpl::isInterfaceBased()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ init();
+ return _xInterfaceTD.is();
+}
+
+//______________________________________________________________________________
+// virtual
+Reference< XTypeDescription > SAL_CALL
+SingletonTypeDescriptionImpl::getInterface()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ init();
+ return _xInterfaceTD;
+}
+
+}
diff --git a/stoc/source/security/access_controller.cxx b/stoc/source/security/access_controller.cxx
new file mode 100644
index 000000000000..c7b1779a5a87
--- /dev/null
+++ b/stoc/source/security/access_controller.cxx
@@ -0,0 +1,1061 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <vector>
+#include <memory>
+
+#include <osl/diagnose.h>
+#include <osl/interlck.h>
+#include <osl/mutex.hxx>
+#include <osl/thread.hxx>
+
+#include <rtl/ustrbuf.hxx>
+#include <rtl/string.hxx>
+
+#include <uno/current_context.h>
+
+#include <cppuhelper/implbase1.hxx>
+#include <cppuhelper/compbase3.hxx>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+
+#include <com/sun/star/uno/XCurrentContext.hpp>
+#include <com/sun/star/uno/DeploymentException.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/security/XAccessController.hpp>
+#include <com/sun/star/security/XPolicy.hpp>
+
+#include "lru_cache.h"
+#include "permissions.h"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define SERVICE_NAME "com.sun.star.security.AccessController"
+#define IMPL_NAME "com.sun.star.security.comp.stoc.AccessController"
+#define USER_CREDS "access-control.user-credentials"
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using ::rtl::OString;
+
+extern ::rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_sec
+{
+// static stuff initialized when loading lib
+static OUString s_envType = OUSTR(CPPU_CURRENT_LANGUAGE_BINDING_NAME);
+static OUString s_implName = OUSTR(IMPL_NAME);
+static OUString s_serviceName = OUSTR(SERVICE_NAME);
+static OUString s_acRestriction = OUSTR("access-control.restriction");
+
+static Sequence< OUString > s_serviceNames = Sequence< OUString >( &s_serviceName, 1 );
+
+//##################################################################################################
+
+/** ac context intersects permissions of two ac contexts
+*/
+class acc_Intersection
+ : public WeakImplHelper1< security::XAccessControlContext >
+{
+ Reference< security::XAccessControlContext > m_x1, m_x2;
+
+ inline acc_Intersection(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () );
+
+public:
+ virtual ~acc_Intersection()
+ SAL_THROW( () );
+
+ static inline Reference< security::XAccessControlContext > create(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () );
+
+ // XAccessControlContext impl
+ virtual void SAL_CALL checkPermission(
+ Any const & perm )
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+inline acc_Intersection::acc_Intersection(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () )
+ : m_x1( x1 )
+ , m_x2( x2 )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+acc_Intersection::~acc_Intersection()
+ SAL_THROW( () )
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//--------------------------------------------------------------------------------------------------
+inline Reference< security::XAccessControlContext > acc_Intersection::create(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () )
+{
+ if (! x1.is())
+ return x2;
+ if (! x2.is())
+ return x1;
+ return new acc_Intersection( x1, x2 );
+}
+//__________________________________________________________________________________________________
+void acc_Intersection::checkPermission(
+ Any const & perm )
+ throw (RuntimeException)
+{
+ m_x1->checkPermission( perm );
+ m_x2->checkPermission( perm );
+}
+
+/** ac context unifies permissions of two ac contexts
+*/
+class acc_Union
+ : public WeakImplHelper1< security::XAccessControlContext >
+{
+ Reference< security::XAccessControlContext > m_x1, m_x2;
+
+ inline acc_Union(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () );
+
+public:
+ virtual ~acc_Union()
+ SAL_THROW( () );
+
+ static inline Reference< security::XAccessControlContext > create(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () );
+
+ // XAccessControlContext impl
+ virtual void SAL_CALL checkPermission(
+ Any const & perm )
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+inline acc_Union::acc_Union(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () )
+ : m_x1( x1 )
+ , m_x2( x2 )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+acc_Union::~acc_Union()
+ SAL_THROW( () )
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//--------------------------------------------------------------------------------------------------
+inline Reference< security::XAccessControlContext > acc_Union::create(
+ Reference< security::XAccessControlContext > const & x1,
+ Reference< security::XAccessControlContext > const & x2 )
+ SAL_THROW( () )
+{
+ if (! x1.is())
+ return Reference< security::XAccessControlContext >(); // unrestricted
+ if (! x2.is())
+ return Reference< security::XAccessControlContext >(); // unrestricted
+ return new acc_Union( x1, x2 );
+}
+//__________________________________________________________________________________________________
+void acc_Union::checkPermission(
+ Any const & perm )
+ throw (RuntimeException)
+{
+ try
+ {
+ m_x1->checkPermission( perm );
+ }
+ catch (security::AccessControlException &)
+ {
+ m_x2->checkPermission( perm );
+ }
+}
+
+/** ac context doing permission checks on static permissions
+*/
+class acc_Policy
+ : public WeakImplHelper1< security::XAccessControlContext >
+{
+ PermissionCollection m_permissions;
+
+public:
+ inline acc_Policy(
+ PermissionCollection const & permissions )
+ SAL_THROW( () );
+ virtual ~acc_Policy()
+ SAL_THROW( () );
+
+ // XAccessControlContext impl
+ virtual void SAL_CALL checkPermission(
+ Any const & perm )
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+inline acc_Policy::acc_Policy(
+ PermissionCollection const & permissions )
+ SAL_THROW( () )
+ : m_permissions( permissions )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+acc_Policy::~acc_Policy()
+ SAL_THROW( () )
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+void acc_Policy::checkPermission(
+ Any const & perm )
+ throw (RuntimeException)
+{
+ m_permissions.checkPermission( perm );
+}
+
+/** current context overriding dynamic ac restriction
+*/
+class acc_CurrentContext
+ : public ImplHelper1< XCurrentContext >
+{
+ oslInterlockedCount m_refcount;
+
+ Reference< XCurrentContext > m_xDelegate;
+ Any m_restriction;
+
+public:
+ inline acc_CurrentContext(
+ Reference< XCurrentContext > const & xDelegate,
+ Reference< security::XAccessControlContext > const & xRestriction )
+ SAL_THROW( () );
+ virtual ~acc_CurrentContext() SAL_THROW( () );
+
+ // XInterface impl
+ virtual void SAL_CALL acquire()
+ throw ();
+ virtual void SAL_CALL release()
+ throw ();
+
+ // XCurrentContext impl
+ virtual Any SAL_CALL getValueByName( OUString const & name )
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+inline acc_CurrentContext::acc_CurrentContext(
+ Reference< XCurrentContext > const & xDelegate,
+ Reference< security::XAccessControlContext > const & xRestriction )
+ SAL_THROW( () )
+ : m_refcount( 0 )
+ , m_xDelegate( xDelegate )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+
+ if (xRestriction.is())
+ {
+ m_restriction = makeAny( xRestriction );
+ }
+ // return empty any otherwise on getValueByName(), not null interface
+}
+//__________________________________________________________________________________________________
+acc_CurrentContext::~acc_CurrentContext()
+ SAL_THROW( () )
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+void acc_CurrentContext::acquire()
+ throw ()
+{
+ ::osl_incrementInterlockedCount( &m_refcount );
+}
+//__________________________________________________________________________________________________
+void acc_CurrentContext::release()
+ throw ()
+{
+ if (! ::osl_decrementInterlockedCount( &m_refcount ))
+ {
+ delete this;
+ }
+}
+//__________________________________________________________________________________________________
+Any acc_CurrentContext::getValueByName( OUString const & name )
+ throw (RuntimeException)
+{
+ if (name.equals( s_acRestriction ))
+ {
+ return m_restriction;
+ }
+ else if (m_xDelegate.is())
+ {
+ return m_xDelegate->getValueByName( name );
+ }
+ else
+ {
+ return Any();
+ }
+}
+
+//##################################################################################################
+
+//--------------------------------------------------------------------------------------------------
+static inline void dispose( Reference< XInterface > const & x )
+ SAL_THROW( (RuntimeException) )
+{
+ Reference< lang::XComponent > xComp( x, UNO_QUERY );
+ if (xComp.is())
+ {
+ xComp->dispose();
+ }
+}
+//--------------------------------------------------------------------------------------------------
+static inline Reference< security::XAccessControlContext > getDynamicRestriction(
+ Reference< XCurrentContext > const & xContext )
+ SAL_THROW( (RuntimeException) )
+{
+ if (xContext.is())
+ {
+ Any acc( xContext->getValueByName( s_acRestriction ) );
+ if (typelib_TypeClass_INTERFACE == acc.pType->eTypeClass)
+ {
+ // avoid ref-counting
+ OUString const & typeName =
+ *reinterpret_cast< OUString const * >( &acc.pType->pTypeName );
+ if (typeName.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.security.XAccessControlContext") ))
+ {
+ return Reference< security::XAccessControlContext >(
+ *reinterpret_cast< security::XAccessControlContext ** const >( acc.pData ) );
+ }
+ else // try to query
+ {
+ return Reference< security::XAccessControlContext >::query(
+ *reinterpret_cast< XInterface ** const >( acc.pData ) );
+ }
+ }
+ }
+ return Reference< security::XAccessControlContext >();
+}
+//==================================================================================================
+class cc_reset
+{
+ void * m_cc;
+public:
+ inline cc_reset( void * cc ) SAL_THROW( () )
+ : m_cc( cc ) {}
+ inline ~cc_reset() SAL_THROW( () )
+ { ::uno_setCurrentContext( m_cc, s_envType.pData, 0 ); }
+};
+
+//##################################################################################################
+
+struct MutexHolder
+{
+ Mutex m_mutex;
+};
+typedef WeakComponentImplHelper3<
+ security::XAccessController, lang::XServiceInfo, lang::XInitialization > t_helper;
+
+//==================================================================================================
+class AccessController
+ : public MutexHolder
+ , public t_helper
+{
+ Reference< XComponentContext > m_xComponentContext;
+
+ Reference< security::XPolicy > m_xPolicy;
+ Reference< security::XPolicy > const & getPolicy()
+ SAL_THROW( (RuntimeException) );
+
+ // mode
+ enum Mode { OFF, ON, DYNAMIC_ONLY, SINGLE_USER, SINGLE_DEFAULT_USER } m_mode;
+
+ PermissionCollection m_defaultPermissions;
+ // for single-user mode
+ PermissionCollection m_singleUserPermissions;
+ OUString m_singleUserId;
+ bool m_defaultPerm_init;
+ bool m_singleUser_init;
+ // for multi-user mode
+ lru_cache< OUString, PermissionCollection, ::rtl::OUStringHash, equal_to< OUString > >
+ m_user2permissions;
+
+ ThreadData m_rec;
+ typedef vector< pair< OUString, Any > > t_rec_vec;
+ inline void clearPostPoned() SAL_THROW( () );
+ void checkAndClearPostPoned() SAL_THROW( (RuntimeException) );
+
+ PermissionCollection getEffectivePermissions(
+ Reference< XCurrentContext > const & xContext,
+ Any const & demanded_perm )
+ SAL_THROW( (RuntimeException) );
+
+protected:
+ virtual void SAL_CALL disposing();
+
+public:
+ AccessController( Reference< XComponentContext > const & xComponentContext )
+ SAL_THROW( (RuntimeException) );
+ virtual ~AccessController()
+ SAL_THROW( () );
+
+ // XInitialization impl
+ virtual void SAL_CALL initialize(
+ Sequence< Any > const & arguments )
+ throw (Exception);
+
+ // XAccessController impl
+ virtual void SAL_CALL checkPermission(
+ Any const & perm )
+ throw (RuntimeException);
+ virtual Any SAL_CALL doRestricted(
+ Reference< security::XAction > const & xAction,
+ Reference< security::XAccessControlContext > const & xRestriction )
+ throw (Exception);
+ virtual Any SAL_CALL doPrivileged(
+ Reference< security::XAction > const & xAction,
+ Reference< security::XAccessControlContext > const & xRestriction )
+ throw (Exception);
+ virtual Reference< security::XAccessControlContext > SAL_CALL getContext()
+ throw (RuntimeException);
+
+ // XServiceInfo impl
+ virtual OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
+ throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+AccessController::AccessController( Reference< XComponentContext > const & xComponentContext )
+ SAL_THROW( (RuntimeException) )
+ : t_helper( m_mutex )
+ , m_xComponentContext( xComponentContext )
+ , m_mode( ON ) // default
+ , m_defaultPerm_init( false )
+ , m_singleUser_init( false )
+ , m_rec( 0 )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+
+ OUString mode;
+ if (m_xComponentContext->getValueByName( OUSTR("/services/" SERVICE_NAME "/mode") ) >>= mode)
+ {
+ if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("off") ))
+ {
+ m_mode = OFF;
+ }
+ else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("on") ))
+ {
+ m_mode = ON;
+ }
+ else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("dynamic-only") ))
+ {
+ m_mode = DYNAMIC_ONLY;
+ }
+ else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("single-user") ))
+ {
+ m_xComponentContext->getValueByName(
+ OUSTR("/services/" SERVICE_NAME "/single-user-id") ) >>= m_singleUserId;
+ if (! m_singleUserId.getLength())
+ {
+ throw RuntimeException(
+ OUSTR("expected a user id in component context entry "
+ "\"/services/" SERVICE_NAME "/single-user-id\"!"),
+ (OWeakObject *)this );
+ }
+ m_mode = SINGLE_USER;
+ }
+ else if (mode.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("single-default-user") ))
+ {
+ m_mode = SINGLE_DEFAULT_USER;
+ }
+ }
+
+ // switch on caching for DYNAMIC_ONLY and ON (sharable multi-user process)
+ if (ON == m_mode || DYNAMIC_ONLY == m_mode)
+ {
+ sal_Int32 cacheSize = 0; // multi-user cache size
+ if (! (m_xComponentContext->getValueByName(
+ OUSTR("/services/" SERVICE_NAME "/user-cache-size") ) >>= cacheSize))
+ {
+ cacheSize = 128; // reasonable default?
+ }
+#ifdef __CACHE_DIAGNOSE
+ cacheSize = 2;
+#endif
+ m_user2permissions.setSize( cacheSize );
+ }
+}
+//__________________________________________________________________________________________________
+AccessController::~AccessController()
+ SAL_THROW( () )
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+void AccessController::disposing()
+{
+ m_mode = OFF; // avoid checks from now on xxx todo review/ better DYNAMIC_ONLY?
+ m_xPolicy.clear();
+ m_xComponentContext.clear();
+}
+
+// XInitialization impl
+//__________________________________________________________________________________________________
+void AccessController::initialize(
+ Sequence< Any > const & arguments )
+ throw (Exception)
+{
+ // xxx todo: review for forking
+ // portal forking hack: re-initialize for another user-id
+ if (SINGLE_USER != m_mode) // only if in single-user mode
+ {
+ throw RuntimeException(
+ OUSTR("invalid call: ac must be in \"single-user\" mode!"), (OWeakObject *)this );
+ }
+ OUString userId;
+ arguments[ 0 ] >>= userId;
+ if (! userId.getLength())
+ {
+ throw RuntimeException(
+ OUSTR("expected a user-id as first argument!"), (OWeakObject *)this );
+ }
+ // assured that no sync is necessary: no check happens at this forking time
+ m_singleUserId = userId;
+ m_singleUser_init = false;
+}
+
+//__________________________________________________________________________________________________
+Reference< security::XPolicy > const & AccessController::getPolicy()
+ SAL_THROW( (RuntimeException) )
+{
+ // get policy singleton
+ if (! m_xPolicy.is())
+ {
+ Reference< security::XPolicy > xPolicy;
+ m_xComponentContext->getValueByName(
+ OUSTR("/singletons/com.sun.star.security.thePolicy") ) >>= xPolicy;
+ if (xPolicy.is())
+ {
+ MutexGuard guard( m_mutex );
+ if (! m_xPolicy.is())
+ {
+ m_xPolicy = xPolicy;
+ }
+ }
+ else
+ {
+ throw SecurityException(
+ OUSTR("cannot get policy singleton!"), (OWeakObject *)this );
+ }
+ }
+ return m_xPolicy;
+}
+
+#ifdef __DIAGNOSE
+static void dumpPermissions(
+ PermissionCollection const & collection, OUString const & userId = OUString() ) SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ if (userId.getLength())
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("> dumping permissions of user \"") );
+ buf.append( userId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\":") );
+ }
+ else
+ {
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("> dumping default permissions:") );
+ }
+ OString str( ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+ Sequence< OUString > permissions( collection.toStrings() );
+ OUString const * p = permissions.getConstArray();
+ for ( sal_Int32 nPos = 0; nPos < permissions.getLength(); ++nPos )
+ {
+ OString str( ::rtl::OUStringToOString( p[ nPos ], RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+ }
+ OSL_TRACE( "> permission dump done" );
+}
+#endif
+
+
+//__________________________________________________________________________________________________
+inline void AccessController::clearPostPoned() SAL_THROW( () )
+{
+ delete reinterpret_cast< t_rec_vec * >( m_rec.getData() );
+ m_rec.setData( 0 );
+}
+//__________________________________________________________________________________________________
+void AccessController::checkAndClearPostPoned() SAL_THROW( (RuntimeException) )
+{
+ // check postponed permissions
+ auto_ptr< t_rec_vec > rec( reinterpret_cast< t_rec_vec * >( m_rec.getData() ) );
+ m_rec.setData( 0 ); // takeover ownership
+ OSL_ASSERT( rec.get() );
+ if (rec.get())
+ {
+ t_rec_vec const & vec = *rec.get();
+ switch (m_mode)
+ {
+ case SINGLE_USER:
+ {
+ OSL_ASSERT( m_singleUser_init );
+ for ( size_t nPos = 0; nPos < vec.size(); ++nPos )
+ {
+ pair< OUString, Any > const & p = vec[ nPos ];
+ OSL_ASSERT( m_singleUserId.equals( p.first ) );
+ m_singleUserPermissions.checkPermission( p.second );
+ }
+ break;
+ }
+ case SINGLE_DEFAULT_USER:
+ {
+ OSL_ASSERT( m_defaultPerm_init );
+ for ( size_t nPos = 0; nPos < vec.size(); ++nPos )
+ {
+ pair< OUString, Any > const & p = vec[ nPos ];
+ OSL_ASSERT( !p.first.getLength() ); // default-user
+ m_defaultPermissions.checkPermission( p.second );
+ }
+ break;
+ }
+ case ON:
+ {
+ for ( size_t nPos = 0; nPos < vec.size(); ++nPos )
+ {
+ pair< OUString, Any > const & p = vec[ nPos ];
+ PermissionCollection const * pPermissions;
+ // lookup policy for user
+ {
+ MutexGuard guard( m_mutex );
+ pPermissions = m_user2permissions.lookup( p.first );
+ }
+ OSL_ASSERT( pPermissions );
+ if (pPermissions)
+ {
+ pPermissions->checkPermission( p.second );
+ }
+ }
+ break;
+ }
+ default:
+ OSL_ENSURE( 0, "### this should never be called in this ac mode!" );
+ break;
+ }
+ }
+}
+//__________________________________________________________________________________________________
+/** this is the only function calling the policy singleton and thus has to take care
+ of recurring calls!
+
+ @param demanded_perm (if not empty) is the demanded permission of a checkPermission() call
+ which will be postponed for recurring calls
+*/
+PermissionCollection AccessController::getEffectivePermissions(
+ Reference< XCurrentContext > const & xContext,
+ Any const & demanded_perm )
+ SAL_THROW( (RuntimeException) )
+{
+ OUString userId;
+
+ switch (m_mode)
+ {
+ case SINGLE_USER:
+ {
+ if (m_singleUser_init)
+ return m_singleUserPermissions;
+ userId = m_singleUserId;
+ break;
+ }
+ case SINGLE_DEFAULT_USER:
+ {
+ if (m_defaultPerm_init)
+ return m_defaultPermissions;
+ break;
+ }
+ case ON:
+ {
+ if (xContext.is())
+ {
+ xContext->getValueByName( OUSTR(USER_CREDS ".id") ) >>= userId;
+ }
+ if (! userId.getLength())
+ {
+ throw SecurityException(
+ OUSTR("cannot determine current user in multi-user ac!"), (OWeakObject *)this );
+ }
+
+ // lookup policy for user
+ MutexGuard guard( m_mutex );
+ PermissionCollection const * pPermissions = m_user2permissions.lookup( userId );
+ if (pPermissions)
+ return *pPermissions;
+ break;
+ }
+ default:
+ OSL_ENSURE( 0, "### this should never be called in this ac mode!" );
+ return PermissionCollection();
+ }
+
+ // call on policy
+ // iff this is a recurring call for the default user, then grant all permissions
+ t_rec_vec * rec = reinterpret_cast< t_rec_vec * >( m_rec.getData() );
+ if (rec) // tls entry exists => this is recursive call
+ {
+ if (demanded_perm.hasValue())
+ {
+ // enqueue
+ rec->push_back( pair< OUString, Any >( userId, demanded_perm ) );
+ }
+#ifdef __DIAGNOSE
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("> info: recurring call of user \"") );
+ buf.append( userId );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"") );
+ OString str(
+ ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+#endif
+ return PermissionCollection( new AllPermission() );
+ }
+ else // no tls
+ {
+ rec = new t_rec_vec;
+ m_rec.setData( rec );
+ }
+
+ try // calls on API
+ {
+ // init default permissions
+ if (! m_defaultPerm_init)
+ {
+ PermissionCollection defaultPermissions(
+ getPolicy()->getDefaultPermissions() );
+ // assign
+ MutexGuard guard( m_mutex );
+ if (! m_defaultPerm_init)
+ {
+ m_defaultPermissions = defaultPermissions;
+ m_defaultPerm_init = true;
+ }
+#ifdef __DIAGNOSE
+ dumpPermissions( m_defaultPermissions );
+#endif
+ }
+
+ PermissionCollection ret;
+
+ // init user permissions
+ switch (m_mode)
+ {
+ case SINGLE_USER:
+ {
+ ret = PermissionCollection(
+ getPolicy()->getPermissions( userId ), m_defaultPermissions );
+ {
+ // assign
+ MutexGuard guard( m_mutex );
+ if (m_singleUser_init)
+ {
+ ret = m_singleUserPermissions;
+ }
+ else
+ {
+ m_singleUserPermissions = ret;
+ m_singleUser_init = true;
+ }
+ }
+#ifdef __DIAGNOSE
+ dumpPermissions( ret, userId );
+#endif
+ break;
+ }
+ case SINGLE_DEFAULT_USER:
+ {
+ ret = m_defaultPermissions;
+ break;
+ }
+ case ON:
+ {
+ ret = PermissionCollection(
+ getPolicy()->getPermissions( userId ), m_defaultPermissions );
+ {
+ // cache
+ MutexGuard guard( m_mutex );
+ m_user2permissions.set( userId, ret );
+ }
+#ifdef __DIAGNOSE
+ dumpPermissions( ret, userId );
+#endif
+ break;
+ }
+ default:
+ break;
+ }
+
+ // check postponed
+ checkAndClearPostPoned();
+ return ret;
+ }
+ catch (security::AccessControlException & exc) // wrapped into DeploymentException
+ {
+ clearPostPoned(); // safety: exception could have happened before checking postponed?
+ OUStringBuffer buf( 64 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("deployment error (AccessControlException occured): ") );
+ buf.append( exc.Message );
+ throw DeploymentException( buf.makeStringAndClear(), exc.Context );
+ }
+ catch (RuntimeException &)
+ {
+ // dont check postponed, just cleanup
+ clearPostPoned();
+ delete reinterpret_cast< t_rec_vec * >( m_rec.getData() );
+ m_rec.setData( 0 );
+ throw;
+ }
+ catch (Exception &)
+ {
+ // check postponed permissions first
+ // => AccessControlExceptions are errors, user exceptions not!
+ checkAndClearPostPoned();
+ throw;
+ }
+ catch (...)
+ {
+ // dont check postponed, just cleanup
+ clearPostPoned();
+ throw;
+ }
+}
+
+// XAccessController impl
+//__________________________________________________________________________________________________
+void AccessController::checkPermission(
+ Any const & perm )
+ throw (RuntimeException)
+{
+ if (rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ OUSTR("checkPermission() call on disposed AccessController!"), (OWeakObject *)this );
+ }
+
+ if (OFF == m_mode)
+ return;
+
+ // first dynamic check of ac contexts
+ Reference< XCurrentContext > xContext;
+ ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
+ Reference< security::XAccessControlContext > xACC( getDynamicRestriction( xContext ) );
+ if (xACC.is())
+ {
+ xACC->checkPermission( perm );
+ }
+
+ if (DYNAMIC_ONLY == m_mode)
+ return;
+
+ // then static check
+ getEffectivePermissions( xContext, perm ).checkPermission( perm );
+}
+//__________________________________________________________________________________________________
+Any AccessController::doRestricted(
+ Reference< security::XAction > const & xAction,
+ Reference< security::XAccessControlContext > const & xRestriction )
+ throw (Exception)
+{
+ if (rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ OUSTR("doRestricted() call on disposed AccessController!"), (OWeakObject *)this );
+ }
+
+ if (OFF == m_mode) // optimize this way, because no dynamic check will be performed
+ return xAction->run();
+
+ if (xRestriction.is())
+ {
+ Reference< XCurrentContext > xContext;
+ ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
+
+ // override restriction
+ Reference< XCurrentContext > xNewContext(
+ new acc_CurrentContext( xContext, acc_Intersection::create(
+ xRestriction, getDynamicRestriction( xContext ) ) ) );
+ ::uno_setCurrentContext( xNewContext.get(), s_envType.pData, 0 );
+ cc_reset reset( xContext.get() );
+ return xAction->run();
+ }
+ else
+ {
+ return xAction->run();
+ }
+}
+//__________________________________________________________________________________________________
+Any AccessController::doPrivileged(
+ Reference< security::XAction > const & xAction,
+ Reference< security::XAccessControlContext > const & xRestriction )
+ throw (Exception)
+{
+ if (rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ OUSTR("doPrivileged() call on disposed AccessController!"), (OWeakObject *)this );
+ }
+
+ if (OFF == m_mode) // no dynamic check will be performed
+ {
+ return xAction->run();
+ }
+
+ Reference< XCurrentContext > xContext;
+ ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
+
+ Reference< security::XAccessControlContext > xOldRestr(
+ getDynamicRestriction( xContext ) );
+
+ if (xOldRestr.is()) // previous restriction
+ {
+ // override restriction
+ Reference< XCurrentContext > xNewContext(
+ new acc_CurrentContext( xContext, acc_Union::create( xRestriction, xOldRestr ) ) );
+ ::uno_setCurrentContext( xNewContext.get(), s_envType.pData, 0 );
+ cc_reset reset( xContext.get() );
+ return xAction->run();
+ }
+ else // no previous restriction => never current restriction
+ {
+ return xAction->run();
+ }
+}
+//__________________________________________________________________________________________________
+Reference< security::XAccessControlContext > AccessController::getContext()
+ throw (RuntimeException)
+{
+ if (rBHelper.bDisposed)
+ {
+ throw lang::DisposedException(
+ OUSTR("getContext() call on disposed AccessController!"), (OWeakObject *)this );
+ }
+
+ if (OFF == m_mode) // optimize this way, because no dynamic check will be performed
+ {
+ return new acc_Policy( PermissionCollection( new AllPermission() ) );
+ }
+
+ Reference< XCurrentContext > xContext;
+ ::uno_getCurrentContext( (void **)&xContext, s_envType.pData, 0 );
+
+ return acc_Intersection::create(
+ getDynamicRestriction( xContext ),
+ new acc_Policy( getEffectivePermissions( xContext, Any() ) ) );
+}
+
+// XServiceInfo impl
+//__________________________________________________________________________________________________
+OUString AccessController::getImplementationName()
+ throw (RuntimeException)
+{
+ return s_implName;
+}
+//__________________________________________________________________________________________________
+sal_Bool AccessController::supportsService( OUString const & serviceName )
+ throw (RuntimeException)
+{
+ OUString const * pNames = s_serviceNames.getConstArray();
+ for ( sal_Int32 nPos = s_serviceNames.getLength(); nPos--; )
+ {
+ if (serviceName.equals( pNames[ nPos ] ))
+ {
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > AccessController::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return s_serviceNames;
+}
+}
+//##################################################################################################
+namespace stoc_bootstrap {
+//--------------------------------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL ac_create(
+ Reference< XComponentContext > const & xComponentContext )
+ SAL_THROW( (Exception) )
+{
+ return (OWeakObject *)new stoc_sec::AccessController( xComponentContext );
+}
+//--------------------------------------------------------------------------------------------------
+Sequence< OUString > ac_getSupportedServiceNames() SAL_THROW( () )
+{
+ return stoc_sec::s_serviceNames;
+}
+//--------------------------------------------------------------------------------------------------
+OUString ac_getImplementationName() SAL_THROW( () )
+{
+ return stoc_sec::s_implName;
+}
+//--------------------------------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL filepolicy_create(
+ Reference< XComponentContext > const & xComponentContext )
+ SAL_THROW( (Exception) );
+//--------------------------------------------------------------------------------------------------
+Sequence< OUString > filepolicy_getSupportedServiceNames() SAL_THROW( () );
+//--------------------------------------------------------------------------------------------------
+OUString filepolicy_getImplementationName() SAL_THROW( () );
+}
diff --git a/stoc/source/security/file_policy.cxx b/stoc/source/security/file_policy.cxx
new file mode 100644
index 000000000000..b59502852d1d
--- /dev/null
+++ b/stoc/source/security/file_policy.cxx
@@ -0,0 +1,603 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <hash_map>
+
+#include <osl/diagnose.h>
+#include <osl/file.h>
+#include <rtl/byteseq.hxx>
+#include <rtl/string.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <cppuhelper/access_control.hxx>
+#include <cppuhelper/compbase2.hxx>
+#include <cppuhelper/implementationentry.hxx>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/security/XAccessController.hpp>
+#include <com/sun/star/security/XPolicy.hpp>
+#include <com/sun/star/security/AllPermission.hpp>
+#include <com/sun/star/security/RuntimePermission.hpp>
+#include <com/sun/star/io/FilePermission.hpp>
+#include <com/sun/star/connection/SocketPermission.hpp>
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define SERVICE_NAME "com.sun.star.security.Policy"
+#define IMPL_NAME "com.sun.star.security.comp.stoc.FilePolicy"
+
+
+using namespace ::osl;
+using namespace ::rtl;
+using namespace ::cppu;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+
+extern ::rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_sec
+{
+// static stuff initialized when loading lib
+static OUString s_implName = OUSTR(IMPL_NAME);
+static OUString s_serviceName = OUSTR(SERVICE_NAME);
+
+static Sequence< OUString > s_serviceNames = Sequence< OUString >( &s_serviceName, 1 );
+//##################################################################################################
+
+//--------------------------------------------------------------------------------------------------
+static inline void dispose( Reference< XInterface > const & x )
+ SAL_THROW( (RuntimeException) )
+{
+ Reference< lang::XComponent > xComp( x, UNO_QUERY );
+ if (xComp.is())
+ {
+ xComp->dispose();
+ }
+}
+
+//##################################################################################################
+
+struct MutexHolder
+{
+ Mutex m_mutex;
+};
+typedef WeakComponentImplHelper2< security::XPolicy, lang::XServiceInfo > t_helper;
+
+//==================================================================================================
+class FilePolicy
+ : public MutexHolder
+ , public t_helper
+{
+ Reference< XComponentContext > m_xComponentContext;
+ AccessControl m_ac;
+
+ Sequence< Any > m_defaultPermissions;
+ typedef std::hash_map< OUString, Sequence< Any >, OUStringHash > t_permissions;
+ t_permissions m_userPermissions;
+ bool m_init;
+
+protected:
+ virtual void SAL_CALL disposing();
+
+public:
+ FilePolicy( Reference< XComponentContext > const & xComponentContext )
+ SAL_THROW( () );
+ virtual ~FilePolicy()
+ SAL_THROW( () );
+
+ // XPolicy impl
+ virtual Sequence< Any > SAL_CALL getPermissions(
+ OUString const & userId )
+ throw (RuntimeException);
+ virtual Sequence< Any > SAL_CALL getDefaultPermissions()
+ throw (RuntimeException);
+ virtual void SAL_CALL refresh()
+ throw (RuntimeException);
+
+ // XServiceInfo impl
+ virtual OUString SAL_CALL getImplementationName()
+ throw (RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( OUString const & serviceName )
+ throw (RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames()
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+FilePolicy::FilePolicy( Reference< XComponentContext > const & xComponentContext )
+ SAL_THROW( () )
+ : t_helper( m_mutex )
+ , m_xComponentContext( xComponentContext )
+ , m_ac( xComponentContext )
+ , m_init( false )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+FilePolicy::~FilePolicy()
+ SAL_THROW( () )
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+void FilePolicy::disposing()
+{
+ m_userPermissions.clear();
+ m_defaultPermissions = Sequence< Any >();
+ m_xComponentContext.clear();
+}
+
+//__________________________________________________________________________________________________
+Sequence< Any > FilePolicy::getPermissions(
+ OUString const & userId )
+ throw (RuntimeException)
+{
+ if (! m_init)
+ {
+ refresh();
+ m_init = true;
+ }
+
+ MutexGuard guard( m_mutex );
+ t_permissions::iterator iFind( m_userPermissions.find( userId ) );
+ if (m_userPermissions.end() == iFind)
+ {
+ return Sequence< Any >();
+ }
+ else
+ {
+ return iFind->second;
+ }
+}
+//__________________________________________________________________________________________________
+Sequence< Any > FilePolicy::getDefaultPermissions()
+ throw (RuntimeException)
+{
+ if (! m_init)
+ {
+ refresh();
+ m_init = true;
+ }
+
+ MutexGuard guard( m_mutex );
+ return m_defaultPermissions;
+}
+
+//==================================================================================================
+class PolicyReader
+{
+ OUString m_fileName;
+ oslFileHandle m_file;
+
+ sal_Int32 m_linepos;
+ ByteSequence m_line;
+ sal_Int32 m_pos;
+ sal_Unicode m_back;
+
+ sal_Unicode get()
+ SAL_THROW( (RuntimeException) );
+ inline void back( sal_Unicode c ) SAL_THROW( () )
+ { m_back = c; }
+
+ inline bool isWhiteSpace( sal_Unicode c ) SAL_THROW( () )
+ { return (' ' == c || '\t' == c || '\n' == c || '\r' == c); }
+ void skipWhiteSpace()
+ SAL_THROW( (RuntimeException) );
+
+ inline bool isCharToken( sal_Unicode c ) SAL_THROW( () )
+ { return (';' == c || ',' == c || '{' == c || '}' == c); }
+
+public:
+ PolicyReader( OUString const & file, AccessControl & ac )
+ SAL_THROW( (RuntimeException) );
+ ~PolicyReader()
+ SAL_THROW( () );
+
+ void error( OUString const & msg )
+ SAL_THROW( (RuntimeException) );
+
+ OUString getToken()
+ SAL_THROW( (RuntimeException) );
+ OUString assureToken()
+ SAL_THROW( (RuntimeException) );
+ OUString getQuotedToken()
+ SAL_THROW( (RuntimeException) );
+ OUString assureQuotedToken()
+ SAL_THROW( (RuntimeException) );
+ void assureToken( sal_Unicode token )
+ SAL_THROW( (RuntimeException) );
+};
+//__________________________________________________________________________________________________
+void PolicyReader::assureToken( sal_Unicode token )
+ SAL_THROW( (RuntimeException) )
+{
+ skipWhiteSpace();
+ sal_Unicode c = get();
+ if (c == token)
+ return;
+ OUStringBuffer buf( 16 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("expected >") );
+ buf.append( c );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("<!") );
+ error( buf.makeStringAndClear() );
+}
+//__________________________________________________________________________________________________
+OUString PolicyReader::assureQuotedToken()
+ SAL_THROW( (RuntimeException) )
+{
+ OUString token( getQuotedToken() );
+ if (! token.getLength())
+ error( OUSTR("unexpected end of file!") );
+ return token;
+}
+//__________________________________________________________________________________________________
+OUString PolicyReader::getQuotedToken()
+ SAL_THROW( (RuntimeException) )
+{
+ skipWhiteSpace();
+ OUStringBuffer buf( 32 );
+ sal_Unicode c = get();
+ if ('\"' != c)
+ error( OUSTR("expected quoting >\"< character!") );
+ c = get();
+ while ('\0' != c && '\"' != c)
+ {
+ buf.append( c );
+ c = get();
+ }
+ return buf.makeStringAndClear();
+}
+//__________________________________________________________________________________________________
+OUString PolicyReader::assureToken()
+ SAL_THROW( (RuntimeException) )
+{
+ OUString token( getToken() );
+ if (! token.getLength())
+ error( OUSTR("unexpected end of file!") );
+ return token;
+}
+//__________________________________________________________________________________________________
+OUString PolicyReader::getToken()
+ SAL_THROW( (RuntimeException) )
+{
+ skipWhiteSpace();
+ sal_Unicode c = get();
+ if (isCharToken( c ))
+ return OUString( &c, 1 );
+ OUStringBuffer buf( 32 );
+ while ('\0' != c && !isCharToken( c ) && !isWhiteSpace( c ))
+ {
+ buf.append( c );
+ c = get();
+ }
+ back( c );
+ return buf.makeStringAndClear();
+}
+//__________________________________________________________________________________________________
+void PolicyReader::skipWhiteSpace()
+ SAL_THROW( (RuntimeException) )
+{
+ sal_Unicode c;
+ do
+ {
+ c = get();
+ }
+ while (isWhiteSpace( c )); // seeking next non-whitespace char
+
+ if ('/' == c) // C/C++ like comment
+ {
+ c = get();
+ if ('/' == c) // C++ like comment
+ {
+ do
+ {
+ c = get();
+ }
+ while ('\n' != c && '\0' != c); // seek eol/eof
+ skipWhiteSpace(); // cont skip on next line
+ }
+ else if ('*' == c) // C like comment
+ {
+ bool fini = true;
+ do
+ {
+ c = get();
+ if ('*' == c)
+ {
+ c = get();
+ fini = ('/' == c || '\0' == c);
+ }
+ else
+ {
+ fini = ('\0' == c);
+ }
+ }
+ while (! fini);
+ skipWhiteSpace(); // cont skip on next line
+ }
+ else
+ {
+ error( OUSTR("expected C/C++ like comment!") );
+ }
+ }
+ else if ('#' == c) // script like comment
+ {
+ do
+ {
+ c = get();
+ }
+ while ('\n' != c && '\0' != c); // seek eol/eof
+ skipWhiteSpace(); // cont skip on next line
+ }
+
+ else // is token char
+ {
+ back( c );
+ }
+}
+//__________________________________________________________________________________________________
+sal_Unicode PolicyReader::get()
+ SAL_THROW( (RuntimeException) )
+{
+ if ('\0' != m_back) // one char push back possible
+ {
+ sal_Unicode c = m_back;
+ m_back = '\0';
+ return c;
+ }
+ else if (m_pos == m_line.getLength()) // provide newline as whitespace
+ {
+ ++m_pos;
+ return '\n';
+ }
+ else if (m_pos > m_line.getLength()) // read new line
+ {
+ sal_Bool eof;
+ oslFileError rc = ::osl_isEndOfFile( m_file, &eof );
+ if (osl_File_E_None != rc)
+ error( OUSTR("checking eof failed!") );
+ if (eof)
+ return '\0';
+
+ rc = ::osl_readLine( m_file, reinterpret_cast< sal_Sequence ** >( &m_line ) );
+ if (osl_File_E_None != rc)
+ error( OUSTR("read line failed!") );
+ ++m_linepos;
+ if (! m_line.getLength()) // empty line read
+ {
+ m_pos = 1; // read new line next time
+ return '\n';
+ }
+ m_pos = 0;
+ }
+ return (m_line.getConstArray()[ m_pos++ ]);
+}
+//__________________________________________________________________________________________________
+void PolicyReader::error( OUString const & msg )
+ SAL_THROW( (RuntimeException) )
+{
+ OUStringBuffer buf( 32 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("error processing file \"") );
+ buf.append( m_fileName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" [line ") );
+ buf.append( m_linepos );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", column ") );
+ buf.append( m_pos );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ buf.append( msg );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
+}
+//__________________________________________________________________________________________________
+PolicyReader::PolicyReader( OUString const & fileName, AccessControl & ac )
+ SAL_THROW( (RuntimeException) )
+ : m_fileName( fileName )
+ , m_linepos( 0 )
+ , m_pos( 1 ) // force readline
+ , m_back( '\0' )
+{
+ ac.checkFilePermission( m_fileName, OUSTR("read") );
+ if (osl_File_E_None != ::osl_openFile( m_fileName.pData, &m_file, osl_File_OpenFlag_Read ))
+ {
+ OUStringBuffer buf( 32 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot open file \"") );
+ buf.append( m_fileName );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
+ throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+}
+//__________________________________________________________________________________________________
+PolicyReader::~PolicyReader()
+ SAL_THROW( () )
+{
+ if ( ::osl_closeFile( m_file ) != osl_File_E_None ) {
+ OSL_ASSERT( false );
+ }
+}
+
+static OUString s_grant = OUSTR("grant");
+static OUString s_user = OUSTR("user");
+static OUString s_permission = OUSTR("permission");
+static OUString s_openBrace = OUSTR("{");
+static OUString s_closingBrace = OUSTR("}");
+
+static OUString s_filePermission = OUSTR("com.sun.star.io.FilePermission");
+static OUString s_socketPermission = OUSTR("com.sun.star.connection.SocketPermission");
+static OUString s_runtimePermission = OUSTR("com.sun.star.security.RuntimePermission");
+static OUString s_allPermission = OUSTR("com.sun.star.security.AllPermission");
+
+//__________________________________________________________________________________________________
+void FilePolicy::refresh()
+ throw (RuntimeException)
+{
+ // read out file
+ OUString fileName;
+ m_xComponentContext->getValueByName(
+ OUSTR("/implementations/" IMPL_NAME "/file-name") ) >>= fileName;
+ if (! fileName.getLength())
+ {
+ throw RuntimeException(
+ OUSTR("name of policy file unknown!"),
+ (OWeakObject *)this );
+ }
+
+ PolicyReader reader( fileName, m_ac );
+
+ // fill these two
+ Sequence< Any > defaultPermissions;
+ t_permissions userPermissions;
+
+ OUString token( reader.getToken() );
+ while (token.getLength())
+ {
+ if (! token.equals( s_grant ))
+ reader.error( OUSTR("expected >grant< token!") );
+ OUString userId;
+ token = reader.assureToken();
+ if (token.equals( s_user )) // next token is user-id
+ {
+ userId = reader.assureQuotedToken();
+ token = reader.assureToken();
+ }
+ if (! token.equals( s_openBrace ))
+ reader.error( OUSTR("expected opening brace >{<!") );
+ token = reader.assureToken();
+ // permissions list
+ while (! token.equals( s_closingBrace ))
+ {
+ if (! token.equals( s_permission ))
+ reader.error( OUSTR("expected >permission< or closing brace >}<!") );
+
+ token = reader.assureToken(); // permission type
+ Any perm;
+ if (token.equals( s_filePermission )) // FilePermission
+ {
+ OUString url( reader.assureQuotedToken() );
+ reader.assureToken( ',' );
+ OUString actions( reader.assureQuotedToken() );
+ perm <<= io::FilePermission( url, actions );
+ }
+ else if (token.equals( s_socketPermission )) // SocketPermission
+ {
+ OUString host( reader.assureQuotedToken() );
+ reader.assureToken( ',' );
+ OUString actions( reader.assureQuotedToken() );
+ perm <<= connection::SocketPermission( host, actions );
+ }
+ else if (token.equals( s_runtimePermission )) // RuntimePermission
+ {
+ OUString name( reader.assureQuotedToken() );
+ perm <<= security::RuntimePermission( name );
+ }
+ else if (token.equals( s_allPermission )) // AllPermission
+ {
+ perm <<= security::AllPermission();
+ }
+ else
+ {
+ reader.error( OUSTR("expected permission type!") );
+ }
+
+ reader.assureToken( ';' );
+
+ // insert
+ if (userId.getLength())
+ {
+ Sequence< Any > perms( userPermissions[ userId ] );
+ sal_Int32 len = perms.getLength();
+ perms.realloc( len +1 );
+ perms[ len ] = perm;
+ userPermissions[ userId ] = perms;
+ }
+ else
+ {
+ sal_Int32 len = defaultPermissions.getLength();
+ defaultPermissions.realloc( len +1 );
+ defaultPermissions[ len ] = perm;
+ }
+
+ token = reader.assureToken(); // next permissions token
+ }
+
+ reader.assureToken( ';' ); // semi
+ token = reader.getToken(); // next grant token
+ }
+
+ // assign new ones
+ MutexGuard guard( m_mutex );
+ m_defaultPermissions = defaultPermissions;
+ m_userPermissions = userPermissions;
+}
+
+//__________________________________________________________________________________________________
+OUString FilePolicy::getImplementationName()
+ throw (RuntimeException)
+{
+ return s_implName;
+}
+//__________________________________________________________________________________________________
+sal_Bool FilePolicy::supportsService( OUString const & serviceName )
+ throw (RuntimeException)
+{
+ OUString const * pNames = s_serviceNames.getConstArray();
+ for ( sal_Int32 nPos = s_serviceNames.getLength(); nPos--; )
+ {
+ if (serviceName.equals( pNames[ nPos ] ))
+ {
+ return sal_True;
+ }
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > FilePolicy::getSupportedServiceNames()
+ throw (RuntimeException)
+{
+ return s_serviceNames;
+}
+}
+//##################################################################################################
+namespace stoc_bootstrap
+{
+//--------------------------------------------------------------------------------------------------
+Reference< XInterface > SAL_CALL filepolicy_create(
+ Reference< XComponentContext > const & xComponentContext )
+ SAL_THROW( (Exception) )
+{
+ return (OWeakObject *)new stoc_sec::FilePolicy( xComponentContext );
+}
+//--------------------------------------------------------------------------------------------------
+Sequence< OUString > filepolicy_getSupportedServiceNames() SAL_THROW( () )
+{
+ return stoc_sec::s_serviceNames;
+}
+//--------------------------------------------------------------------------------------------------
+OUString filepolicy_getImplementationName() SAL_THROW( () )
+{
+ return stoc_sec::s_implName;
+}
+}
diff --git a/stoc/source/security/lru_cache.h b/stoc/source/security/lru_cache.h
new file mode 100644
index 000000000000..3f2312a67aab
--- /dev/null
+++ b/stoc/source/security/lru_cache.h
@@ -0,0 +1,279 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _STOC_SEC_LRU_CACHE_H_
+#define _STOC_SEC_LRU_CACHE_H_
+
+#include <hash_map>
+
+// __CACHE_DIAGNOSE works only for OUString keys
+#ifdef __CACHE_DIAGNOSE
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <rtl/ustring.hxx>
+#include <rtl/string.hxx>
+#endif
+
+
+namespace stoc_sec
+{
+
+/** Implementation of a least recently used (lru) cache.
+*/
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+class lru_cache
+{
+ struct Entry
+ {
+ t_key m_key;
+ t_val m_val;
+ Entry * m_pred;
+ Entry * m_succ;
+ };
+ typedef ::std::hash_map< t_key, Entry *, t_hashKey, t_equalKey > t_key2element;
+ t_key2element m_key2element;
+ ::std::size_t m_size;
+
+ Entry * m_block;
+ mutable Entry * m_head;
+ mutable Entry * m_tail;
+ inline void toFront( Entry * entry ) const SAL_THROW( () );
+
+public:
+ /** Default Ctor. Does not cache.
+ */
+ inline lru_cache() SAL_THROW( () );
+ /** Ctor.
+
+ @param size number of elements to be cached; default param set to 128
+ */
+ inline lru_cache( ::std::size_t size ) SAL_THROW( () );
+
+ /** Destructor: releases all cached elements and keys.
+ */
+ inline ~lru_cache() SAL_THROW( () );
+
+ /** Retrieves a pointer to value in cache. Returns 0, if none was found.
+
+ @param key a key
+ @return pointer to value or 0
+ */
+ inline t_val const * lookup( t_key const & key ) const SAL_THROW( () );
+
+ /** Sets a value to be cached for given key.
+
+ @param key a key
+ @param val a value
+ */
+ inline void set( t_key const & key, t_val const & val ) SAL_THROW( () );
+
+ /** Tests whether a value is cached for given key.
+
+ @param key a key
+ @return true, if value is cached
+ */
+ inline bool has( t_key const & key ) const SAL_THROW( () );
+
+ /** Clears the cache, releasing all cached elements and keys.
+ */
+ inline void clear() SAL_THROW( () );
+
+ /** Sets the number of elements to be cached. This will clear previous entries.
+
+ @param cacheSize number of elements to be cached
+ */
+ inline void setSize( ::std::size_t size ) SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline void lru_cache< t_key, t_val, t_hashKey, t_equalKey >::setSize(
+ ::std::size_t size ) SAL_THROW( () )
+{
+ m_key2element.clear();
+ delete [] m_block;
+ m_block = 0;
+ m_size = size;
+
+ if (0 < m_size)
+ {
+ m_block = new Entry[ m_size ];
+ m_head = m_block;
+ m_tail = m_block + m_size -1;
+ for ( ::std::size_t nPos = m_size; nPos--; )
+ {
+ m_block[ nPos ].m_pred = m_block + nPos -1;
+ m_block[ nPos ].m_succ = m_block + nPos +1;
+ }
+ }
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline lru_cache< t_key, t_val, t_hashKey, t_equalKey >::lru_cache(
+ ::std::size_t size ) SAL_THROW( () )
+ : m_size( 0 )
+ , m_block( 0 )
+{
+ setSize( size );
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline lru_cache< t_key, t_val, t_hashKey, t_equalKey >::lru_cache() SAL_THROW( () )
+ : m_size( 0 )
+ , m_block( 0 )
+{
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline lru_cache< t_key, t_val, t_hashKey, t_equalKey >::~lru_cache()
+ SAL_THROW( () )
+{
+ delete [] m_block;
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline void lru_cache< t_key, t_val, t_hashKey, t_equalKey >::toFront(
+ Entry * entry ) const SAL_THROW( () )
+{
+ if (entry != m_head)
+ {
+ // cut out element
+ if (entry == m_tail)
+ {
+ m_tail = entry->m_pred;
+ }
+ else
+ {
+ entry->m_succ->m_pred = entry->m_pred;
+ entry->m_pred->m_succ = entry->m_succ;
+ }
+ // push to front
+ m_head->m_pred = entry;
+ entry->m_succ = m_head;
+ m_head = entry;
+ }
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline bool lru_cache< t_key, t_val, t_hashKey, t_equalKey >::has(
+ t_key const & key ) const SAL_THROW( () )
+{
+ typename t_key2element::const_iterator const iFind( m_key2element.find( key ) );
+ return (iFind != m_key2element.end());
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline t_val const * lru_cache< t_key, t_val, t_hashKey, t_equalKey >::lookup(
+ t_key const & key ) const SAL_THROW( () )
+{
+ if (0 < m_size)
+ {
+ typename t_key2element::const_iterator const iFind( m_key2element.find( key ) );
+ if (iFind != m_key2element.end())
+ {
+ Entry * entry = iFind->second;
+ toFront( entry );
+#ifdef __CACHE_DIAGNOSE
+ ::rtl::OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("> retrieved element \"") );
+ buf.append( entry->m_key );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" from cache") );
+ ::rtl::OString str( ::rtl::OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+#endif
+ return &entry->m_val;
+ }
+ }
+ return 0;
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline void lru_cache< t_key, t_val, t_hashKey, t_equalKey >::set(
+ t_key const & key, t_val const & val ) SAL_THROW( () )
+{
+ if (0 < m_size)
+ {
+ typename t_key2element::const_iterator const iFind( m_key2element.find( key ) );
+
+ Entry * entry;
+ if (iFind == m_key2element.end())
+ {
+ entry = m_tail; // erase last element
+#ifdef __CACHE_DIAGNOSE
+ if (entry->m_key.getLength())
+ {
+ ::rtl::OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("> kicking element \"") );
+ buf.append( entry->m_key );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" from cache") );
+ ::rtl::OString str( ::rtl::OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+ }
+#endif
+ m_key2element.erase( entry->m_key );
+ entry->m_key = key;
+ ::std::pair< typename t_key2element::iterator, bool > insertion(
+ m_key2element.insert( typename t_key2element::value_type( key, entry ) ) );
+#ifdef __CACHE_DIAGNOSE
+ OSL_ENSURE( insertion.second, "### inserting new cache entry failed?!" );
+#endif
+ }
+ else
+ {
+ entry = iFind->second;
+#ifdef __CACHE_DIAGNOSE
+ ::rtl::OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("> replacing element \"") );
+ buf.append( entry->m_key );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" in cache") );
+ ::rtl::OString str( ::rtl::OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+#endif
+ }
+ entry->m_val = val;
+ toFront( entry );
+ }
+}
+//__________________________________________________________________________________________________
+template< typename t_key, typename t_val, typename t_hashKey, typename t_equalKey >
+inline void lru_cache< t_key, t_val, t_hashKey, t_equalKey >::clear() SAL_THROW( () )
+{
+ m_key2element.clear();
+ for ( ::std::size_t nPos = m_size; nPos--; )
+ {
+ m_block[ nPos ].m_key = t_key();
+ m_block[ nPos ].m_val = t_val();
+ }
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> cleared cache\n" );
+#endif
+}
+
+}
+
+#endif
diff --git a/stoc/source/security/makefile.mk b/stoc/source/security/makefile.mk
new file mode 100644
index 000000000000..25cddaa22539
--- /dev/null
+++ b/stoc/source/security/makefile.mk
@@ -0,0 +1,62 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=stoc
+TARGET = security
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT=$(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/permissions.obj \
+ $(SLO)$/access_controller.obj \
+ $(SLO)$/file_policy.obj
+
+.IF "$(debug)" != ""
+
+# some diagnose
+.IF "$(diag)" == "full"
+CFLAGS += -D__DIAGNOSE -D__CACHE_DIAGNOSE
+.ELIF "$(diag)" == "cache"
+CFLAGS += -D__CACHE_DIAGNOSE
+.ELIF "$(diag)" != ""
+CFLAGS += -D__DIAGNOSE
+.ENDIF
+
+.ENDIF
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/stoc/source/security/permissions.cxx b/stoc/source/security/permissions.cxx
new file mode 100644
index 000000000000..f889725986b7
--- /dev/null
+++ b/stoc/source/security/permissions.cxx
@@ -0,0 +1,666 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <vector>
+
+#include <osl/process.h>
+#include <osl/socket.hxx>
+#include <osl/mutex.hxx>
+
+#include <rtl/string.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <com/sun/star/security/RuntimePermission.hpp>
+#include <com/sun/star/security/AllPermission.hpp>
+#include <com/sun/star/io/FilePermission.hpp>
+#include <com/sun/star/connection/SocketPermission.hpp>
+#include <com/sun/star/security/AccessControlException.hpp>
+
+#include "permissions.h"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+using namespace ::std;
+using namespace ::osl;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+
+namespace stoc_sec
+{
+
+//--------------------------------------------------------------------------------------------------
+static inline sal_Int32 makeMask(
+ OUString const & items, char const * const * strings ) SAL_THROW( () )
+{
+ sal_Int32 mask = 0;
+
+ sal_Int32 n = 0;
+ do
+ {
+ OUString item( items.getToken( 0, ',', n ).trim() );
+ if (! item.getLength())
+ continue;
+ sal_Int32 nPos = 0;
+ while (strings[ nPos ])
+ {
+ if (item.equalsAscii( strings[ nPos ] ))
+ {
+ mask |= (0x80000000 >> nPos);
+ break;
+ }
+ ++nPos;
+ }
+#if OSL_DEBUG_LEVEL > 0
+ if (! strings[ nPos ])
+ {
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("### ignoring unknown socket action: ") );
+ buf.append( item );
+ ::rtl::OString str( ::rtl::OUStringToOString(
+ buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+ }
+#endif
+ }
+ while (n >= 0); // all items
+ return mask;
+}
+//--------------------------------------------------------------------------------------------------
+static inline OUString makeStrings(
+ sal_Int32 mask, char const * const * strings ) SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ while (mask)
+ {
+ if (0x80000000 & mask)
+ {
+ buf.appendAscii( *strings );
+ if (mask << 1) // more items following
+ buf.append( (sal_Unicode)',' );
+ }
+ mask = (mask << 1);
+ ++strings;
+ }
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//==================================================================================================
+class SocketPermission : public Permission
+{
+ static char const * s_actions [];
+ sal_Int32 m_actions;
+
+ OUString m_host;
+ sal_Int32 m_lowerPort;
+ sal_Int32 m_upperPort;
+ mutable OUString m_ip;
+ mutable bool m_resolveErr;
+ mutable bool m_resolvedHost;
+ bool m_wildCardHost;
+
+ inline bool resolveHost() const SAL_THROW( () );
+
+public:
+ SocketPermission(
+ connection::SocketPermission const & perm,
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () );
+ virtual bool implies( Permission const & perm ) const SAL_THROW( () );
+ virtual OUString toString() const SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+char const * SocketPermission::s_actions [] = { "accept", "connect", "listen", "resolve", 0 };
+//__________________________________________________________________________________________________
+SocketPermission::SocketPermission(
+ connection::SocketPermission const & perm,
+ ::rtl::Reference< Permission > const & next )
+ SAL_THROW( () )
+ : Permission( SOCKET, next )
+ , m_actions( makeMask( perm.Actions, s_actions ) )
+ , m_host( perm.Host )
+ , m_lowerPort( 0 )
+ , m_upperPort( 65535 )
+ , m_resolveErr( false )
+ , m_resolvedHost( false )
+ , m_wildCardHost( perm.Host.getLength() && '*' == perm.Host.pData->buffer[ 0 ] )
+{
+ if (0xe0000000 & m_actions) // if any (except resolve) is given => resolve implied
+ m_actions |= 0x10000000;
+
+ // separate host from portrange
+ sal_Int32 colon = m_host.indexOf( ':' );
+ if (colon >= 0) // port [range] given
+ {
+ sal_Int32 minus = m_host.indexOf( '-', colon +1 );
+ if (minus < 0)
+ {
+ m_lowerPort = m_upperPort = m_host.copy( colon +1 ).toInt32();
+ }
+ else if (minus == (colon +1)) // -N
+ {
+ m_upperPort = m_host.copy( minus +1 ).toInt32();
+ }
+ else if (minus == (m_host.getLength() -1)) // N-
+ {
+ m_lowerPort = m_host.copy( colon +1, m_host.getLength() -1 -colon -1 ).toInt32();
+ }
+ else // A-B
+ {
+ m_lowerPort = m_host.copy( colon +1, minus - colon -1 ).toInt32();
+ m_upperPort = m_host.copy( minus +1, m_host.getLength() -minus -1 ).toInt32();
+ }
+ m_host = m_host.copy( 0, colon );
+ }
+}
+//__________________________________________________________________________________________________
+inline bool SocketPermission::resolveHost() const SAL_THROW( () )
+{
+ if (m_resolveErr)
+ return false;
+
+ if (! m_resolvedHost)
+ {
+ // dns lookup
+ SocketAddr addr;
+ SocketAddr::resolveHostname( m_host, addr );
+ OUString ip;
+ m_resolveErr = (::osl_Socket_Ok != ::osl_getDottedInetAddrOfSocketAddr(
+ addr.getHandle(), &ip.pData ));
+ if (m_resolveErr)
+ return false;
+
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! m_resolvedHost)
+ {
+ m_ip = ip;
+ m_resolvedHost = true;
+ }
+ }
+ return m_resolvedHost;
+}
+//__________________________________________________________________________________________________
+bool SocketPermission::implies( Permission const & perm ) const SAL_THROW( () )
+{
+ // check type
+ if (SOCKET != perm.m_type)
+ return false;
+ SocketPermission const & demanded = static_cast< SocketPermission const & >( perm );
+
+ // check actions
+ if ((m_actions & demanded.m_actions) != demanded.m_actions)
+ return false;
+
+ // check ports
+ if (demanded.m_lowerPort < m_lowerPort)
+ return false;
+ if (demanded.m_upperPort > m_upperPort)
+ return false;
+
+ // quick check host (DNS names: RFC 1034/1035)
+ if (m_host.equalsIgnoreAsciiCase( demanded.m_host ))
+ return true;
+ // check for host wildcards
+ if (m_wildCardHost)
+ {
+ OUString const & demanded_host = demanded.m_host;
+ if (demanded_host.getLength() <= m_host.getLength())
+ return false;
+ sal_Int32 len = m_host.getLength() -1; // skip star
+ return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ demanded_host.getStr() + demanded_host.getLength() - len, len,
+ m_host.pData->buffer + 1, len ));
+ }
+ if (demanded.m_wildCardHost)
+ return false;
+
+ // compare IP addresses
+ if (! resolveHost())
+ return false;
+ if (! demanded.resolveHost())
+ return false;
+ return (sal_False != m_ip.equals( demanded.m_ip ));
+}
+//__________________________________________________________________________________________________
+OUString SocketPermission::toString() const SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ // host
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.connection.SocketPermission (host=\"") );
+ buf.append( m_host );
+ if (m_resolvedHost)
+ {
+ buf.append( (sal_Unicode)'[' );
+ buf.append( m_ip );
+ buf.append( (sal_Unicode)']' );
+ }
+ // port
+ if (0 != m_lowerPort || 65535 != m_upperPort)
+ {
+ buf.append( (sal_Unicode)':' );
+ if (m_lowerPort > 0)
+ buf.append( m_lowerPort );
+ if (m_upperPort > m_lowerPort)
+ {
+ buf.append( (sal_Unicode)'-' );
+ if (m_upperPort < 65535)
+ buf.append( m_upperPort );
+ }
+ }
+ // actions
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") );
+ buf.append( makeStrings( m_actions, s_actions ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//==================================================================================================
+class FilePermission : public Permission
+{
+ static char const * s_actions [];
+ sal_Int32 m_actions;
+
+ OUString m_url;
+ bool m_allFiles;
+
+public:
+ FilePermission(
+ io::FilePermission const & perm,
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () );
+ virtual bool implies( Permission const & perm ) const SAL_THROW( () );
+ virtual OUString toString() const SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+char const * FilePermission::s_actions [] = { "read", "write", "execute", "delete", 0 };
+//--------------------------------------------------------------------------------------------------
+static OUString const & getWorkingDir() SAL_THROW( () )
+{
+ static OUString * s_workingDir = 0;
+ if (! s_workingDir)
+ {
+ OUString workingDir;
+ ::osl_getProcessWorkingDir( &workingDir.pData );
+
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if (! s_workingDir)
+ {
+ static OUString s_dir( workingDir );
+ s_workingDir = &s_dir;
+ }
+ }
+ return *s_workingDir;
+}
+//__________________________________________________________________________________________________
+FilePermission::FilePermission(
+ io::FilePermission const & perm,
+ ::rtl::Reference< Permission > const & next )
+ SAL_THROW( () )
+ : Permission( FILE, next )
+ , m_actions( makeMask( perm.Actions, s_actions ) )
+ , m_url( perm.URL )
+ , m_allFiles( sal_False != perm.URL.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("<<ALL FILES>>")) )
+{
+ if (! m_allFiles)
+ {
+ if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("*") ))
+ {
+ OUStringBuffer buf( 64 );
+ buf.append( getWorkingDir() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/*") );
+ m_url = buf.makeStringAndClear();
+ }
+ else if (m_url.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("-") ))
+ {
+ OUStringBuffer buf( 64 );
+ buf.append( getWorkingDir() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("/-") );
+ m_url = buf.makeStringAndClear();
+ }
+ else if (0 != m_url.compareToAscii( RTL_CONSTASCII_STRINGPARAM("file:///") ))
+ {
+ // relative path
+ OUString out;
+ oslFileError rc = ::osl_getAbsoluteFileURL(
+ getWorkingDir().pData, perm.URL.pData, &out.pData );
+ m_url = (osl_File_E_None == rc ? out : perm.URL); // fallback
+ }
+#ifdef SAL_W32
+ // correct win drive letters
+ if (9 < m_url.getLength() && '|' == m_url[ 9 ]) // file:///X|
+ {
+ static OUString s_colon = OUSTR(":");
+ // common case in API is a ':' (sal), so convert '|' to ':'
+ m_url = m_url.replaceAt( 9, 1, s_colon );
+ }
+#endif
+ }
+}
+//__________________________________________________________________________________________________
+bool FilePermission::implies( Permission const & perm ) const SAL_THROW( () )
+{
+ // check type
+ if (FILE != perm.m_type)
+ return false;
+ FilePermission const & demanded = static_cast< FilePermission const & >( perm );
+
+ // check actions
+ if ((m_actions & demanded.m_actions) != demanded.m_actions)
+ return false;
+
+ // check url
+ if (m_allFiles)
+ return true;
+ if (demanded.m_allFiles)
+ return false;
+
+#ifdef SAL_W32
+ if (m_url.equalsIgnoreAsciiCase( demanded.m_url ))
+ return true;
+#else
+ if (m_url.equals( demanded.m_url ))
+ return true;
+#endif
+ if (m_url.getLength() > demanded.m_url.getLength())
+ return false;
+ // check /- wildcard: all files and recursive in that path
+ if (1 < m_url.getLength() &&
+ 0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/-" ))
+ {
+ // demanded url must start with granted path (including path trailing path sep)
+ sal_Int32 len = m_url.getLength() -1;
+#ifdef SAL_W32
+ return (0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len ));
+#else
+ return (0 == ::rtl_ustr_reverseCompare_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len ));
+#endif
+ }
+ // check /* wildcard: all files in that path (not recursive!)
+ if (1 < m_url.getLength() &&
+ 0 == ::rtl_ustr_ascii_compare_WithLength( m_url.getStr() + m_url.getLength() - 2, 2, "/*" ))
+ {
+ // demanded url must start with granted path (including path trailing path sep)
+ sal_Int32 len = m_url.getLength() -1;
+#ifdef SAL_W32
+ return ((0 == ::rtl_ustr_compareIgnoreAsciiCase_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) &&
+ (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes
+#else
+ return ((0 == ::rtl_ustr_reverseCompare_WithLength(
+ demanded.m_url.pData->buffer, len, m_url.pData->buffer, len )) &&
+ (0 > demanded.m_url.indexOf( '/', len ))); // in addition, no deeper pathes
+#endif
+ }
+ return false;
+}
+//__________________________________________________________________________________________________
+OUString FilePermission::toString() const SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ // url
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("com.sun.star.io.FilePermission (url=\"") );
+ buf.append( m_url );
+ // actions
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\", actions=\"") );
+ buf.append( makeStrings( m_actions, s_actions ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//==================================================================================================
+class RuntimePermission : public Permission
+{
+ OUString m_name;
+
+public:
+ inline RuntimePermission(
+ security::RuntimePermission const & perm,
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () )
+ : Permission( RUNTIME, next )
+ , m_name( perm.Name )
+ {}
+ virtual bool implies( Permission const & perm ) const SAL_THROW( () );
+ virtual OUString toString() const SAL_THROW( () );
+};
+//__________________________________________________________________________________________________
+bool RuntimePermission::implies( Permission const & perm ) const SAL_THROW( () )
+{
+ // check type
+ if (RUNTIME != perm.m_type)
+ return false;
+ RuntimePermission const & demanded = static_cast< RuntimePermission const & >( perm );
+
+ // check name
+ return (sal_False != m_name.equals( demanded.m_name ));
+}
+//__________________________________________________________________________________________________
+OUString RuntimePermission::toString() const SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.security.RuntimePermission (name=\"") );
+ buf.append( m_name );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\")") );
+ return buf.makeStringAndClear();
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+bool AllPermission::implies( Permission const & ) const SAL_THROW( () )
+{
+ return true;
+}
+//__________________________________________________________________________________________________
+OUString AllPermission::toString() const SAL_THROW( () )
+{
+ return OUSTR("com.sun.star.security.AllPermission");
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+PermissionCollection::PermissionCollection(
+ Sequence< Any > const & permissions, PermissionCollection const & addition )
+ SAL_THROW( (RuntimeException) )
+ : m_head( addition.m_head )
+{
+ Any const * perms = permissions.getConstArray();
+ for ( sal_Int32 nPos = permissions.getLength(); nPos--; )
+ {
+ Any const & perm = perms[ nPos ];
+ Type const & perm_type = perm.getValueType();
+
+ // supported permission types
+ if (perm_type.equals( ::getCppuType( (io::FilePermission const *)0 ) ))
+ {
+ m_head = new FilePermission(
+ *reinterpret_cast< io::FilePermission const * >( perm.pData ), m_head );
+ }
+ else if (perm_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) ))
+ {
+ m_head = new SocketPermission(
+ *reinterpret_cast< connection::SocketPermission const * >( perm.pData ), m_head );
+ }
+ else if (perm_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) ))
+ {
+ m_head = new RuntimePermission(
+ *reinterpret_cast< security::RuntimePermission const * >( perm.pData ), m_head );
+ }
+ else if (perm_type.equals( ::getCppuType( (security::AllPermission const *)0 ) ))
+ {
+ m_head = new AllPermission( m_head );
+ }
+ else
+ {
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "checking for unsupported permission type: ") );
+ buf.append( perm_type.getTypeName() );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+ }
+}
+#ifdef __DIAGNOSE
+//__________________________________________________________________________________________________
+Sequence< OUString > PermissionCollection::toStrings() const SAL_THROW( () )
+{
+ vector< OUString > strings;
+ strings.reserve( 8 );
+ for ( Permission * perm = m_head.get(); perm; perm = perm->m_next.get() )
+ {
+ strings.push_back( perm->toString() );
+ }
+ return Sequence< OUString >(
+ strings.empty() ? 0 : &strings[ 0 ], strings.size() );
+}
+#endif
+//__________________________________________________________________________________________________
+inline static bool __implies(
+ ::rtl::Reference< Permission > const & head, Permission const & demanded ) SAL_THROW( () )
+{
+ for ( Permission * perm = head.get(); perm; perm = perm->m_next.get() )
+ {
+ if (perm->implies( demanded ))
+ return true;
+ }
+ return false;
+}
+
+#ifdef __DIAGNOSE
+//--------------------------------------------------------------------------------------------------
+static void demanded_diag(
+ Permission const & perm )
+ SAL_THROW( () )
+{
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("demanding ") );
+ buf.append( perm.toString() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" => ok.") );
+ ::rtl::OString str(
+ ::rtl::OUStringToOString( buf.makeStringAndClear(), RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( str.getStr() );
+}
+#endif
+//--------------------------------------------------------------------------------------------------
+static void throwAccessControlException(
+ Permission const & perm, Any const & demanded_perm )
+ SAL_THROW( (security::AccessControlException) )
+{
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("access denied: ") );
+ buf.append( perm.toString() );
+ throw security::AccessControlException(
+ buf.makeStringAndClear(), Reference< XInterface >(), demanded_perm );
+}
+//==================================================================================================
+void PermissionCollection::checkPermission( Any const & perm ) const
+ SAL_THROW( (RuntimeException) )
+{
+ Type const & demanded_type = perm.getValueType();
+
+ // supported permission types
+ // stack object of SimpleReferenceObject are ok, as long as they are not
+ // assigned to a ::rtl::Reference<> (=> delete this)
+ if (demanded_type.equals( ::getCppuType( (io::FilePermission const *)0 ) ))
+ {
+ FilePermission demanded(
+ *reinterpret_cast< io::FilePermission const * >( perm.pData ) );
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else if (demanded_type.equals( ::getCppuType( (connection::SocketPermission const *)0 ) ))
+ {
+ SocketPermission demanded(
+ *reinterpret_cast< connection::SocketPermission const * >( perm.pData ) );
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else if (demanded_type.equals( ::getCppuType( (security::RuntimePermission const *)0 ) ))
+ {
+ RuntimePermission demanded(
+ *reinterpret_cast< security::RuntimePermission const * >( perm.pData ) );
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else if (demanded_type.equals( ::getCppuType( (security::AllPermission const *)0 ) ))
+ {
+ AllPermission demanded;
+ if (__implies( m_head, demanded ))
+ {
+#ifdef __DIAGNOSE
+ demanded_diag( demanded );
+#endif
+ return;
+ }
+ throwAccessControlException( demanded, perm );
+ }
+ else
+ {
+ OUStringBuffer buf( 48 );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("checking for unsupported permission type: ") );
+ buf.append( demanded_type.getTypeName() );
+ throw RuntimeException(
+ buf.makeStringAndClear(), Reference< XInterface >() );
+ }
+}
+
+}
diff --git a/stoc/source/security/permissions.h b/stoc/source/security/permissions.h
new file mode 100644
index 000000000000..4599023eb205
--- /dev/null
+++ b/stoc/source/security/permissions.h
@@ -0,0 +1,102 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _STOC_SEC_PERMISSIONS_H_
+#define _STOC_SEC_PERMISSIONS_H_
+
+#include <rtl/unload.h>
+#include <rtl/ref.hxx>
+#include <rtl/ustring.hxx>
+#include <salhelper/simplereferenceobject.hxx>
+
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/uno/RuntimeException.hpp>
+
+extern ::rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_sec
+{
+//==================================================================================================
+class Permission : public ::salhelper::SimpleReferenceObject
+{
+public:
+ ::rtl::Reference< Permission > m_next;
+ // mode
+ enum t_type { ALL, RUNTIME, SOCKET, FILE } m_type;
+
+ inline Permission(
+ t_type type,
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () )
+ : m_next( next )
+ , m_type( type )
+ {}
+
+ virtual bool implies( Permission const & perm ) const SAL_THROW( () ) = 0;
+ virtual ::rtl::OUString toString() const SAL_THROW( () ) = 0;
+};
+//==================================================================================================
+class AllPermission : public Permission
+{
+public:
+ inline AllPermission(
+ ::rtl::Reference< Permission > const & next = ::rtl::Reference< Permission >() )
+ SAL_THROW( () )
+ : Permission( ALL, next )
+ {}
+
+ virtual bool implies( Permission const & ) const SAL_THROW( () );
+ virtual ::rtl::OUString toString() const SAL_THROW( () );
+};
+
+//==================================================================================================
+class PermissionCollection
+{
+ ::rtl::Reference< Permission > m_head;
+public:
+ inline PermissionCollection() SAL_THROW( () )
+ {}
+ inline PermissionCollection( PermissionCollection const & collection ) SAL_THROW( () )
+ : m_head( collection.m_head )
+ {}
+ inline PermissionCollection( ::rtl::Reference< Permission > const & single ) SAL_THROW( () )
+ : m_head( single )
+ {}
+ PermissionCollection(
+ ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > const & permissions,
+ PermissionCollection const & addition = PermissionCollection() )
+ SAL_THROW( (::com::sun::star::uno::RuntimeException) );
+#ifdef __DIAGNOSE
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > toStrings() const SAL_THROW( () );
+#endif
+ void checkPermission( ::com::sun::star::uno::Any const & perm ) const
+ SAL_THROW( (::com::sun::star::uno::RuntimeException) );
+};
+
+}
+
+#endif
diff --git a/stoc/source/servicemanager/makefile.mk b/stoc/source/servicemanager/makefile.mk
new file mode 100644
index 000000000000..f86c65d5f052
--- /dev/null
+++ b/stoc/source/servicemanager/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = servicemgr
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT=$(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/servicemanager.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/stoc/source/servicemanager/servicemanager.cxx b/stoc/source/servicemanager/servicemanager.cxx
new file mode 100644
index 000000000000..97eb82b6b997
--- /dev/null
+++ b/stoc/source/servicemanager/servicemanager.cxx
@@ -0,0 +1,2059 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/mutex.hxx>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+
+#include <hash_map>
+#include <hash_set>
+#include <list>
+#include <uno/mapping.hxx>
+#include <uno/dispatcher.h>
+#include <cppuhelper/queryinterface.hxx>
+#include <cppuhelper/weakref.hxx>
+#include <cppuhelper/component.hxx>
+#include <cppuhelper/factory.hxx>
+#ifndef _CPPUHELPER_IMPLBASE1_HXX
+#include <cppuhelper/implbase1.hxx>
+#endif
+#include <cppuhelper/typeprovider.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+#include <rtl/unload.h>
+#include <cppuhelper/component_context.hxx>
+#include <cppuhelper/bootstrap.hxx>
+#include <cppuhelper/compbase8.hxx>
+
+
+#include <com/sun/star/lang/XUnoTunnel.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/lang/XMultiComponentFactory.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/DisposedException.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/container/XElementAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/uno/XUnloadingPreference.hpp>
+
+#include <bootstrapservices.hxx>
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::container;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+using namespace std;
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+namespace stoc_bootstrap
+{
+Sequence< OUString > smgr_wrapper_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") );
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString smgr_wrapper_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManagerWrapper" ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+
+Sequence< OUString > smgr_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(2);
+ seqNames.getArray()[0] = OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory") );
+ seqNames.getArray()[1] = OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.ServiceManager") );
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString smgr_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName(
+ RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.OServiceManager" ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+
+Sequence< OUString > regsmgr_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(2);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.MultiServiceFactory"));
+ seqNames.getArray()[1] = OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.lang.RegistryServiceManager"));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString regsmgr_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.stoc.ORegistryServiceManager" ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+}
+
+namespace stoc_smgr
+{
+static Sequence< sal_Int8 > smgr_getImplementationId()
+{
+ static OImplementationId * s_pId = 0;
+ if (! s_pId)
+ {
+ MutexGuard aGuard( Mutex::getGlobalMutex() );
+ if (! s_pId)
+ {
+ static OImplementationId s_aId;
+ s_pId = &s_aId;
+ }
+ }
+ return s_pId->getImplementationId();
+}
+
+
+static Sequence< OUString > retrieveAsciiValueList(
+ const Reference< XSimpleRegistry > &xReg, const OUString &keyName )
+{
+ Reference< XEnumerationAccess > xAccess( xReg, UNO_QUERY );
+ Sequence< OUString > seq;
+ if( xAccess.is() )
+ {
+ Reference< XEnumeration > xEnum = xAccess->createEnumeration();
+ while( xEnum.is() && xEnum->hasMoreElements() )
+ {
+ Reference< XSimpleRegistry > xTempReg;
+ xEnum->nextElement() >>= xTempReg;
+ if( xTempReg.is() )
+ {
+ Sequence< OUString > seq2 = retrieveAsciiValueList( xTempReg, keyName );
+
+ if( seq2.getLength() )
+ {
+ sal_Int32 n1Len = seq.getLength();
+ sal_Int32 n2Len = seq2.getLength();
+
+ seq.realloc( n1Len + n2Len );
+ const OUString *pSource = seq2.getConstArray();
+ OUString *pTarget = seq.getArray();
+ for( int i = 0 ; i < n2Len ; i ++ )
+ {
+ pTarget[i+n1Len] = pSource[i];
+ }
+ }
+ }
+ }
+ }
+ else if( xReg.is () )
+ {
+ try
+ {
+ Reference< XRegistryKey > rRootKey = xReg->getRootKey();
+ if( rRootKey.is() )
+ {
+ Reference<XRegistryKey > xKey = rRootKey->openKey(keyName);
+ if( xKey.is() )
+ {
+ seq = xKey->getAsciiListValue();
+ }
+ }
+ }
+ catch( InvalidRegistryException & )
+ {
+ }
+ catch (InvalidValueException &)
+ {
+ }
+ }
+ return seq;
+}
+
+/*****************************************************************************
+ Enumeration by ServiceName
+*****************************************************************************/
+struct hashRef_Impl
+{
+ size_t operator()(const Reference<XInterface > & rName) const
+ {
+ // query to XInterface. The cast to XInterface* must be the same for the same object
+ Reference<XInterface > x( Reference<XInterface >::query( rName ) );
+ return (size_t)x.get();
+ }
+};
+
+struct equaltoRef_Impl
+{
+ size_t operator()(const Reference<XInterface > & rName1, const Reference<XInterface > & rName2 ) const
+ { return rName1 == rName2; }
+};
+
+typedef hash_set
+<
+ Reference<XInterface >,
+ hashRef_Impl,
+ equaltoRef_Impl
+> HashSet_Ref;
+
+
+class ServiceEnumeration_Impl : public WeakImplHelper1< XEnumeration >
+{
+public:
+ ServiceEnumeration_Impl( const Sequence< Reference<XInterface > > & rFactories )
+ : aFactories( rFactories )
+ , nIt( 0 )
+ { g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt ); }
+ virtual ~ServiceEnumeration_Impl()
+ { g_moduleCount.modCnt.release( &g_moduleCount.modCnt ); }
+
+ // XEnumeration
+ sal_Bool SAL_CALL hasMoreElements()
+ throw(::com::sun::star::uno::RuntimeException);
+ Any SAL_CALL nextElement()
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+private:
+ Mutex aMutex;
+ Sequence< Reference<XInterface > > aFactories;
+ sal_Int32 nIt;
+};
+
+// XEnumeration
+sal_Bool ServiceEnumeration_Impl::hasMoreElements() throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( aMutex );
+ return nIt != aFactories.getLength();
+}
+
+// XEnumeration
+Any ServiceEnumeration_Impl::nextElement()
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( aMutex );
+ if( nIt == aFactories.getLength() )
+ throw NoSuchElementException();
+
+ return Any( &aFactories.getConstArray()[nIt++], ::getCppuType( (const Reference<XInterface > *)0 ) );
+}
+
+//==================================================================================================
+class PropertySetInfo_Impl : public WeakImplHelper1< beans::XPropertySetInfo >
+{
+ Sequence< beans::Property > m_properties;
+
+public:
+ inline PropertySetInfo_Impl( Sequence< beans::Property > const & properties ) SAL_THROW( () )
+ : m_properties( properties )
+ {}
+
+ // XPropertySetInfo impl
+ virtual Sequence< beans::Property > SAL_CALL getProperties()
+ throw (RuntimeException);
+ virtual beans::Property SAL_CALL getPropertyByName( OUString const & name )
+ throw (beans::UnknownPropertyException, RuntimeException);
+ virtual sal_Bool SAL_CALL hasPropertyByName( OUString const & name )
+ throw (RuntimeException);
+};
+//__________________________________________________________________________________________________
+Sequence< beans::Property > PropertySetInfo_Impl::getProperties()
+ throw (RuntimeException)
+{
+ return m_properties;
+}
+//__________________________________________________________________________________________________
+beans::Property PropertySetInfo_Impl::getPropertyByName( OUString const & name )
+ throw (beans::UnknownPropertyException, RuntimeException)
+{
+ beans::Property const * p = m_properties.getConstArray();
+ for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
+ {
+ if (p[ nPos ].Name.equals( name ))
+ return p[ nPos ];
+ }
+ throw beans::UnknownPropertyException(
+ OUSTR("unknown property: ") + name, Reference< XInterface >() );
+}
+//__________________________________________________________________________________________________
+sal_Bool PropertySetInfo_Impl::hasPropertyByName( OUString const & name )
+ throw (RuntimeException)
+{
+ beans::Property const * p = m_properties.getConstArray();
+ for ( sal_Int32 nPos = m_properties.getLength(); nPos--; )
+ {
+ if (p[ nPos ].Name.equals( name ))
+ return sal_True;
+ }
+ return sal_False;
+}
+
+
+/*****************************************************************************
+ Enumeration by implementation
+*****************************************************************************/
+class ImplementationEnumeration_Impl : public WeakImplHelper1< XEnumeration >
+{
+public:
+ ImplementationEnumeration_Impl( const HashSet_Ref & rImplementationMap )
+ : aImplementationMap( rImplementationMap )
+ , aIt( aImplementationMap.begin() )
+ {
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ }
+ virtual ~ImplementationEnumeration_Impl();
+
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements()
+ throw(::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL nextElement()
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+private:
+ Mutex aMutex;
+ HashSet_Ref aImplementationMap;
+ HashSet_Ref::iterator aIt;
+ sal_Int32 nNext;
+ Reference<XInterface > xNext;
+};
+
+ImplementationEnumeration_Impl::~ImplementationEnumeration_Impl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XEnumeration
+sal_Bool ImplementationEnumeration_Impl::hasMoreElements()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( aMutex );
+ return aIt != aImplementationMap.end();
+}
+
+// XEnumeration
+Any ImplementationEnumeration_Impl::nextElement()
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( aMutex );
+ if( aIt == aImplementationMap.end() )
+ throw NoSuchElementException();
+
+ Any ret( &(*aIt), ::getCppuType( (const Reference<XInterface > *)0 ) );
+ ++aIt;
+ return ret;
+}
+
+/*****************************************************************************
+ Hash tables
+*****************************************************************************/
+struct equalOWString_Impl
+{
+ sal_Bool operator()(const OUString & s1, const OUString & s2) const
+ { return s1 == s2; }
+};
+
+struct hashOWString_Impl
+{
+ size_t operator()(const OUString & rName) const
+ { return rName.hashCode(); }
+};
+
+typedef hash_set
+<
+ OUString,
+ hashOWString_Impl,
+ equalOWString_Impl
+> HashSet_OWString;
+
+typedef hash_multimap
+<
+ OUString,
+ Reference<XInterface >,
+ hashOWString_Impl,
+ equalOWString_Impl
+> HashMultimap_OWString_Interface;
+
+typedef hash_map
+<
+ OUString,
+ Reference<XInterface >,
+ hashOWString_Impl,
+ equalOWString_Impl
+> HashMap_OWString_Interface;
+
+/*****************************************************************************
+ class OServiceManager_Listener
+*****************************************************************************/
+class OServiceManager_Listener : public WeakImplHelper1< XEventListener >
+{
+private:
+ WeakReference<XSet > xSMgr;
+
+public:
+ OServiceManager_Listener( const Reference<XSet > & rSMgr )
+ : xSMgr( rSMgr )
+ {}
+
+ // XEventListener
+ virtual void SAL_CALL disposing(const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+void OServiceManager_Listener::disposing(const EventObject & rEvt )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference<XSet > x( xSMgr );
+ if( x.is() )
+ {
+ try
+ {
+ x->remove( Any( &rEvt.Source, ::getCppuType( (const Reference<XInterface > *)0 ) ) );
+ }
+ catch( const IllegalArgumentException & )
+ {
+ OSL_ENSURE( sal_False, "IllegalArgumentException catched" );
+ }
+ catch( const NoSuchElementException & )
+ {
+ OSL_ENSURE( sal_False, "NoSuchElementException catched" );
+ }
+ }
+}
+
+
+/*****************************************************************************
+ class OServiceManager
+*****************************************************************************/
+struct OServiceManagerMutex
+{
+ Mutex m_mutex;
+};
+
+extern "C" void SAL_CALL smgrUnloadingListener(void* id);
+
+typedef WeakComponentImplHelper8<
+ lang::XMultiServiceFactory, lang::XMultiComponentFactory, lang::XServiceInfo,
+ lang::XInitialization, lang::XUnoTunnel,
+ container::XSet, container::XContentEnumerationAccess,
+ beans::XPropertySet > t_OServiceManager_impl;
+
+class OServiceManager
+ : public OServiceManagerMutex
+ , public t_OServiceManager_impl
+{
+public:
+ friend void SAL_CALL smgrUnloadingListener(void* id);
+
+ OServiceManager( Reference< XComponentContext > const & xContext );
+ virtual ~OServiceManager();
+
+ // XUnoTunnel
+ sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id )
+ throw (RuntimeException);
+
+ // XInitialization
+ void SAL_CALL initialize( Sequence< Any > const & args )
+ throw (Exception);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
+ static OUString getImplementationName_Static() throw(::com::sun::star::uno::RuntimeException)
+ { return stoc_bootstrap::smgr_getImplementationName(); }
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XMultiComponentFactory
+ virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
+ OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext )
+ throw (Exception, RuntimeException);
+ virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
+ OUString const & rServiceSpecifier,
+ Sequence< Any > const & rArguments,
+ Reference< XComponentContext > const & xContext )
+ throw (Exception, RuntimeException);
+// virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
+// throw (RuntimeException);
+
+ // XMultiServiceFactory
+ virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference<XInterface > SAL_CALL createInstance(const OUString &) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+ virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString &, const Sequence<Any >& Arguments) throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // The same as the getAvailableServiceNames, but only uique names
+ Sequence< OUString > getUniqueAvailableServiceNames(
+ HashSet_OWString & aNameSet );
+
+ // XElementAccess
+ virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException);
+
+ // XSet
+ virtual sal_Bool SAL_CALL has( const Any & Element ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insert( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL remove( const Any & Element ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+
+ // XContentEnumerationAccess
+ //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
+ virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(
+ const OUString& aServiceName, Reference< XComponentContext > const & xContext )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+ virtual void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+
+ // XPropertySet
+ Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
+ throw(::com::sun::star::uno::RuntimeException);
+ void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ Any SAL_CALL getPropertyValue(const OUString& PropertyName)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+ void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ inline bool is_disposed() const SAL_THROW( (lang::DisposedException) );
+ inline void check_undisposed() const SAL_THROW( (lang::DisposedException) );
+ virtual void SAL_CALL disposing();
+
+ sal_Bool haveFactoryWithThisImplementation(const OUString& aImplName);
+
+ virtual Sequence< Reference< XInterface > > queryServiceFactories(
+ const OUString& aServiceName, Reference< XComponentContext > const & xContext );
+
+ Reference< XComponentContext > m_xContext;
+
+ Reference< beans::XPropertySetInfo > m_xPropertyInfo;
+
+ sal_Int32 m_nUnloadingListenerId;
+
+ // Does clean up when the unloading mechanism has been set off. It is called from
+ // the listener function smgrUnloadingListener.
+ void onUnloadingNotify();
+ // factories which have been loaded and not inserted( by XSet::insert)
+ // are remembered by this set. Those factories
+ // are not released on a call to onUnloadingNotify
+ HashSet_Ref m_SetLoadedFactories;
+private:
+
+ Reference<XEventListener > getFactoryListener();
+
+
+ HashMultimap_OWString_Interface m_ServiceMap;
+ HashSet_Ref m_ImplementationMap;
+ HashMap_OWString_Interface m_ImplementationNameMap;
+ Reference<XEventListener > xFactoryListener;
+ bool m_bInDisposing;
+};
+
+
+//______________________________________________________________________________
+inline bool OServiceManager::is_disposed() const
+ SAL_THROW( (lang::DisposedException) )
+{
+ // ought to be guarded by m_mutex:
+ return (m_bInDisposing || rBHelper.bDisposed);
+}
+
+//______________________________________________________________________________
+inline void OServiceManager::check_undisposed() const
+ SAL_THROW( (lang::DisposedException) )
+{
+ if (is_disposed())
+ {
+ throw lang::DisposedException(
+ OUSTR("service manager instance has already been disposed!"),
+ (OWeakObject *)this );
+ }
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+class OServiceManagerWrapper : public OServiceManagerMutex, public t_OServiceManager_impl
+{
+ Reference< XComponentContext > m_xContext;
+ OServiceManager * m_root;
+ inline OServiceManager * getRoot() SAL_THROW( (RuntimeException) )
+ {
+ if (! m_root)
+ {
+ throw lang::DisposedException(
+ OUSTR("service manager instance has already been disposed!"),
+ Reference< XInterface >() );
+ }
+ return m_root;
+ }
+
+protected:
+ virtual void SAL_CALL disposing();
+
+public:
+ OServiceManagerWrapper(
+ Reference< XComponentContext > const & xContext )
+ SAL_THROW( (RuntimeException) );
+ virtual ~OServiceManagerWrapper() SAL_THROW( () );
+
+ // XUnoTunnel
+ sal_Int64 SAL_CALL getSomething( Sequence< sal_Int8 > const & id ) throw (RuntimeException)
+ { return getRoot()->getSomething( id ); }
+
+ // XInitialization
+ void SAL_CALL initialize( Sequence< Any > const & args ) throw (Exception)
+ { getRoot()->initialize( args ); }
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw (RuntimeException)
+ { return getRoot()->getImplementationName(); }
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) throw (RuntimeException)
+ { return getRoot()->supportsService( ServiceName ); }
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw (RuntimeException)
+ { return getRoot()->getSupportedServiceNames(); }
+
+ // XMultiComponentFactory
+ virtual Reference< XInterface > SAL_CALL createInstanceWithContext(
+ OUString const & rServiceSpecifier, Reference< XComponentContext > const & xContext )
+ throw (Exception, RuntimeException)
+ { return getRoot()->createInstanceWithContext( rServiceSpecifier, xContext ); }
+ virtual Reference< XInterface > SAL_CALL createInstanceWithArgumentsAndContext(
+ OUString const & rServiceSpecifier,
+ Sequence< Any > const & rArguments,
+ Reference< XComponentContext > const & xContext )
+ throw (Exception, RuntimeException)
+ { return getRoot()->createInstanceWithArgumentsAndContext( rServiceSpecifier, rArguments, xContext ); }
+// virtual Sequence< OUString > SAL_CALL getAvailableServiceNames()
+// throw (RuntimeException);
+
+ // XMultiServiceFactory
+ virtual Sequence< OUString > SAL_CALL getAvailableServiceNames() throw (RuntimeException)
+ { return getRoot()->getAvailableServiceNames(); }
+ virtual Reference<XInterface > SAL_CALL createInstance(const OUString & name) throw (Exception)
+ { return getRoot()->createInstanceWithContext( name, m_xContext ); }
+ virtual Reference<XInterface > SAL_CALL createInstanceWithArguments(const OUString & name, const Sequence<Any >& Arguments) throw (Exception)
+ { return getRoot()->createInstanceWithArgumentsAndContext( name, Arguments, m_xContext ); }
+
+ // XElementAccess
+ virtual Type SAL_CALL getElementType() throw (RuntimeException)
+ { return getRoot()->getElementType(); }
+ virtual sal_Bool SAL_CALL hasElements() throw (RuntimeException)
+ { return getRoot()->hasElements(); }
+
+ // XEnumerationAccess
+ virtual Reference<XEnumeration > SAL_CALL createEnumeration() throw (RuntimeException)
+ { return getRoot()->createEnumeration(); }
+
+ // XSet
+ virtual sal_Bool SAL_CALL has( const Any & Element ) throw (RuntimeException)
+ { return getRoot()->has( Element ); }
+ virtual void SAL_CALL insert( const Any & Element ) throw (lang::IllegalArgumentException, container::ElementExistException, RuntimeException)
+ { getRoot()->insert( Element ); }
+ virtual void SAL_CALL remove( const Any & Element ) throw (lang::IllegalArgumentException, container::NoSuchElementException, RuntimeException)
+ { getRoot()->remove( Element ); }
+
+ // XContentEnumerationAccess
+ //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
+ virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw (RuntimeException)
+ { return getRoot()->createContentEnumeration( aServiceName, m_xContext ); }
+
+ // XPropertySet
+ Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo() throw (RuntimeException)
+ { return getRoot()->getPropertySetInfo(); }
+
+ void SAL_CALL setPropertyValue(const OUString& PropertyName, const Any& aValue)
+ throw (beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException);
+ Any SAL_CALL getPropertyValue(const OUString& PropertyName)
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException);
+
+ void SAL_CALL addPropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
+ { getRoot()->addPropertyChangeListener( PropertyName, aListener ); }
+ void SAL_CALL removePropertyChangeListener(const OUString& PropertyName, const Reference<XPropertyChangeListener >& aListener)
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
+ { getRoot()->removePropertyChangeListener( PropertyName, aListener ); }
+ void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
+ { getRoot()->addVetoableChangeListener( PropertyName, aListener ); }
+ void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener >& aListener)
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
+ { getRoot()->removeVetoableChangeListener( PropertyName, aListener ); }
+};
+//__________________________________________________________________________________________________
+void SAL_CALL OServiceManagerWrapper::setPropertyValue(
+ const OUString& PropertyName, const Any& aValue )
+ throw (beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException, RuntimeException)
+{
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
+ {
+ Reference< XComponentContext > xContext;
+ if (aValue >>= xContext)
+ {
+ MutexGuard aGuard( m_mutex );
+ m_xContext = xContext;
+ }
+ else
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ),
+ (OWeakObject *)this, 1 );
+ }
+ }
+ else
+ {
+ getRoot()->setPropertyValue( PropertyName, aValue );
+ }
+}
+//__________________________________________________________________________________________________
+Any SAL_CALL OServiceManagerWrapper::getPropertyValue(
+ const OUString& PropertyName )
+ throw (beans::UnknownPropertyException, lang::WrappedTargetException, RuntimeException)
+{
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
+ {
+ MutexGuard aGuard( m_mutex );
+ if( m_xContext.is() )
+ return makeAny( m_xContext );
+ else
+ return Any();
+ }
+ else
+ {
+ return getRoot()->getPropertyValue( PropertyName );
+ }
+}
+//__________________________________________________________________________________________________
+void OServiceManagerWrapper::disposing()
+{
+ m_xContext.clear();
+
+ if (m_root)
+ {
+// no m_root->dispose(), because every context disposes its service manager...
+ m_root->release();
+ m_root = 0;
+ }
+}
+//__________________________________________________________________________________________________
+OServiceManagerWrapper::~OServiceManagerWrapper() SAL_THROW( () )
+{
+ if (m_root)
+ {
+ m_root->release();
+ m_root = 0;
+ }
+
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+OServiceManagerWrapper::OServiceManagerWrapper(
+ Reference< XComponentContext > const & xContext )
+ SAL_THROW( (RuntimeException) )
+ : t_OServiceManager_impl( m_mutex )
+ , m_xContext( xContext )
+ , m_root( 0 )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+
+ Reference< XUnoTunnel > xTunnel( m_xContext->getServiceManager(), UNO_QUERY );
+ OSL_ASSERT( xTunnel.is() );
+ if (xTunnel.is())
+ {
+ m_root = reinterpret_cast< OServiceManager * >(
+ xTunnel->getSomething( smgr_getImplementationId() ) );
+ OSL_ASSERT( m_root );
+ if (m_root)
+ {
+ m_root->acquire();
+ }
+ }
+
+ if (! m_root)
+ {
+ throw RuntimeException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("can only wrap OServiceManager instances!") ),
+ Reference< XInterface >() );
+ }
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+// XUnoTunnel
+sal_Int64 OServiceManager::getSomething( Sequence< sal_Int8 > const & id )
+ throw (RuntimeException)
+{
+ check_undisposed();
+ if (id == smgr_getImplementationId())
+ return reinterpret_cast< sal_Int64 >(this);
+ else
+ return 0;
+}
+
+/**
+ * Create a ServiceManager
+ */
+OServiceManager::OServiceManager( Reference< XComponentContext > const & xContext )
+ : t_OServiceManager_impl( m_mutex )
+ , m_xContext( xContext )
+ , m_bInDisposing( false )
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+ m_nUnloadingListenerId= rtl_addUnloadingListener( smgrUnloadingListener, this);
+}
+
+/**
+ * Destroy the ServiceManager
+ */
+OServiceManager::~OServiceManager()
+{
+ if( m_nUnloadingListenerId != 0)
+ rtl_removeUnloadingListener( m_nUnloadingListenerId );
+
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// Removes entries in m_ServiceMap, m_ImplementationNameMap and m_ImplementationNameMap
+// if those entries have not been inserted through XSet::insert. Therefore the entries
+// are compared with the entries in m_SetLoadedFactories.
+void OServiceManager::onUnloadingNotify()
+{
+ MutexGuard aGuard( m_mutex);
+
+ typedef HashSet_Ref::const_iterator CIT_S;
+ typedef HashMultimap_OWString_Interface::iterator IT_MM;
+
+ CIT_S it_SetEnd= m_SetLoadedFactories.end();
+ IT_MM it_end1= m_ServiceMap.end();
+ list<IT_MM> listDeleteServiceMap;
+ typedef list<IT_MM>::const_iterator CIT_DMM;
+ // find occurences in m_ServiceMap
+ for(IT_MM it_i1= m_ServiceMap.begin(); it_i1 != it_end1; it_i1++)
+ {
+ if( m_SetLoadedFactories.find( it_i1->second) != it_SetEnd)
+ {
+ Reference<XUnloadingPreference> xunl( it_i1->second, UNO_QUERY);
+ if( xunl.is())
+ {
+ if( xunl->releaseOnNotification())
+ listDeleteServiceMap.push_front( it_i1);
+ }
+ else
+ listDeleteServiceMap.push_front( it_i1);
+ }
+ }
+ // delete elements from m_ServiceMap
+ CIT_DMM it_end2= listDeleteServiceMap.end();
+ for( CIT_DMM it_i2= listDeleteServiceMap.begin(); it_i2 != it_end2; it_i2++)
+ m_ServiceMap.erase( *it_i2);
+
+ // find elements in m_ImplementationNameMap
+ typedef HashMap_OWString_Interface::iterator IT_M;
+ IT_M it_end3= m_ImplementationNameMap.end();
+ list<IT_M> listDeleteImplementationNameMap;
+ typedef list<IT_M>::const_iterator CIT_DM;
+ for( IT_M it_i3= m_ImplementationNameMap.begin(); it_i3 != it_end3; it_i3++)
+ {
+ if( m_SetLoadedFactories.find( it_i3->second) != it_SetEnd)
+ {
+ Reference<XUnloadingPreference> xunl( it_i3->second, UNO_QUERY);
+ if( xunl.is())
+ {
+ if( xunl->releaseOnNotification())
+ listDeleteImplementationNameMap.push_front( it_i3);
+ }
+ else
+ listDeleteImplementationNameMap.push_front( it_i3);
+ }
+ }
+ // delete elements from m_ImplementationNameMap
+ CIT_DM it_end4= listDeleteImplementationNameMap.end();
+ for( CIT_DM it_i4= listDeleteImplementationNameMap.begin(); it_i4 != it_end4; it_i4++)
+ m_ImplementationNameMap.erase( *it_i4);
+
+ // find elements in m_ImplementationMap
+ typedef HashSet_Ref::iterator IT_S;
+ IT_S it_end5= m_ImplementationMap.end();
+ list<IT_S> listDeleteImplementationMap;
+ typedef list<IT_S>::const_iterator CIT_DS;
+ for( IT_S it_i5= m_ImplementationMap.begin(); it_i5 != it_end5; it_i5++)
+ {
+ if( m_SetLoadedFactories.find( *it_i5) != it_SetEnd)
+ {
+ Reference<XUnloadingPreference> xunl( *it_i5, UNO_QUERY);
+ if( xunl.is())
+ {
+ if( xunl->releaseOnNotification())
+ listDeleteImplementationMap.push_front( it_i5);
+ }
+ else
+ listDeleteImplementationMap.push_front( it_i5);
+ }
+ }
+ // delete elements from m_ImplementationMap
+ CIT_DS it_end6= listDeleteImplementationMap.end();
+ for( CIT_DS it_i6= listDeleteImplementationMap.begin(); it_i6 != it_end6; it_i6++)
+ m_ImplementationMap.erase( *it_i6);
+
+ // remove Event listener before the factories are released.
+ IT_S it_end7= m_SetLoadedFactories.end();
+
+ Reference<XEventListener> xlistener= getFactoryListener();
+ for( IT_S it_i7= m_SetLoadedFactories.begin(); it_i7 != it_end7; it_i7++)
+ {
+ Reference<XComponent> xcomp( *it_i7, UNO_QUERY);
+ if( xcomp.is())
+ xcomp->removeEventListener( xlistener);
+ }
+ // release the factories in m_SetLoadedFactories
+ m_SetLoadedFactories.clear();
+}
+
+// XComponent
+void OServiceManager::dispose()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ return;
+ t_OServiceManager_impl::dispose();
+}
+
+void OServiceManager::disposing()
+{
+ // dispose all factories
+ HashSet_Ref aImpls;
+ {
+ MutexGuard aGuard( m_mutex );
+ m_bInDisposing = true;
+ aImpls = m_ImplementationMap;
+ }
+ HashSet_Ref::iterator aIt = aImpls.begin();
+ while( aIt != aImpls.end() )
+ {
+ try
+ {
+ Reference<XComponent > xComp( Reference<XComponent >::query( *aIt++ ) );
+ if( xComp.is() )
+ xComp->dispose();
+ }
+ catch (RuntimeException & exc)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "### RuntimeException occured upon disposing factory: %s", str.getStr() );
+#else
+ (void) exc; // unused
+#endif
+ }
+ }
+
+ // dispose
+ HashSet_Ref aImplMap;
+ {
+ MutexGuard aGuard( m_mutex );
+ // erase all members
+ m_ServiceMap = HashMultimap_OWString_Interface();
+ aImplMap = m_ImplementationMap;
+ m_ImplementationMap = HashSet_Ref();
+ m_ImplementationNameMap = HashMap_OWString_Interface();
+ m_SetLoadedFactories= HashSet_Ref();
+ }
+
+ m_xContext.clear();
+
+ // not only the Event should hold the object
+ OSL_ASSERT( m_refCount != 1 );
+
+ // Revoke this service manager as unloading listener
+ rtl_removeUnloadingListener( m_nUnloadingListenerId);
+ m_nUnloadingListenerId=0;
+}
+
+// XPropertySet
+Reference<XPropertySetInfo > OServiceManager::getPropertySetInfo()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ if (! m_xPropertyInfo.is())
+ {
+ Sequence< beans::Property > seq( 1 );
+ seq[ 0 ] = beans::Property(
+ OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 );
+ Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
+
+ MutexGuard aGuard( m_mutex );
+ if (! m_xPropertyInfo.is())
+ {
+ m_xPropertyInfo = xInfo;
+ }
+ }
+ return m_xPropertyInfo;
+}
+
+void OServiceManager::setPropertyValue(
+ const OUString& PropertyName, const Any& aValue )
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
+ {
+ Reference< XComponentContext > xContext;
+ if (aValue >>= xContext)
+ {
+ MutexGuard aGuard( m_mutex );
+ m_xContext = xContext;
+ }
+ else
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no XComponentContext given!") ),
+ (OWeakObject *)this, 1 );
+ }
+ }
+ else
+ {
+ throw UnknownPropertyException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("unknown property ") ) + PropertyName,
+ (OWeakObject *)this );
+ }
+}
+
+Any OServiceManager::getPropertyValue(const OUString& PropertyName)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("DefaultContext") ))
+ {
+ MutexGuard aGuard( m_mutex );
+ if( m_xContext.is() )
+ return makeAny( m_xContext );
+ else
+ return Any();
+ }
+ else
+ {
+ UnknownPropertyException except;
+ except.Message = OUString( RTL_CONSTASCII_USTRINGPARAM( "ServiceManager : unknown property " ) );
+ except.Message += PropertyName;
+ throw except;
+ }
+}
+
+void OServiceManager::addPropertyChangeListener(
+ const OUString&, const Reference<XPropertyChangeListener >&)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ throw UnknownPropertyException();
+}
+
+void OServiceManager::removePropertyChangeListener(
+ const OUString&, const Reference<XPropertyChangeListener >&)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ throw UnknownPropertyException();
+}
+
+void OServiceManager::addVetoableChangeListener(
+ const OUString&, const Reference<XVetoableChangeListener >&)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ throw UnknownPropertyException();
+}
+
+void OServiceManager::removeVetoableChangeListener(
+ const OUString&, const Reference<XVetoableChangeListener >&)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ throw UnknownPropertyException();
+}
+
+// OServiceManager
+Reference<XEventListener > OServiceManager::getFactoryListener()
+{
+ check_undisposed();
+ MutexGuard aGuard( m_mutex );
+ if( !xFactoryListener.is() )
+ xFactoryListener = new OServiceManager_Listener( this );
+ return xFactoryListener;
+}
+
+// XMultiServiceFactory, XContentEnumeration
+Sequence< OUString > OServiceManager::getUniqueAvailableServiceNames(
+ HashSet_OWString & aNameSet )
+{
+ check_undisposed();
+ MutexGuard aGuard( m_mutex );
+ HashMultimap_OWString_Interface::iterator aSIt = m_ServiceMap.begin();
+ while( aSIt != m_ServiceMap.end() )
+ aNameSet.insert( (*aSIt++).first );
+
+ /* do not return the implementation names
+ HashMap_OWString_Interface m_ImplementationNameMap;
+ HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.begin();
+ while( aIt != m_ImplementationNameMap.end() )
+ aNameSet.insert( (*aIt++).first );
+ */
+
+ Sequence< OUString > aNames( aNameSet.size() );
+ OUString * pArray = aNames.getArray();
+ sal_Int32 i = 0;
+ HashSet_OWString::iterator next = aNameSet.begin();
+ while( next != aNameSet.end() )
+ pArray[i++] = (*next++);
+
+ return aNames;
+}
+
+// XMultiComponentFactory
+Reference< XInterface > OServiceManager::createInstanceWithContext(
+ OUString const & rServiceSpecifier,
+ Reference< XComponentContext > const & xContext )
+ throw (Exception, RuntimeException)
+{
+ check_undisposed();
+#if OSL_DEBUG_LEVEL > 0
+ Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ Reference< XComponentContext > xDefContext;
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext;
+ OSL_ENSURE(
+ xContext == xDefContext,
+ "### default context of service manager singleton differs from context holding it!" );
+ }
+#endif
+
+ Sequence< Reference< XInterface > > factories(
+ queryServiceFactories( rServiceSpecifier, xContext ) );
+ Reference< XInterface > const * p = factories.getConstArray();
+ for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
+ {
+ try
+ {
+ Reference< XInterface > const & xFactory = p[ nPos ];
+ if (xFactory.is())
+ {
+ Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
+ if (xFac.is())
+ {
+ return xFac->createInstanceWithContext( xContext );
+ }
+ else
+ {
+ Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
+ if (xFac2.is())
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() );
+#endif
+ return xFac2->createInstance();
+ }
+ }
+ }
+ }
+ catch (lang::DisposedException & exc)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "### DisposedException occured: %s", str.getStr() );
+#else
+ (void) exc; // unused
+#endif
+ }
+ }
+
+ return Reference< XInterface >();
+}
+// XMultiComponentFactory
+Reference< XInterface > OServiceManager::createInstanceWithArgumentsAndContext(
+ OUString const & rServiceSpecifier,
+ Sequence< Any > const & rArguments,
+ Reference< XComponentContext > const & xContext )
+ throw (Exception, RuntimeException)
+{
+ check_undisposed();
+#if OSL_DEBUG_LEVEL > 0
+ Reference< beans::XPropertySet > xProps( xContext->getServiceManager(), UNO_QUERY );
+ OSL_ASSERT( xProps.is() );
+ if (xProps.is())
+ {
+ Reference< XComponentContext > xDefContext;
+ xProps->getPropertyValue(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DefaultContext") ) ) >>= xDefContext;
+ OSL_ENSURE(
+ xContext == xDefContext,
+ "### default context of service manager singleton differs from context holding it!" );
+ }
+#endif
+
+ Sequence< Reference< XInterface > > factories(
+ queryServiceFactories( rServiceSpecifier, xContext ) );
+ Reference< XInterface > const * p = factories.getConstArray();
+ for ( sal_Int32 nPos = 0; nPos < factories.getLength(); ++nPos )
+ {
+ try
+ {
+ Reference< XInterface > const & xFactory = p[ nPos ];
+ if (xFactory.is())
+ {
+ Reference< XSingleComponentFactory > xFac( xFactory, UNO_QUERY );
+ if (xFac.is())
+ {
+ return xFac->createInstanceWithArgumentsAndContext( rArguments, xContext );
+ }
+ else
+ {
+ Reference< XSingleServiceFactory > xFac2( xFactory, UNO_QUERY );
+ if (xFac2.is())
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString aStr( OUStringToOString( rServiceSpecifier, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "### ignoring given context raising service %s !!!\n", aStr.getStr() );
+#endif
+ return xFac2->createInstanceWithArguments( rArguments );
+ }
+ }
+ }
+ }
+ catch (lang::DisposedException & exc)
+ {
+#if OSL_DEBUG_LEVEL > 1
+ OString str( OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
+ OSL_TRACE( "### DisposedException occured: %s", str.getStr() );
+#else
+ (void) exc; // unused
+#endif
+ }
+ }
+
+ return Reference< XInterface >();
+}
+
+// XMultiServiceFactory, XMultiComponentFactory, XContentEnumeration
+Sequence< OUString > OServiceManager::getAvailableServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ // all names
+ HashSet_OWString aNameSet;
+ return getUniqueAvailableServiceNames( aNameSet );
+}
+
+// XMultibleServiceFactory
+Reference<XInterface > OServiceManager::createInstance(
+ const OUString& rServiceSpecifier )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ return createInstanceWithContext(
+ rServiceSpecifier, m_xContext );
+}
+
+// XMultibleServiceFactory
+Reference<XInterface > OServiceManager::createInstanceWithArguments(
+ const OUString& rServiceSpecifier,
+ const Sequence<Any >& rArguments )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ return createInstanceWithArgumentsAndContext(
+ rServiceSpecifier, rArguments, m_xContext );
+}
+
+// XInitialization
+void OServiceManager::initialize( Sequence< Any > const & )
+ throw (Exception)
+{
+ check_undisposed();
+ OSL_ENSURE( 0, "not impl!" );
+}
+
+// XServiceInfo
+OUString OServiceManager::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ return getImplementationName_Static();
+}
+
+// XServiceInfo
+sal_Bool OServiceManager::supportsService(const OUString& ServiceName)
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > OServiceManager::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ return stoc_bootstrap::smgr_getSupportedServiceNames();
+}
+
+
+Sequence< Reference< XInterface > > OServiceManager::queryServiceFactories(
+ const OUString& aServiceName, Reference< XComponentContext > const & )
+{
+ Sequence< Reference< XInterface > > ret;
+
+ MutexGuard aGuard( m_mutex );
+ ::std::pair<
+ HashMultimap_OWString_Interface::iterator,
+ HashMultimap_OWString_Interface::iterator> p(
+ m_ServiceMap.equal_range( aServiceName ) );
+
+ if (p.first == p.second) // no factories
+ {
+ // no service found, look for an implementation
+ HashMap_OWString_Interface::iterator aIt = m_ImplementationNameMap.find( aServiceName );
+ if( aIt != m_ImplementationNameMap.end() )
+ {
+ Reference< XInterface > const & x = aIt->second;
+ // an implementation found
+ ret = Sequence< Reference< XInterface > >( &x, 1 );
+ }
+ }
+ else
+ {
+ ::std::vector< Reference< XInterface > > vec;
+ vec.reserve( 4 );
+ while (p.first != p.second)
+ {
+ vec.push_back( p.first->second );
+ ++p.first;
+ }
+ ret = Sequence< Reference< XInterface > >(
+ vec.empty() ? 0 : &vec[ 0 ], vec.size() );
+ }
+
+ return ret;
+}
+
+// XContentEnumerationAccess
+Reference<XEnumeration > OServiceManager::createContentEnumeration(
+ const OUString& aServiceName, Reference< XComponentContext > const & xContext )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ Sequence< Reference< XInterface > > factories(
+ OServiceManager::queryServiceFactories( aServiceName, xContext ) );
+ if (factories.getLength())
+ return new ServiceEnumeration_Impl( factories );
+ else
+ return Reference< XEnumeration >();
+}
+Reference<XEnumeration > OServiceManager::createContentEnumeration(
+ const OUString& aServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return createContentEnumeration( aServiceName, m_xContext );
+}
+
+// XEnumeration
+Reference<XEnumeration > OServiceManager::createEnumeration() throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ MutexGuard aGuard( m_mutex );
+ return new ImplementationEnumeration_Impl( m_ImplementationMap );
+}
+
+// XElementAccess
+Type OServiceManager::getElementType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ return ::getCppuType( (const Reference< XInterface > *)0 );
+}
+
+// XElementAccess
+sal_Bool OServiceManager::hasElements()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ MutexGuard aGuard( m_mutex );
+ return !m_ImplementationMap.empty();
+}
+
+// XSet
+sal_Bool OServiceManager::has( const Any & Element )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ if( Element.getValueTypeClass() == TypeClass_INTERFACE )
+ {
+ Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
+ MutexGuard aGuard( m_mutex );
+ return m_ImplementationMap.find( xEle ) !=
+ m_ImplementationMap.end();
+ }
+ else if (Element.getValueTypeClass() == TypeClass_STRING)
+ {
+ OUString const & implName =
+ *reinterpret_cast< OUString const * >(Element.getValue());
+ MutexGuard aGuard( m_mutex );
+ return m_ImplementationNameMap.find( implName ) !=
+ m_ImplementationNameMap.end();
+ }
+ return sal_False;
+}
+
+// XSet
+void OServiceManager::insert( const Any & Element )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ if( Element.getValueTypeClass() != TypeClass_INTERFACE )
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no interface given!") ),
+ Reference< XInterface >(), 0 );
+ }
+ Reference<XInterface > xEle( Element, UNO_QUERY_THROW );
+
+ {
+ MutexGuard aGuard( m_mutex );
+ HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
+ if( aIt != m_ImplementationMap.end() )
+ {
+ throw ElementExistException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("element already exists!") ),
+ Reference< XInterface >() );
+ }
+
+ // put into the implementation hashmap
+ m_ImplementationMap.insert( xEle );
+
+ // put into the implementation name hashmap
+ Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
+ if( xInfo.is() )
+ {
+ OUString aImplName = xInfo->getImplementationName();
+ if( aImplName.getLength() )
+ m_ImplementationNameMap[ aImplName ] = xEle;
+
+ //put into the service map
+ Sequence< OUString > aServiceNames = xInfo->getSupportedServiceNames();
+ const OUString * pArray = aServiceNames.getConstArray();
+ for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
+ {
+ m_ServiceMap.insert( HashMultimap_OWString_Interface::value_type(
+ pArray[i], *(Reference<XInterface > *)Element.getValue() ) );
+ }
+ }
+ }
+ // add the disposing listener to the factory
+ Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
+ if( xComp.is() )
+ xComp->addEventListener( getFactoryListener() );
+}
+
+// helper function
+sal_Bool OServiceManager::haveFactoryWithThisImplementation(const OUString& aImplName)
+{
+ return ( m_ImplementationNameMap.find(aImplName) != m_ImplementationNameMap.end());
+}
+
+// XSet
+void OServiceManager::remove( const Any & Element )
+ throw(::com::sun::star::lang::IllegalArgumentException,
+ ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException)
+{
+ if (is_disposed())
+ return;
+
+ Reference<XInterface > xEle;
+ if (Element.getValueTypeClass() == TypeClass_INTERFACE)
+ {
+ xEle.set( Element, UNO_QUERY_THROW );
+ }
+ else if (Element.getValueTypeClass() == TypeClass_STRING)
+ {
+ OUString const & implName =
+ *reinterpret_cast< OUString const * >(Element.getValue());
+ MutexGuard aGuard( m_mutex );
+ HashMap_OWString_Interface::const_iterator const iFind(
+ m_ImplementationNameMap.find( implName ) );
+ if (iFind == m_ImplementationNameMap.end())
+ {
+ throw NoSuchElementException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in: ") )
+ + implName, static_cast< OWeakObject * >(this) );
+ }
+ xEle = iFind->second;
+ }
+ else
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "neither interface nor string given!") ),
+ Reference< XInterface >(), 0 );
+ }
+
+ // remove the disposing listener from the factory
+ Reference<XComponent > xComp( Reference<XComponent >::query( xEle ) );
+ if( xComp.is() )
+ xComp->removeEventListener( getFactoryListener() );
+
+ MutexGuard aGuard( m_mutex );
+ HashSet_Ref::iterator aIt = m_ImplementationMap.find( xEle );
+ if( aIt == m_ImplementationMap.end() )
+ {
+ throw NoSuchElementException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("element is not in!") ),
+ static_cast< OWeakObject * >(this) );
+ }
+ //First remove all factories which have been loaded by ORegistryServiceManager.
+ m_SetLoadedFactories.erase( *aIt);
+ //Remove from the implementation map. It contains all factories of m_SetLoadedFactories
+ //which have been added directly through XSet, that is not via ORegistryServiceManager
+ m_ImplementationMap.erase( aIt );
+
+ // remove from the implementation name hashmap
+ Reference<XServiceInfo > xInfo( Reference<XServiceInfo >::query( xEle ) );
+ if( xInfo.is() )
+ {
+ OUString aImplName = xInfo->getImplementationName();
+ if( aImplName.getLength() )
+ m_ImplementationNameMap.erase( aImplName );
+ }
+
+ //remove from the service map
+ Reference<XServiceInfo > xSF( Reference<XServiceInfo >::query( xEle ) );
+ if( xSF.is() )
+ {
+ Sequence< OUString > aServiceNames = xSF->getSupportedServiceNames();
+ const OUString * pArray = aServiceNames.getConstArray();
+ for( sal_Int32 i = 0; i < aServiceNames.getLength(); i++ )
+ {
+ pair<HashMultimap_OWString_Interface::iterator, HashMultimap_OWString_Interface::iterator> p =
+ m_ServiceMap.equal_range( pArray[i] );
+
+ while( p.first != p.second )
+ {
+ if( xEle == (*p.first).second )
+ {
+ m_ServiceMap.erase( p.first );
+ break;
+ }
+ ++p.first;
+ }
+ }
+ }
+}
+
+/*****************************************************************************
+ class ORegistryServiceManager
+*****************************************************************************/
+class ORegistryServiceManager : public OServiceManager
+{
+public:
+ ORegistryServiceManager( Reference< XComponentContext > const & xContext );
+ virtual ~ORegistryServiceManager();
+
+ // XInitialization
+ void SAL_CALL initialize(const Sequence< Any >& Arguments)
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException);
+
+ // XServiceInfo
+ OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException)
+ { return stoc_bootstrap::regsmgr_getImplementationName(); }
+
+ Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XMultiServiceFactory
+ Sequence< OUString > SAL_CALL getAvailableServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XContentEnumerationAccess
+ //Sequence< OUString > getAvailableServiceNames() throw( (Exception) );
+ Reference<XEnumeration > SAL_CALL createContentEnumeration(const OUString& aServiceName) throw(::com::sun::star::uno::RuntimeException);
+ virtual Reference<XEnumeration > SAL_CALL createContentEnumeration(
+ const OUString& aServiceName, Reference< XComponentContext > const & xContext )
+ throw(::com::sun::star::uno::RuntimeException);
+
+ // XComponent
+ void SAL_CALL dispose() throw(::com::sun::star::uno::RuntimeException);
+
+ // OServiceManager
+ Reference<XPropertySetInfo > SAL_CALL getPropertySetInfo()
+ throw(::com::sun::star::uno::RuntimeException);
+ Any SAL_CALL getPropertyValue(const OUString& PropertyName)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+
+protected:
+ //OServiceManager
+ Sequence< Reference< XInterface > > queryServiceFactories(
+ const OUString& aServiceName, Reference< XComponentContext > const & xContext );
+private:
+ Reference<XRegistryKey > getRootKey();
+ Reference<XInterface > loadWithImplementationName(
+ const OUString & rImplName, Reference< XComponentContext > const & xContext );
+ Sequence<OUString> getFromServiceName(const OUString& serviceName);
+ Reference<XInterface > loadWithServiceName(
+ const OUString & rImplName, Reference< XComponentContext > const & xContext );
+ void fillAllNamesFromRegistry( HashSet_OWString & );
+
+ sal_Bool m_searchedRegistry;
+ Reference<XSimpleRegistry > m_xRegistry; // readonly property Registry
+ Reference<XRegistryKey > m_xRootKey;
+
+#if OSL_DEBUG_LEVEL > 0
+ bool m_init;
+#endif
+};
+
+/**
+ * Create a ServiceManager
+ */
+ORegistryServiceManager::ORegistryServiceManager( Reference< XComponentContext > const & xContext )
+ : OServiceManager( xContext )
+ , m_searchedRegistry(sal_False)
+#if OSL_DEBUG_LEVEL > 0
+ , m_init( false )
+#endif
+{
+}
+
+/**
+ * Destroy the ServiceManager
+ */
+ORegistryServiceManager::~ORegistryServiceManager()
+{
+}
+
+// XComponent
+void ORegistryServiceManager::dispose()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ if (rBHelper.bDisposed || rBHelper.bInDispose)
+ return;
+ OServiceManager::dispose();
+ // dispose
+ MutexGuard aGuard( m_mutex );
+ // erase all members
+ m_xRegistry = Reference<XSimpleRegistry >();
+ m_xRootKey = Reference<XRegistryKey >();
+}
+
+/**
+ * Return the root key of the registry. The Default registry service is ordered
+ * if no registry is set.
+ */
+//Reference<XServiceProvider > create_DefaultRegistry_ServiceProvider();
+
+Reference<XRegistryKey > ORegistryServiceManager::getRootKey()
+{
+ if( !m_xRootKey.is() )
+ {
+ MutexGuard aGuard( m_mutex );
+ // DefaultRegistry suchen !!!!
+ if( !m_xRegistry.is() && !m_searchedRegistry )
+ {
+ // merken, es wird nur einmal gesucht
+ m_searchedRegistry = sal_True;
+
+ m_xRegistry.set(
+ createInstanceWithContext(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.DefaultRegistry") ),
+ m_xContext ),
+ UNO_QUERY );
+ }
+ if( m_xRegistry.is() && !m_xRootKey.is() )
+ m_xRootKey = m_xRegistry->getRootKey();
+ }
+
+ return m_xRootKey;
+}
+
+/**
+ * Create a service provider from the registry with an implementation name
+ */
+Reference<XInterface > ORegistryServiceManager::loadWithImplementationName(
+ const OUString& name, Reference< XComponentContext > const & xContext )
+{
+ Reference<XInterface > ret;
+
+ Reference<XRegistryKey > xRootKey = getRootKey();
+ if( !xRootKey.is() )
+ return ret;
+
+ try
+ {
+ OUString implementationName = OUString( RTL_CONSTASCII_USTRINGPARAM("/IMPLEMENTATIONS/") ) + name;
+ Reference<XRegistryKey > xImpKey = m_xRootKey->openKey(implementationName);
+
+ if( xImpKey.is() )
+ {
+ Reference< lang::XMultiServiceFactory > xMgr;
+ if (xContext.is())
+ xMgr.set( xContext->getServiceManager(), UNO_QUERY_THROW );
+ else
+ xMgr.set( this );
+ ret = createSingleRegistryFactory( xMgr, name, xImpKey );
+ insert( makeAny( ret ) );
+ // Remember this factory as loaded in contrast to inserted ( XSet::insert)
+ // factories. Those loaded factories in this set are candidates for being
+ // released on an unloading notification.
+ m_SetLoadedFactories.insert( ret);
+ }
+ }
+ catch (InvalidRegistryException &)
+ {
+ }
+
+ return ret;
+}
+
+/**
+ * Return all implementation out of the registry.
+ */
+Sequence<OUString> ORegistryServiceManager::getFromServiceName(
+ const OUString& serviceName )
+{
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( "/SERVICES/" ) );
+ buf.append( serviceName );
+ return retrieveAsciiValueList( m_xRegistry, buf.makeStringAndClear() );
+}
+
+/**
+ * Create a service provider from the registry
+ */
+Reference<XInterface > ORegistryServiceManager::loadWithServiceName(
+ const OUString& serviceName, Reference< XComponentContext > const & xContext )
+{
+ Sequence<OUString> implEntries = getFromServiceName( serviceName );
+ for (sal_Int32 i = 0; i < implEntries.getLength(); i++)
+ {
+ Reference< XInterface > x(
+ loadWithImplementationName( implEntries.getConstArray()[i], xContext ) );
+ if (x.is())
+ return x;
+ }
+
+ return Reference<XInterface >();
+}
+
+/**
+ * Return a sequence of all service names from the registry.
+ */
+void ORegistryServiceManager::fillAllNamesFromRegistry( HashSet_OWString & rSet )
+{
+ Reference<XRegistryKey > xRootKey = getRootKey();
+ if( !xRootKey.is() )
+ return;
+
+ try
+ {
+ Reference<XRegistryKey > xServicesKey = xRootKey->openKey(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("SERVICES") ) );
+ // root + /Services + /
+ if( xServicesKey.is() )
+ {
+ sal_Int32 nPrefix = xServicesKey->getKeyName().getLength() +1;
+ Sequence<Reference<XRegistryKey > > aKeys = xServicesKey->openKeys();
+ for( sal_Int32 i = 0; i < aKeys.getLength(); i++ )
+ rSet.insert( aKeys.getConstArray()[i]->getKeyName().copy( nPrefix ) );
+ }
+ }
+ catch (InvalidRegistryException &)
+ {
+ }
+}
+
+// XInitialization
+void ORegistryServiceManager::initialize(const Sequence< Any >& Arguments)
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ MutexGuard aGuard( m_mutex );
+ if (Arguments.getLength() > 0)
+ {
+ m_xRootKey.clear();
+ Arguments[ 0 ] >>= m_xRegistry;
+ }
+#if OSL_DEBUG_LEVEL > 0
+ // to find all bootstrapping processes to be fixed...
+ OSL_ENSURE( !m_init, "### second init of service manager instance!" );
+ m_init = true;
+#endif
+}
+
+// XMultiServiceFactory, XContentEnumeration
+Sequence< OUString > ORegistryServiceManager::getAvailableServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ MutexGuard aGuard( m_mutex );
+ // all names
+ HashSet_OWString aNameSet;
+
+ // all names from the registry
+ fillAllNamesFromRegistry( aNameSet );
+
+ return OServiceManager::getUniqueAvailableServiceNames( aNameSet );
+}
+
+// XServiceInfo
+Sequence< OUString > ORegistryServiceManager::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ return stoc_bootstrap::regsmgr_getSupportedServiceNames();
+}
+
+
+// OServiceManager
+Sequence< Reference< XInterface > > ORegistryServiceManager::queryServiceFactories(
+ const OUString& aServiceName, Reference< XComponentContext > const & xContext )
+{
+ Sequence< Reference< XInterface > > ret(
+ OServiceManager::queryServiceFactories( aServiceName, xContext ) );
+ if (ret.getLength())
+ {
+ return ret;
+ }
+ else
+ {
+ MutexGuard aGuard( m_mutex );
+ Reference< XInterface > x( loadWithServiceName( aServiceName, xContext ) );
+ if (! x.is())
+ x = loadWithImplementationName( aServiceName, xContext );
+ return Sequence< Reference< XInterface > >( &x, 1 );
+ }
+}
+
+// XContentEnumerationAccess
+Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
+ const OUString& aServiceName, Reference< XComponentContext > const & xContext )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ MutexGuard aGuard( ((ORegistryServiceManager *)this)->m_mutex );
+ // get all implementation names registered under this service name from the registry
+ Sequence<OUString> aImpls = ((ORegistryServiceManager *)this)->getFromServiceName( aServiceName );
+ // load and insert all factories specified by the registry
+ sal_Int32 i;
+ OUString aImplName;
+ for( i = 0; i < aImpls.getLength(); i++ )
+ {
+ aImplName = aImpls.getConstArray()[i];
+ if ( !haveFactoryWithThisImplementation(aImplName) )
+ {
+ loadWithImplementationName( aImplName, xContext );
+ }
+ }
+ // call the superclass to enumerate all contents
+ return OServiceManager::createContentEnumeration( aServiceName, xContext );
+}
+Reference<XEnumeration > ORegistryServiceManager::createContentEnumeration(
+ const OUString& aServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return createContentEnumeration( aServiceName, m_xContext );
+}
+
+// OServiceManager
+Reference<XPropertySetInfo > ORegistryServiceManager::getPropertySetInfo()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ if (! m_xPropertyInfo.is())
+ {
+ Sequence< beans::Property > seq( 2 );
+ seq[ 0 ] = beans::Property(
+ OUSTR("DefaultContext"), -1, ::getCppuType( &m_xContext ), 0 );
+ seq[ 1 ] = beans::Property(
+ OUSTR("Registry"), -1, ::getCppuType( &m_xRegistry ),
+ beans::PropertyAttribute::READONLY );
+ Reference< beans::XPropertySetInfo > xInfo( new PropertySetInfo_Impl( seq ) );
+
+ MutexGuard aGuard( m_mutex );
+ if (! m_xPropertyInfo.is())
+ {
+ m_xPropertyInfo = xInfo;
+ }
+ }
+ return m_xPropertyInfo;
+}
+
+Any ORegistryServiceManager::getPropertyValue(const OUString& PropertyName)
+ throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ check_undisposed();
+ if (PropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("Registry") ))
+ {
+ MutexGuard aGuard( m_mutex );
+ if( m_xRegistry.is() )
+ return makeAny( m_xRegistry );
+ else
+ return Any();
+ }
+ return OServiceManager::getPropertyValue( PropertyName );
+}
+
+/* This is the listener function used by the service manager in order
+to implement the unloading mechanism, id is the this pointer of the
+service manager instances. On notification, that is the function is being called
+by rtl_unloadUnusedModules, the cached factroies are being removed from the
+service manager ( except manually inserted factories).
+*/
+extern "C" void SAL_CALL smgrUnloadingListener(void* id)
+{
+ stoc_smgr::OServiceManager* pMgr= reinterpret_cast<stoc_smgr::OServiceManager*>( id);
+ pMgr->onUnloadingNotify();
+}
+
+} // namespace
+
+namespace stoc_bootstrap
+{
+/**
+ * Create the ServiceManager
+ */
+Reference<XInterface > SAL_CALL OServiceManager_CreateInstance(
+ const Reference< XComponentContext > & xContext )
+{
+ return Reference<XInterface >(
+ SAL_STATIC_CAST(
+ XInterface *, SAL_STATIC_CAST(
+ OWeakObject *, new stoc_smgr::OServiceManager( xContext ) ) ) );
+}
+
+/**
+ * Create the ServiceManager
+ */
+Reference<XInterface > SAL_CALL ORegistryServiceManager_CreateInstance(
+ const Reference< XComponentContext > & xContext )
+ throw(::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
+{
+ return Reference<XInterface >(
+ SAL_STATIC_CAST(
+ XInterface *, SAL_STATIC_CAST(
+ OWeakObject *, new stoc_smgr::ORegistryServiceManager( xContext ) ) ) );
+}
+
+Reference<XInterface > SAL_CALL OServiceManagerWrapper_CreateInstance(
+ const Reference< XComponentContext > & xContext )
+ throw (Exception)
+{
+ return (OWeakObject *)new stoc_smgr::OServiceManagerWrapper( xContext );
+}
+}
diff --git a/stoc/source/simpleregistry/makefile.mk b/stoc/source/simpleregistry/makefile.mk
new file mode 100644
index 000000000000..bc0ddf7cc71a
--- /dev/null
+++ b/stoc/source/simpleregistry/makefile.mk
@@ -0,0 +1,47 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = simplereg
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT=$(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)/simpleregistry.obj \
+ $(SLO)/textualservices.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/stoc/source/simpleregistry/simpleregistry.cxx b/stoc/source/simpleregistry/simpleregistry.cxx
new file mode 100755
index 000000000000..9c6b71bc6c83
--- /dev/null
+++ b/stoc/source/simpleregistry/simpleregistry.cxx
@@ -0,0 +1,1320 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+************************************************************************/
+
+#include "precompiled_stoc.hxx"
+#include "sal/config.h"
+
+#include <cstdlib>
+#include <memory>
+#include <vector>
+
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/registry/InvalidRegistryException.hpp"
+#include "com/sun/star/registry/InvalidValueException.hpp"
+#include "com/sun/star/registry/MergeConflictException.hpp"
+#include "com/sun/star/registry/RegistryKeyType.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/registry/XSimpleRegistry.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/mutex.hxx"
+#include "registry/registry.hxx"
+#include "registry/regtype.h"
+#include "rtl/ref.hxx"
+#include "rtl/string.h"
+#include "rtl/string.hxx"
+#include "rtl/textcvt.h"
+#include "rtl/textenc.h"
+#include "rtl/unload.h"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include "bootstrapservices.hxx"
+
+#include "textualservices.hxx"
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace {
+
+namespace css = com::sun::star;
+
+class SimpleRegistry:
+ public cppu::WeakImplHelper2<
+ css::registry::XSimpleRegistry, css::lang::XServiceInfo >
+{
+public:
+ SimpleRegistry() { g_moduleCount.modCnt.acquire(&g_moduleCount.modCnt); }
+
+ ~SimpleRegistry() { g_moduleCount.modCnt.release(&g_moduleCount.modCnt); }
+
+ osl::Mutex mutex_;
+
+private:
+ virtual rtl::OUString SAL_CALL getURL() throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL open(
+ rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isValid() throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL close() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL destroy() throw(
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
+ getRootKey() throw(
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isReadOnly() throw(
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL mergeKey(
+ rtl::OUString const & aKeyName, rtl::OUString const & aUrl)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::MergeConflictException, css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException)
+ { return stoc_bootstrap::simreg_getImplementationName(); }
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & ServiceName)
+ throw (css::uno::RuntimeException)
+ { return ServiceName == getSupportedServiceNames()[0]; }
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException)
+ { return stoc_bootstrap::simreg_getSupportedServiceNames(); }
+
+ Registry registry_;
+ std::auto_ptr< stoc::simpleregistry::TextualServices > textual_;
+};
+
+class Key: public cppu::WeakImplHelper1< css::registry::XRegistryKey > {
+public:
+ Key(
+ rtl::Reference< SimpleRegistry > const & registry,
+ RegistryKey const & key):
+ registry_(registry), key_(key) {}
+
+private:
+ virtual rtl::OUString SAL_CALL getKeyName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isReadOnly() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isValid() throw(css::uno::RuntimeException);
+
+ virtual css::registry::RegistryKeyType SAL_CALL getKeyType(
+ rtl::OUString const & rKeyName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::registry::RegistryValueType SAL_CALL getValueType() throw(
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getLongValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setLongValue(sal_Int32 value) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() throw(
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setLongListValue(
+ com::sun::star::uno::Sequence< sal_Int32 > const & seqValue)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getAsciiValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setAsciiValue(rtl::OUString const & value) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getAsciiListValue()
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setAsciiListValue(
+ css::uno::Sequence< rtl::OUString > const & seqValue)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getStringValue() throw(
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setStringValue(rtl::OUString const & value) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getStringListValue()
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setStringListValue(
+ css::uno::Sequence< rtl::OUString > const & seqValue)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setBinaryValue(
+ css::uno::Sequence< sal_Int8 > const & value)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey(
+ rtl::OUString const & aKeyName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
+ createKey(rtl::OUString const & aKeyName) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL closeKey() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL deleteKey(rtl::OUString const & rKeyName) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
+ SAL_CALL openKeys() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getKeyNames() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL createLink(
+ rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL deleteLink(rtl::OUString const & rLinkName) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getLinkTarget(
+ rtl::OUString const & rLinkName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getResolvedName(
+ rtl::OUString const & aKeyName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ rtl::Reference< SimpleRegistry > registry_;
+ RegistryKey key_;
+};
+
+rtl::OUString Key::getKeyName() throw (css::uno::RuntimeException) {
+ osl::MutexGuard guard(registry_->mutex_);
+ return key_.getName();
+}
+
+sal_Bool Key::isReadOnly()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ return key_.isReadOnly();
+}
+
+sal_Bool Key::isValid() throw (css::uno::RuntimeException) {
+ osl::MutexGuard guard(registry_->mutex_);
+ return key_.isValid();
+}
+
+css::registry::RegistryKeyType Key::getKeyType(rtl::OUString const & rKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegKeyType type;
+ RegError err = key_.getKeyType(rKeyName, &type);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getKeyType:"
+ " underlying RegistryKey::getKeyType() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ switch (type) {
+ default:
+ std::abort(); // this cannot happen
+ // pseudo-fall-through to avoid warnings on MSC
+ case RG_KEYTYPE:
+ return css::registry::RegistryKeyType_KEY;
+ case RG_LINKTYPE:
+ return css::registry::RegistryKeyType_LINK;
+ }
+}
+
+css::registry::RegistryValueType Key::getValueType()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegValueType type;
+ sal_uInt32 size;
+ RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
+ switch (err) {
+ case REG_NO_ERROR:
+ break;
+ case REG_INVALID_VALUE:
+ type = RG_VALUETYPE_NOT_DEFINED;
+ break;
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getValueType:"
+ " underlying RegistryKey::getValueInfo() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ switch (type) {
+ default:
+ std::abort(); // this cannot happen
+ // pseudo-fall-through to avoid warnings on MSC
+ case RG_VALUETYPE_NOT_DEFINED:
+ return css::registry::RegistryValueType_NOT_DEFINED;
+ case RG_VALUETYPE_LONG:
+ return css::registry::RegistryValueType_LONG;
+ case RG_VALUETYPE_STRING:
+ return css::registry::RegistryValueType_ASCII;
+ case RG_VALUETYPE_UNICODE:
+ return css::registry::RegistryValueType_STRING;
+ case RG_VALUETYPE_BINARY:
+ return css::registry::RegistryValueType_BINARY;
+ case RG_VALUETYPE_LONGLIST:
+ return css::registry::RegistryValueType_LONGLIST;
+ case RG_VALUETYPE_STRINGLIST:
+ return css::registry::RegistryValueType_ASCIILIST;
+ case RG_VALUETYPE_UNICODELIST:
+ return css::registry::RegistryValueType_STRINGLIST;
+ }
+}
+
+sal_Int32 Key::getLongValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ sal_Int32 value;
+ RegError err = key_.getValue(rtl::OUString(), &value);
+ switch (err) {
+ case REG_NO_ERROR:
+ break;
+ case REG_INVALID_VALUE:
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getLongValue:"
+ " underlying RegistryKey::getValue() = REG_INVALID_VALUE")),
+ static_cast< OWeakObject * >(this));
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getLongValue:"
+ " underlying RegistryKey::getValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ return value;
+}
+
+void Key::setLongValue(sal_Int32 value)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegError err = key_.setValue(
+ rtl::OUString(), RG_VALUETYPE_LONG, &value, sizeof (sal_Int32));
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key setLongValue:"
+ " underlying RegistryKey::setValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Sequence< sal_Int32 > Key::getLongListValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegistryValueList< sal_Int32 > list;
+ RegError err = key_.getLongListValue(rtl::OUString(), list);
+ switch (err) {
+ case REG_NO_ERROR:
+ break;
+ case REG_VALUE_NOT_EXISTS:
+ return css::uno::Sequence< sal_Int32 >();
+ case REG_INVALID_VALUE:
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getLongListValue:"
+ " underlying RegistryKey::getLongListValue() ="
+ " REG_INVALID_VALUE")),
+ static_cast< OWeakObject * >(this));
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getLongListValue:"
+ " underlying RegistryKey::getLongListValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ sal_uInt32 n = list.getLength();
+ if (n > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getLongListValue:"
+ " underlying RegistryKey::getLongListValue() too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< sal_Int32 > value(static_cast< sal_Int32 >(n));
+ for (sal_uInt32 i = 0; i < n; ++i) {
+ value[static_cast< sal_Int32 >(i)] = list.getElement(i);
+ }
+ return value;
+}
+
+void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const & seqValue)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ std::vector< sal_Int32 > list;
+ for (sal_Int32 i = 0; i < seqValue.getLength(); ++i) {
+ list.push_back(seqValue[i]);
+ }
+ RegError err = key_.setLongListValue(
+ rtl::OUString(), list.empty() ? 0 : &list[0],
+ static_cast< sal_uInt32 >(list.size()));
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key setLongListValue:"
+ " underlying RegistryKey::setLongListValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+rtl::OUString Key::getAsciiValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegValueType type;
+ sal_uInt32 size;
+ RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
+ " underlying RegistryKey::getValueInfo() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ if (type != RG_VALUETYPE_STRING) {
+ throw css::registry::InvalidValueException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
+ " underlying RegistryKey type = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(type))),
+ static_cast< OWeakObject * >(this));
+ }
+ // size contains terminating null (error in underlying registry.cxx):
+ if (size == 0) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
+ " underlying RegistryKey size 0 cannot happen due to"
+ " design error")),
+ static_cast< OWeakObject * >(this));
+ }
+ if (size > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
+ " underlying RegistryKey size too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ std::vector< char > list(size);
+ err = key_.getValue(rtl::OUString(), &list[0]);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
+ " underlying RegistryKey::getValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ if (list[size - 1] != '\0') {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
+ " underlying RegistryKey value must be null-terminated due"
+ " to design error")),
+ static_cast< OWeakObject * >(this));
+ }
+ rtl::OUString value;
+ if (!rtl_convertStringToUString(
+ &value.pData, &list[0],
+ static_cast< sal_Int32 >(size - 1), RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getAsciiValue:"
+ " underlying RegistryKey not UTF-8")),
+ static_cast< OWeakObject * >(this));
+ }
+ return value;
+}
+
+void Key::setAsciiValue(rtl::OUString const & value)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ rtl::OString utf8;
+ if (!value.convertToString(
+ &utf8, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key setAsciiValue:"
+ " value not UTF-16")),
+ static_cast< OWeakObject * >(this));
+ }
+ RegError err = key_.setValue(
+ rtl::OUString(), RG_VALUETYPE_STRING,
+ const_cast< char * >(utf8.getStr()), utf8.getLength() + 1);
+ // +1 for terminating null (error in underlying registry.cxx)
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key setAsciiValue:"
+ " underlying RegistryKey::setValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Sequence< rtl::OUString > Key::getAsciiListValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegistryValueList< char * > list;
+ RegError err = key_.getStringListValue(rtl::OUString(), list);
+ switch (err) {
+ case REG_NO_ERROR:
+ break;
+ case REG_VALUE_NOT_EXISTS:
+ return css::uno::Sequence< rtl::OUString >();
+ case REG_INVALID_VALUE:
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " getAsciiListValue: underlying"
+ " RegistryKey::getStringListValue() = REG_INVALID_VALUE")),
+ static_cast< OWeakObject * >(this));
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " getAsciiListValue: underlying"
+ " RegistryKey::getStringListValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ sal_uInt32 n = list.getLength();
+ if (n > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " getAsciiListValue: underlying"
+ " RegistryKey::getStringListValue() too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > value(static_cast< sal_Int32 >(n));
+ for (sal_uInt32 i = 0; i < n; ++i) {
+ char * el = list.getElement(i);
+ sal_Int32 size = rtl_str_getLength(el);
+ if (!rtl_convertStringToUString(
+ &value[static_cast< sal_Int32 >(i)].pData, el, size,
+ RTL_TEXTENCODING_UTF8,
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR)))
+ {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " getAsciiListValue: underlying RegistryKey not"
+ " UTF-8")),
+ static_cast< OWeakObject * >(this));
+ }
+ }
+ return value;
+}
+
+void Key::setAsciiListValue(
+ css::uno::Sequence< rtl::OUString > const & seqValue)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ std::vector< rtl::OString > list;
+ for (sal_Int32 i = 0; i < seqValue.getLength(); ++i) {
+ rtl::OString utf8;
+ if (!seqValue[i].convertToString(
+ &utf8, RTL_TEXTENCODING_UTF8,
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR)))
+ {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " setAsciiListValue: value not UTF-16")),
+ static_cast< OWeakObject * >(this));
+ }
+ list.push_back(utf8);
+ }
+ std::vector< char * > list2;
+ for (std::vector< rtl::OString >::iterator i(list.begin()); i != list.end();
+ ++i)
+ {
+ list2.push_back(const_cast< char * >(i->getStr()));
+ }
+ RegError err = key_.setStringListValue(
+ rtl::OUString(), list2.empty() ? 0 : &list2[0],
+ static_cast< sal_uInt32 >(list2.size()));
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " setAsciiListValue: underlying"
+ " RegistryKey::setStringListValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+rtl::OUString Key::getStringValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegValueType type;
+ sal_uInt32 size;
+ RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getStringValue:"
+ " underlying RegistryKey::getValueInfo() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ if (type != RG_VALUETYPE_UNICODE) {
+ throw css::registry::InvalidValueException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getStringValue:"
+ " underlying RegistryKey type = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(type))),
+ static_cast< OWeakObject * >(this));
+ }
+ // size contains terminating null and is *2 (error in underlying
+ // registry.cxx):
+ if (size == 0 || (size & 1) == 1) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getStringValue:"
+ " underlying RegistryKey size 0 or odd cannot happen due to"
+ " design error")),
+ static_cast< OWeakObject * >(this));
+ }
+ if (size > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getStringValue:"
+ " underlying RegistryKey size too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ std::vector< sal_Unicode > list(size);
+ err = key_.getValue(rtl::OUString(), &list[0]);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getStringValue:"
+ " underlying RegistryKey::getValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ if (list[size/2 - 1] != 0) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getStringValue:"
+ " underlying RegistryKey value must be null-terminated due"
+ " to design error")),
+ static_cast< OWeakObject * >(this));
+ }
+ return rtl::OUString(&list[0], static_cast< sal_Int32 >(size/2 - 1));
+}
+
+void Key::setStringValue(rtl::OUString const & value)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegError err = key_.setValue(
+ rtl::OUString(), RG_VALUETYPE_UNICODE,
+ const_cast< sal_Unicode * >(value.getStr()),
+ (value.getLength() + 1) * sizeof (sal_Unicode));
+ // +1 for terminating null (error in underlying registry.cxx)
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key setStringValue:"
+ " underlying RegistryKey::setValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Sequence< rtl::OUString > Key::getStringListValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegistryValueList< sal_Unicode * > list;
+ RegError err = key_.getUnicodeListValue(rtl::OUString(), list);
+ switch (err) {
+ case REG_NO_ERROR:
+ break;
+ case REG_VALUE_NOT_EXISTS:
+ return css::uno::Sequence< rtl::OUString >();
+ case REG_INVALID_VALUE:
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " getStringListValue: underlying"
+ " RegistryKey::getUnicodeListValue() = REG_INVALID_VALUE")),
+ static_cast< OWeakObject * >(this));
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " getStringListValue: underlying"
+ " RegistryKey::getUnicodeListValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ sal_uInt32 n = list.getLength();
+ if (n > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " getStringListValue: underlying"
+ " RegistryKey::getUnicodeListValue() too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > value(static_cast< sal_Int32 >(n));
+ for (sal_uInt32 i = 0; i < n; ++i) {
+ value[static_cast< sal_Int32 >(i)] = list.getElement(i);
+ }
+ return value;
+}
+
+void Key::setStringListValue(
+ css::uno::Sequence< rtl::OUString > const & seqValue)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ std::vector< sal_Unicode * > list;
+ for (sal_Int32 i = 0; i < seqValue.getLength(); ++i) {
+ list.push_back(const_cast< sal_Unicode * >(seqValue[i].getStr()));
+ }
+ RegError err = key_.setUnicodeListValue(
+ rtl::OUString(), list.empty() ? 0 : &list[0],
+ static_cast< sal_uInt32 >(list.size()));
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key"
+ " setStringListValue: underlying"
+ " RegistryKey::setUnicodeListValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Sequence< sal_Int8 > Key::getBinaryValue()
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegValueType type;
+ sal_uInt32 size;
+ RegError err = key_.getValueInfo(rtl::OUString(), &type, &size);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
+ " underlying RegistryKey::getValueInfo() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ if (type != RG_VALUETYPE_BINARY) {
+ throw css::registry::InvalidValueException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
+ " underlying RegistryKey type = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(type))),
+ static_cast< OWeakObject * >(this));
+ }
+ if (size > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
+ " underlying RegistryKey size too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< sal_Int8 > value(static_cast< sal_Int32 >(size));
+ err = key_.getValue(rtl::OUString(), value.getArray());
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getBinaryValue:"
+ " underlying RegistryKey::getValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ return value;
+}
+
+void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const & value)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegError err = key_.setValue(
+ rtl::OUString(), RG_VALUETYPE_BINARY,
+ const_cast< sal_Int8 * >(value.getConstArray()),
+ static_cast< sal_uInt32 >(value.getLength()));
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key setBinaryValue:"
+ " underlying RegistryKey::setValue() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Reference< css::registry::XRegistryKey > Key::openKey(
+ rtl::OUString const & aKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegistryKey key;
+ RegError err = key_.openKey(aKeyName, key);
+ switch (err) {
+ case REG_NO_ERROR:
+ return new Key(registry_, key);
+ case REG_KEY_NOT_EXISTS:
+ return css::uno::Reference< css::registry::XRegistryKey >();
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key openKey:"
+ " underlying RegistryKey::openKey() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Reference< css::registry::XRegistryKey > Key::createKey(
+ rtl::OUString const & aKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegistryKey key;
+ RegError err = key_.createKey(aKeyName, key);
+ switch (err) {
+ case REG_NO_ERROR:
+ return new Key(registry_, key);
+ case REG_INVALID_KEYNAME:
+ return css::uno::Reference< css::registry::XRegistryKey >();
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key createKey:"
+ " underlying RegistryKey::createKey() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+void Key::closeKey()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegError err = key_.closeKey();
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key closeKey:"
+ " underlying RegistryKey::closeKey() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+void Key::deleteKey(rtl::OUString const & rKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegError err = key_.deleteKey(rKeyName);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key deleteKey:"
+ " underlying RegistryKey::deleteKey() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
+Key::openKeys()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegistryKeyArray list;
+ RegError err = key_.openSubKeys(rtl::OUString(), list);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key openKeys:"
+ " underlying RegistryKey::openSubKeys() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ sal_uInt32 n = list.getLength();
+ if (n > SAL_MAX_INT32) {
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getKeyNames:"
+ " underlying RegistryKey::getKeyNames() too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
+ keys(static_cast< sal_Int32 >(n));
+ for (sal_uInt32 i = 0; i < n; ++i) {
+ keys[static_cast< sal_Int32 >(i)] = new Key(
+ registry_, list.getElement(i));
+ }
+ return keys;
+}
+
+css::uno::Sequence< rtl::OUString > Key::getKeyNames()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegistryKeyNames list;
+ RegError err = key_.getKeyNames(rtl::OUString(), list);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getKeyNames:"
+ " underlying RegistryKey::getKeyNames() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ sal_uInt32 n = list.getLength();
+ if (n > SAL_MAX_INT32) {
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getKeyNames:"
+ " underlying RegistryKey::getKeyNames() too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > names(static_cast< sal_Int32 >(n));
+ for (sal_uInt32 i = 0; i < n; ++i) {
+ names[static_cast< sal_Int32 >(i)] = list.getElement(i);
+ }
+ return names;
+}
+
+sal_Bool Key::createLink(
+ rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegError err = key_.createLink(aLinkName, aLinkTarget);
+ switch (err) {
+ case REG_NO_ERROR:
+ return true;
+ case REG_INVALID_KEY:
+ case REG_DETECT_RECURSION:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key createLink:"
+ " underlying RegistryKey::createLink() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ default:
+ return false;
+ }
+}
+
+void Key::deleteLink(rtl::OUString const & rLinkName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ RegError err = key_.deleteLink(rLinkName);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key deleteLink:"
+ " underlying RegistryKey::deleteLink() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+rtl::OUString Key::getLinkTarget(rtl::OUString const & rLinkName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ rtl::OUString target;
+ RegError err = key_.getLinkTarget(rLinkName, target);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getLinkTarget:"
+ " underlying RegistryKey::getLinkTarget() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ return target;
+}
+
+rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(registry_->mutex_);
+ rtl::OUString resolved;
+ RegError err = key_.getResolvedKeyName(aKeyName, true, resolved);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry key getResolvedName:"
+ " underlying RegistryKey::getResolvedName() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ return resolved;
+}
+
+rtl::OUString SimpleRegistry::getURL() throw (css::uno::RuntimeException) {
+ osl::MutexGuard guard(mutex_);
+ return textual_.get() == 0 ? registry_.getName() : textual_->getUri();
+}
+
+void SimpleRegistry::open(
+ rtl::OUString const & rURL, sal_Bool bReadOnly, sal_Bool bCreate)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(mutex_);
+ if (textual_.get() != 0) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.open(")) +
+ rURL +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "): instance already open"))),
+ static_cast< OWeakObject * >(this));
+ }
+ RegError err = (rURL.getLength() == 0 && bCreate)
+ ? REG_REGISTRY_NOT_EXISTS
+ : registry_.open(rURL, bReadOnly ? REG_READONLY : REG_READWRITE);
+ if (err == REG_REGISTRY_NOT_EXISTS && bCreate) {
+ err = registry_.create(rURL);
+ }
+ switch (err) {
+ case REG_NO_ERROR:
+ break;
+ case REG_INVALID_REGISTRY:
+ if (bReadOnly && !bCreate) {
+ textual_.reset(new stoc::simpleregistry::TextualServices(rURL));
+ break;
+ }
+ // fall through
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.open(")) +
+ rURL +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "): underlying Registry::open/create() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+sal_Bool SimpleRegistry::isValid() throw (css::uno::RuntimeException) {
+ osl::MutexGuard guard(mutex_);
+ return textual_.get() != 0 || registry_.isValid();
+}
+
+void SimpleRegistry::close()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(mutex_);
+ if (textual_.get() != 0) {
+ textual_.reset();
+ return;
+ }
+ RegError err = registry_.close();
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.close:"
+ " underlying Registry::close() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+void SimpleRegistry::destroy()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(mutex_);
+ if (textual_.get() != 0) {
+ textual_.reset();
+ return;
+ }
+ RegError err = registry_.destroy(rtl::OUString());
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.destroy:"
+ " underlying Registry::destroy() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+css::uno::Reference< css::registry::XRegistryKey > SimpleRegistry::getRootKey()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(mutex_);
+ if (textual_.get() != 0) {
+ return textual_->getRootKey();
+ }
+ RegistryKey root;
+ RegError err = registry_.openRootKey(root);
+ if (err != REG_NO_ERROR) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.getRootKey:"
+ " underlying Registry::getRootKey() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+ return new Key(this, root);
+}
+
+sal_Bool SimpleRegistry::isReadOnly()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(mutex_);
+ return textual_.get() != 0 || registry_.isReadOnly();
+}
+
+void SimpleRegistry::mergeKey(
+ rtl::OUString const & aKeyName, rtl::OUString const & aUrl)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::MergeConflictException, css::uno::RuntimeException)
+{
+ osl::MutexGuard guard(mutex_);
+ if (textual_.get() != 0) {
+ throw css::uno::RuntimeException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.mergeKey: not"
+ " supported for textual representation")),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ RegistryKey root;
+ RegError err = registry_.openRootKey(root);
+ if (err == REG_NO_ERROR) {
+ err = registry_.mergeKey(root, aKeyName, aUrl, false, false);
+ }
+ switch (err) {
+ case REG_NO_ERROR:
+ case REG_MERGE_CONFLICT:
+ break;
+ case REG_MERGE_ERROR:
+ throw css::registry::MergeConflictException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.mergeKey:"
+ " underlying Registry::mergeKey() = REG_MERGE_ERROR")),
+ static_cast< cppu::OWeakObject * >(this));
+ default:
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry.mergeKey:"
+ " underlying Registry::getRootKey/mergeKey() = ")) +
+ rtl::OUString::valueOf(static_cast< sal_Int32 >(err))),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+}
+
+namespace stoc_bootstrap {
+
+css::uno::Reference< css::uno::XInterface > SimpleRegistry_CreateInstance(
+ css::uno::Reference< css::uno::XComponentContext > const &)
+{
+ return static_cast< cppu::OWeakObject * >(new SimpleRegistry);
+}
+
+css::uno::Sequence< rtl::OUString > simreg_getSupportedServiceNames() {
+ css::uno::Sequence< rtl::OUString > names(1);
+ names[0] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.registry.SimpleRegistry"));
+ return names;
+}
+
+rtl::OUString simreg_getImplementationName() {
+ return rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.stoc.SimpleRegistry"));
+}
+
+}
diff --git a/stoc/source/simpleregistry/textualservices.cxx b/stoc/source/simpleregistry/textualservices.cxx
new file mode 100644
index 000000000000..5a50a5aa62c6
--- /dev/null
+++ b/stoc/source/simpleregistry/textualservices.cxx
@@ -0,0 +1,1228 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+************************************************************************/
+
+#include "precompiled_stoc.hxx"
+#include "sal/config.h"
+
+#include <cstddef>
+#include <cstdlib>
+#include <map>
+#include <vector>
+
+#include "boost/noncopyable.hpp"
+#include "com/sun/star/container/NoSuchElementException.hpp"
+#include "com/sun/star/registry/InvalidRegistryException.hpp"
+#include "com/sun/star/registry/XRegistryKey.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "osl/diagnose.h"
+#include "rtl/malformeduriexception.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/string.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "xmlreader/span.hxx"
+#include "xmlreader/xmlreader.hxx"
+
+#include "textualservices.hxx"
+
+namespace stoc { namespace simpleregistry {
+
+namespace {
+
+namespace css = com::sun::star;
+
+struct Implementation {
+ rtl::OUString uri;
+ rtl::OUString loader;
+ std::vector< rtl::OUString > services;
+ std::vector< rtl::OUString > singletons;
+};
+
+typedef std::map< rtl::OUString, Implementation > Implementations;
+
+typedef std::map< rtl::OUString, std::vector< rtl::OUString > >
+ ImplementationMap;
+
+}
+
+class Data: public salhelper::SimpleReferenceObject, private boost::noncopyable
+{
+public:
+ Implementations implementations;
+ ImplementationMap services;
+ ImplementationMap singletons;
+};
+
+namespace {
+
+class Parser: private boost::noncopyable {
+public:
+ Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data);
+
+private:
+ void handleComponent();
+
+ void handleImplementation();
+
+ void handleService();
+
+ void handleSingleton();
+
+ rtl::OUString getNameAttribute();
+
+ xmlreader::XmlReader reader_;
+ rtl::Reference< Data > data_;
+ rtl::OUString attrUri_;
+ rtl::OUString attrLoader_;
+ rtl::OUString attrImplementation_;
+};
+
+Parser::Parser(rtl::OUString const & uri, rtl::Reference< Data > const & data):
+ reader_(uri), data_(data)
+{
+ OSL_ASSERT(data.is());
+ int ucNsId = reader_.registerNamespaceIri(
+ xmlreader::Span(
+ RTL_CONSTASCII_STRINGPARAM(
+ "http://openoffice.org/2010/uno-components")));
+ enum State {
+ STATE_BEGIN, STATE_END, STATE_COMPONENTS, STATE_COMPONENT_INITIAL,
+ STATE_COMPONENT, STATE_IMPLEMENTATION, STATE_SERVICE, STATE_SINGLETON };
+ for (State state = STATE_BEGIN;;) {
+ xmlreader::Span name;
+ int nsId;
+ xmlreader::XmlReader::Result res = reader_.nextItem(
+ xmlreader::XmlReader::TEXT_NONE, &name, &nsId);
+ switch (state) {
+ case STATE_BEGIN:
+ if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("components")))
+ {
+ state = STATE_COMPONENTS;
+ break;
+ }
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": unexpected item in outer level"))),
+ css::uno::Reference< css::uno::XInterface >());
+ case STATE_END:
+ if (res == xmlreader::XmlReader::RESULT_DONE) {
+ return;
+ }
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": unexpected item in outer level"))),
+ css::uno::Reference< css::uno::XInterface >());
+ case STATE_COMPONENTS:
+ if (res == xmlreader::XmlReader::RESULT_END) {
+ state = STATE_END;
+ break;
+ }
+ if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("component")))
+ {
+ handleComponent();
+ state = STATE_COMPONENT_INITIAL;
+ break;
+ }
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": unexpected item in <components>"))),
+ css::uno::Reference< css::uno::XInterface >());
+ case STATE_COMPONENT:
+ if (res == xmlreader::XmlReader::RESULT_END) {
+ state = STATE_COMPONENTS;
+ break;
+ }
+ // fall through
+ case STATE_COMPONENT_INITIAL:
+ if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("implementation")))
+ {
+ handleImplementation();
+ state = STATE_IMPLEMENTATION;
+ break;
+ }
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": unexpected item in <component>"))),
+ css::uno::Reference< css::uno::XInterface >());
+ case STATE_IMPLEMENTATION:
+ if (res == xmlreader::XmlReader::RESULT_END) {
+ state = STATE_COMPONENT;
+ break;
+ }
+ if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("service")))
+ {
+ handleService();
+ state = STATE_SERVICE;
+ break;
+ }
+ if (res == xmlreader::XmlReader::RESULT_BEGIN && nsId == ucNsId &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("singleton")))
+ {
+ handleSingleton();
+ state = STATE_SINGLETON;
+ break;
+ }
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": unexpected item in <implementation>"))),
+ css::uno::Reference< css::uno::XInterface >());
+ case STATE_SERVICE:
+ if (res == xmlreader::XmlReader::RESULT_END) {
+ state = STATE_IMPLEMENTATION;
+ break;
+ }
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": unexpected item in <service>"))),
+ css::uno::Reference< css::uno::XInterface >());
+ case STATE_SINGLETON:
+ if (res == xmlreader::XmlReader::RESULT_END) {
+ state = STATE_IMPLEMENTATION;
+ break;
+ }
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": unexpected item in <service>"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+}
+
+void Parser::handleComponent() {
+ attrUri_ = rtl::OUString();
+ attrLoader_ = rtl::OUString();
+ xmlreader::Span name;
+ int nsId;
+ while (reader_.nextAttribute(&nsId, &name)) {
+ if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("uri")))
+ {
+ if (attrUri_.getLength() != 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": <component> has multiple \"uri\" attributes"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ attrUri_ = reader_.getAttributeValue(false).convertFromUtf8();
+ if (attrUri_.getLength() == 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": <component> has empty \"uri\" attribute"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ } else if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("loader")))
+ {
+ if (attrLoader_.getLength() != 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": <component> has multiple \"loader\""
+ " attributes"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ attrLoader_ = reader_.getAttributeValue(false).convertFromUtf8();
+ if (attrLoader_.getLength() == 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": <component> has empty \"loader\" attribute"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ } else {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": expected <component> attribute \"uri\" or"
+ " \"loader\""))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+ if (attrUri_.getLength() == 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": <component> is missing \"uri\" attribute"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ if (attrLoader_.getLength() == 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": <component> is missing \"loader\" attribute"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ try {
+ attrUri_ = rtl::Uri::convertRelToAbs(reader_.getUrl(), attrUri_);
+ } catch (rtl::MalformedUriException & e) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(": bad \"uri\" attribute: ")) +
+ e.getMessage()),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+void Parser::handleImplementation() {
+ attrImplementation_ = getNameAttribute();
+ if (data_->implementations.find(attrImplementation_) !=
+ data_->implementations.end())
+ {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": duplicate <implementation name=\"")) +
+ attrImplementation_ +
+ rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("\">"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ data_->implementations[attrImplementation_].uri = attrUri_;
+ data_->implementations[attrImplementation_].loader = attrLoader_;
+}
+
+void Parser::handleService() {
+ rtl::OUString name = getNameAttribute();
+ data_->implementations[attrImplementation_].services.push_back(name);
+ data_->services[name].push_back(attrImplementation_);
+}
+
+void Parser::handleSingleton() {
+ rtl::OUString name = getNameAttribute();
+ data_->implementations[attrImplementation_].singletons.push_back(name);
+ data_->singletons[name].push_back(attrImplementation_);
+}
+
+rtl::OUString Parser::getNameAttribute() {
+ rtl::OUString attrName;
+ xmlreader::Span name;
+ int nsId;
+ while (reader_.nextAttribute(&nsId, &name)) {
+ if (nsId == xmlreader::XmlReader::NAMESPACE_NONE &&
+ name.equals(RTL_CONSTASCII_STRINGPARAM("name")))
+ {
+ if (attrName.getLength() != 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": element has multiple \"name\" attributes"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ attrName = reader_.getAttributeValue(false).convertFromUtf8();
+ if (attrName.getLength() == 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": element has empty \"name\" attribute"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ } else {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": expected element attribute \"name\""))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ }
+ if (attrName.getLength() == 0) {
+ throw css::registry::InvalidRegistryException(
+ (reader_.getUrl() +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ ": element is missing \"name\" attribute"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+ return attrName;
+}
+
+rtl::OUString pathToString(std::vector< rtl::OUString > const & path) {
+ rtl::OUStringBuffer buf;
+ for (std::vector< rtl::OUString >::const_iterator i(path.begin());
+ i != path.end(); ++i)
+ {
+ buf.append(sal_Unicode('/'));
+ buf.append(*i);
+ }
+ if (buf.getLength() == 0) {
+ buf.append(sal_Unicode('/'));
+ }
+ return buf.makeStringAndClear();
+}
+
+class Key: public cppu::WeakImplHelper1< css::registry::XRegistryKey > {
+public:
+ Key(
+ rtl::Reference< Data > const & data,
+ std::vector< rtl::OUString > const & path):
+ data_(data), path_(path) { OSL_ASSERT(data.is());
+ }
+
+private:
+ /*
+ /
+ IMPLEMENTATIONS
+ <implementation>
+ UNO
+ LOCATION utf-8
+ ACTIVATOR utf-8
+ SERVICES
+ <service>
+ ...
+ SINGLETONS
+ <singleton> utf-16
+ ...
+ ...
+ SERVICES
+ <service> utf-8-list
+ ...
+ SINGLETONS
+ <singleton> utf-16
+ REGISTERED_BY utf-8-list
+ ...
+ */
+ enum State {
+ STATE_ROOT, STATE_IMPLEMENTATIONS, STATE_IMPLEMENTATION, STATE_UNO,
+ STATE_LOCATION, STATE_ACTIVATOR, STATE_IMPLEMENTATION_SERVICES,
+ STATE_IMPLEMENTATION_SERVICE, STATE_IMPLEMENTATION_SINGLETONS,
+ STATE_IMPLEMENTATION_SINGLETON, STATE_SERVICES, STATE_SERVICE,
+ STATE_SINGLETONS, STATE_SINGLETON, STATE_REGISTEREDBY };
+
+ virtual rtl::OUString SAL_CALL getKeyName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isReadOnly() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL isValid() throw(css::uno::RuntimeException);
+
+ virtual css::registry::RegistryKeyType SAL_CALL getKeyType(
+ rtl::OUString const & rKeyName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::registry::RegistryValueType SAL_CALL getValueType() throw(
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual sal_Int32 SAL_CALL getLongValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setLongValue(sal_Int32 value) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< sal_Int32 > SAL_CALL getLongListValue() throw(
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setLongListValue(
+ com::sun::star::uno::Sequence< sal_Int32 > const & seqValue)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getAsciiValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setAsciiValue(rtl::OUString const & value) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getAsciiListValue()
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setAsciiListValue(
+ css::uno::Sequence< rtl::OUString > const & seqValue)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getStringValue() throw(
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setStringValue(rtl::OUString const & value) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getStringListValue()
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setStringListValue(
+ css::uno::Sequence< rtl::OUString > const & seqValue)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< sal_Int8 > SAL_CALL getBinaryValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL setBinaryValue(
+ css::uno::Sequence< sal_Int8 > const & value)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL openKey(
+ rtl::OUString const & aKeyName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::registry::XRegistryKey > SAL_CALL
+ createKey(rtl::OUString const & aKeyName) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL closeKey() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual void SAL_CALL deleteKey(rtl::OUString const & rKeyName) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual
+ css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
+ SAL_CALL openKeys() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL getKeyNames() throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL createLink(
+ rtl::OUString const & aLinkName, rtl::OUString const & aLinkTarget)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual void SAL_CALL deleteLink(rtl::OUString const & rLinkName) throw (
+ css::registry::InvalidRegistryException, css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getLinkTarget(
+ rtl::OUString const & rLinkName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getResolvedName(
+ rtl::OUString const & aKeyName)
+ throw (
+ css::registry::InvalidRegistryException,
+ css::uno::RuntimeException);
+
+ bool find(
+ rtl::OUString const & relative, std::vector< rtl::OUString > * path,
+ State * state, css::registry::RegistryValueType * type) const;
+
+ css::uno::Sequence< rtl::OUString > getChildren();
+
+ rtl::Reference< Data > data_;
+ std::vector< rtl::OUString > path_;
+};
+
+rtl::OUString Key::getKeyName() throw (css::uno::RuntimeException) {
+ return pathToString(path_);
+}
+
+sal_Bool Key::isReadOnly()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ return true;
+}
+
+sal_Bool Key::isValid() throw(css::uno::RuntimeException) {
+ return true;
+}
+
+css::registry::RegistryKeyType Key::getKeyType(rtl::OUString const & rKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ if (!find(rtl::OUString(), 0, 0, 0)) {
+ throw css::registry::InvalidRegistryException(
+ (rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("unknown key ")) +
+ rKeyName),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ return css::registry::RegistryKeyType_KEY;
+}
+
+css::registry::RegistryValueType Key::getValueType()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ css::registry::RegistryValueType type =
+ css::registry::RegistryValueType_NOT_DEFINED;
+ OSL_VERIFY(find(rtl::OUString(), 0, 0, &type));
+ return type;
+}
+
+sal_Int32 Key::getLongValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getLongValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+void Key::setLongValue(sal_Int32)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " setLongValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+css::uno::Sequence< sal_Int32 > Key::getLongListValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getLongListValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+void Key::setLongListValue(css::uno::Sequence< sal_Int32 > const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " setLongListValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+rtl::OUString Key::getAsciiValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ State state = STATE_ROOT;
+ OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
+ switch (state) {
+ case STATE_LOCATION:
+ return data_->implementations[path_[1]].uri;
+ case STATE_ACTIVATOR:
+ return data_->implementations[path_[1]].loader;
+ default:
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getAsciiValue: wrong type")),
+ static_cast< OWeakObject * >(this));
+ }
+}
+
+void Key::setAsciiValue(rtl::OUString const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " setAsciiValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+css::uno::Sequence< rtl::OUString > Key::getAsciiListValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ State state = STATE_ROOT;
+ OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
+ std::vector< rtl::OUString > const * list;
+ switch (state) {
+ case STATE_SERVICE:
+ list = &data_->services[path_[1]];
+ break;
+ case STATE_REGISTEREDBY:
+ list = &data_->singletons[path_[1]];
+ break;
+ default:
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getAsciiListValue: wrong type")),
+ static_cast< OWeakObject * >(this));
+ }
+ if (list->size() > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getAsciiListValue: too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > seq(
+ static_cast< sal_Int32 >(list->size()));
+ sal_Int32 i = 0;
+ for (std::vector< rtl::OUString >::const_iterator j(list->begin());
+ j != list->end(); ++j)
+ {
+ seq[i++] = *j;
+ }
+ return seq;
+}
+
+void Key::setAsciiListValue(css::uno::Sequence< rtl::OUString > const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " setAsciiListValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+rtl::OUString Key::getStringValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ State state = STATE_ROOT;
+ OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
+ switch (state) {
+ case STATE_IMPLEMENTATION_SINGLETON:
+ case STATE_SINGLETON:
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getStringValue: does not associate singletons with"
+ " services")),
+ static_cast< OWeakObject * >(this));
+ default:
+ break;
+ }
+ // default case extracted from switch to avoid erroneous compiler warnings
+ // on Solaris:
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getStringValue: wrong type")),
+ static_cast< OWeakObject * >(this));
+}
+
+void Key::setStringValue(rtl::OUString const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " setStringValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+css::uno::Sequence< rtl::OUString > Key::getStringListValue() throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getStringListValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+void Key::setStringListValue(css::uno::Sequence< rtl::OUString > const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " setStringListValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+css::uno::Sequence< sal_Int8 > Key::getBinaryValue()
+ throw (
+ css::registry::InvalidRegistryException,
+ css::registry::InvalidValueException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getBinarValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+void Key::setBinaryValue(css::uno::Sequence< sal_Int8 > const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " setBinaryValue not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+css::uno::Reference< css::registry::XRegistryKey > Key::openKey(
+ rtl::OUString const & aKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ std::vector< rtl::OUString > path;
+ if (!find(aKeyName, &path, 0, 0)) {
+ return css::uno::Reference< css::registry::XRegistryKey >();
+ }
+ return new Key(data_, path);
+}
+
+css::uno::Reference< css::registry::XRegistryKey > Key::createKey(
+ rtl::OUString const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " createKey not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+void Key::closeKey()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{}
+
+void Key::deleteKey(rtl::OUString const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " deleteKey not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
+Key::openKeys()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ css::uno::Sequence< rtl::OUString > names(getChildren());
+ css::uno::Sequence< css::uno::Reference< css::registry::XRegistryKey > >
+ keys(names.getLength());
+ for (sal_Int32 i = 0; i < keys.getLength(); ++i) {
+ keys[i] = openKey(names[i]);
+ OSL_ASSERT(keys[i].is());
+ }
+ return keys;
+}
+
+css::uno::Sequence< rtl::OUString > Key::getKeyNames()
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ css::uno::Sequence< rtl::OUString > names(getChildren());
+ rtl::OUString prefix(pathToString(path_));
+ prefix += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("/"));
+ for (sal_Int32 i = 0; i < names.getLength(); ++i) {
+ names[i] = prefix + names[i];
+ }
+ return names;
+}
+
+sal_Bool Key::createLink(rtl::OUString const &, rtl::OUString const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " createLink not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+void Key::deleteLink(rtl::OUString const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " deleteLink not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+rtl::OUString Key::getLinkTarget(rtl::OUString const &)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ throw css::registry::InvalidRegistryException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual services key"
+ " getLinkTarget not supported")),
+ static_cast< OWeakObject * >(this));
+}
+
+rtl::OUString Key::getResolvedName(rtl::OUString const & aKeyName)
+ throw (css::registry::InvalidRegistryException, css::uno::RuntimeException)
+{
+ std::vector< rtl::OUString > path;
+ find(aKeyName, &path, 0, 0);
+ return pathToString(path);
+}
+
+bool Key::find(
+ rtl::OUString const & relative, std::vector< rtl::OUString > * path,
+ State * state, css::registry::RegistryValueType * type) const
+{
+ std::vector< rtl::OUString > p(path_);
+ sal_Int32 i = 0;
+ do {
+ rtl::OUString seg(relative.getToken(0, '/', i));
+ if (seg.getLength() != 0) {
+ p.push_back(seg);
+ }
+ } while (i >= 0);
+ if (path != 0) {
+ *path = p;
+ }
+ std::size_t const MAX_TRANSITIONS = 4;
+ struct StateInfo {
+ css::registry::RegistryValueType type;
+ std::size_t count;
+ struct { char const * segment; State state; }
+ transitions[MAX_TRANSITIONS];
+ };
+ static StateInfo const info[] = {
+ // STATE_ROOT:
+ { css::registry::RegistryValueType_NOT_DEFINED, 3,
+ { { "IMPLEMENTATIONS", STATE_IMPLEMENTATIONS },
+ { "SERVICES", STATE_SERVICES },
+ { "SINGLETONS", STATE_SINGLETONS } } },
+ // STATE_IMPLEMENTATIONS:
+ { css::registry::RegistryValueType_NOT_DEFINED, 1,
+ { { 0, STATE_IMPLEMENTATION } } },
+ // STATE_IMPLEMENTATION:
+ { css::registry::RegistryValueType_NOT_DEFINED, 1,
+ { { "UNO", STATE_UNO } } },
+ // STATE_UNO:
+ { css::registry::RegistryValueType_NOT_DEFINED, 4,
+ { { "LOCATION", STATE_LOCATION },
+ { "ACTIVATOR", STATE_ACTIVATOR },
+ { "SERVICES", STATE_IMPLEMENTATION_SERVICES },
+ { "SINGLETONS", STATE_IMPLEMENTATION_SINGLETONS } } },
+ // STATE_LOCATION:
+ { css::registry::RegistryValueType_ASCII, 0, {} },
+ // STATE_ACTIVATOR:
+ { css::registry::RegistryValueType_ASCII, 0, {} },
+ // STATE_IMPLEMENTATION_SERVICES:
+ { css::registry::RegistryValueType_NOT_DEFINED, 1,
+ { { 0, STATE_IMPLEMENTATION_SERVICE } } },
+ // STATE_IMPLEMENTATION_SERVICE:
+ { css::registry::RegistryValueType_NOT_DEFINED, 0, {} },
+ // STATE_IMPLEMENTATION_SINGLETONS:
+ { css::registry::RegistryValueType_NOT_DEFINED, 1,
+ { { 0, STATE_IMPLEMENTATION_SINGLETON } } },
+ // STATE_IMPLEMENTATION_SINGLETON:
+ { css::registry::RegistryValueType_STRING, 0, {} },
+ // STATE_SERVICES:
+ { css::registry::RegistryValueType_NOT_DEFINED, 1,
+ { { 0, STATE_SERVICE } } },
+ // STATE_SERVICE:
+ { css::registry::RegistryValueType_ASCIILIST, 0, {} },
+ // STATE_SINGLETONS:
+ { css::registry::RegistryValueType_NOT_DEFINED, 1,
+ { { 0, STATE_SINGLETON } } },
+ // STATE_SINGLETON:
+ { css::registry::RegistryValueType_STRING, 1,
+ { { "REGISTERED_BY", STATE_REGISTEREDBY } } },
+ // STATE_REGISTEREDBY:
+ { css::registry::RegistryValueType_ASCIILIST, 0, {} } };
+ State s = STATE_ROOT;
+ for (std::vector< rtl::OUString >::iterator j(p.begin()); j != p.end(); ++j)
+ {
+ bool found = false;
+ for (std::size_t k = 0; k < info[s].count; ++k) {
+ if (info[s].transitions[k].segment == 0) {
+ switch (info[s].transitions[k].state) {
+ case STATE_IMPLEMENTATION:
+ found = data_->implementations.find(*j) !=
+ data_->implementations.end();
+ break;
+ case STATE_IMPLEMENTATION_SERVICE:
+ case STATE_IMPLEMENTATION_SINGLETON:
+ found = true; //TODO
+ break;
+ case STATE_SERVICE:
+ found = data_->services.find(*j) != data_->services.end();
+ break;
+ case STATE_SINGLETON:
+ found = data_->singletons.find(*j) !=
+ data_->singletons.end();
+ break;
+ default:
+ std::abort(); // this cannot happen
+ }
+ } else {
+ found = j->equalsAscii(info[s].transitions[k].segment);
+ }
+ if (found) {
+ s = info[s].transitions[k].state;
+ break;
+ }
+ }
+ if (!found) {
+ return false;
+ }
+ }
+ if (state != 0) {
+ *state = s;
+ }
+ if (type != 0) {
+ *type = info[s].type;
+ }
+ return true;
+}
+
+css::uno::Sequence< rtl::OUString > Key::getChildren() {
+ State state = STATE_ROOT;
+ OSL_VERIFY(find(rtl::OUString(), 0, &state, 0));
+ switch (state) {
+ default:
+ std::abort(); // this cannot happen
+ // pseudo-fall-through to avoid warnings on MSC
+ case STATE_ROOT:
+ {
+ css::uno::Sequence< rtl::OUString > seq(3);
+ seq[0] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("IMPLEMENTATIONS"));
+ seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES"));
+ seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS"));
+ return seq;
+ }
+ case STATE_IMPLEMENTATIONS:
+ {
+ if (data_->implementations.size() > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual"
+ " services key openKeys: too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > seq(
+ static_cast< sal_Int32 >(data_->implementations.size()));
+ sal_Int32 i = 0;
+ for (Implementations::iterator j(data_->implementations.begin());
+ j != data_->implementations.end(); ++j)
+ {
+ seq[i++] = j->first;
+ }
+ return seq;
+ }
+ case STATE_UNO:
+ {
+ css::uno::Sequence< rtl::OUString > seq(4);
+ seq[0] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("LOCATION"));
+ seq[1] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ACTIVATOR"));
+ seq[2] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SERVICES"));
+ seq[3] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SINGLETONS"));
+ return seq;
+ }
+ case STATE_LOCATION:
+ case STATE_ACTIVATOR:
+ case STATE_IMPLEMENTATION_SERVICE:
+ case STATE_IMPLEMENTATION_SINGLETON:
+ case STATE_SERVICE:
+ case STATE_REGISTEREDBY:
+ return css::uno::Sequence< rtl::OUString >();
+ case STATE_IMPLEMENTATION_SERVICES:
+ {
+ if (data_->implementations[path_[1]].services.size() >
+ SAL_MAX_INT32)
+ {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual"
+ " services key openKeys: too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > seq(
+ static_cast< sal_Int32 >(
+ data_->implementations[path_[1]].services.size()));
+ sal_Int32 i = 0;
+ for (std::vector< rtl::OUString >::iterator j(
+ data_->implementations[path_[1]].services.begin());
+ j != data_->implementations[path_[1]].services.end(); ++j)
+ {
+ seq[i++] = *j;
+ }
+ return seq;
+ }
+ case STATE_IMPLEMENTATION_SINGLETONS:
+ {
+ if (data_->implementations[path_[1]].singletons.size() >
+ SAL_MAX_INT32)
+ {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual"
+ " services key openKeys: too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > seq(
+ static_cast< sal_Int32 >(
+ data_->implementations[path_[1]].singletons.size()));
+ sal_Int32 i = 0;
+ for (std::vector< rtl::OUString >::iterator j(
+ data_->implementations[path_[1]].singletons.begin());
+ j != data_->implementations[path_[1]].singletons.end(); ++j)
+ {
+ seq[i++] = *j;
+ }
+ return seq;
+ }
+ case STATE_SERVICES:
+ {
+ if (data_->services.size() > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual"
+ " services key openKeys: too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > seq(
+ static_cast< sal_Int32 >(data_->services.size()));
+ sal_Int32 i = 0;
+ for (ImplementationMap::iterator j(data_->services.begin());
+ j != data_->services.end(); ++j)
+ {
+ seq[i++] = j->first;
+ }
+ return seq;
+ }
+ case STATE_SINGLETONS:
+ {
+ if (data_->singletons.size() > SAL_MAX_INT32) {
+ throw css::registry::InvalidValueException(
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.registry.SimpleRegistry textual"
+ " services key openKeys: too large")),
+ static_cast< OWeakObject * >(this));
+ }
+ css::uno::Sequence< rtl::OUString > seq(
+ static_cast< sal_Int32 >(data_->singletons.size()));
+ sal_Int32 i = 0;
+ for (ImplementationMap::iterator j(data_->singletons.begin());
+ j != data_->singletons.end(); ++j)
+ {
+ seq[i++] = j->first;
+ }
+ return seq;
+ }
+ case STATE_SINGLETON:
+ {
+ css::uno::Sequence< rtl::OUString > seq(1);
+ seq[0] = rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM("REGISTERED_BY"));
+ return seq;
+ }
+ }
+}
+
+}
+
+TextualServices::TextualServices(rtl::OUString const & uri):
+ uri_(uri), data_(new Data)
+{
+ try {
+ Parser(uri, data_);
+ } catch (css::container::NoSuchElementException &) {
+ throw css::registry::InvalidRegistryException(
+ (uri +
+ rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(": no such file"))),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+TextualServices::~TextualServices() {}
+
+css::uno::Reference< css::registry::XRegistryKey > TextualServices::getRootKey()
+{
+ return new Key(data_, std::vector< rtl::OUString >());
+}
+
+} }
diff --git a/stoc/source/simpleregistry/textualservices.hxx b/stoc/source/simpleregistry/textualservices.hxx
new file mode 100644
index 000000000000..0261e260444e
--- /dev/null
+++ b/stoc/source/simpleregistry/textualservices.hxx
@@ -0,0 +1,67 @@
+/*************************************************************************
+*
+* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+*
+* Copyright 2000, 2010 Oracle and/or its affiliates.
+*
+* OpenOffice.org - a multi-platform office productivity suite
+*
+* This file is part of OpenOffice.org.
+*
+* OpenOffice.org is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License version 3
+* only, as published by the Free Software Foundation.
+*
+* OpenOffice.org is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Lesser General Public License version 3 for more details
+* (a copy is included in the LICENSE file that accompanied this code).
+*
+* You should have received a copy of the GNU Lesser General Public License
+* version 3 along with OpenOffice.org. If not, see
+* <http://www.openoffice.org/license.html>
+* for a copy of the LGPLv3 License.
+*
+************************************************************************/
+
+#ifndef INCLUDED_STOC_SOURCE_SIMPLEREGISTRY_TEXTUALSERVICES_HXX
+#define INCLUDED_STOC_SOURCE_SIMPLEREGISTRY_TEXTUALSERVICES_HXX
+
+#include "sal/config.h"
+
+#include <memory>
+
+#include "boost/noncopyable.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "rtl/ref.hxx"
+#include "rtl/ustring.hxx"
+
+namespace com { namespace sun { namespace star { namespace registry {
+ class XRegistryKey;
+} } } }
+
+namespace stoc { namespace simpleregistry {
+
+class Data;
+
+class TextualServices: private boost::noncopyable {
+public:
+ explicit TextualServices(rtl::OUString const & uri);
+ // throws com::sun::star::registry::InvalidRegistryException
+
+ virtual ~TextualServices();
+
+ inline rtl::OUString getUri() { return uri_; }
+
+ com::sun::star::uno::Reference< com::sun::star::registry::XRegistryKey >
+ getRootKey();
+
+private:
+ rtl::OUString uri_;
+ rtl::Reference< Data > data_;
+};
+
+} }
+
+#endif
diff --git a/stoc/source/stocservices/makefile.mk b/stoc/source/stocservices/makefile.mk
new file mode 100644
index 000000000000..2d2444f8a996
--- /dev/null
+++ b/stoc/source/stocservices/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = stocservices
+ENABLE_EXCEPTIONS=TRUE
+COMP1TYPELIST = stocserv
+
+# --- openoffice.org.orig/Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+# --- openoffice.org.orig/Files ------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/stocservices.obj
+
+# --- openoffice.org.orig/Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
diff --git a/stoc/source/stocservices/stocserv.xml b/stoc/source/stocservices/stocserv.xml
new file mode 100644
index 000000000000..73de7da1bd54
--- /dev/null
+++ b/stoc/source/stocservices/stocserv.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE module-description PUBLIC "-//StarOffice//DTD ComponentDescription 1.0//EN" "module-description.dtd">
+<module-description xmlns:xlink="http://www.w3.org/1999/xlink">
+ <module-name> stocservices.uno </module-name>
+ <component-description>
+ <author> Daniel Boelzle </author>
+ <name> com.sun.star.comp.stoc.TypeConverter </name>
+ <description>
+This service provide a widening converter. This means it can convert
+from one type to another if possible.
+</description>
+ <loader-name> com.sun.star.loader.SharedLibrary </loader-name>
+ <language> C++ </language>
+ <status value="final"/>
+ <supported-service> com.sun.star.script.Converter </supported-service>
+ <type> com.sun.star.reflection.FieldAccessMode </type>
+ <type> com.sun.star.lang.IllegalArgumentException </type>
+ <type> com.sun.star.lang.XEventListener </type>
+ <type> com.sun.star.lang.XTypeProvider </type>
+ <type> com.sun.star.lang.XServiceInfo </type>
+ <type> com.sun.star.lang.XSingleServiceFactory </type>
+ <type> com.sun.star.lang.XSingleComponentFactory </type>
+ <type> com.sun.star.lang.XMultiServiceFactory </type>
+ <type> com.sun.star.registry.XRegistryKey </type>
+ <type> com.sun.star.script.XTypeConverter </type>
+ <type> com.sun.star.script.FailReason </type>
+ <type> com.sun.star.container.XSet </type>
+ <type> com.sun.star.container.XNameContainer </type>
+ <type> com.sun.star.container.XIndexContainer </type>
+ <type> com.sun.star.uno.XAggregation </type>
+ <type> com.sun.star.uno.XWeak </type>
+ <type> com.sun.star.uno.TypeClass </type>
+ <type> com.sun.star.uno.XComponentContext </type>
+ </component-description>
+ <component-description>
+ <author>Stephan Bergmann</author>
+ <name>com.sun.star.comp.uri.ExternalUriReferenceTranslator</name>
+ <description>
+ Instances of this service translate between external and internal
+ URI references.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="under_construction"/>
+ <supported-service>
+ com.sun.star.uri.ExternalUriReferenceTranslator
+ </supported-service>
+ </component-description>
+ <component-description>
+ <author>Stephan Bergmann</author>
+ <name>com.sun.star.comp.uri.UriReferenceFactory</name>
+ <description>
+ Instances of this service create URI references.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="under_construction"/>
+ <supported-service>
+ com.sun.star.uri.UriReferenceFactory
+ </supported-service>
+ </component-description>
+ <component-description>
+ <author>Stephan Bergmann</author>
+ <name>
+ com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript
+ </name>
+ <description>
+ Instances of this service parse textual representations of absolute
+ &#x201C;vnd.sun.star.script&#x201D; URLs.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="under_construction"/>
+ <supported-service>
+ com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript
+ </supported-service>
+ </component-description>
+ <component-description>
+ <author>Stephan Bergmann</author>
+ <name>com.sun.star.comp.uri.VndSunStarPkgUrlReferenceFactory</name>
+ <description>
+ Instances of this service create &#x201C;vnd.sun.star.pkg&#x201D;
+ URL references.
+ </description>
+ <loader-name>com.sun.star.loader.SharedLibrary</loader-name>
+ <language>C++</language>
+ <status value="under_construction"/>
+ <supported-service>
+ com.sun.star.uri.VndSunStarPkgUrlReferenceFactory
+ </supported-service>
+ </component-description>
+ <project-build-dependency> cppuhelper </project-build-dependency>
+ <project-build-dependency> cppu </project-build-dependency>
+ <project-build-dependency> sal </project-build-dependency>
+ <runtime-module-dependency> cppuhelper2(COM) </runtime-module-dependency>
+ <runtime-module-dependency> cppu2 </runtime-module-dependency>
+ <runtime-module-dependency> sal2 </runtime-module-dependency>
+</module-description>
diff --git a/stoc/source/stocservices/stocservices.cxx b/stoc/source/stocservices/stocservices.cxx
new file mode 100644
index 000000000000..6270d508eb37
--- /dev/null
+++ b/stoc/source/stocservices/stocservices.cxx
@@ -0,0 +1,111 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "stocservices.hxx"
+
+#include "cppuhelper/factory.hxx"
+#include "cppuhelper/implementationentry.hxx"
+#include "sal/types.h"
+#include "uno/environment.h"
+#include "uno/lbnames.h"
+
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace cppu;
+using namespace osl;
+using namespace rtl;
+using namespace stoc_services;
+
+rtl_StandardModuleCount g_moduleCount = MODULE_COUNT_INIT;
+
+static struct ImplementationEntry g_entries[] =
+{
+ // typeconv
+ {
+ TypeConverter_Impl_CreateInstance, tcv_getImplementationName,
+ tcv_getSupportedServiceNames, createSingleComponentFactory,
+ &g_moduleCount.modCnt , 0
+ },
+ // uriproc
+ {
+ ExternalUriReferenceTranslator::create,
+ ExternalUriReferenceTranslator::getImplementationName,
+ ExternalUriReferenceTranslator::getSupportedServiceNames,
+ createSingleComponentFactory, 0, 0
+ },
+ {
+ UriReferenceFactory::create,
+ UriReferenceFactory::getImplementationName,
+ UriReferenceFactory::getSupportedServiceNames,
+ createSingleComponentFactory, 0, 0
+ },
+ {
+ UriSchemeParser_vndDOTsunDOTstarDOTexpand::create,
+ UriSchemeParser_vndDOTsunDOTstarDOTexpand::getImplementationName,
+ UriSchemeParser_vndDOTsunDOTstarDOTexpand::getSupportedServiceNames,
+ createSingleComponentFactory, 0, 0
+ },
+ {
+ UriSchemeParser_vndDOTsunDOTstarDOTscript::create,
+ UriSchemeParser_vndDOTsunDOTstarDOTscript::getImplementationName,
+ UriSchemeParser_vndDOTsunDOTstarDOTscript::getSupportedServiceNames,
+ createSingleComponentFactory, 0, 0
+ },
+ {
+ VndSunStarPkgUrlReferenceFactory::create,
+ VndSunStarPkgUrlReferenceFactory::getImplementationName,
+ VndSunStarPkgUrlReferenceFactory::getSupportedServiceNames,
+ createSingleComponentFactory, 0, 0
+ },
+ { 0, 0, 0, 0, 0, 0 }
+};
+
+extern "C"
+{
+
+sal_Bool SAL_CALL component_canUnload( TimeValue *pTime )
+{
+ return g_moduleCount.canUnload( &g_moduleCount , pTime );
+}
+
+//==================================================================================================
+void SAL_CALL component_getImplementationEnvironment(
+ const sal_Char ** ppEnvTypeName, uno_Environment ** )
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+//==================================================================================================
+void * SAL_CALL component_getFactory(
+ const sal_Char * pImplName, void * pServiceManager, void * pRegistryKey )
+{
+ return component_getFactoryHelper( pImplName, pServiceManager, pRegistryKey , g_entries );
+}
+
+}
diff --git a/stoc/source/tdmanager/lrucache.hxx b/stoc/source/tdmanager/lrucache.hxx
new file mode 100644
index 000000000000..fadc0a59b7bf
--- /dev/null
+++ b/stoc/source/tdmanager/lrucache.hxx
@@ -0,0 +1,247 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+#ifndef _LRU_CACHE_HXX_
+#define _LRU_CACHE_HXX_
+
+// __CACHE_DIAGNOSE forces cache size to 4 and works only for OUString keys
+// #define __CACHE_DIAGNOSE 1
+
+#include <osl/mutex.hxx>
+#include "rtl/ustring.hxx"
+
+#include <hash_map>
+
+
+/** Implementation of a least recently used (lru) cache.
+ <br>
+ @author Daniel Boelzle
+*/
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+class LRU_Cache
+{
+ struct CacheEntry
+ {
+ t_Key aKey;
+ t_Val aVal;
+ CacheEntry * pPred;
+ CacheEntry * pSucc;
+ };
+ typedef ::std::hash_map< t_Key, CacheEntry *, t_KeyHash, t_KeyEqual > t_Key2Element;
+
+ mutable ::osl::Mutex _aCacheMutex;
+ sal_Int32 _nCachedElements;
+ t_Key2Element _aKey2Element;
+
+ CacheEntry * _pBlock;
+ mutable CacheEntry * _pHead;
+ mutable CacheEntry * _pTail;
+ inline void toFront( CacheEntry * pEntry ) const;
+
+public:
+ /** Constructor:
+ <br>
+ @param nCachedElements number of elements to be cached; default param set to 128
+ */
+ inline LRU_Cache( sal_Int32 nCachedElements = 128 );
+ /** Destructor: releases all cached elements and keys.
+ <br>
+ */
+ inline ~LRU_Cache();
+
+ /** Retrieves a value from the cache. Returns default constructed value,
+ if none was found.
+ <br>
+ @param rKey a key
+ @return value
+ */
+ inline t_Val getValue( t_Key const & rKey ) const;
+ /** Sets a value to be cached for given key.
+ <br>
+ @param rKey a key
+ @param rValue a value
+ */
+ inline void setValue( t_Key const & rKey, t_Val const & rValue );
+ /** Tests whether a value is cached for given key.
+ <br>
+ @param rKey a key
+ @return true, if value is cached
+ */
+ inline sal_Bool hasValue( t_Key const & rKey ) const;
+ /** Clears the cache, thus releasing all cached elements and keys.
+ <br>
+ */
+ inline void clear();
+};
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::LRU_Cache( sal_Int32 nCachedElements )
+#ifdef __CACHE_DIAGNOSE
+ : _nCachedElements( 4 )
+#else
+ : _nCachedElements( nCachedElements )
+#endif
+ , _pBlock( 0 )
+{
+ if (_nCachedElements > 0)
+ {
+ _pBlock = new CacheEntry[_nCachedElements];
+ _pHead = _pBlock;
+ _pTail = _pBlock + _nCachedElements -1;
+ for ( sal_Int32 nPos = _nCachedElements; nPos--; )
+ {
+ _pBlock[nPos].pPred = _pBlock + nPos -1;
+ _pBlock[nPos].pSucc = _pBlock + nPos +1;
+ }
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::~LRU_Cache()
+{
+ delete [] _pBlock;
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::toFront(
+ CacheEntry * pEntry ) const
+{
+ if (pEntry != _pHead)
+ {
+ // cut out element
+ if (pEntry == _pTail)
+ {
+ _pTail = pEntry->pPred;
+ }
+ else
+ {
+ pEntry->pSucc->pPred = pEntry->pPred;
+ pEntry->pPred->pSucc = pEntry->pSucc;
+ }
+ // push to front
+ _pHead->pPred = pEntry;
+ pEntry->pSucc = _pHead;
+ _pHead = pEntry;
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline sal_Bool LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::hasValue(
+ t_Key const & rKey ) const
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ typename t_Key2Element::const_iterator const iFind( _aKey2Element.find( rKey ) );
+ return (iFind != _aKey2Element.end());
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline t_Val LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::getValue(
+ t_Key const & rKey ) const
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ const typename t_Key2Element::const_iterator iFind( _aKey2Element.find( rKey ) );
+ if (iFind != _aKey2Element.end())
+ {
+ CacheEntry * pEntry = (*iFind).second;
+ toFront( pEntry );
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> retrieved element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" from cache <\n" );
+#endif
+ return pEntry->aVal;
+ }
+ return t_Val();
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::setValue(
+ t_Key const & rKey, t_Val const & rValue )
+{
+ if (_nCachedElements > 0)
+ {
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ typename t_Key2Element::const_iterator const iFind( _aKey2Element.find( rKey ) );
+
+ CacheEntry * pEntry;
+ if (iFind == _aKey2Element.end())
+ {
+ pEntry = _pTail; // erase last element
+#ifdef __CACHE_DIAGNOSE
+ if (pEntry->aKey.getLength())
+ {
+ OSL_TRACE( "> kicking element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" from cache <\n" );
+ }
+#endif
+ _aKey2Element.erase( pEntry->aKey );
+ _aKey2Element[ pEntry->aKey = rKey ] = pEntry;
+ }
+ else
+ {
+ pEntry = (*iFind).second;
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> replacing element \"" );
+ OSL_TRACE( ::rtl::OUStringToOString( pEntry->aKey, RTL_TEXTENCODING_ASCII_US ).getStr() );
+ OSL_TRACE( "\" in cache <\n" );
+#endif
+ }
+ pEntry->aVal = rValue;
+ toFront( pEntry );
+ }
+}
+//__________________________________________________________________________________________________
+template< class t_Key, class t_Val, class t_KeyHash, class t_KeyEqual >
+inline void LRU_Cache< t_Key, t_Val, t_KeyHash, t_KeyEqual >::clear()
+{
+ ::osl::MutexGuard aGuard( _aCacheMutex );
+ _aKey2Element.clear();
+ for ( sal_Int32 nPos = _nCachedElements; nPos--; )
+ {
+ _pBlock[nPos].aKey = t_Key();
+ _pBlock[nPos].aVal = t_Val();
+ }
+#ifdef __CACHE_DIAGNOSE
+ OSL_TRACE( "> cleared cache <\n" );
+#endif
+}
+
+//==================================================================================================
+struct FctHashOUString : public ::std::unary_function< ::rtl::OUString const &, size_t >
+{
+ size_t operator()( ::rtl::OUString const & rKey ) const
+ { return (size_t)rKey.hashCode(); }
+};
+
+/** Template instance for OUString keys, Any values.<br>
+*/
+typedef LRU_Cache< ::rtl::OUString, ::com::sun::star::uno::Any,
+ FctHashOUString, ::std::equal_to< ::rtl::OUString > >
+ LRU_CacheAnyByOUString;
+
+
+#endif
diff --git a/stoc/source/tdmanager/makefile.mk b/stoc/source/tdmanager/makefile.mk
new file mode 100644
index 000000000000..dbc4e762afff
--- /dev/null
+++ b/stoc/source/tdmanager/makefile.mk
@@ -0,0 +1,49 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME= stoc
+TARGET = typemgr
+ENABLE_EXCEPTIONS=TRUE
+BOOTSTRAP_SERVICE=TRUE
+UNOUCROUT= $(OUT)$/inc$/bootstrap
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+
+# ------------------------------------------------------------------
+
+SLOFILES= \
+ $(SLO)$/tdmgr.obj \
+ $(SLO)$/tdmgr_check.obj \
+ $(SLO)$/tdmgr_tdenumeration.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/stoc/source/tdmanager/tdmgr.cxx b/stoc/source/tdmanager/tdmgr.cxx
new file mode 100644
index 000000000000..390881bb0d1d
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr.cxx
@@ -0,0 +1,1163 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include <osl/mutex.hxx>
+#include "rtl/ustrbuf.hxx"
+#include <cppuhelper/factory.hxx>
+#ifndef _CPPUHELPER_IMPLBASE5_HXX_
+#include <cppuhelper/compbase5.hxx>
+#endif
+#include <cppuhelper/implbase1.hxx>
+#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
+#include <cppuhelper/implementationentry.hxx>
+#endif
+#include "tdmgr_common.hxx"
+#include "tdmgr_tdenumeration.hxx"
+#include "lrucache.hxx"
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#include <com/sun/star/lang/XEventListener.hpp>
+#include <com/sun/star/lang/XTypeProvider.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XInitialization.hpp>
+#include <com/sun/star/container/XHierarchicalNameAccess.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/reflection/XTypeDescription.hpp>
+#include <com/sun/star/reflection/XArrayTypeDescription.hpp>
+#include <com/sun/star/reflection/XIndirectTypeDescription.hpp>
+#include <com/sun/star/reflection/XInterfaceTypeDescription.hpp>
+#include "com/sun/star/reflection/XStructTypeDescription.hpp"
+#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+#include "com/sun/star/uno/RuntimeException.hpp"
+
+#include <algorithm>
+#include <vector>
+
+using namespace std;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::reflection;
+using namespace com::sun::star::container;
+using namespace com::sun::star::registry;
+
+
+
+static const sal_Int32 CACHE_SIZE = 512;
+
+#define SERVICENAME "com.sun.star.reflection.TypeDescriptionManager"
+#define IMPLNAME "com.sun.star.comp.stoc.TypeDescriptionManager"
+
+//--------------------------------------------------------------------------------------------------
+// exported via tdmgr_common.hxx
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_bootstrap
+{
+Sequence< OUString > SAL_CALL tdmgr_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString SAL_CALL tdmgr_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+}
+
+namespace stoc_tdmgr
+{
+typedef vector< Reference< XHierarchicalNameAccess > > ProviderVector;
+
+class EnumerationImpl;
+class ManagerImpl;
+
+//==================================================================================================
+class EventListenerImpl : public ImplHelper1< XEventListener >
+{
+ ManagerImpl * _pMgr;
+
+public:
+ EventListenerImpl( ManagerImpl * pMgr )
+ : _pMgr( pMgr )
+ {
+ ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
+ }
+ virtual ~EventListenerImpl();
+
+ // lifetime delegated to manager
+ virtual void SAL_CALL acquire() throw();
+ virtual void SAL_CALL release() throw();
+
+ // XEventListener
+ virtual void SAL_CALL disposing( const EventObject & rEvt ) throw(::com::sun::star::uno::RuntimeException);
+};
+
+EventListenerImpl::~EventListenerImpl()
+{
+ ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
+}
+
+//==================================================================================================
+class ManagerImpl
+ : public WeakComponentImplHelper5< XServiceInfo,
+ XSet,
+ XHierarchicalNameAccess,
+ XTypeDescriptionEnumerationAccess,
+ XInitialization >
+{
+ friend class EnumerationImpl;
+ friend class EventListenerImpl;
+
+ Mutex _aComponentMutex;
+ Reference< XComponentContext > _xContext;
+ EventListenerImpl _aEventListener;
+
+ // elements
+ sal_Bool _bCaching;
+ LRU_CacheAnyByOUString _aElements;
+ // provider chain
+ ProviderVector _aProviders;
+
+ inline Any getSimpleType( const OUString & rName );
+
+ Reference< XTypeDescription > getInstantiatedStruct(OUString const & name);
+
+protected:
+ virtual void SAL_CALL disposing();
+
+public:
+ ManagerImpl( Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize );
+ virtual ~ManagerImpl();
+
+ // XInitialization
+ virtual void SAL_CALL initialize( const Sequence< Any > & args ) throw (Exception, RuntimeException);
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL supportsService( const OUString & rServiceName ) throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException);
+
+ // XElementAccess
+ virtual Type SAL_CALL getElementType() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException);
+
+ // XEnumerationAccess
+ virtual Reference< XEnumeration > SAL_CALL createEnumeration() throw(::com::sun::star::uno::RuntimeException);
+
+ // XSet
+ virtual sal_Bool SAL_CALL has( const Any & rElement ) throw(::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL insert( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
+ virtual void SAL_CALL remove( const Any & rElement ) throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+
+ // XHierarchicalNameAccess
+ virtual Any SAL_CALL getByHierarchicalName( const OUString & rName ) throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
+ virtual sal_Bool SAL_CALL hasByHierarchicalName( const OUString & rName ) throw(::com::sun::star::uno::RuntimeException);
+
+ // XTypeDescriptionEnumerationAccess
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescriptionEnumeration > SAL_CALL
+ createTypeDescriptionEnumeration(
+ const ::rtl::OUString& moduleName,
+ const ::com::sun::star::uno::Sequence<
+ ::com::sun::star::uno::TypeClass >& types,
+ ::com::sun::star::reflection::TypeDescriptionSearchDepth depth )
+ throw ( ::com::sun::star::reflection::NoSuchTypeNameException,
+ ::com::sun::star::reflection::InvalidTypeNameException,
+ ::com::sun::star::uno::RuntimeException );
+};
+
+//==================================================================================================
+class EnumerationImpl
+ : public WeakImplHelper1< XEnumeration >
+{
+ ManagerImpl * _pMgr;
+ size_t _nPos;
+
+public:
+ EnumerationImpl( ManagerImpl * pManager );
+ virtual ~EnumerationImpl();
+
+ // XEnumeration
+ virtual sal_Bool SAL_CALL hasMoreElements() throw(::com::sun::star::uno::RuntimeException);
+ virtual Any SAL_CALL nextElement() throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
+};
+
+//##################################################################################################
+
+// lifetime delegated to manager
+//__________________________________________________________________________________________________
+void EventListenerImpl::acquire() throw()
+{
+ _pMgr->acquire();
+}
+//__________________________________________________________________________________________________
+void EventListenerImpl::release() throw()
+{
+ _pMgr->release();
+}
+
+// XEventListener
+//__________________________________________________________________________________________________
+void EventListenerImpl::disposing( const EventObject & rEvt )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ _pMgr->remove( makeAny( rEvt.Source ) );
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+EnumerationImpl::EnumerationImpl( ManagerImpl * pManager )
+ : _pMgr( pManager )
+ , _nPos( 0 )
+{
+ _pMgr->acquire();
+}
+//__________________________________________________________________________________________________
+EnumerationImpl::~EnumerationImpl()
+{
+ _pMgr->release();
+}
+
+// XEnumeration
+//__________________________________________________________________________________________________
+sal_Bool EnumerationImpl::hasMoreElements()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( _pMgr->_aComponentMutex );
+ return (_nPos < _pMgr->_aProviders.size());
+}
+//__________________________________________________________________________________________________
+Any EnumerationImpl::nextElement()
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( _pMgr->_aComponentMutex );
+ if (_nPos >= _pMgr->_aProviders.size())
+ {
+ throw NoSuchElementException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("there is no further element!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+ return makeAny( _pMgr->_aProviders[_nPos++] );
+}
+
+//##################################################################################################
+
+//__________________________________________________________________________________________________
+ManagerImpl::ManagerImpl(
+ Reference< XComponentContext > const & xContext, sal_Int32 nCacheSize )
+ : WeakComponentImplHelper5<
+ XServiceInfo, XSet, XHierarchicalNameAccess,
+ XTypeDescriptionEnumerationAccess, XInitialization >( _aComponentMutex )
+ , _xContext( xContext )
+ , _aEventListener( this )
+ , _bCaching( sal_True )
+ , _aElements( nCacheSize )
+{
+ ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+ManagerImpl::~ManagerImpl()
+{
+ OSL_ENSURE( _aProviders.size() == 0, "### still providers left!" );
+ OSL_TRACE( "> TypeDescriptionManager shut down. <\n" );
+ ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
+}
+//__________________________________________________________________________________________________
+void ManagerImpl::disposing()
+{
+ // called on disposing the tdmgr instance (supposedly from context)
+ _bCaching = sal_False;
+ _aElements.clear();
+ _xContext.clear();
+ _aProviders.clear();
+}
+
+// XInitialization
+//__________________________________________________________________________________________________
+void ManagerImpl::initialize(
+ const Sequence< Any > & args )
+ throw (Exception, RuntimeException)
+{
+ // additional providers
+ Any const * pProviders = args.getConstArray();
+ for ( sal_Int32 nPos = 0; nPos < args.getLength(); ++nPos )
+ {
+ Reference< XHierarchicalNameAccess > xHA( pProviders[ nPos ], UNO_QUERY );
+ OSL_ENSURE( xHA.is(), "### no td provider!" );
+
+ if (xHA.is())
+ {
+ try
+ {
+ insert( makeAny( xHA ) );
+ }
+ catch (IllegalArgumentException &)
+ {
+ }
+ catch (ElementExistException &)
+ {
+ }
+ }
+ }
+}
+
+// XServiceInfo
+//__________________________________________________________________________________________________
+OUString ManagerImpl::getImplementationName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::tdmgr_getImplementationName();
+}
+//__________________________________________________________________________________________________
+sal_Bool ManagerImpl::supportsService( const OUString & rServiceName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ const Sequence< OUString > & rSNL = getSupportedServiceNames();
+ const OUString * pArray = rSNL.getConstArray();
+ for ( sal_Int32 nPos = rSNL.getLength(); nPos--; )
+ {
+ if (pArray[nPos] == rServiceName)
+ return sal_True;
+ }
+ return sal_False;
+}
+//__________________________________________________________________________________________________
+Sequence< OUString > ManagerImpl::getSupportedServiceNames()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return stoc_bootstrap::tdmgr_getSupportedServiceNames();
+}
+
+// XElementAccess
+//__________________________________________________________________________________________________
+Type ManagerImpl::getElementType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return ::getCppuType( (const Reference< XHierarchicalNameAccess > *)0 );
+}
+//__________________________________________________________________________________________________
+sal_Bool ManagerImpl::hasElements()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ MutexGuard aGuard( _aComponentMutex );
+ return (_aProviders.size() > 0);
+}
+
+// XEnumerationAccess
+//__________________________________________________________________________________________________
+Reference< XEnumeration > ManagerImpl::createEnumeration()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return new EnumerationImpl( this );
+}
+
+// XSet
+//__________________________________________________________________________________________________
+sal_Bool SAL_CALL ManagerImpl::has( const Any & rElement )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ Reference< XHierarchicalNameAccess > xElem;
+ if (rElement >>= xElem)
+ {
+ MutexGuard aGuard( _aComponentMutex );
+ return (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end());
+ }
+ return sal_False;
+}
+
+//__________________________________________________________________________________________________
+void SAL_CALL ManagerImpl::insert( const Any & rElement )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException)
+{
+ Reference< XHierarchicalNameAccess > xElem;
+ if (! (rElement >>= xElem) || !xElem.is())
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no valid type description provider given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+
+ MutexGuard aGuard( _aComponentMutex );
+ if (find( _aProviders.begin(), _aProviders.end(), xElem ) != _aProviders.end())
+ {
+ throw ElementExistException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("provider already inserted!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+
+ if (! _aProviders.empty())
+ {
+ // check whether all types are compatible, if possible:
+ Reference<reflection::XTypeDescriptionEnumerationAccess> xTDEnumAccess(
+ xElem, UNO_QUERY );
+ OSL_ENSURE( xTDEnumAccess.is(),
+ "### providers ought to implement "
+ "reflection::XTypeDescriptionEnumerationAccess!" );
+ if (xTDEnumAccess.is())
+ {
+ try
+ {
+ TypeClass ar [] = {
+ TypeClass_ENUM, TypeClass_TYPEDEF, TypeClass_SEQUENCE,
+ TypeClass_STRUCT, TypeClass_EXCEPTION,
+ /* TypeClass_UNION, TypeClass_ARRAY not supported */
+ TypeClass_INTERFACE,
+ TypeClass_SERVICE,
+ TypeClass_INTERFACE_METHOD, TypeClass_INTERFACE_ATTRIBUTE,
+ TypeClass_PROPERTY, TypeClass_CONSTANT, TypeClass_CONSTANTS,
+ TypeClass_SINGLETON
+ };
+ Reference<reflection::XTypeDescriptionEnumeration> xTDEnum(
+ xTDEnumAccess->createTypeDescriptionEnumeration(
+ OUString() /* all modules */,
+ Sequence<TypeClass>( ar, ARLEN(ar) ),
+ reflection::TypeDescriptionSearchDepth_INFINITE ) );
+
+ while (xTDEnum->hasMoreElements())
+ {
+ Reference<reflection::XTypeDescription> xNewTD;
+ try
+ {
+ xNewTD = xTDEnum->nextTypeDescription();
+ }
+ catch (container::NoSuchElementException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("NoSuchElementException occured: ") +
+ exc.Message, static_cast<OWeakObject *>(this),
+ -1 /* unknown */ );
+ }
+
+ try
+ {
+ OUString newName( xNewTD->getName() );
+ Reference<reflection::XTypeDescription> xExistingTD(
+ getByHierarchicalName( newName ), UNO_QUERY );
+ OSL_ASSERT( xExistingTD.is() );
+ // existing, check whether compatible:
+ if (xExistingTD.is())
+ {
+ try
+ {
+ check( xNewTD, xExistingTD );
+ }
+ catch (IncompatibleTypeException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("Rejecting types due to "
+ "incompatibility! ") + exc.m_cause,
+ static_cast<OWeakObject *>(this), 0 );
+ }
+ }
+ }
+ catch (container::NoSuchElementException &)
+ {
+ // type not in: ok
+ }
+ }
+ }
+ catch (reflection::NoSuchTypeNameException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("NoSuchTypeNameException occured: ") + exc.Message,
+ static_cast<OWeakObject *>(this), -1 /* unknown */ );
+ }
+ catch (reflection::InvalidTypeNameException & exc)
+ {
+ throw lang::IllegalArgumentException(
+ OUSTR("InvalidTypeNameException occured: ") + exc.Message,
+ static_cast<OWeakObject *>(this), -1 /* unknown */ );
+ }
+ }
+ }
+
+ _aProviders.push_back( xElem );
+ Reference< XComponent > xComp( xElem, UNO_QUERY );
+ if (xComp.is())
+ xComp->addEventListener( &_aEventListener );
+}
+//__________________________________________________________________________________________________
+void SAL_CALL ManagerImpl::remove( const Any & rElement )
+ throw(::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+{
+ if (!rBHelper.bDisposed && !rBHelper.bInDispose)
+ {
+ Reference< XHierarchicalNameAccess > xElem;
+ if (! (rElement >>= xElem))
+ {
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("no type description provider given!") ),
+ (XWeak *)(OWeakObject *)this, 0 );
+ }
+
+ MutexGuard aGuard( _aComponentMutex );
+ ProviderVector::iterator iFind( find( _aProviders.begin(), _aProviders.end(), xElem ) );
+ if (iFind == _aProviders.end())
+ {
+ throw NoSuchElementException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("provider not found!") ),
+ (XWeak *)(OWeakObject *)this );
+ }
+ _aProviders.erase( iFind );
+ }
+
+ Reference< XComponent > xComp;
+ if (rElement >>= xComp)
+ xComp->removeEventListener( &_aEventListener );
+}
+
+// XTypeDescriptionEnumerationAccess
+//__________________________________________________________________________________________________
+// virtual
+Reference< XTypeDescriptionEnumeration > SAL_CALL
+ManagerImpl::createTypeDescriptionEnumeration(
+ const OUString & moduleName,
+ const Sequence< TypeClass > & types,
+ TypeDescriptionSearchDepth depth )
+ throw ( NoSuchTypeNameException,
+ InvalidTypeNameException,
+ RuntimeException )
+{
+ MutexGuard aGuard( _aComponentMutex );
+
+ TDEnumerationAccessStack aStack;
+ ProviderVector::const_iterator it = _aProviders.begin();
+ const ProviderVector::const_iterator end = _aProviders.end();
+ while ( it != end )
+ {
+ Reference< XTypeDescriptionEnumerationAccess >xEnumAccess(
+ (*it), UNO_QUERY );
+ OSL_ENSURE( xEnumAccess.is(),
+ "### no XTypeDescriptionEnumerationAccess!" );
+ if ( xEnumAccess.is() )
+ aStack.push( xEnumAccess );
+
+ it++;
+ }
+
+ return Reference< XTypeDescriptionEnumeration >(
+ new TypeDescriptionEnumerationImpl( moduleName,
+ types,
+ depth,
+ aStack ) );
+}
+
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//==================================================================================================
+class SimpleTypeDescriptionImpl
+ : public WeakImplHelper1< XTypeDescription >
+{
+ TypeClass _eTC;
+ OUString _aName;
+
+public:
+ SimpleTypeDescriptionImpl( TypeClass eTC, const OUString & rName )
+ : _eTC( eTC )
+ , _aName( rName )
+ {}
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+};
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass SimpleTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _eTC;
+}
+//__________________________________________________________________________________________________
+OUString SimpleTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _aName;
+}
+
+//==================================================================================================
+class SequenceTypeDescriptionImpl
+ : public WeakImplHelper1< XIndirectTypeDescription >
+{
+ Reference< XTypeDescription > _xElementTD;
+
+public:
+ SequenceTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD )
+ : _xElementTD( xElementTD )
+ {}
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XIndirectTypeDescription
+ virtual Reference< XTypeDescription > SAL_CALL getReferencedType() throw(::com::sun::star::uno::RuntimeException);
+};
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass SequenceTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_SEQUENCE;
+}
+//__________________________________________________________________________________________________
+OUString SequenceTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (OUString( RTL_CONSTASCII_USTRINGPARAM("[]") ) + _xElementTD->getName());
+}
+
+// XIndirectTypeDescription
+//__________________________________________________________________________________________________
+Reference< XTypeDescription > SequenceTypeDescriptionImpl::getReferencedType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _xElementTD;
+}
+
+//==================================================================================================
+class ArrayTypeDescriptionImpl
+ : public WeakImplHelper1< XArrayTypeDescription >
+{
+ Reference< XTypeDescription > _xElementTD;
+ Mutex _aDimensionMutex;
+ sal_Int32 _nDimensions;
+ Sequence< sal_Int32 > _seqDimensions;
+ OUString _sDimensions;
+
+ void initDimensions(const OUString& rSDimensions);
+public:
+ ArrayTypeDescriptionImpl( const Reference< XTypeDescription > & xElementTD,
+ sal_Int32 nDimensions, const OUString& rSDimensions )
+ : _xElementTD( xElementTD )
+ , _nDimensions( nDimensions )
+ , _seqDimensions( Sequence< sal_Int32 >(nDimensions) )
+ , _sDimensions( rSDimensions )
+ {
+ initDimensions( rSDimensions );
+ }
+ virtual ~ArrayTypeDescriptionImpl() {}
+
+ // XTypeDescription
+ virtual TypeClass SAL_CALL getTypeClass() throw(::com::sun::star::uno::RuntimeException);
+ virtual OUString SAL_CALL getName() throw(::com::sun::star::uno::RuntimeException);
+
+ // XArrayTypeDescription
+ virtual Reference< XTypeDescription > SAL_CALL getType() throw(::com::sun::star::uno::RuntimeException);
+ virtual sal_Int32 SAL_CALL getNumberOfDimensions() throw(::com::sun::star::uno::RuntimeException);
+ virtual Sequence< sal_Int32 > SAL_CALL getDimensions() throw(::com::sun::star::uno::RuntimeException);
+};
+//__________________________________________________________________________________________________
+static sal_Int32 unicodeToInteger( sal_Int8 base, const sal_Unicode *s )
+{
+ sal_Int32 r = 0;
+ sal_Int32 negative = 0;
+
+ if (*s == '-')
+ {
+ negative = 1;
+ s++;
+ }
+ if (base == 8 && *s == '0')
+ s++;
+ else if (base == 16 && *s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
+ s += 2;
+
+ for (; *s; s++)
+ {
+ if (*s <= '9' && *s >= '0')
+ r = (r * base) + (*s - '0');
+ else if (base > 10 && *s <= 'f' && *s >= 'a')
+ r = (r * base) + (*s - 'a' + 10);
+ else if (base > 10 && *s <= 'F' && *s >= 'A')
+ r = (r * base) + (*s - 'A' + 10);
+ else
+ break;
+ }
+ if (negative) r *= -1;
+ return r;
+}
+//__________________________________________________________________________________________________
+void ArrayTypeDescriptionImpl::initDimensions(const OUString& rSDimensions)
+{
+ MutexGuard aGuard( _aDimensionMutex );
+
+ sal_Int32 * pDimensions = _seqDimensions.getArray();
+ OUString tmp(rSDimensions);
+ sal_Unicode* p = (sal_Unicode*)tmp.getStr()+1;
+ sal_Unicode* pOffset = p;
+ sal_Int32 len = tmp.getLength() - 1 ;
+ sal_Int32 i = 0;
+
+ while ( len > 0)
+ {
+ pOffset++;
+ if (*pOffset == ']')
+ {
+ *pOffset = '\0';
+ pOffset += 2;
+ len -= 3;
+ pDimensions[i++] = unicodeToInteger(10, p);
+ p = pOffset;
+ } else
+ len--;
+ }
+}
+
+// XTypeDescription
+//__________________________________________________________________________________________________
+TypeClass ArrayTypeDescriptionImpl::getTypeClass()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return TypeClass_ARRAY;
+}
+//__________________________________________________________________________________________________
+OUString ArrayTypeDescriptionImpl::getName()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return (_xElementTD->getName() + _sDimensions);
+}
+
+// XArrayTypeDescription
+//__________________________________________________________________________________________________
+Reference< XTypeDescription > ArrayTypeDescriptionImpl::getType()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _xElementTD;
+}
+
+//__________________________________________________________________________________________________
+sal_Int32 ArrayTypeDescriptionImpl::getNumberOfDimensions()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _nDimensions;
+}
+
+//__________________________________________________________________________________________________
+Sequence< sal_Int32 > ArrayTypeDescriptionImpl::getDimensions()
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ return _seqDimensions;
+}
+
+//##################################################################################################
+//##################################################################################################
+//##################################################################################################
+
+
+//__________________________________________________________________________________________________
+inline Any ManagerImpl::getSimpleType( const OUString & rName )
+{
+ Any aRet;
+
+ if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("string") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_STRING, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("long") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_LONG, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned long") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_LONG, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("boolean") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BOOLEAN, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("char") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_CHAR, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("byte") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_BYTE, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("short") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_SHORT, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned short") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_SHORT, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("hyper") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_HYPER, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("unsigned hyper") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_UNSIGNED_HYPER, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("float") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_FLOAT, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("double") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_DOUBLE, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("any") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_ANY, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("void") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_VOID, rName ) );
+ else if (rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("type") ))
+ aRet <<= Reference< XTypeDescription >( new SimpleTypeDescriptionImpl( TypeClass_TYPE, rName ) );
+
+ return aRet;
+}
+
+namespace {
+
+Reference< XTypeDescription > resolveTypedefs(
+ Reference< XTypeDescription > const & type)
+{
+ Reference< XTypeDescription > resolved(type);
+ while (resolved->getTypeClass() == TypeClass_TYPEDEF) {
+ resolved = Reference< XIndirectTypeDescription >(
+ type, UNO_QUERY_THROW)->getReferencedType();
+ }
+ return resolved;
+}
+
+bool isNonVoidNonExceptionType(Reference< XTypeDescription > const & type) {
+ switch (type->getTypeClass()) {
+ case TypeClass_BOOLEAN:
+ case TypeClass_BYTE:
+ case TypeClass_SHORT:
+ case TypeClass_UNSIGNED_SHORT:
+ case TypeClass_LONG:
+ case TypeClass_UNSIGNED_LONG:
+ case TypeClass_HYPER:
+ case TypeClass_UNSIGNED_HYPER:
+ case TypeClass_FLOAT:
+ case TypeClass_DOUBLE:
+ case TypeClass_CHAR:
+ case TypeClass_STRING:
+ case TypeClass_TYPE:
+ case TypeClass_ANY:
+ case TypeClass_SEQUENCE:
+ case TypeClass_ENUM:
+ case TypeClass_STRUCT:
+ case TypeClass_INTERFACE:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+class InstantiatedStruct: public WeakImplHelper1< XStructTypeDescription > {
+public:
+ InstantiatedStruct(
+ Reference< XStructTypeDescription > const & structType,
+ std::vector< Reference< XTypeDescription > > const & arguments);
+
+ virtual TypeClass SAL_CALL getTypeClass() throw (RuntimeException)
+ { return TypeClass_STRUCT; }
+
+ virtual OUString SAL_CALL getName() throw (RuntimeException);
+
+ virtual Reference< XTypeDescription > SAL_CALL getBaseType()
+ throw (RuntimeException)
+ { return m_struct->getBaseType(); }
+
+ virtual Sequence< Reference< XTypeDescription > > SAL_CALL getMemberTypes()
+ throw (RuntimeException);
+
+ virtual Sequence< OUString > SAL_CALL getMemberNames()
+ throw (RuntimeException)
+ { return m_struct->getMemberNames(); }
+
+ virtual Sequence< OUString > SAL_CALL getTypeParameters()
+ throw (RuntimeException)
+ { return Sequence< OUString >(); }
+
+ virtual Sequence< Reference< XTypeDescription > > SAL_CALL
+ getTypeArguments() throw (RuntimeException)
+ { return m_arguments; }
+
+private:
+ Reference< XStructTypeDescription > m_struct;
+ Sequence< Reference< XTypeDescription > > m_arguments;
+};
+
+InstantiatedStruct::InstantiatedStruct(
+ Reference< XStructTypeDescription > const & structType,
+ std::vector< Reference< XTypeDescription > > const & arguments):
+ m_struct(structType),
+ m_arguments(static_cast< sal_Int32 >(arguments.size()))
+{
+ for (std::vector< Reference< XTypeDescription > >::size_type i = 0;
+ i < arguments.size(); ++i)
+ {
+ m_arguments[static_cast< sal_Int32 >(i)] = arguments[i];
+ }
+}
+
+OUString InstantiatedStruct::getName() throw (RuntimeException) {
+ OUStringBuffer buf(m_struct->getName());
+ buf.append(static_cast< sal_Unicode >('<'));
+ for (sal_Int32 i = 0; i < m_arguments.getLength(); ++i) {
+ if (i != 0) {
+ buf.append(static_cast< sal_Unicode >(','));
+ }
+ buf.append(m_arguments[i]->getName());
+ }
+ buf.append(static_cast< sal_Unicode >('>'));
+ return buf.makeStringAndClear();
+}
+
+Sequence< Reference< XTypeDescription > > InstantiatedStruct::getMemberTypes()
+ throw (RuntimeException)
+{
+ Sequence< Reference< XTypeDescription > > types(m_struct->getMemberTypes());
+ for (sal_Int32 i = 0; i < types.getLength(); ++i) {
+ if (types[i]->getTypeClass() == TypeClass_UNKNOWN) {
+ Sequence< OUString > parameters(m_struct->getTypeParameters());
+ OSL_ASSERT(parameters.getLength() == m_arguments.getLength());
+ for (sal_Int32 j = 0; j < parameters.getLength(); ++j) {
+ if (parameters[j] == types[i]->getName()) {
+ types[i] = m_arguments[j];
+ break;
+ }
+ }
+ }
+ }
+ return types;
+}
+
+}
+
+Reference< XTypeDescription > ManagerImpl::getInstantiatedStruct(
+ OUString const & name)
+{
+ sal_Int32 i = name.indexOf('<');
+ OSL_ASSERT(i >= 0);
+ Reference< XStructTypeDescription > structType(
+ getByHierarchicalName(name.copy(0, i)), UNO_QUERY);
+ std::vector< Reference< XTypeDescription > > args;
+ bool good = structType.is();
+ if (good) {
+ do {
+ ++i; // skip '<' or ','
+ sal_Int32 j = i;
+ for (sal_Int32 level = 0; j != name.getLength(); ++j) {
+ sal_Unicode c = name[j];
+ if (c == ',') {
+ if (level == 0) {
+ break;
+ }
+ } else if (c == '<') {
+ ++level;
+ } else if (c == '>') {
+ if (level == 0) {
+ break;
+ }
+ --level;
+ }
+ }
+ if (j != name.getLength()) {
+ Reference< XTypeDescription > type(
+ getByHierarchicalName(name.copy(i, j - i)), UNO_QUERY);
+ if (isNonVoidNonExceptionType(resolveTypedefs(type))) {
+ args.push_back(type);
+ } else {
+ good = false;
+ break;
+ }
+ }
+ i = j;
+ } while (i != name.getLength() && name[i] != '>');
+ good = good && i == name.getLength() - 1
+ && name[i] == '>' && !args.empty();
+ }
+ // args.size() cannot exceed SAL_MAX_INT32, as each argument consumes at
+ // least one position within an rtl::OUString (which is no longer than
+ // SAL_MAX_INT32):
+ if (!good
+ || (args.size()
+ != sal::static_int_cast< sal_uInt32 >(
+ structType->getTypeParameters().getLength())))
+ {
+ throw NoSuchElementException(name, static_cast< OWeakObject * >(this));
+ }
+ return new InstantiatedStruct(structType, args);
+}
+
+// XHierarchicalNameAccess
+//__________________________________________________________________________________________________
+Any ManagerImpl::getByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException)
+{
+ Any aRet;
+ if (_bCaching)
+ aRet = _aElements.getValue( rName );
+ if (rName.getLength() && !aRet.hasValue())
+ {
+ sal_Int32 nIndex;
+ if (rName[0] == '[') // test for sequence
+ {
+ Reference< XTypeDescription > xElemType(
+ getByHierarchicalName( rName.copy( 2 ) ),
+ UNO_QUERY_THROW );
+ aRet <<= Reference< XTypeDescription >(
+ new SequenceTypeDescriptionImpl( xElemType ) );
+ }
+ else if (rName[rName.getLength()-1] == ']') // test for array
+ {
+ sal_Int32 nIndex2 = 0, nTokens = 0;
+ do { rName.getToken( 0, '[', nIndex2 ); nTokens++; } while( nIndex2 != -1 );
+ sal_Int32 nDims = nTokens - 1;
+ sal_Int32 dimOffset = rName.indexOf('[');
+ Reference< XTypeDescription > xElemType(
+ getByHierarchicalName( rName.copy( 0, dimOffset ) ),
+ UNO_QUERY_THROW );
+ aRet <<= Reference< XTypeDescription >(
+ new ArrayTypeDescriptionImpl(
+ xElemType, nDims, rName.copy(dimOffset) ) );
+ }
+ // test for interface member names:
+ else if ((nIndex = rName.indexOf( ':' )) >= 0)
+ {
+ Reference< XInterfaceTypeDescription > xIfaceTD(
+ getByHierarchicalName( rName.copy( 0, nIndex ) ),
+ UNO_QUERY_THROW );
+ const Sequence< Reference< XInterfaceMemberTypeDescription > > &
+ rMembers = xIfaceTD->getMembers();
+ const Reference< XInterfaceMemberTypeDescription > * pMembers =
+ rMembers.getConstArray();
+
+ for ( sal_Int32 nPos = rMembers.getLength(); nPos--; )
+ {
+ if (rName == pMembers[nPos]->getName())
+ {
+ aRet <<= Reference< XTypeDescription >(
+ pMembers[nPos], UNO_QUERY_THROW );
+ break;
+ }
+ }
+ if (! aRet.hasValue())
+ {
+ // member not found:
+ throw NoSuchElementException(
+ rName, static_cast< OWeakObject * >(this) );
+ }
+ }
+ // test for instantiated polymorphic struct types:
+ else if (rName.indexOf('<') >= 0)
+ {
+ aRet <<= getInstantiatedStruct(rName);
+ }
+ else if (rName.indexOf( '.' ) < 0) // test for simple/ build in types
+ {
+ aRet = getSimpleType( rName );
+ }
+
+ if (! aRet.hasValue())
+ {
+ // last, try callback chain
+ for ( ProviderVector::const_iterator iPos( _aProviders.begin() );
+ iPos != _aProviders.end(); ++iPos )
+ {
+ try
+ {
+ if ((aRet = (*iPos)->getByHierarchicalName(
+ rName )).hasValue())
+ {
+ break;
+ }
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ }
+ }
+
+ // update cache
+ if (_bCaching && aRet.hasValue())
+ _aElements.setValue( rName, aRet );
+ }
+
+ if (! aRet.hasValue())
+ {
+ throw NoSuchElementException(
+ rName, static_cast< OWeakObject * >(this) );
+ }
+ return aRet;
+}
+//__________________________________________________________________________________________________
+sal_Bool ManagerImpl::hasByHierarchicalName( const OUString & rName )
+ throw(::com::sun::star::uno::RuntimeException)
+{
+ try
+ {
+ return getByHierarchicalName( rName ).hasValue();
+ }
+ catch (NoSuchElementException &)
+ {
+ }
+ return sal_False;
+}
+}
+
+namespace stoc_bootstrap
+{
+//==================================================================================================
+Reference< XInterface > SAL_CALL ManagerImpl_create(
+ Reference< XComponentContext > const & xContext )
+ SAL_THROW( (::com::sun::star::uno::Exception) )
+{
+ sal_Int32 nCacheSize = CACHE_SIZE;
+ if (xContext.is()) {
+ xContext->getValueByName(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "/implementations/" IMPLNAME "/CacheSize"))) >>=
+ nCacheSize;
+ }
+
+ return Reference< XInterface >( *new stoc_tdmgr::ManagerImpl( xContext, nCacheSize ) );
+}
+
+}
+
diff --git a/stoc/source/tdmanager/tdmgr_check.cxx b/stoc/source/tdmanager/tdmgr_check.cxx
new file mode 100644
index 000000000000..0a19403532bf
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_check.cxx
@@ -0,0 +1,556 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "tdmgr_common.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "typelib/typedescription.h"
+#include "com/sun/star/beans/PropertyAttribute.hpp"
+#include "com/sun/star/reflection/XConstantsTypeDescription.hpp"
+#include "com/sun/star/reflection/XIndirectTypeDescription.hpp"
+#include "com/sun/star/reflection/XEnumTypeDescription.hpp"
+#include "com/sun/star/reflection/XStructTypeDescription.hpp"
+#include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp"
+#include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp"
+#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp"
+#include "com/sun/star/reflection/XServiceTypeDescription2.hpp"
+#include "com/sun/star/reflection/XSingletonTypeDescription2.hpp"
+
+
+using ::rtl::OUString;
+using ::rtl::OUStringBuffer;
+using namespace ::com::sun::star;
+using namespace ::com::sun::star::uno;
+using namespace ::stoc_tdmgr;
+
+namespace {
+
+OUString getTypeClassName( TypeClass tc )
+{
+ typelib_EnumTypeDescription * typeDescr = 0;
+ OUString name = OUSTR("com.sun.star.uno.TypeClass");
+ typelib_typedescription_getByName(
+ reinterpret_cast<typelib_TypeDescription **>(&typeDescr), name.pData );
+ OSL_ASSERT( typeDescr != 0 );
+ if (typeDescr == 0)
+ return OUSTR("Cannot get type description of ") + name;
+ typelib_typedescription_complete(
+ reinterpret_cast<typelib_TypeDescription **>(&typeDescr) );
+
+ sal_Int32 const * pValues = typeDescr->pEnumValues;
+ sal_Int32 nPos = typeDescr->nEnumValues;
+ while (nPos--)
+ {
+ if (pValues[ nPos ] == (sal_Int32) tc)
+ break;
+ }
+ if (nPos >= 0)
+ name = typeDescr->ppEnumNames[ nPos ];
+ else
+ name = OUSTR("unknown TypeClass value: ") +
+ OUString::valueOf( (sal_Int32) tc );
+
+ typelib_typedescription_release(
+ reinterpret_cast<typelib_TypeDescription *>(typeDescr) );
+ return name;
+}
+
+OUString getPropertyFlagsAsString( sal_Int16 attributes )
+{
+ OUStringBuffer buf;
+ if ((attributes & beans::PropertyAttribute::MAYBEVOID) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEVOID, ") );
+ if ((attributes & beans::PropertyAttribute::BOUND) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("BOUND, ") );
+ if ((attributes & beans::PropertyAttribute::CONSTRAINED) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("CONSTRAINED, ") );
+ if ((attributes & beans::PropertyAttribute::TRANSIENT) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("TRANSIENT, ") );
+ if ((attributes & beans::PropertyAttribute::READONLY) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("READONLY, ") );
+ if ((attributes & beans::PropertyAttribute::MAYBEAMBIGUOUS) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEAMBIGUOUS, ") );
+ if ((attributes & beans::PropertyAttribute::MAYBEDEFAULT) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("MAYBEDEFAULT, ") );
+ if ((attributes & beans::PropertyAttribute::REMOVEABLE) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("REMOVEABLE, ") );
+ if ((attributes & beans::PropertyAttribute::OPTIONAL) != 0)
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("OPTIONAL") );
+ else if (buf.getLength() > 0)
+ buf.setLength( buf.getLength() - 2 ); // truncate ", "
+ return buf.makeStringAndClear();
+}
+
+void typeError( OUString const & msg, OUString const & context )
+{
+ OUStringBuffer buf;
+ if (context.getLength() > 0) {
+ buf.append( static_cast<sal_Unicode>('[') );
+ buf.append( context );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("] ") );
+ }
+ buf.append( msg );
+ throw IncompatibleTypeException( buf.makeStringAndClear() );
+}
+
+template<typename T>
+void checkSeq( Sequence< Reference<T> > const & newTypes,
+ Sequence< Reference<T> > const & existingTypes,
+ OUString const & context,
+ bool optionalMode = false )
+{
+ sal_Int32 len = newTypes.getLength();
+ if (len != existingTypes.getLength())
+ {
+ if (!optionalMode || len < newTypes.getLength())
+ typeError( OUSTR("Different number of types!"), context );
+ len = existingTypes.getLength();
+ }
+
+ Reference<T> const * pNewTypes = newTypes.getConstArray();
+ Reference<T> const * pExistingTypes = existingTypes.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ OUStringBuffer buf;
+ buf.append( context );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", position ") );
+ buf.append( pos );
+ check( pNewTypes[pos].get(), pExistingTypes[pos].get(),
+ buf.makeStringAndClear() );
+ }
+}
+
+void checkEnum(
+ Reference<reflection::XEnumTypeDescription> const & xNewTD,
+ Reference<reflection::XEnumTypeDescription> const & xExistingTD )
+{
+ if (xNewTD->getEnumNames() != xExistingTD->getEnumNames())
+ typeError( OUSTR("ENUM names don't match!"), xNewTD->getName() );
+ if (xNewTD->getEnumValues() != xExistingTD->getEnumValues())
+ typeError( OUSTR("ENUM values don't match!"), xNewTD->getName() );
+}
+
+void checkStruct(
+ Reference<reflection::XCompoundTypeDescription> const & xNewTD,
+ Reference<reflection::XCompoundTypeDescription> const & xExistingTD )
+{
+ check( xNewTD->getBaseType(), xExistingTD->getBaseType(),
+ xNewTD->getName() + OUSTR(", base type") );
+ checkSeq( xNewTD->getMemberTypes(), xExistingTD->getMemberTypes(),
+ xNewTD->getName() + OUSTR(", member types") );
+
+ if (xNewTD->getMemberNames() != xExistingTD->getMemberNames())
+ typeError( OUSTR("Different member names!"), xNewTD->getName() );
+
+ if (xNewTD->getTypeClass() == TypeClass_STRUCT)
+ {
+ Reference<reflection::XStructTypeDescription> xNewStructTD(
+ xNewTD, UNO_QUERY );
+ Reference<reflection::XStructTypeDescription> xExistingStructTD(
+ xExistingTD, UNO_QUERY );
+ if (xNewStructTD.is() && xExistingStructTD.is())
+ {
+ if (xNewStructTD->getTypeParameters() !=
+ xExistingStructTD->getTypeParameters())
+ typeError( OUSTR("Different type parameters of instantiated "
+ "polymorphic STRUCT!"), xNewTD->getName() );
+ checkSeq( xNewStructTD->getTypeArguments(),
+ xExistingStructTD->getTypeArguments(),
+ xNewTD->getName() + OUSTR(", argument types") );
+ }
+ else if (xNewStructTD.is() || xExistingStructTD.is())
+ typeError( OUSTR("Mixing polymorphic STRUCT types "
+ "with non-polymorphic!"), xNewTD->getName() );
+ }
+}
+
+void checkInterface(
+ Reference<reflection::XInterfaceTypeDescription2> const & xNewTD,
+ Reference<reflection::XInterfaceTypeDescription2> const & xExistingTD )
+{
+ checkSeq( xNewTD->getBaseTypes(), xExistingTD->getBaseTypes(),
+ xNewTD->getName() + OUSTR(", base types") );
+ checkSeq(xNewTD->getOptionalBaseTypes(),xExistingTD->getOptionalBaseTypes(),
+ xNewTD->getName() + OUSTR(", optional base types") );
+ checkSeq( xNewTD->getMembers(), xExistingTD->getMembers(),
+ xNewTD->getName() + OUSTR(", members") );
+}
+
+void checkRestParam( Reference<reflection::XParameter> const & xNewParam,
+ Reference<reflection::XParameter> const & xExistingParam,
+ OUString const & context )
+{
+ if (xNewParam->isRestParameter() != xExistingParam->isRestParameter())
+ typeError( OUSTR("Different ... parameters specified!"), context );
+}
+
+void checkRestParam( Reference<reflection::XMethodParameter> const &,
+ Reference<reflection::XMethodParameter> const &,
+ OUString const & )
+{
+}
+
+template<typename T>
+void checkParameters( Sequence< Reference<T> > const & newParams,
+ Sequence< Reference<T> > const & existingParams,
+ OUString const & context_ )
+{
+ sal_Int32 len = newParams.getLength();
+ if (len != existingParams.getLength())
+ typeError( OUSTR("Different number of parameters!"), context_ );
+ Reference<T> const * pNewParams = newParams.getConstArray();
+ Reference<T> const * pExistingParams = existingParams.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ Reference<T> const & xNewParam = pNewParams[pos];
+ Reference<T> const & xExistingParam = pExistingParams[pos];
+
+ OUStringBuffer buf;
+ buf.append( context_ );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", parameter ") );
+ buf.append( pos );
+ OSL_ASSERT( pos == xNewParam->getPosition() &&
+ pos == xExistingParam->getPosition() );
+ OUString context( buf.makeStringAndClear() );
+
+ if (xNewParam->getName() != xExistingParam->getName())
+ {
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Name differs: ") );
+ buf.append( xNewParam->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", ") );
+ buf.append( xExistingParam->getName() );
+ typeError( buf.makeStringAndClear(), context );
+ }
+ check( xNewParam->getType(), xExistingParam->getType(), context );
+
+ if (xNewParam->isIn() != xExistingParam->isIn())
+ typeError( OUSTR("IN attribute differs!"), context );
+ if (xNewParam->isOut() != xExistingParam->isOut())
+ typeError( OUSTR("OUT attribute differs!"), context );
+ checkRestParam( xNewParam, xExistingParam, context );
+ }
+}
+
+static void checkMethod(
+ Reference<reflection::XInterfaceMethodTypeDescription> const & xNewTD,
+ Reference<reflection::XInterfaceMethodTypeDescription> const & xExistingTD )
+{
+ check( xNewTD->getReturnType(), xExistingTD->getReturnType(),
+ xNewTD->getName() );
+
+ if (xNewTD->isOneway() != xExistingTD->isOneway())
+ typeError( OUSTR("Methods have differing OneWay attribute!"),
+ xNewTD->getName() );
+
+ checkParameters( xNewTD->getParameters(), xExistingTD->getParameters(),
+ xNewTD->getName() );
+
+ checkSeq( xNewTD->getExceptions(), xExistingTD->getExceptions(),
+ xNewTD->getName() + OUSTR(", declared exceptions") );
+}
+
+void checkAttribute(
+ Reference<reflection::XInterfaceAttributeTypeDescription2> const & xNewTD,
+ Reference<reflection::XInterfaceAttributeTypeDescription2>
+ const & xExistingTD )
+{
+ if (xNewTD->isReadOnly() != xExistingTD->isReadOnly())
+ typeError( OUSTR("ReadOnly attribute differs!"), xNewTD->getName() );
+
+ check( xNewTD->getType(), xExistingTD->getType(),
+ xNewTD->getName() + OUSTR(", attribute type") );
+
+ if (xNewTD->isBound() != xExistingTD->isBound())
+ typeError( OUSTR("Bound attribute differs!"), xNewTD->getName() );
+
+ checkSeq( xNewTD->getGetExceptions(), xExistingTD->getGetExceptions(),
+ xNewTD->getName() + OUSTR(", getter exceptions") );
+ checkSeq( xNewTD->getSetExceptions(), xExistingTD->getSetExceptions(),
+ xNewTD->getName() + OUSTR(", setter exceptions") );
+}
+
+void checkProperty(
+ Reference<reflection::XPropertyTypeDescription> const & xNewTD,
+ Reference<reflection::XPropertyTypeDescription> const & xExistingTD )
+{
+ if (xNewTD->getPropertyFlags() != xExistingTD->getPropertyFlags())
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "Different set of property flags: { ") );
+ buf.append( getPropertyFlagsAsString(
+ xNewTD->getPropertyFlags() ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } (new), { ") );
+ buf.append( getPropertyFlagsAsString(
+ xExistingTD->getPropertyFlags() ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" } (existing)!") );
+ typeError( buf.makeStringAndClear(), xNewTD->getName() );
+ }
+
+ check( xNewTD->getPropertyTypeDescription(),
+ xExistingTD->getPropertyTypeDescription(),
+ xNewTD->getName() );
+}
+
+void checkSingleton(
+ Reference<reflection::XSingletonTypeDescription2> const & xNewTD,
+ Reference<reflection::XSingletonTypeDescription2> const & xExistingTD )
+{
+ sal_Bool ifaceBased = xNewTD->isInterfaceBased();
+ if (ifaceBased != xExistingTD->isInterfaceBased())
+ typeError(
+ OUSTR("Mixing interface and NON-interface based singletons!"),
+ xNewTD->getName() );
+ if (ifaceBased)
+ check( xNewTD->getInterface(), xExistingTD->getInterface(),
+ xNewTD->getName() );
+ else
+ check( xNewTD->getService().get(), xExistingTD->getService().get(),
+ xNewTD->getName() );
+}
+
+void checkService(
+ Reference<reflection::XServiceTypeDescription2> const & xNewTD,
+ Reference<reflection::XServiceTypeDescription2> const & xExistingTD )
+{
+ sal_Bool singleIfaceBased = xNewTD->isSingleInterfaceBased();
+ if (singleIfaceBased != xExistingTD->isSingleInterfaceBased())
+ typeError( OUSTR("Mixing interface and NON-interface based services!"),
+ xNewTD->getName() );
+ if (singleIfaceBased)
+ {
+ check( xNewTD->getInterface(), xExistingTD->getInterface(),
+ xNewTD->getName() );
+ Sequence< Reference<reflection::XServiceConstructorDescription> >
+ newCtors( xNewTD->getConstructors() );
+ Sequence< Reference<reflection::XServiceConstructorDescription> >
+ existingCtors( xExistingTD->getConstructors() );
+ sal_Int32 len = newCtors.getLength();
+ if (len != existingCtors.getLength())
+ typeError( OUSTR("Different number of service constructors!"),
+ xNewTD->getName() );
+ Reference<reflection::XServiceConstructorDescription> const *
+ pNewCtors = newCtors.getConstArray();
+ Reference<reflection::XServiceConstructorDescription> const *
+ pExistingCtors = existingCtors.getConstArray();
+ for ( sal_Int32 pos = 0; pos < len; ++pos )
+ {
+ Reference<reflection::XServiceConstructorDescription> const &
+ xNewCtor = pNewCtors[pos];
+ Reference<reflection::XServiceConstructorDescription> const &
+ xExistingCtor = pExistingCtors[pos];
+
+ if (xNewCtor->getName() != xExistingCtor->getName())
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ "Different constructor names: ") );
+ buf.append( xNewCtor->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
+ buf.append( xExistingCtor->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
+ typeError( buf.makeStringAndClear(), xNewTD->getName() );
+ }
+
+ OUStringBuffer buf;
+ buf.append( xNewTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(", constructor ") );
+ buf.append( xNewCtor->getName() );
+ OUString context( buf.makeStringAndClear() );
+ checkParameters( xNewCtor->getParameters(),
+ xExistingCtor->getParameters(),
+ context );
+ checkSeq( xNewCtor->getExceptions(), xExistingCtor->getExceptions(),
+ context + OUSTR(", exceptions") );
+ }
+ }
+ else // old-style service descriptions:
+ {
+ checkSeq( xNewTD->getMandatoryServices(),
+ xExistingTD->getMandatoryServices(),
+ xNewTD->getName() + OUSTR(", mandatory services") );
+ checkSeq( xNewTD->getOptionalServices(),
+ xExistingTD->getOptionalServices(),
+ xNewTD->getName() + OUSTR(", optional services"),
+ true /* optionalMode */ );
+ checkSeq( xNewTD->getMandatoryInterfaces(),
+ xExistingTD->getMandatoryInterfaces(),
+ xNewTD->getName() + OUSTR(", mandatory interfaces") );
+ checkSeq( xNewTD->getOptionalInterfaces(),
+ xExistingTD->getOptionalInterfaces(),
+ xNewTD->getName() + OUSTR(", optional interfaces"),
+ true /* optionalMode */ );
+
+ Sequence< Reference<reflection::XPropertyTypeDescription> >
+ newProperties( xNewTD->getProperties() );
+ Sequence< Reference<reflection::XPropertyTypeDescription> >
+ existingProperties( xExistingTD->getProperties() );
+ checkSeq( newProperties, existingProperties,
+ xNewTD->getName() + OUSTR(", properties"),
+ true /* optionalMode */ );
+ if (newProperties.getLength() > existingProperties.getLength())
+ {
+ // check whether all added properties are OPTIONAL:
+ Reference<reflection::XPropertyTypeDescription> const *
+ pNewProperties = newProperties.getConstArray();
+ for ( sal_Int32 pos = existingProperties.getLength() + 1;
+ pos < newProperties.getLength(); ++pos )
+ {
+ if ((pNewProperties[pos]->getPropertyFlags() &
+ beans::PropertyAttribute::OPTIONAL) == 0)
+ typeError( OUSTR("New property is not OPTIONAL!"),
+ pNewProperties[pos]->getName() );
+ }
+ }
+ }
+}
+
+}
+
+namespace stoc_tdmgr {
+
+void check( Reference<reflection::XTypeDescription> const & xNewTD,
+ Reference<reflection::XTypeDescription> const & xExistingTD,
+ OUString const & context )
+{
+ if (xNewTD == xExistingTD)
+ return;
+ if (xNewTD->getName() != xExistingTD->getName())
+ {
+ OUStringBuffer buf;
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("Different type names: ") );
+ buf.append( xNewTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
+ buf.append( xExistingTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
+ typeError( buf.makeStringAndClear(), context );
+ }
+
+ TypeClass tc = xNewTD->getTypeClass();
+ if (tc != xExistingTD->getTypeClass())
+ {
+ OUStringBuffer buf;
+ buf.append( xNewTD->getName() );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(
+ " has different type classes: ") );
+ buf.append( getTypeClassName( tc ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (new), ") );
+ buf.append( getTypeClassName( xExistingTD->getTypeClass() ) );
+ buf.appendAscii( RTL_CONSTASCII_STRINGPARAM(" (existing)!") );
+ typeError( buf.makeStringAndClear(), context );
+ }
+
+ switch (tc)
+ {
+ case TypeClass_ENUM:
+ checkEnum( Reference<reflection::XEnumTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XEnumTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_TYPEDEF:
+ case TypeClass_SEQUENCE:
+ check( Reference<reflection::XIndirectTypeDescription>(
+ xNewTD, UNO_QUERY_THROW )->getReferencedType(),
+ Reference<reflection::XIndirectTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW )->getReferencedType() );
+ break;
+
+ case TypeClass_STRUCT:
+ case TypeClass_EXCEPTION:
+ checkStruct( Reference<reflection::XCompoundTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XCompoundTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_INTERFACE:
+ checkInterface( Reference<reflection::XInterfaceTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XInterfaceTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_SERVICE:
+ checkService( Reference<reflection::XServiceTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XServiceTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_INTERFACE_METHOD:
+ checkMethod( Reference<reflection::XInterfaceMethodTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XInterfaceMethodTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+ case TypeClass_INTERFACE_ATTRIBUTE:
+ checkAttribute(
+ Reference<reflection::XInterfaceAttributeTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XInterfaceAttributeTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_PROPERTY:
+ checkProperty( Reference<reflection::XPropertyTypeDescription>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XPropertyTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ case TypeClass_CONSTANT:
+ if (Reference<reflection::XConstantTypeDescription>(
+ xNewTD, UNO_QUERY_THROW )->getConstantValue() !=
+ Reference<reflection::XConstantTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW )->getConstantValue())
+ typeError( OUSTR("Different constant value!"), xNewTD->getName() );
+ break;
+ case TypeClass_CONSTANTS:
+ checkSeq( Reference<reflection::XConstantsTypeDescription>(
+ xNewTD, UNO_QUERY_THROW )->getConstants(),
+ Reference<reflection::XConstantsTypeDescription>(
+ xExistingTD, UNO_QUERY_THROW )->getConstants(),
+ xNewTD->getName() );
+ break;
+
+ case TypeClass_SINGLETON:
+ checkSingleton( Reference<reflection::XSingletonTypeDescription2>(
+ xNewTD, UNO_QUERY_THROW ),
+ Reference<reflection::XSingletonTypeDescription2>(
+ xExistingTD, UNO_QUERY_THROW ) );
+ break;
+
+ default:
+ break;
+ }
+}
+
+}
diff --git a/stoc/source/tdmanager/tdmgr_common.hxx b/stoc/source/tdmanager/tdmgr_common.hxx
new file mode 100644
index 000000000000..5d640e99f919
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_common.hxx
@@ -0,0 +1,60 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STOC_TDMGR_COMMON_HXX
+#define _STOC_TDMGR_COMMON_HXX
+
+#include <rtl/unload.h>
+
+#include "com/sun/star/reflection/XTypeDescription.hpp"
+
+#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )
+#define ARLEN(x) (sizeof (x) / sizeof *(x))
+
+
+namespace css = ::com::sun::star;
+
+namespace stoc_tdmgr
+{
+ extern rtl_StandardModuleCount g_moduleCount;
+
+struct IncompatibleTypeException
+{
+ ::rtl::OUString m_cause;
+ IncompatibleTypeException( ::rtl::OUString const & cause )
+ : m_cause( cause ) {}
+};
+
+void check(
+ css::uno::Reference<css::reflection::XTypeDescription> const & xNewTD,
+ css::uno::Reference<css::reflection::XTypeDescription> const & xExistingTD,
+ ::rtl::OUString const & context = ::rtl::OUString() );
+/* throw (css::uno::RuntimeException, IncompatibleTypeException) */
+
+} // namespace stoc_tdmgr
+
+#endif /* _STOC_TDMGR_COMMON_HXX */
diff --git a/stoc/source/tdmanager/tdmgr_tdenumeration.cxx b/stoc/source/tdmanager/tdmgr_tdenumeration.cxx
new file mode 100644
index 000000000000..c1815c932db5
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_tdenumeration.cxx
@@ -0,0 +1,187 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+#include <osl/diagnose.h>
+#include "tdmgr_common.hxx"
+#include "tdmgr_tdenumeration.hxx"
+
+using namespace com::sun::star;
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_tdmgr
+{
+
+//=========================================================================
+//=========================================================================
+//
+// TypeDescriptionEnumerationImpl Implementation.
+//
+//=========================================================================
+//=========================================================================
+
+TypeDescriptionEnumerationImpl::TypeDescriptionEnumerationImpl(
+ const rtl::OUString & rModuleName,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::TypeClass > & rTypes,
+ com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
+ const TDEnumerationAccessStack & rTDEAS )
+: m_aModuleName( rModuleName ),
+ m_aTypes( rTypes ),
+ m_eDepth( eDepth ),
+ m_aChildren( rTDEAS )
+{
+ ::g_moduleCount.modCnt.acquire( &::g_moduleCount.modCnt );
+}
+
+//=========================================================================
+// virtual
+TypeDescriptionEnumerationImpl::~TypeDescriptionEnumerationImpl()
+{
+ ::g_moduleCount.modCnt.release( &::g_moduleCount.modCnt );
+}
+
+//=========================================================================
+//
+// XEnumeration (base of XTypeDescriptionEnumeration) methods
+//
+//=========================================================================
+
+// virtual
+sal_Bool SAL_CALL TypeDescriptionEnumerationImpl::hasMoreElements()
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
+ = queryCurrentChildEnumeration();
+ if ( xEnum.is() )
+ return xEnum->hasMoreElements();
+
+ return sal_False;
+}
+
+//=========================================================================
+// virtual
+uno::Any SAL_CALL TypeDescriptionEnumerationImpl::nextElement()
+ throw ( container::NoSuchElementException,
+ lang::WrappedTargetException,
+ uno::RuntimeException )
+{
+ uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
+ = queryCurrentChildEnumeration();
+ if ( xEnum.is() )
+ return xEnum->nextElement();
+
+ throw container::NoSuchElementException(
+ rtl::OUString::createFromAscii(
+ "No further elements in enumeration!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+}
+
+//=========================================================================
+//
+// XTypeDescriptionEnumeration methods
+//
+//=========================================================================
+
+// virtual
+uno::Reference< reflection::XTypeDescription > SAL_CALL
+TypeDescriptionEnumerationImpl::nextTypeDescription()
+ throw ( container::NoSuchElementException,
+ uno::RuntimeException )
+{
+ uno::Reference< reflection::XTypeDescriptionEnumeration > xEnum
+ = queryCurrentChildEnumeration();
+ if ( xEnum.is() )
+ return xEnum->nextTypeDescription();
+
+ throw container::NoSuchElementException(
+ rtl::OUString::createFromAscii(
+ "No further elements in enumeration!" ),
+ static_cast< cppu::OWeakObject * >( this ) );
+}
+
+//=========================================================================
+uno::Reference< reflection::XTypeDescriptionEnumeration >
+TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ for (;;)
+ {
+ if ( m_xEnum.is() )
+ {
+ if ( m_xEnum->hasMoreElements() )
+ {
+ return m_xEnum;
+ }
+ else
+ {
+ // Forget about enumeration without further elements. Try next.
+ m_xEnum.clear();
+ }
+ }
+
+ // Note: m_xEnum is always null here.
+
+ if ( m_aChildren.empty() )
+ {
+ // No child enumerations left.
+ return m_xEnum;
+ }
+
+ try
+ {
+ m_xEnum =
+ m_aChildren.top()->createTypeDescriptionEnumeration(
+ m_aModuleName, m_aTypes, m_eDepth );
+ }
+ catch ( reflection::NoSuchTypeNameException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
+ "- Caught NoSuchTypeNameException!" );
+ }
+ catch ( reflection::InvalidTypeNameException const & )
+ {
+ OSL_ENSURE( sal_False,
+ "TypeDescriptionEnumerationImpl::queryCurrentChildEnumeration "
+ "- Caught InvalidTypeNameException!" );
+ }
+
+ // We're done with this enumeration access in any case (Either
+ // enumeration was successfully created or creation failed for some
+ // reason).
+ m_aChildren.pop();
+ }
+
+ // unreachable
+}
+
+} // namespace stoc_tdmgr
+
diff --git a/stoc/source/tdmanager/tdmgr_tdenumeration.hxx b/stoc/source/tdmanager/tdmgr_tdenumeration.hxx
new file mode 100644
index 000000000000..1b383af538c1
--- /dev/null
+++ b/stoc/source/tdmanager/tdmgr_tdenumeration.hxx
@@ -0,0 +1,89 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef _STOC_TDMGR_TDENUMERATION_HXX
+#define _STOC_TDMGR_TDENUMERATION_HXX
+
+#include <stack>
+#include <osl/mutex.hxx>
+#include <com/sun/star/reflection/XTypeDescriptionEnumeration.hpp>
+#include <com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp>
+#include <cppuhelper/implbase1.hxx>
+
+namespace stoc_tdmgr
+{
+
+typedef std::stack< com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescriptionEnumerationAccess > >
+ TDEnumerationAccessStack;
+
+class TypeDescriptionEnumerationImpl
+ : public cppu::WeakImplHelper1<
+ com::sun::star::reflection::XTypeDescriptionEnumeration >
+{
+public:
+ TypeDescriptionEnumerationImpl(
+ const rtl::OUString & rModuleName,
+ const com::sun::star::uno::Sequence<
+ com::sun::star::uno::TypeClass > & rTypes,
+ com::sun::star::reflection::TypeDescriptionSearchDepth eDepth,
+ const TDEnumerationAccessStack & rTDEAS );
+ virtual ~TypeDescriptionEnumerationImpl();
+
+ // XEnumeration (base of XTypeDescriptionEnumeration)
+ virtual sal_Bool SAL_CALL hasMoreElements()
+ throw ( ::com::sun::star::uno::RuntimeException );
+ virtual ::com::sun::star::uno::Any SAL_CALL nextElement()
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::lang::WrappedTargetException,
+ ::com::sun::star::uno::RuntimeException );
+
+ // XTypeDescriptionEnumeration
+ virtual ::com::sun::star::uno::Reference<
+ ::com::sun::star::reflection::XTypeDescription > SAL_CALL
+ nextTypeDescription()
+ throw ( ::com::sun::star::container::NoSuchElementException,
+ ::com::sun::star::uno::RuntimeException );
+
+private:
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescriptionEnumeration >
+ queryCurrentChildEnumeration();
+
+ osl::Mutex m_aMutex;
+ rtl::OUString m_aModuleName;
+ com::sun::star::uno::Sequence< com::sun::star::uno::TypeClass > m_aTypes;
+ com::sun::star::reflection::TypeDescriptionSearchDepth m_eDepth;
+ TDEnumerationAccessStack m_aChildren;
+ com::sun::star::uno::Reference<
+ com::sun::star::reflection::XTypeDescriptionEnumeration > m_xEnum;
+};
+
+} // namespace stoc_tdmgr
+
+#endif /* _STOC_TDMGR_TDENUMERATION_HXX */
+
diff --git a/stoc/source/typeconv/convert.cxx b/stoc/source/typeconv/convert.cxx
new file mode 100644
index 000000000000..0b81d3e49d1c
--- /dev/null
+++ b/stoc/source/typeconv/convert.cxx
@@ -0,0 +1,963 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include <osl/diagnose.h>
+#include <cppuhelper/factory.hxx>
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/implbase2.hxx>
+
+#include <typelib/typedescription.hxx>
+#include <uno/data.h>
+
+#ifdef WNT
+#include <cmath>
+#else
+#include <math.h>
+#endif
+#include <float.h>
+
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/script/XTypeConverter.hpp>
+#include <com/sun/star/script/FailReason.hpp>
+#include <com/sun/star/container/XSet.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
+
+using namespace com::sun::star::uno;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::script;
+using namespace com::sun::star::registry;
+using namespace cppu;
+using namespace rtl;
+using namespace osl;
+
+#define SERVICENAME "com.sun.star.script.Converter"
+#define IMPLNAME "com.sun.star.comp.stoc.TypeConverter"
+
+
+extern rtl_StandardModuleCount g_moduleCount;
+
+namespace stoc_services
+{
+Sequence< OUString > tcv_getSupportedServiceNames()
+{
+ static Sequence < OUString > *pNames = 0;
+ if( ! pNames )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( !pNames )
+ {
+ static Sequence< OUString > seqNames(1);
+ seqNames.getArray()[0] = OUString(RTL_CONSTASCII_USTRINGPARAM(SERVICENAME));
+ pNames = &seqNames;
+ }
+ }
+ return *pNames;
+}
+
+OUString tcv_getImplementationName()
+{
+ static OUString *pImplName = 0;
+ if( ! pImplName )
+ {
+ MutexGuard guard( Mutex::getGlobalMutex() );
+ if( ! pImplName )
+ {
+ static OUString implName( RTL_CONSTASCII_USTRINGPARAM( IMPLNAME ) );
+ pImplName = &implName;
+ }
+ }
+ return *pImplName;
+}
+}
+
+namespace stoc_tcv
+{
+
+static const sal_uInt64 SAL_UINT64_MAX =
+ ((((sal_uInt64)0xffffffff) << 32) | (sal_uInt64)0xffffffff);
+static const sal_Int64 SAL_INT64_MAX =
+ (sal_Int64)((((sal_uInt64)0x7fffffff) << 32) | (sal_uInt64)0xffffffff);
+static const sal_Int64 SAL_INT64_MIN =
+ (sal_Int64)(((sal_uInt64)0x80000000) << 32);
+
+/* MS Visual C++ no conversion from unsigned __int64 to double */
+#ifdef _MSC_VER
+static const double DOUBLE_SAL_UINT64_MAX = ((((double)SAL_INT64_MAX) * 2) + 1);
+
+static inline double unsigned_int64_to_double( sal_uInt64 n ) SAL_THROW( () )
+{
+ sal_uInt64 n2 = (n / 3);
+ n -= (2 * n2);
+ return (((double)(sal_Int64)n2) * 2.0) + ((double)(sal_Int64)n);
+}
+#else
+static const double DOUBLE_SAL_UINT64_MAX =
+ (double)((((sal_uInt64)0xffffffff) << 32) | (sal_uInt64)0xffffffff);
+
+static inline double unsigned_int64_to_double( sal_uInt64 n ) SAL_THROW( () )
+{
+ return (double)n;
+}
+#endif
+
+
+//--------------------------------------------------------------------------------------------------
+static inline double round( double aVal )
+{
+ sal_Bool bPos = (aVal >= 0.0); //
+ aVal = ::fabs( aVal );
+ double aUpper = ::ceil( aVal );
+
+ aVal = ((aUpper-aVal) <= 0.5) ? aUpper : (aUpper - 1.0);
+ return (bPos ? aVal : -aVal);
+}
+
+//--------------------------------------------------------------------------------------------------
+static sal_Bool getNumericValue( double & rfVal, const OUString & rStr )
+{
+ double fRet = rStr.toDouble();
+ if (fRet == 0.0)
+ {
+ sal_Int32 nLen = rStr.getLength();
+ if (!nLen || (nLen == 1 && rStr[0] == '0')) // common case
+ {
+ rfVal = 0.0;
+ return sal_True;
+ }
+
+ OUString trim( rStr.trim() );
+
+ // try hex
+ sal_Int32 nX = trim.indexOf( 'x' );
+ if (nX < 0)
+ nX = trim.indexOf( 'X' );
+
+ if (nX > 0 && trim[nX-1] == '0') // 0x
+ {
+ sal_Bool bNeg = sal_False;
+ switch (nX)
+ {
+ case 2: // (+|-)0x...
+ if (trim[0] == '-')
+ bNeg = sal_True;
+ else if (trim[0] != '+')
+ return sal_False;
+ case 1: // 0x...
+ break;
+ default:
+ return sal_False;
+ }
+
+ OUString aHexRest( trim.copy( nX+1 ) );
+ sal_Int64 nRet = aHexRest.toInt64( 16 );
+
+ if (nRet == 0)
+ {
+ for ( sal_Int32 nPos = aHexRest.getLength(); nPos--; )
+ {
+ if (aHexRest[nPos] != '0')
+ return sal_False;
+ }
+ }
+
+ rfVal = (bNeg ? -(double)nRet : (double)nRet);
+ return sal_True;
+ }
+
+ nLen = trim.getLength();
+ sal_Int32 nPos = 0;
+
+ // skip +/-
+ if (nLen && (trim[0] == '-' || trim[0] == '+'))
+ ++nPos;
+
+ while (nPos < nLen) // skip leading zeros
+ {
+ if (trim[nPos] != '0')
+ {
+ if (trim[nPos] != '.')
+ return sal_False;
+ ++nPos;
+ while (nPos < nLen) // skip trailing zeros
+ {
+ if (trim[nPos] != '0')
+ return sal_False;
+ ++nPos;
+ }
+ break;
+ }
+ ++nPos;
+ }
+ }
+ rfVal = fRet;
+ return sal_True;
+}
+
+//==================================================================================================
+static sal_Bool getHyperValue( sal_Int64 & rnVal, const OUString & rStr )
+{
+ sal_Int32 nLen = rStr.getLength();
+ if (!nLen || (nLen == 1 && rStr[0] == '0')) // common case
+ {
+ rnVal = 0;
+ return sal_True;
+ }
+
+ OUString trim( rStr.trim() );
+
+ // try hex
+ sal_Int32 nX = trim.indexOf( 'x' );
+ if (nX < 0)
+ nX = trim.indexOf( 'X' );
+
+ if (nX >= 0)
+ {
+ if (nX > 0 && trim[nX-1] == '0') // 0x
+ {
+ sal_Bool bNeg = sal_False;
+ switch (nX)
+ {
+ case 2: // (+|-)0x...
+ if (trim[0] == '-')
+ bNeg = sal_True;
+ else if (trim[0] != '+')
+ return sal_False;
+ case 1: // 0x...
+ break;
+ default:
+ return sal_False;
+ }
+
+ OUString aHexRest( trim.copy( nX+1 ) );
+ sal_Int64 nRet = aHexRest.toInt64( 16 );
+
+ if (nRet == 0)
+ {
+ for ( sal_Int32 nPos = aHexRest.getLength(); nPos--; )
+ {
+ if (aHexRest[nPos] != '0')
+ return sal_False;
+ }
+ }
+
+ rnVal = (bNeg ? -nRet : nRet);
+ return sal_True;
+ }
+ return sal_False;
+ }
+
+ double fVal;
+ if (getNumericValue( fVal, rStr ) &&
+ fVal >= (double)SAL_INT64_MIN &&
+ fVal <= DOUBLE_SAL_UINT64_MAX)
+ {
+ rnVal = (sal_Int64)round( fVal );
+ return sal_True;
+ }
+ return sal_False;
+}
+
+//==================================================================================================
+class TypeConverter_Impl : public WeakImplHelper2< XTypeConverter, XServiceInfo >
+{
+ // ...misc helpers...
+ sal_Int64 toHyper(
+ const Any& rAny, sal_Int64 min = SAL_INT64_MIN, sal_uInt64 max = SAL_UINT64_MAX )
+ throw( CannotConvertException );
+ double toDouble( const Any& rAny, double min = -DBL_MAX, double max = DBL_MAX ) const
+ throw( CannotConvertException );
+
+public:
+ TypeConverter_Impl();
+ virtual ~TypeConverter_Impl();
+
+ // XServiceInfo
+ virtual OUString SAL_CALL getImplementationName() throw( RuntimeException );
+ virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName)
+ throw( RuntimeException );
+ virtual Sequence< OUString > SAL_CALL getSupportedServiceNames(void)
+ throw( RuntimeException );
+
+ // XTypeConverter
+ virtual Any SAL_CALL convertTo( const Any& aFrom, const Type& DestinationType )
+ throw( IllegalArgumentException, CannotConvertException, RuntimeException);
+ virtual Any SAL_CALL convertToSimpleType( const Any& aFrom, TypeClass aDestinationType )
+ throw( IllegalArgumentException, CannotConvertException, RuntimeException);
+};
+
+TypeConverter_Impl::TypeConverter_Impl()
+{
+ g_moduleCount.modCnt.acquire( &g_moduleCount.modCnt );
+}
+
+TypeConverter_Impl::~TypeConverter_Impl()
+{
+ g_moduleCount.modCnt.release( &g_moduleCount.modCnt );
+}
+
+// XServiceInfo
+OUString TypeConverter_Impl::getImplementationName() throw( RuntimeException )
+{
+ return stoc_services::tcv_getImplementationName();
+}
+
+// XServiceInfo
+sal_Bool TypeConverter_Impl::supportsService(const OUString& ServiceName) throw( RuntimeException )
+{
+ Sequence< OUString > aSNL = getSupportedServiceNames();
+ const OUString * pArray = aSNL.getConstArray();
+ for( sal_Int32 i = 0; i < aSNL.getLength(); i++ )
+ if( pArray[i] == ServiceName )
+ return sal_True;
+ return sal_False;
+}
+
+// XServiceInfo
+Sequence< OUString > TypeConverter_Impl::getSupportedServiceNames(void) throw( RuntimeException )
+{
+ return stoc_services::tcv_getSupportedServiceNames();
+}
+
+//--------------------------------------------------------------------------------------------------
+sal_Int64 TypeConverter_Impl::toHyper( const Any& rAny, sal_Int64 min, sal_uInt64 max )
+ throw( CannotConvertException )
+{
+ sal_Int64 nRet;
+ TypeClass aDestinationClass = rAny.getValueTypeClass();
+
+ switch (aDestinationClass)
+ {
+ // ENUM
+ case TypeClass_ENUM:
+ nRet = *(sal_Int32 *)rAny.getValue();
+ break;
+ // BOOL
+ case TypeClass_BOOLEAN:
+ nRet = (*(sal_Bool*)rAny.getValue() ? 1 : 0);
+ break;
+ // CHAR, BYTE
+ case TypeClass_CHAR:
+ nRet = *(sal_Unicode *)rAny.getValue();
+ break;
+ case TypeClass_BYTE:
+ nRet = *(sal_Int8 *)rAny.getValue();
+ break;
+ // SHORT
+ case TypeClass_SHORT:
+ nRet = *(sal_Int16 *)rAny.getValue();
+ break;
+ // UNSIGNED SHORT
+ case TypeClass_UNSIGNED_SHORT:
+ nRet = *(sal_uInt16 *)rAny.getValue();
+ break;
+ // LONG
+ case TypeClass_LONG:
+ nRet = *(sal_Int32 *)rAny.getValue();
+ break;
+ // UNSIGNED LONG
+ case TypeClass_UNSIGNED_LONG:
+ nRet = *(sal_uInt32 *)rAny.getValue();
+ break;
+ // HYPER
+ case TypeClass_HYPER:
+ nRet = *(sal_Int64 *)rAny.getValue();
+ break;
+ // UNSIGNED HYPER
+ case TypeClass_UNSIGNED_HYPER:
+ {
+ nRet = *(sal_Int64 *)rAny.getValue();
+ if ((min < 0 || (sal_uInt64)nRet >= (sal_uInt64)min) && // lower bound
+ (sal_uInt64)nRet <= max) // upper bound
+ {
+ return nRet;
+ }
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("UNSIGNED HYPER out of range!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 );
+ }
+
+ // FLOAT, DOUBLE
+ case TypeClass_FLOAT:
+ {
+ double fVal = round( *(float *)rAny.getValue() );
+ nRet = (fVal > SAL_INT64_MAX ? (sal_Int64)(sal_uInt64)fVal : (sal_Int64)fVal);
+ if (fVal >= min && fVal <= unsigned_int64_to_double( max ))
+ {
+ return nRet;
+ }
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("FLOAT out of range!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 );
+ }
+ case TypeClass_DOUBLE:
+ {
+ double fVal = round( *(double *)rAny.getValue() );
+ nRet = (fVal > SAL_INT64_MAX ? (sal_Int64)(sal_uInt64)fVal : (sal_Int64)fVal);
+ if (fVal >= min && fVal <= unsigned_int64_to_double( max ))
+ {
+ return nRet;
+ }
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("DOUBLE out of range!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 );
+ }
+
+ // STRING
+ case TypeClass_STRING:
+ {
+ sal_Int64 fVal = SAL_CONST_INT64(0);
+ if (! getHyperValue( fVal, *(OUString const *)rAny.getValue() ))
+ {
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("invalid STRING value!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::IS_NOT_NUMBER, 0 );
+ }
+ nRet = (fVal > SAL_INT64_MAX ? (sal_Int64)(sal_uInt64)fVal : (sal_Int64)fVal);
+ if (fVal >= min && (fVal < 0 || ((sal_uInt64)fVal) <= max))
+ return nRet;
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("STRING value out of range!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 );
+ }
+
+ default:
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("TYPE is not supported!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::TYPE_NOT_SUPPORTED, 0 );
+ }
+
+ if (nRet >= min && (nRet < 0 || (sal_uInt64)nRet <= max))
+ return nRet;
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("VALUE is out of range!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 );
+}
+
+//--------------------------------------------------------------------------------------------------
+double TypeConverter_Impl::toDouble( const Any& rAny, double min, double max ) const
+ throw( CannotConvertException )
+{
+ double fRet;
+ TypeClass aDestinationClass = rAny.getValueTypeClass();
+
+ switch (aDestinationClass)
+ {
+ // ENUM
+ case TypeClass_ENUM:
+ fRet = *(sal_Int32 *)rAny.getValue();
+ break;
+ // BOOL
+ case TypeClass_BOOLEAN:
+ fRet = (*(sal_Bool*)rAny.getValue() ? 1.0 : 0.0);
+ break;
+ // CHAR, BYTE
+ case TypeClass_CHAR:
+ fRet = *(sal_Unicode *)rAny.getValue();
+ break;
+ case TypeClass_BYTE:
+ fRet = *(sal_Int8 *)rAny.getValue();
+ break;
+ // SHORT
+ case TypeClass_SHORT:
+ fRet = *(sal_Int16 *)rAny.getValue();
+ break;
+ // UNSIGNED SHORT
+ case TypeClass_UNSIGNED_SHORT:
+ fRet = *(sal_uInt16 *)rAny.getValue();
+ break;
+ // LONG
+ case TypeClass_LONG:
+ fRet = *(sal_Int32 *)rAny.getValue();
+ break;
+ // UNSIGNED LONG
+ case TypeClass_UNSIGNED_LONG:
+ fRet = *(sal_uInt32 *)rAny.getValue();
+ break;
+ // HYPER
+ case TypeClass_HYPER:
+ fRet = (double)*(sal_Int64 *)rAny.getValue();
+ break;
+ // UNSIGNED HYPER
+ case TypeClass_UNSIGNED_HYPER:
+ fRet = unsigned_int64_to_double( *(sal_uInt64 const *)rAny.getValue() );
+ break;
+ // FLOAT, DOUBLE
+ case TypeClass_FLOAT:
+ fRet = *(float *)rAny.getValue();
+ break;
+ case TypeClass_DOUBLE:
+ fRet = *(double *)rAny.getValue();
+ break;
+
+ // STRING
+ case TypeClass_STRING:
+ {
+ if (! getNumericValue( fRet, *(OUString *)rAny.getValue() ))
+ {
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("invalid STRING value!") ),
+ Reference<XInterface>(), aDestinationClass, FailReason::IS_NOT_NUMBER, 0 );
+ }
+ break;
+ }
+
+ default:
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("TYPE is not supported!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::TYPE_NOT_SUPPORTED, 0 );
+ }
+
+ if (fRet >= min && fRet <= max)
+ return fRet;
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("VALUE is out of range!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::OUT_OF_RANGE, 0 );
+}
+
+//--------------------------------------------------------------------------------------------------
+Any SAL_CALL TypeConverter_Impl::convertTo( const Any& rVal, const Type& aDestType )
+ throw( IllegalArgumentException, CannotConvertException, RuntimeException)
+{
+ Type aSourceType = rVal.getValueType();
+ if (aSourceType == aDestType)
+ return rVal;
+
+ TypeClass aSourceClass = aSourceType.getTypeClass();
+ TypeClass aDestinationClass = aDestType.getTypeClass();
+
+ Any aRet;
+
+ // convert to...
+ switch (aDestinationClass)
+ {
+ // --- to VOID ------------------------------------------------------------------------------
+ case TypeClass_VOID:
+ return Any();
+ // --- to ANY -------------------------------------------------------------------------------
+ case TypeClass_ANY:
+ return rVal;
+
+ // --- to STRUCT, UNION, EXCEPTION ----------------------------------------------------------
+ case TypeClass_STRUCT:
+// case TypeClass_UNION: // xxx todo
+ case TypeClass_EXCEPTION:
+ {
+ // same types or destination type is derived source type?
+ TypeDescription aSourceTD( aSourceType );
+ TypeDescription aDestTD( aDestType );
+ if (typelib_typedescription_isAssignableFrom( aDestTD.get(), aSourceTD.get() ))
+ {
+ aRet.setValue( rVal.getValue(), aDestTD.get() ); // evtl. .uP.cAsT.
+ }
+ else
+ {
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("value is not of same or derived type!") ),
+ Reference< XInterface >(), aDestinationClass,
+ FailReason::SOURCE_IS_NO_DERIVED_TYPE, 0 );
+ }
+ break;
+ }
+ // --- to INTERFACE -------------------------------------------------------------------------
+ case TypeClass_INTERFACE:
+ {
+ if (! rVal.hasValue())
+ {
+ // void -> interface (null)
+ void * null_ref = 0;
+ aRet.setValue( &null_ref, aDestType );
+ break;
+ }
+
+ if (rVal.getValueTypeClass() != TypeClass_INTERFACE ||
+ !*(XInterface * const *)rVal.getValue())
+ {
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("value is no interface!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::NO_SUCH_INTERFACE, 0 );
+ }
+ if (! (aRet = (*(XInterface * const *)rVal.getValue())->queryInterface(
+ aDestType )).hasValue())
+ {
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("value has no such interface!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::NO_SUCH_INTERFACE, 0 );
+ }
+ break;
+ }
+ // --- to SEQUENCE --------------------------------------------------------------------------
+ case TypeClass_SEQUENCE:
+ {
+ if (aSourceClass==TypeClass_SEQUENCE)
+ {
+ if( aSourceType == aDestType )
+ return rVal;
+
+ TypeDescription aSourceTD( aSourceType );
+ TypeDescription aDestTD( aDestType );
+ typelib_TypeDescription * pSourceElementTD = 0;
+ TYPELIB_DANGER_GET(
+ &pSourceElementTD,
+ ((typelib_IndirectTypeDescription *)aSourceTD.get())->pType );
+ typelib_TypeDescription * pDestElementTD = 0;
+ TYPELIB_DANGER_GET(
+ &pDestElementTD,
+ ((typelib_IndirectTypeDescription *)aDestTD.get())->pType );
+
+ sal_uInt32 nPos = (*(const uno_Sequence * const *)rVal.getValue())->nElements;
+ uno_Sequence * pRet = 0;
+ uno_sequence_construct(
+ &pRet, aDestTD.get(), 0, nPos,
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire) );
+ aRet.setValue( &pRet, aDestTD.get() );
+ uno_destructData(
+ &pRet, aDestTD.get(),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) );
+ // decr ref count
+
+ char * pDestElements = (*(uno_Sequence * const *)aRet.getValue())->elements;
+ const char * pSourceElements =
+ (*(const uno_Sequence * const *)rVal.getValue())->elements;
+
+ while (nPos--)
+ {
+ char * pDestPos = pDestElements + (nPos * pDestElementTD->nSize);
+ const char * pSourcePos = pSourceElements + (nPos * pSourceElementTD->nSize);
+
+ Any aElement(
+ convertTo( Any( pSourcePos, pSourceElementTD ), pDestElementTD->pWeakRef ) );
+
+ if (!uno_assignData(
+ pDestPos, pDestElementTD,
+ (pDestElementTD->eTypeClass == typelib_TypeClass_ANY
+ ? &aElement
+ : const_cast< void * >( aElement.getValue() )),
+ pDestElementTD,
+ reinterpret_cast< uno_QueryInterfaceFunc >(
+ cpp_queryInterface),
+ reinterpret_cast< uno_AcquireFunc >(cpp_acquire),
+ reinterpret_cast< uno_ReleaseFunc >(cpp_release) ))
+ {
+ OSL_ASSERT( false );
+ }
+ }
+ TYPELIB_DANGER_RELEASE( pDestElementTD );
+ TYPELIB_DANGER_RELEASE( pSourceElementTD );
+ }
+ break;
+ }
+ // --- to ENUM ------------------------------------------------------------------------------
+ case TypeClass_ENUM:
+ {
+ TypeDescription aEnumTD( aDestType );
+ aEnumTD.makeComplete();
+ sal_Int32 nPos = -1;
+
+ if (aSourceClass==TypeClass_STRING)
+ {
+ for ( nPos = ((typelib_EnumTypeDescription *)aEnumTD.get())->nEnumValues; nPos--; )
+ {
+ if (((const OUString *)rVal.getValue())->equalsIgnoreAsciiCase(
+ ((typelib_EnumTypeDescription *)aEnumTD.get())->ppEnumNames[nPos] ))
+ break;
+ }
+ }
+ else if (aSourceClass!=TypeClass_ENUM && // exclude some unwanted types for toHyper()
+ aSourceClass!=TypeClass_BOOLEAN &&
+ aSourceClass!=TypeClass_CHAR)
+ {
+ sal_Int32 nEnumValue = (sal_Int32)toHyper( rVal, -(sal_Int64)0x80000000, 0x7fffffff );
+ for ( nPos = ((typelib_EnumTypeDescription *)aEnumTD.get())->nEnumValues; nPos--; )
+ {
+ if (nEnumValue == ((typelib_EnumTypeDescription *)aEnumTD.get())->pEnumValues[nPos])
+ break;
+ }
+ }
+
+ if (nPos >= 0)
+ {
+ aRet.setValue(
+ &((typelib_EnumTypeDescription *)aEnumTD.get())->pEnumValues[nPos],
+ aEnumTD.get() );
+ }
+ else
+ {
+ throw CannotConvertException(
+ OUString(
+ RTL_CONSTASCII_USTRINGPARAM("value cannot be converted to demanded ENUM!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::IS_NOT_ENUM, 0 );
+ }
+ break;
+ }
+
+ default:
+ // else simple type conversion possible?
+ try
+ {
+ aRet = convertToSimpleType( rVal, aDestinationClass );
+ }
+ catch (IllegalArgumentException &)
+ {
+ // ...FailReason::INVALID is thrown
+ }
+ }
+
+ if (aRet.hasValue())
+ return aRet;
+
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("conversion not possible!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::INVALID, 0 );
+}
+
+//--------------------------------------------------------------------------------------------------
+Any TypeConverter_Impl::convertToSimpleType( const Any& rVal, TypeClass aDestinationClass )
+ throw( IllegalArgumentException, CannotConvertException, RuntimeException )
+{
+ switch (aDestinationClass)
+ {
+ // only simple Conversion of _simple_ types
+ case TypeClass_INTERFACE:
+ case TypeClass_SERVICE:
+ case TypeClass_STRUCT:
+ case TypeClass_TYPEDEF:
+ case TypeClass_UNION:
+ case TypeClass_EXCEPTION:
+ case TypeClass_ARRAY:
+ case TypeClass_SEQUENCE:
+ case TypeClass_ENUM:
+ case TypeClass_UNKNOWN:
+ case TypeClass_MODULE:
+ throw IllegalArgumentException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("destination type is not simple!") ),
+ Reference< XInterface >(), (sal_Int16) 1 );
+ default:
+ break;
+ }
+
+ Type aSourceType = rVal.getValueType();
+ TypeClass aSourceClass = aSourceType.getTypeClass();
+ if (aDestinationClass == aSourceClass)
+ return rVal;
+
+ Any aRet;
+
+ // Convert to...
+ switch (aDestinationClass)
+ {
+ // --- to VOID ------------------------------------------------------------------------------
+ case TypeClass_VOID:
+ return Any();
+
+ // --- to ANY -------------------------------------------------------------------------------
+ case TypeClass_ANY:
+ return rVal;
+
+ // --- to BOOL ------------------------------------------------------------------------------
+ case TypeClass_BOOLEAN:
+ switch (aSourceClass)
+ {
+ default:
+ {
+ sal_Bool bTmp = (toDouble( rVal ) != 0.0);
+ aRet.setValue( &bTmp, getBooleanCppuType() );
+ }
+ case TypeClass_ENUM: // exclude enums
+ break;
+
+ case TypeClass_STRING:
+ {
+ const OUString & aStr = *(const OUString *)rVal.getValue();
+ if (aStr.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("0") ) ||
+ aStr.equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("false") ) ))
+ {
+ sal_Bool bFalse = sal_False;
+ aRet.setValue( &bFalse, getCppuBooleanType() );
+ }
+ else if (aStr.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("1") ) ||
+ aStr.equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("true") ) ))
+ {
+ sal_Bool bTrue = sal_True;
+ aRet.setValue( &bTrue, getCppuBooleanType() );
+ }
+ else
+ {
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("STRING has no boolean value!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::IS_NOT_BOOL, 0 );
+ }
+ }
+ }
+ break;
+
+ // --- to CHAR, BYTE ------------------------------------------------------------------------
+ case TypeClass_CHAR:
+ {
+ if (aSourceClass==TypeClass_STRING)
+ {
+ if ((*(const OUString *)rVal.getValue()).getLength() == 1) // single char
+ aRet.setValue( (*(const OUString *)rVal.getValue()).getStr(), ::getCharCppuType() );
+ }
+ else if (aSourceClass!=TypeClass_ENUM && // exclude enums, chars
+ aSourceClass!=TypeClass_CHAR)
+ {
+ sal_Unicode cRet = (sal_Unicode)toHyper( rVal, 0, 0xffff ); // range
+ aRet.setValue( &cRet, ::getCharCppuType() );
+ }
+ break;
+ }
+ case TypeClass_BYTE:
+ aRet <<= (sal_Int8)( toHyper( rVal, -(sal_Int64)0x80, 0x7f ) );
+ break;
+
+ // --- to SHORT, UNSIGNED SHORT -------------------------------------------------------------
+ case TypeClass_SHORT:
+ aRet <<= (sal_Int16)( toHyper( rVal, -(sal_Int64)0x8000, 0x7fff ) );
+ break;
+ case TypeClass_UNSIGNED_SHORT:
+ aRet <<= (sal_uInt16)( toHyper( rVal, 0, 0xffff ) );
+ break;
+
+ // --- to LONG, UNSIGNED LONG ---------------------------------------------------------------
+ case TypeClass_LONG:
+ aRet <<= (sal_Int32)( toHyper( rVal, -(sal_Int64)0x80000000, 0x7fffffff ) );
+ break;
+ case TypeClass_UNSIGNED_LONG:
+ aRet <<= (sal_uInt32)( toHyper( rVal, 0, 0xffffffff ) );
+ break;
+
+ // --- to HYPER, UNSIGNED HYPER--------------------------------------------
+ case TypeClass_HYPER:
+ aRet <<= toHyper( rVal, SAL_INT64_MIN, SAL_INT64_MAX );
+ break;
+ case TypeClass_UNSIGNED_HYPER:
+ aRet <<= (sal_uInt64)( toHyper( rVal, 0, SAL_UINT64_MAX ) );
+ break;
+
+ // --- to FLOAT, DOUBLE ---------------------------------------------------------------------
+ case TypeClass_FLOAT:
+ aRet <<= (float)( toDouble( rVal, -FLT_MAX, FLT_MAX ) );
+ break;
+ case TypeClass_DOUBLE:
+ aRet <<= (double)( toDouble( rVal, -DBL_MAX, DBL_MAX ) );
+ break;
+
+ // --- to STRING ----------------------------------------------------------------------------
+ case TypeClass_STRING:
+ switch (aSourceClass)
+ {
+ case TypeClass_ENUM:
+ {
+ TypeDescription aEnumTD( aSourceType );
+ aEnumTD.makeComplete();
+ sal_Int32 nPos;
+ sal_Int32 nEnumValue = *(sal_Int32 *)rVal.getValue();
+ for ( nPos = ((typelib_EnumTypeDescription *)aEnumTD.get())->nEnumValues; nPos--; )
+ {
+ if (nEnumValue == ((typelib_EnumTypeDescription *)aEnumTD.get())->pEnumValues[nPos])
+ break;
+ }
+ if (nPos >= 0)
+ {
+ aRet.setValue(
+ &((typelib_EnumTypeDescription *)aEnumTD.get())->ppEnumNames[nPos],
+ ::getCppuType( (const OUString *)0 ) );
+ }
+ else
+ {
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("value is not ENUM!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::IS_NOT_ENUM, 0 );
+ }
+ break;
+ }
+
+ case TypeClass_BOOLEAN:
+ aRet <<= OUString::createFromAscii( (*(sal_Bool *)rVal.getValue() ? "true" : "false") );
+ break;
+ case TypeClass_CHAR:
+ aRet <<= OUString( (sal_Unicode *)rVal.getValue(), 1 );
+ break;
+
+ case TypeClass_BYTE:
+ aRet <<= OUString::valueOf( (sal_Int32)*(sal_Int8 const *)rVal.getValue() );
+ break;
+ case TypeClass_SHORT:
+ aRet <<= OUString::valueOf( (sal_Int32)*(sal_Int16 const *)rVal.getValue() );
+ break;
+ case TypeClass_UNSIGNED_SHORT:
+ aRet <<= OUString::valueOf( (sal_Int32)*(sal_uInt16 const *)rVal.getValue() );
+ break;
+ case TypeClass_LONG:
+ aRet <<= OUString::valueOf( *(sal_Int32 const *)rVal.getValue() );
+ break;
+ case TypeClass_UNSIGNED_LONG:
+ aRet <<= OUString::valueOf( (sal_Int64)*(sal_uInt32 const *)rVal.getValue() );
+ break;
+ case TypeClass_HYPER:
+ aRet <<= OUString::valueOf( *(sal_Int64 const *)rVal.getValue() );
+ break;
+// case TypeClass_UNSIGNED_HYPER:
+// aRet <<= OUString::valueOf( (sal_Int64)*(sal_uInt64 const *)rVal.getValue() );
+// break;
+ // handle unsigned hyper like double
+
+ default:
+ aRet <<= OUString::valueOf( toDouble( rVal ) );
+ }
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+
+ if (aRet.hasValue())
+ return aRet;
+
+ throw CannotConvertException(
+ OUString( RTL_CONSTASCII_USTRINGPARAM("conversion not possible!") ),
+ Reference< XInterface >(), aDestinationClass, FailReason::INVALID, 0 );
+}
+}
+
+namespace stoc_services
+{
+//*************************************************************************
+Reference< XInterface > SAL_CALL TypeConverter_Impl_CreateInstance(
+ const Reference< XComponentContext > & )
+ throw( RuntimeException )
+{
+ static Reference< XInterface > s_ref( (OWeakObject *) new stoc_tcv::TypeConverter_Impl() );
+ return s_ref;
+}
+}
+
diff --git a/stoc/source/typeconv/makefile.mk b/stoc/source/typeconv/makefile.mk
new file mode 100644
index 000000000000..e84f51889b98
--- /dev/null
+++ b/stoc/source/typeconv/makefile.mk
@@ -0,0 +1,48 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+PRJ=..$/..
+
+PRJNAME=stoc
+TARGET = typeconverter
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings -----------------------------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES= \
+ $(SLO)$/convert.obj
+
+# --- Targets ------------------------------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/stoc/source/uriproc/ExternalUriReferenceTranslator.cxx b/stoc/source/uriproc/ExternalUriReferenceTranslator.cxx
new file mode 100644
index 000000000000..b11ba0fc0df2
--- /dev/null
+++ b/stoc/source/uriproc/ExternalUriReferenceTranslator.cxx
@@ -0,0 +1,240 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "stocservices.hxx"
+
+#include "supportsService.hxx"
+
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uri/XExternalUriReferenceTranslator.hpp"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/thread.h"
+#include "rtl/string.h"
+#include "rtl/textenc.h"
+#include "rtl/uri.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include <new>
+
+namespace css = com::sun::star;
+
+namespace {
+
+class Translator: public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::uri::XExternalUriReferenceTranslator >
+{
+public:
+ explicit Translator(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ m_context(context) {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ translateToInternal(rtl::OUString const & externalUriReference)
+ throw (css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL
+ translateToExternal(rtl::OUString const & internalUriReference)
+ throw (css::uno::RuntimeException);
+
+private:
+ Translator(Translator &); // not implemented
+ void operator =(Translator); // not implemented
+
+ virtual ~Translator() {}
+
+ css::uno::Reference< css::uno::XComponentContext > m_context;
+};
+
+rtl::OUString Translator::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return
+ stoc_services::ExternalUriReferenceTranslator::getImplementationName();
+}
+
+sal_Bool Translator::supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ return stoc::uriproc::supportsService(
+ getSupportedServiceNames(), serviceName);
+}
+
+css::uno::Sequence< rtl::OUString > Translator::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::ExternalUriReferenceTranslator::
+ getSupportedServiceNames();
+}
+
+rtl::OUString Translator::translateToInternal(
+ rtl::OUString const & externalUriReference)
+ throw (css::uno::RuntimeException)
+{
+ if (!externalUriReference.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("file:/")))
+ {
+ return externalUriReference;
+ }
+ sal_Int32 i = RTL_CONSTASCII_LENGTH("file:");
+ rtl::OUStringBuffer buf;
+ buf.append(externalUriReference.getStr(), i);
+ // Some environments (e.g., Java) produce illegal file URLs without an
+ // authority part; treat them as having an empty authority part:
+ if (!externalUriReference.matchAsciiL(RTL_CONSTASCII_STRINGPARAM("//"), i))
+ {
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ }
+ rtl_TextEncoding encoding = osl_getThreadTextEncoding();
+ for (bool path = true;;) {
+ sal_Int32 j = i;
+ while (j != externalUriReference.getLength()
+ && externalUriReference[j] != '#'
+ && (!path || externalUriReference[j] != '/'))
+ {
+ ++j;
+ }
+ if (j != i) {
+ rtl::OUString seg(
+ rtl::Uri::encode(
+ rtl::Uri::decode(
+ externalUriReference.copy(i, j - i),
+ rtl_UriDecodeStrict, encoding),
+ rtl_UriCharClassPchar, rtl_UriEncodeStrict,
+ RTL_TEXTENCODING_UTF8));
+ if (seg.getLength() == 0) {
+ return rtl::OUString();
+ }
+ buf.append(seg);
+ }
+ if (j == externalUriReference.getLength()) {
+ break;
+ }
+ buf.append(externalUriReference[j]);
+ path = externalUriReference[j] == '/';
+ i = j + 1;
+ }
+ return buf.makeStringAndClear();
+}
+
+rtl::OUString Translator::translateToExternal(
+ rtl::OUString const & internalUriReference)
+ throw (css::uno::RuntimeException)
+{
+ if (!internalUriReference.matchIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("file://")))
+ {
+ return internalUriReference;
+ }
+ sal_Int32 i = RTL_CONSTASCII_LENGTH("file://");
+ rtl::OUStringBuffer buf;
+ buf.append(internalUriReference.getStr(), i);
+ rtl_TextEncoding encoding = osl_getThreadTextEncoding();
+ for (bool path = true;;) {
+ sal_Int32 j = i;
+ while (j != internalUriReference.getLength()
+ && internalUriReference[j] != '#'
+ && (!path || internalUriReference[j] != '/'))
+ {
+ ++j;
+ }
+ if (j != i) {
+ // Use rtl_UriDecodeToIuri -> rtl_UriEncodeStrictKeepEscapes instead
+ // of rtl_UriDecodeStrict -> rtl_UriEncodeStrict, so that spurious
+ // non--UTF-8 octets like "%FE" are copied verbatim:
+ rtl::OUString seg(
+ rtl::Uri::encode(
+ rtl::Uri::decode(
+ internalUriReference.copy(i, j - i),
+ rtl_UriDecodeToIuri, RTL_TEXTENCODING_UTF8),
+ rtl_UriCharClassPchar, rtl_UriEncodeStrictKeepEscapes,
+ encoding));
+ if (seg.getLength() == 0) {
+ return rtl::OUString();
+ }
+ buf.append(seg);
+ }
+ if (j == internalUriReference.getLength()) {
+ break;
+ }
+ buf.append(internalUriReference[j]);
+ path = internalUriReference[j] == '/';
+ i = j + 1;
+ }
+ return buf.makeStringAndClear();
+}
+
+}
+
+namespace stoc_services { namespace ExternalUriReferenceTranslator {
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ SAL_THROW((css::uno::Exception))
+{
+ try {
+ return static_cast< cppu::OWeakObject * >(new Translator(context));
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString::createFromAscii("std::bad_alloc"), 0);
+ }
+}
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.uri.ExternalUriReferenceTranslator");
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ css::uno::Sequence< rtl::OUString > s(1);
+ s[0] = rtl::OUString::createFromAscii(
+ "com.sun.star.uri.ExternalUriReferenceTranslator");
+ return s;
+}
+
+} }
diff --git a/stoc/source/uriproc/ExternalUriReferenceTranslator.hxx b/stoc/source/uriproc/ExternalUriReferenceTranslator.hxx
new file mode 100644
index 000000000000..60b17bf39a6f
--- /dev/null
+++ b/stoc/source/uriproc/ExternalUriReferenceTranslator.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_uriproc_ExternalUriReferenceTranslator_hxx
+#define INCLUDED_stoc_source_uriproc_ExternalUriReferenceTranslator_hxx
+
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+ class XInterface;
+} } } }
+namespace rtl { class OUString; }
+
+namespace stoc { namespace uriproc {
+
+namespace ExternalUriReferenceTranslator {
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+ create(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ const & context)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ rtl::OUString SAL_CALL getImplementationName();
+
+ com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames();
+}
+
+} }
+
+#endif
diff --git a/stoc/source/uriproc/UriReference.cxx b/stoc/source/uriproc/UriReference.cxx
new file mode 100644
index 000000000000..12654f4d6b90
--- /dev/null
+++ b/stoc/source/uriproc/UriReference.cxx
@@ -0,0 +1,206 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "UriReference.hxx"
+
+#include "osl/diagnose.h"
+#include "osl/mutex.hxx"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace css = com::sun::star;
+using stoc::uriproc::UriReference;
+
+UriReference::UriReference(
+ rtl::OUString const & scheme, bool bIsHierarchical, bool bHasAuthority,
+ rtl::OUString const & authority, rtl::OUString const & path,
+ bool bHasQuery, rtl::OUString const & query):
+ m_scheme(scheme),
+ m_authority(authority),
+ m_path(path),
+ m_query(query),
+ m_isHierarchical(bIsHierarchical),
+ m_hasAuthority(bHasAuthority),
+ m_hasQuery(bHasQuery),
+ m_hasFragment(false)
+{
+ OSL_ASSERT(scheme.getLength() != 0 || bIsHierarchical);
+ OSL_ASSERT(!bHasAuthority || bIsHierarchical);
+ OSL_ASSERT(authority.getLength() == 0 || bHasAuthority);
+ OSL_ASSERT(!bHasQuery || bIsHierarchical);
+ OSL_ASSERT(query.getLength() == 0 || bHasQuery);
+}
+
+UriReference::~UriReference() {}
+
+rtl::OUString UriReference::getUriReference() throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_mutex);
+ rtl::OUStringBuffer buf;
+ if (m_scheme.getLength() != 0) {
+ buf.append(m_scheme);
+ buf.append(static_cast< sal_Unicode >(':'));
+ }
+ appendSchemeSpecificPart(buf);
+ if (m_hasFragment) {
+ buf.append(static_cast< sal_Unicode >('#'));
+ buf.append(m_fragment);
+ }
+ return buf.makeStringAndClear();
+}
+
+sal_Bool UriReference::isAbsolute() throw (css::uno::RuntimeException) {
+ return m_scheme.getLength() != 0;
+}
+
+rtl::OUString UriReference::getScheme() throw (css::uno::RuntimeException) {
+ return m_scheme;
+}
+
+rtl::OUString UriReference::getSchemeSpecificPart()
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_mutex);
+ rtl::OUStringBuffer buf;
+ appendSchemeSpecificPart(buf);
+ return buf.makeStringAndClear();
+}
+
+sal_Bool UriReference::isHierarchical() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_isHierarchical;
+}
+
+sal_Bool UriReference::hasAuthority() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_hasAuthority;
+}
+
+rtl::OUString UriReference::getAuthority() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_authority;
+}
+
+rtl::OUString UriReference::getPath() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_path;
+}
+
+sal_Bool UriReference::hasRelativePath() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_isHierarchical && !m_hasAuthority
+ && (m_path.getLength() == 0 || m_path[0] != '/');
+}
+
+sal_Int32 UriReference::getPathSegmentCount() throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_mutex);
+ if (!m_isHierarchical || m_path.getLength() == 0) {
+ return 0;
+ } else {
+ sal_Int32 n = m_path[0] == '/' ? 0 : 1;
+ for (sal_Int32 i = 0;; ++i) {
+ i = m_path.indexOf('/', i);
+ if (i < 0) {
+ break;
+ }
+ ++n;
+ }
+ return n;
+ }
+}
+
+rtl::OUString UriReference::getPathSegment(sal_Int32 index)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_mutex);
+ if (m_isHierarchical && m_path.getLength() != 0 && index >= 0) {
+ for (sal_Int32 i = m_path[0] == '/' ? 1 : 0;; ++i) {
+ if (index-- == 0) {
+ sal_Int32 j = m_path.indexOf('/', i);
+ return j < 0 ? m_path.copy(i) : m_path.copy(i, j - i);
+ }
+ i = m_path.indexOf('/', i);
+ if (i < 0) {
+ break;
+ }
+ }
+ }
+ return rtl::OUString();
+}
+
+sal_Bool UriReference::hasQuery() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_hasQuery;
+}
+
+rtl::OUString UriReference::getQuery() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_query;
+}
+
+sal_Bool UriReference::hasFragment() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_hasFragment;
+}
+
+rtl::OUString UriReference::getFragment() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ return m_fragment;
+}
+
+void UriReference::setFragment(rtl::OUString const & fragment)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_mutex);
+ m_hasFragment = true;
+ m_fragment = fragment;
+}
+
+void UriReference::clearFragment() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_mutex);
+ m_hasFragment = false;
+ m_fragment = rtl::OUString();
+}
+
+void UriReference::appendSchemeSpecificPart(rtl::OUStringBuffer & buffer) const
+{
+ if (m_hasAuthority) {
+ buffer.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ buffer.append(m_authority);
+ }
+ buffer.append(m_path);
+ if (m_hasQuery) {
+ buffer.append(static_cast< sal_Unicode >('?'));
+ buffer.append(m_query);
+ }
+}
diff --git a/stoc/source/uriproc/UriReference.hxx b/stoc/source/uriproc/UriReference.hxx
new file mode 100644
index 000000000000..38b8f5518fbf
--- /dev/null
+++ b/stoc/source/uriproc/UriReference.hxx
@@ -0,0 +1,108 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_uriproc_UriReference_hxx
+#define INCLUDED_stoc_source_uriproc_UriReference_hxx
+
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "osl/mutex.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace rtl { class OUStringBuffer; }
+
+namespace stoc { namespace uriproc {
+
+class UriReference {
+public:
+ UriReference(
+ rtl::OUString const & scheme, bool isHierarchical, bool hasAuthority,
+ rtl::OUString const & authority, rtl::OUString const & path,
+ bool hasQuery, rtl::OUString const & query);
+
+ ~UriReference();
+
+ rtl::OUString getUriReference()
+ throw (com::sun::star::uno::RuntimeException);
+
+ sal_Bool isAbsolute() throw (com::sun::star::uno::RuntimeException);
+
+ rtl::OUString getScheme() throw (com::sun::star::uno::RuntimeException);
+
+ rtl::OUString getSchemeSpecificPart()
+ throw (com::sun::star::uno::RuntimeException);
+
+ sal_Bool isHierarchical() throw (com::sun::star::uno::RuntimeException);
+
+ sal_Bool hasAuthority() throw (com::sun::star::uno::RuntimeException);
+
+ rtl::OUString getAuthority() throw (com::sun::star::uno::RuntimeException);
+
+ rtl::OUString getPath() throw (com::sun::star::uno::RuntimeException);
+
+ sal_Bool hasRelativePath() throw (com::sun::star::uno::RuntimeException);
+
+ sal_Int32 getPathSegmentCount()
+ throw (com::sun::star::uno::RuntimeException);
+
+ rtl::OUString getPathSegment(sal_Int32 index)
+ throw (com::sun::star::uno::RuntimeException);
+
+ sal_Bool hasQuery() throw (com::sun::star::uno::RuntimeException);
+
+ rtl::OUString getQuery() throw (com::sun::star::uno::RuntimeException);
+
+ sal_Bool hasFragment() throw (com::sun::star::uno::RuntimeException);
+
+ rtl::OUString getFragment() throw (com::sun::star::uno::RuntimeException);
+
+ void setFragment(rtl::OUString const & fragment)
+ throw (com::sun::star::uno::RuntimeException);
+
+ void clearFragment() throw (com::sun::star::uno::RuntimeException);
+
+ osl::Mutex m_mutex;
+ rtl::OUString m_scheme;
+ rtl::OUString m_authority;
+ rtl::OUString m_path;
+ rtl::OUString m_query;
+ rtl::OUString m_fragment;
+ bool m_isHierarchical;
+ bool m_hasAuthority;
+ bool m_hasQuery;
+ bool m_hasFragment;
+
+private:
+ UriReference(UriReference &); // not implemented
+ void operator =(UriReference); // not implemented
+
+ void appendSchemeSpecificPart(rtl::OUStringBuffer & buffer) const;
+};
+
+} }
+
+#endif
diff --git a/stoc/source/uriproc/UriReferenceFactory.cxx b/stoc/source/uriproc/UriReferenceFactory.cxx
new file mode 100644
index 000000000000..89367ade36cf
--- /dev/null
+++ b/stoc/source/uriproc/UriReferenceFactory.cxx
@@ -0,0 +1,724 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "stocservices.hxx"
+
+#include "UriReference.hxx"
+#include "supportsService.hxx"
+
+#include "com/sun/star/lang/WrappedTargetRuntimeException.hpp"
+#include "com/sun/star/lang/XMultiComponentFactory.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Any.hxx"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uri/RelativeUriExcessParentSegments.hpp"
+#include "com/sun/star/uri/XUriReference.hpp"
+#include "com/sun/star/uri/XUriReferenceFactory.hpp"
+#include "com/sun/star/uri/XUriSchemeParser.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/diagnose.h"
+#include "rtl/string.h"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include <algorithm>
+#include /*MSVC trouble: <cstdlib>*/ <stdlib.h>
+#include <new>
+#include <vector>
+
+namespace css = com::sun::star;
+
+namespace {
+
+bool isDigit(sal_Unicode c) { //TODO: generally available?
+ return c >= '0' && c <= '9';
+}
+
+bool isUpperCase(sal_Unicode c) { //TODO: generally available?
+ return c >= 'A' && c <= 'Z';
+}
+
+bool isLowerCase(sal_Unicode c) { //TODO: generally available?
+ return c >= 'a' && c <= 'z';
+}
+
+bool isAlpha(sal_Unicode c) { //TODO: generally available?
+ return isUpperCase(c) || isLowerCase(c);
+}
+
+bool isHexDigit(sal_Unicode c) { //TODO: generally available?
+ return isDigit(c) || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
+}
+
+sal_Unicode toLowerCase(sal_Unicode c) { //TODO: generally available?
+ return isUpperCase(c) ? c + ('a' - 'A') : c;
+}
+
+bool equalIgnoreCase(sal_Unicode c1, sal_Unicode c2) {
+ //TODO: generally available?
+ return toLowerCase(c1) == toLowerCase(c2);
+}
+
+bool equalIgnoreEscapeCase(rtl::OUString const & s1, rtl::OUString const & s2) {
+ if (s1.getLength() == s2.getLength()) {
+ for (sal_Int32 i = 0; i < s1.getLength();) {
+ if (s1[i] == '%' && s2[i] == '%' && s1.getLength() - i > 2
+ && isHexDigit(s1[i + 1]) && isHexDigit(s1[i + 2])
+ && isHexDigit(s2[i + 1]) && isHexDigit(s2[i + 2])
+ && equalIgnoreCase(s1[i + 1], s2[i + 1])
+ && equalIgnoreCase(s1[i + 2], s2[i + 2]))
+ {
+ i += 3;
+ } else if (s1[i] != s2[i]) {
+ return false;
+ } else {
+ ++i;
+ }
+ }
+ return true;
+ } else {
+ return false;
+ }
+}
+
+sal_Int32 parseScheme(rtl::OUString const & uriReference) {
+ if (uriReference.getLength() >= 2 && isAlpha(uriReference[0])) {
+ for (sal_Int32 i = 0; i < uriReference.getLength(); ++i) {
+ sal_Unicode c = uriReference[i];
+ if (c == ':') {
+ return i;
+ } else if (!isAlpha(c) && !isDigit(c) && c != '+' && c != '-'
+ && c != '.')
+ {
+ break;
+ }
+ }
+ }
+ return -1;
+}
+
+class UriReference: public cppu::WeakImplHelper1< css::uri::XUriReference > {
+public:
+ UriReference(
+ rtl::OUString const & scheme, bool bIsHierarchical, bool bHasAuthority,
+ rtl::OUString const & authority, rtl::OUString const & path,
+ bool bHasQuery, rtl::OUString const & query):
+ m_base(
+ scheme, bIsHierarchical, bHasAuthority, authority, path, bHasQuery,
+ query)
+ {}
+
+ virtual rtl::OUString SAL_CALL getUriReference()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getUriReference(); }
+
+ virtual sal_Bool SAL_CALL isAbsolute()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.isAbsolute(); }
+
+ virtual rtl::OUString SAL_CALL getScheme()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getScheme(); }
+
+ virtual rtl::OUString SAL_CALL getSchemeSpecificPart()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getSchemeSpecificPart(); }
+
+ virtual sal_Bool SAL_CALL isHierarchical()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.isHierarchical(); }
+
+ virtual sal_Bool SAL_CALL hasAuthority()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasAuthority(); }
+
+ virtual rtl::OUString SAL_CALL getAuthority()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getAuthority(); }
+
+ virtual rtl::OUString SAL_CALL getPath()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPath(); }
+
+ virtual sal_Bool SAL_CALL hasRelativePath()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasRelativePath(); }
+
+ virtual sal_Int32 SAL_CALL getPathSegmentCount()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPathSegmentCount(); }
+
+ virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPathSegment(index); }
+
+ virtual sal_Bool SAL_CALL hasQuery()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasQuery(); }
+
+ virtual rtl::OUString SAL_CALL getQuery()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getQuery(); }
+
+ virtual sal_Bool SAL_CALL hasFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasFragment(); }
+
+ virtual rtl::OUString SAL_CALL getFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getFragment(); }
+
+ virtual void SAL_CALL setFragment(rtl::OUString const & fragment)
+ throw (com::sun::star::uno::RuntimeException)
+ { m_base.setFragment(fragment); }
+
+ virtual void SAL_CALL clearFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { m_base.clearFragment(); }
+
+private:
+ UriReference(UriReference &); // not implemented
+ void operator =(UriReference); // not implemented
+
+ virtual ~UriReference() {}
+
+ stoc::uriproc::UriReference m_base;
+};
+
+// throws std::bad_alloc
+css::uno::Reference< css::uri::XUriReference > parseGeneric(
+ rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
+{
+ bool isAbsolute = scheme.getLength() != 0;
+ bool isHierarchical
+ = !isAbsolute
+ || (schemeSpecificPart.getLength() > 0 && schemeSpecificPart[0] == '/');
+ bool hasAuthority = false;
+ rtl::OUString authority;
+ rtl::OUString path;
+ bool hasQuery = false;
+ rtl::OUString query;
+ if (isHierarchical) {
+ sal_Int32 len = schemeSpecificPart.getLength();
+ sal_Int32 i = 0;
+ if (len - i >= 2 && schemeSpecificPart[i] == '/'
+ && schemeSpecificPart[i + 1] == '/')
+ {
+ i += 2;
+ sal_Int32 n = i;
+ while (i < len && schemeSpecificPart[i] != '/'
+ && schemeSpecificPart[i] != '?') {
+ ++i;
+ }
+ hasAuthority = true;
+ authority = schemeSpecificPart.copy(n, i - n);
+ }
+ sal_Int32 n = i;
+ i = schemeSpecificPart.indexOf('?', i);
+ if (i == -1) {
+ i = len;
+ }
+ path = schemeSpecificPart.copy(n, i - n);
+ if (i != len) {
+ hasQuery = true;
+ query = schemeSpecificPart.copy(i + 1);
+ }
+ } else {
+ if (schemeSpecificPart.getLength() == 0) {
+ // The scheme-specific part of an opaque URI must not be empty:
+ return 0;
+ }
+ path = schemeSpecificPart;
+ }
+ return new UriReference(
+ scheme, isHierarchical, hasAuthority, authority, path, hasQuery, query);
+}
+
+typedef std::vector< sal_Int32 > Segments;
+
+void processSegments(
+ Segments & segments,
+ css::uno::Reference< css::uri::XUriReference > const & uriReference,
+ bool base, bool processSpecialSegments)
+{
+ sal_Int32 count = uriReference->getPathSegmentCount() - (base ? 1 : 0);
+ OSL_ASSERT(count <= SAL_MAX_INT32 - 1 && -count >= SAL_MIN_INT32 + 1);
+ for (sal_Int32 i = 0; i < count; ++i) {
+ if (processSpecialSegments) {
+ rtl::OUString segment(uriReference->getPathSegment(i));
+ if (segment.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM("."))) {
+ if (!base && i == count - 1) {
+ segments.push_back(0);
+ }
+ continue;
+ } else if (segment.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".."))) {
+ if (segments.empty()
+ || /*MSVC trouble: std::*/abs(segments.back()) == 1)
+ {
+ segments.push_back(base ? -1 : 1);
+ } else {
+ segments.pop_back();
+ }
+ continue;
+ }
+ }
+ segments.push_back(base ? -(i + 2) : i + 2);
+ }
+}
+
+class Factory: public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::uri::XUriReferenceFactory >
+{
+public:
+ explicit Factory(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ m_context(context) {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
+ parse(rtl::OUString const & uriReference)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
+ makeAbsolute(
+ css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
+ css::uno::Reference< css::uri::XUriReference > const & uriReference,
+ sal_Bool processSpecialBaseSegments,
+ css::uri::RelativeUriExcessParentSegments excessParentSegments)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
+ makeRelative(
+ css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
+ css::uno::Reference< css::uri::XUriReference > const & uriReference,
+ sal_Bool preferAuthorityOverRelativePath,
+ sal_Bool preferAbsoluteOverRelativePath,
+ sal_Bool encodeRetainedSpecialSegments)
+ throw (css::uno::RuntimeException);
+
+private:
+ Factory(Factory &); // not implemented
+ void operator =(Factory); // not implemented
+
+ virtual ~Factory() {}
+
+ css::uno::Reference< css::uri::XUriReference > clone(
+ css::uno::Reference< css::uri::XUriReference > const & uriReference)
+ { return parse(uriReference->getUriReference()); }
+
+ css::uno::Reference< css::uno::XComponentContext > m_context;
+};
+
+rtl::OUString Factory::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::UriReferenceFactory::getImplementationName();
+}
+
+sal_Bool Factory::supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ return stoc::uriproc::supportsService(
+ getSupportedServiceNames(), serviceName);
+}
+
+css::uno::Sequence< rtl::OUString > Factory::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::UriReferenceFactory::getSupportedServiceNames();
+}
+
+css::uno::Reference< css::uri::XUriReference > Factory::parse(
+ rtl::OUString const & uriReference) throw (css::uno::RuntimeException)
+{
+ sal_Int32 fragment = uriReference.indexOf('#');
+ if (fragment == -1) {
+ fragment = uriReference.getLength();
+ }
+ rtl::OUString scheme;
+ rtl::OUString schemeSpecificPart;
+ rtl::OUString serviceName;
+ sal_Int32 n = parseScheme(uriReference);
+ OSL_ASSERT(n < fragment);
+ if (n >= 0) {
+ scheme = uriReference.copy(0, n);
+ schemeSpecificPart = uriReference.copy(n + 1, fragment - (n + 1));
+ rtl::OUStringBuffer buf;
+ buf.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("com.sun.star.uri.UriSchemeParser_"));
+ for (sal_Int32 i = 0; i < scheme.getLength(); ++i) {
+ sal_Unicode c = scheme[i];
+ if (isUpperCase(c)) {
+ buf.append(toLowerCase(c));
+ } else if (c == '+') {
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("PLUS"));
+ } else if (c == '-') {
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("HYPHEN"));
+ } else if (c == '.') {
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("DOT"));
+ } else {
+ OSL_ASSERT(isLowerCase(c) || isDigit(c));
+ buf.append(c);
+ }
+ }
+ serviceName = buf.makeStringAndClear();
+ } else {
+ schemeSpecificPart = uriReference.copy(0, fragment);
+ }
+ css::uno::Reference< css::uri::XUriSchemeParser > parser;
+ if (serviceName.getLength() != 0) {
+ css::uno::Reference< css::lang::XMultiComponentFactory > factory(
+ m_context->getServiceManager());
+ if (factory.is()) {
+ css::uno::Reference< css::uno::XInterface > service;
+ try {
+ service = factory->createInstanceWithContext(
+ serviceName, m_context);
+ } catch (css::uno::RuntimeException &) {
+ throw;
+ } catch (css::uno::Exception & e) {
+ throw css::lang::WrappedTargetRuntimeException(
+ rtl::OUString::createFromAscii("creating service ")
+ + serviceName,
+ static_cast< cppu::OWeakObject * >(this),
+ css::uno::makeAny(e)); //TODO: preserve type of e
+ }
+ if (service.is()) {
+ parser = css::uno::Reference< css::uri::XUriSchemeParser >(
+ service, css::uno::UNO_QUERY_THROW);
+ }
+ }
+ }
+ css::uno::Reference< css::uri::XUriReference > uriRef;
+ if (parser.is()) {
+ uriRef = parser->parse(scheme, schemeSpecificPart);
+ } else {
+ try {
+ uriRef = parseGeneric(scheme, schemeSpecificPart);
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString::createFromAscii("std::bad_alloc"),
+ static_cast< cppu::OWeakObject * >(this));
+ }
+ }
+ if (uriRef.is() && fragment != uriReference.getLength()) {
+ uriRef->setFragment(uriReference.copy(fragment + 1));
+ }
+ return uriRef;
+}
+
+css::uno::Reference< css::uri::XUriReference > Factory::makeAbsolute(
+ css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
+ css::uno::Reference< css::uri::XUriReference > const & uriReference,
+ sal_Bool processSpecialBaseSegments,
+ css::uri::RelativeUriExcessParentSegments excessParentSegments)
+ throw (css::uno::RuntimeException)
+{
+ if (!baseUriReference.is() || !baseUriReference->isAbsolute()
+ || !baseUriReference->isHierarchical() || !uriReference.is()) {
+ return 0;
+ } else if (uriReference->isAbsolute()) {
+ return clone(uriReference);
+ } else if (!uriReference->hasAuthority()
+ && uriReference->getPath().getLength() == 0
+ && !uriReference->hasQuery()) {
+ css::uno::Reference< css::uri::XUriReference > abs(
+ clone(baseUriReference));
+ if (uriReference->hasFragment()) {
+ abs->setFragment(uriReference->getFragment());
+ } else {
+ abs->clearFragment();
+ }
+ return abs;
+ } else {
+ rtl::OUStringBuffer abs(baseUriReference->getScheme());
+ abs.append(static_cast< sal_Unicode >(':'));
+ if (uriReference->hasAuthority()) {
+ abs.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ abs.append(uriReference->getAuthority());
+ } else if (baseUriReference->hasAuthority()) {
+ abs.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ abs.append(baseUriReference->getAuthority());
+ }
+ if (uriReference->hasRelativePath()) {
+ Segments segments;
+ processSegments(
+ segments, baseUriReference, true, processSpecialBaseSegments);
+ processSegments(segments, uriReference, false, true);
+ // If the path component of the base URI reference is empty (which
+ // implies that the base URI reference denotes a "root entity"), and
+ // the resulting URI reference denotes the same root entity, make
+ // sure the path component of the resulting URI reference is also
+ // empty (and not "/"). RFC 2396 is unclear about this, and I chose
+ // these rules for consistent results.
+ bool slash = baseUriReference->getPath().getLength() != 0;
+ if (slash) {
+ abs.append(static_cast< sal_Unicode >('/'));
+ }
+ for (Segments::iterator i(segments.begin()); i != segments.end();
+ ++i)
+ {
+ if (*i < -1) {
+ rtl::OUString segment(
+ baseUriReference->getPathSegment(-(*i + 2)));
+ if (segment.getLength() != 0 || segments.size() > 1) {
+ if (!slash) {
+ abs.append(static_cast< sal_Unicode >('/'));
+ }
+ abs.append(segment);
+ slash = true;
+ abs.append(static_cast< sal_Unicode >('/'));
+ }
+ } else if (*i > 1) {
+ rtl::OUString segment(uriReference->getPathSegment(*i - 2));
+ if (segment.getLength() != 0 || segments.size() > 1) {
+ if (!slash) {
+ abs.append(static_cast< sal_Unicode >('/'));
+ }
+ abs.append(segment);
+ slash = false;
+ }
+ } else if (*i == 0) {
+ if (segments.size() > 1 && !slash) {
+ abs.append(static_cast< sal_Unicode >('/'));
+ }
+ } else {
+ switch (excessParentSegments) {
+ case css::uri::RelativeUriExcessParentSegments_ERROR:
+ return 0;
+
+ case css::uri::RelativeUriExcessParentSegments_RETAIN:
+ if (!slash) {
+ abs.append(static_cast< sal_Unicode >('/'));
+ }
+ abs.appendAscii(RTL_CONSTASCII_STRINGPARAM(".."));
+ slash = *i < 0;
+ if (slash) {
+ abs.append(static_cast< sal_Unicode >('/'));
+ }
+ break;
+
+ case css::uri::RelativeUriExcessParentSegments_REMOVE:
+ break;
+
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ }
+ }
+ } else {
+ abs.append(uriReference->getPath());
+ }
+ if (uriReference->hasQuery()) {
+ abs.append(static_cast< sal_Unicode >('?'));
+ abs.append(uriReference->getQuery());
+ }
+ if (uriReference->hasFragment()) {
+ abs.append(static_cast< sal_Unicode >('#'));
+ abs.append(uriReference->getFragment());
+ }
+ return parse(abs.makeStringAndClear());
+ }
+}
+
+css::uno::Reference< css::uri::XUriReference > Factory::makeRelative(
+ css::uno::Reference< css::uri::XUriReference > const & baseUriReference,
+ css::uno::Reference< css::uri::XUriReference > const & uriReference,
+ sal_Bool preferAuthorityOverRelativePath,
+ sal_Bool preferAbsoluteOverRelativePath,
+ sal_Bool encodeRetainedSpecialSegments)
+ throw (css::uno::RuntimeException)
+{
+ if (!baseUriReference.is() || !baseUriReference->isAbsolute()
+ || !baseUriReference->isHierarchical() || !uriReference.is()) {
+ return 0;
+ } else if (!uriReference->isAbsolute() || !uriReference->isHierarchical()
+ || !baseUriReference->getScheme().equalsIgnoreAsciiCase(
+ uriReference->getScheme())) {
+ return clone(uriReference);
+ } else {
+ rtl::OUStringBuffer rel;
+ bool omitQuery = false;
+ if ((baseUriReference->hasAuthority() != uriReference->hasAuthority())
+ || !equalIgnoreEscapeCase(
+ baseUriReference->getAuthority(),
+ uriReference->getAuthority()))
+ {
+ if (uriReference->hasAuthority()) {
+ rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ rel.append(uriReference->getAuthority());
+ }
+ rel.append(uriReference->getPath());
+ } else if ((equalIgnoreEscapeCase(
+ baseUriReference->getPath(), uriReference->getPath())
+ || (baseUriReference->getPath().getLength() <= 1
+ && uriReference->getPath().getLength() <= 1))
+ && baseUriReference->hasQuery() == uriReference->hasQuery()
+ && equalIgnoreEscapeCase(
+ baseUriReference->getQuery(), uriReference->getQuery()))
+ {
+ omitQuery = true;
+ } else {
+ sal_Int32 count1 = std::max< sal_Int32 >(
+ baseUriReference->getPathSegmentCount(), 1);
+ sal_Int32 count2 = std::max< sal_Int32 >(
+ uriReference->getPathSegmentCount(), 1);
+ sal_Int32 i = 0;
+ for (; i < std::min(count1, count2) - 1; ++i) {
+ if (!equalIgnoreEscapeCase(
+ baseUriReference->getPathSegment(i),
+ uriReference->getPathSegment(i)))
+ {
+ break;
+ }
+ }
+ if (i == 0 && preferAbsoluteOverRelativePath
+ && (preferAuthorityOverRelativePath
+ || !uriReference->getPath().matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("//"))))
+ {
+ if (baseUriReference->getPath().getLength() > 1
+ || uriReference->getPath().getLength() > 1)
+ {
+ if (uriReference->getPath().getLength() == 0) {
+ rel.append(static_cast< sal_Unicode >('/'));
+ } else {
+ OSL_ASSERT(uriReference->getPath()[0] == '/');
+ if (uriReference->getPath().matchAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("//"))) {
+ OSL_ASSERT(uriReference->hasAuthority());
+ rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("//"));
+ rel.append(uriReference->getAuthority());
+ }
+ rel.append(uriReference->getPath());
+ }
+ }
+ } else {
+ bool segments = false;
+ for (sal_Int32 j = i; j < count1 - 1; ++j) {
+ if (segments) {
+ rel.append(static_cast< sal_Unicode >('/'));
+ }
+ rel.appendAscii(RTL_CONSTASCII_STRINGPARAM(".."));
+ segments = true;
+ }
+ if (i < count2 - 1
+ || (uriReference->getPathSegment(count2 - 1).getLength()
+ != 0))
+ {
+ if (!segments
+ && (uriReference->getPathSegment(i).getLength() == 0
+ || (parseScheme(uriReference->getPathSegment(i))
+ >= 0)))
+ {
+ rel.append(static_cast< sal_Unicode >('.'));
+ segments = true;
+ }
+ for (; i < count2; ++i) {
+ if (segments) {
+ rel.append(static_cast< sal_Unicode >('/'));
+ }
+ rtl::OUString s(uriReference->getPathSegment(i));
+ if (encodeRetainedSpecialSegments
+ && s.equalsAsciiL(RTL_CONSTASCII_STRINGPARAM(".")))
+ {
+ rel.appendAscii(RTL_CONSTASCII_STRINGPARAM("%2E"));
+ } else if (encodeRetainedSpecialSegments
+ && s.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("..")))
+ {
+ rel.appendAscii(
+ RTL_CONSTASCII_STRINGPARAM("%2E%2E"));
+ } else {
+ rel.append(s);
+ }
+ segments = true;
+ }
+ }
+ }
+ }
+ if (!omitQuery && uriReference->hasQuery()) {
+ rel.append(static_cast< sal_Unicode >('?'));
+ rel.append(uriReference->getQuery());
+ }
+ if (uriReference->hasFragment()) {
+ rel.append(static_cast< sal_Unicode >('#'));
+ rel.append(uriReference->getFragment());
+ }
+ return parse(rel.makeStringAndClear());
+ }
+}
+
+}
+
+namespace stoc_services { namespace UriReferenceFactory {
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ SAL_THROW((css::uno::Exception))
+{
+ try {
+ return static_cast< cppu::OWeakObject * >(new Factory(context));
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString::createFromAscii("std::bad_alloc"), 0);
+ }
+}
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.uri.UriReferenceFactory");
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ css::uno::Sequence< rtl::OUString > s(1);
+ s[0] = rtl::OUString::createFromAscii(
+ "com.sun.star.uri.UriReferenceFactory");
+ return s;
+}
+
+} }
diff --git a/stoc/source/uriproc/UriReferenceFactory.hxx b/stoc/source/uriproc/UriReferenceFactory.hxx
new file mode 100644
index 000000000000..0aca96fce962
--- /dev/null
+++ b/stoc/source/uriproc/UriReferenceFactory.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_uriproc_UriReferenceFactory_hxx
+#define INCLUDED_stoc_source_uriproc_UriReferenceFactory_hxx
+
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+ class XInterface;
+} } } }
+namespace rtl { class OUString; }
+
+namespace stoc { namespace uriproc {
+
+namespace UriReferenceFactory {
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+ create(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ const & context)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ rtl::OUString SAL_CALL getImplementationName();
+
+ com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames();
+}
+
+} }
+
+#endif
diff --git a/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.cxx b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.cxx
new file mode 100644
index 000000000000..a84a1200c953
--- /dev/null
+++ b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.cxx
@@ -0,0 +1,268 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "sal/config.h"
+
+#include "stocservices.hxx"
+
+#include <new>
+
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uri/XUriReference.hpp"
+#include "com/sun/star/uri/XUriSchemeParser.hpp"
+#include "com/sun/star/uri/XVndSunStarExpandUrlReference.hpp"
+#include "com/sun/star/util/XMacroExpander.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "rtl/textenc.h"
+#include "rtl/uri.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustring.h"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include "UriReference.hxx"
+#include "supportsService.hxx"
+
+namespace {
+
+namespace css = ::com::sun::star;
+
+bool parseSchemeSpecificPart(::rtl::OUString const & part) {
+ // Liberally accepts both an empty opaque_part and an opaque_part that
+ // starts with a non-escaped "/":
+ return part.getLength() == 0
+ || ((::rtl::Uri::decode(
+ part, ::rtl_UriDecodeStrict, RTL_TEXTENCODING_UTF8).
+ getLength())
+ != 0);
+}
+
+class UrlReference:
+ public ::cppu::WeakImplHelper1< css::uri::XVndSunStarExpandUrlReference >
+{
+public:
+ UrlReference(::rtl::OUString const & scheme, ::rtl::OUString const & path):
+ base_(
+ scheme, false, false, ::rtl::OUString(), path, false,
+ ::rtl::OUString())
+ {}
+
+ virtual ::rtl::OUString SAL_CALL getUriReference()
+ throw (css::uno::RuntimeException)
+ { return base_.getUriReference(); }
+
+ virtual ::sal_Bool SAL_CALL isAbsolute() throw (css::uno::RuntimeException)
+ { return base_.isAbsolute(); }
+
+ virtual ::rtl::OUString SAL_CALL getScheme()
+ throw (css::uno::RuntimeException)
+ { return base_.getScheme(); }
+
+ virtual ::rtl::OUString SAL_CALL getSchemeSpecificPart()
+ throw (css::uno::RuntimeException)
+ { return base_.getSchemeSpecificPart(); }
+
+ virtual ::sal_Bool SAL_CALL isHierarchical()
+ throw (css::uno::RuntimeException)
+ { return base_.isHierarchical(); }
+
+ virtual ::sal_Bool SAL_CALL hasAuthority()
+ throw (css::uno::RuntimeException)
+ { return base_.hasAuthority(); }
+
+ virtual ::rtl::OUString SAL_CALL getAuthority()
+ throw (css::uno::RuntimeException)
+ { return base_.getAuthority(); }
+
+ virtual ::rtl::OUString SAL_CALL getPath()
+ throw (css::uno::RuntimeException)
+ { return base_.getPath(); }
+
+ virtual ::sal_Bool SAL_CALL hasRelativePath()
+ throw (css::uno::RuntimeException)
+ { return base_.hasRelativePath(); }
+
+ virtual ::sal_Int32 SAL_CALL getPathSegmentCount()
+ throw (css::uno::RuntimeException)
+ { return base_.getPathSegmentCount(); }
+
+ virtual ::rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
+ throw (css::uno::RuntimeException)
+ { return base_.getPathSegment(index); }
+
+ virtual ::sal_Bool SAL_CALL hasQuery() throw (css::uno::RuntimeException)
+ { return base_.hasQuery(); }
+
+ virtual ::rtl::OUString SAL_CALL getQuery()
+ throw (css::uno::RuntimeException)
+ { return base_.getQuery(); }
+
+ virtual ::sal_Bool SAL_CALL hasFragment() throw (css::uno::RuntimeException)
+ { return base_.hasFragment(); }
+
+ virtual ::rtl::OUString SAL_CALL getFragment()
+ throw (css::uno::RuntimeException)
+ { return base_.getFragment(); }
+
+ virtual void SAL_CALL setFragment(::rtl::OUString const & fragment)
+ throw (css::uno::RuntimeException)
+ { base_.setFragment(fragment); }
+
+ virtual void SAL_CALL clearFragment() throw (css::uno::RuntimeException)
+ { base_.clearFragment(); }
+
+ virtual ::rtl::OUString SAL_CALL expand(
+ css::uno::Reference< css::util::XMacroExpander > const & expander)
+ throw (css::lang::IllegalArgumentException, css::uno::RuntimeException);
+
+private:
+ UrlReference(UrlReference &); // not defined
+ void operator =(UrlReference); // not defined
+
+ virtual ~UrlReference() {}
+
+ stoc::uriproc::UriReference base_;
+};
+
+::rtl::OUString UrlReference::expand(
+ css::uno::Reference< css::util::XMacroExpander > const & expander)
+ throw (css::lang::IllegalArgumentException, css::uno::RuntimeException)
+{
+ OSL_ASSERT(expander.is());
+ return expander->expandMacros(
+ ::rtl::Uri::decode(
+ getPath(), ::rtl_UriDecodeWithCharset, RTL_TEXTENCODING_UTF8));
+}
+
+class Parser: public ::cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::uri::XUriSchemeParser >
+{
+public:
+ Parser() {}
+
+ virtual ::rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual ::sal_Bool SAL_CALL supportsService(
+ ::rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
+ parse(
+ ::rtl::OUString const & scheme,
+ ::rtl::OUString const & schemeSpecificPart)
+ throw (css::uno::RuntimeException);
+
+private:
+ Parser(Parser &); // not defined
+ void operator =(Parser); // not defined
+
+ virtual ~Parser() {}
+};
+
+::rtl::OUString Parser::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return ::stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTexpand::
+ getImplementationName();
+}
+
+::sal_Bool Parser::supportsService(::rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ return ::stoc::uriproc::supportsService(
+ getSupportedServiceNames(), serviceName);
+}
+
+css::uno::Sequence< ::rtl::OUString > Parser::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return ::stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTexpand::
+ getSupportedServiceNames();
+}
+
+css::uno::Reference< css::uri::XUriReference > Parser::parse(
+ ::rtl::OUString const & scheme, ::rtl::OUString const & schemeSpecificPart)
+ throw (css::uno::RuntimeException)
+{
+ if (!parseSchemeSpecificPart(schemeSpecificPart)) {
+ return css::uno::Reference< css::uri::XUriReference >();
+ }
+ try {
+ return new UrlReference(scheme, schemeSpecificPart);
+ } catch (::std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("std::bad_alloc")),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+}
+
+namespace stoc_services { namespace UriSchemeParser_vndDOTsunDOTstarDOTexpand {
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const &)
+ SAL_THROW((css::uno::Exception))
+{
+ //TODO: single instance
+ try {
+ return static_cast< ::cppu::OWeakObject * >(new Parser);
+ } catch (::std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("std::bad_alloc")),
+ css::uno::Reference< css::uno::XInterface >());
+ }
+}
+
+::rtl::OUString getImplementationName() {
+ return ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTexpand"));
+}
+
+css::uno::Sequence< ::rtl::OUString > getSupportedServiceNames() {
+ css::uno::Sequence< ::rtl::OUString > s(1);
+ s[0] = ::rtl::OUString(
+ RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTexpand"));
+ return s;
+}
+
+} }
diff --git a/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.hxx b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.hxx
new file mode 100644
index 000000000000..2008b7ba82e3
--- /dev/null
+++ b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTexpand.hxx
@@ -0,0 +1,62 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef \
+ INCLUDED_STOC_SOURCE_URIPROC_URISCHEMEPARSER_VNDDOTSUNDOTSTARDOTEXPAND_HXX
+#define \
+ INCLUDED_STOC_SOURCE_URIPROC_URISCHEMEPARSER_VNDDOTSUNDOTSTARDOTEXPAND_HXX
+
+#include "sal/config.h"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+ class XInterface;
+} } } }
+namespace rtl { class OUString; }
+
+namespace stoc { namespace uriproc {
+
+namespace UriSchemeParser_vndDOTsunDOTstarDOTexpand {
+ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >
+ SAL_CALL create(
+ ::com::sun::star::uno::Reference<
+ ::com::sun::star::uno::XComponentContext > const &)
+ SAL_THROW((::com::sun::star::uno::Exception));
+
+ ::rtl::OUString SAL_CALL getImplementationName();
+
+ ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
+ getSupportedServiceNames();
+}
+
+} }
+
+#endif
diff --git a/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
new file mode 100644
index 000000000000..512f18a114ab
--- /dev/null
+++ b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.cxx
@@ -0,0 +1,485 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "stocservices.hxx"
+
+#include "UriReference.hxx"
+#include "supportsService.hxx"
+
+#include "com/sun/star/lang/IllegalArgumentException.hpp"
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uri/XUriReference.hpp"
+#include "com/sun/star/uri/XUriSchemeParser.hpp"
+#include "com/sun/star/uri/XVndSunStarScriptUrlReference.hpp"
+#include "cppuhelper/implbase1.hxx"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "osl/mutex.hxx"
+#include "rtl/uri.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include <new>
+
+namespace css = com::sun::star;
+
+namespace {
+
+int getHexWeight(sal_Unicode c) {
+ return c >= '0' && c <= '9' ? static_cast< int >(c - '0')
+ : c >= 'A' && c <= 'F' ? static_cast< int >(c - 'A' + 10)
+ : c >= 'a' && c <= 'f' ? static_cast< int >(c - 'a' + 10)
+ : -1;
+}
+
+int parseEscaped(rtl::OUString const & part, sal_Int32 * index) {
+ if (part.getLength() - *index < 3 || part[*index] != '%') {
+ return -1;
+ }
+ int n1 = getHexWeight(part[*index + 1]);
+ int n2 = getHexWeight(part[*index + 2]);
+ if (n1 < 0 || n2 < 0) {
+ return -1;
+ }
+ *index += 3;
+ return (n1 << 4) | n2;
+}
+
+rtl::OUString parsePart(
+ rtl::OUString const & part, bool namePart, sal_Int32 * index)
+{
+ rtl::OUStringBuffer buf;
+ while (*index < part.getLength()) {
+ sal_Unicode c = part[*index];
+ if (namePart ? c == '?' : c == '&' || c == '=') {
+ break;
+ } else if (c == '%') {
+ sal_Int32 i = *index;
+ int n = parseEscaped(part, &i);
+ if (n >= 0 && n <= 0x7F) {
+ buf.append(static_cast< sal_Unicode >(n));
+ } else if (n >= 0xC0 && n <= 0xFC) {
+ sal_Int32 encoded;
+ int shift;
+ sal_Int32 min;
+ if (n <= 0xDF) {
+ encoded = (n & 0x1F) << 6;
+ shift = 0;
+ min = 0x80;
+ } else if (n <= 0xEF) {
+ encoded = (n & 0x0F) << 12;
+ shift = 6;
+ min = 0x800;
+ } else if (n <= 0xF7) {
+ encoded = (n & 0x07) << 18;
+ shift = 12;
+ min = 0x10000;
+ } else if (n <= 0xFB) {
+ encoded = (n & 0x03) << 24;
+ shift = 18;
+ min = 0x200000;
+ } else {
+ encoded = 0;
+ shift = 24;
+ min = 0x4000000;
+ }
+ bool utf8 = true;
+ for (; shift >= 0; shift -= 6) {
+ n = parseEscaped(part, &i);
+ if (n < 0x80 || n > 0xBF) {
+ utf8 = false;
+ break;
+ }
+ encoded |= (n & 0x3F) << shift;
+ }
+ if (!utf8 || encoded < min
+ || (encoded >= 0xD800 && encoded <= 0xDFFF)
+ || encoded > 0x10FFFF)
+ {
+ break;
+ }
+ if (encoded <= 0xFFFF) {
+ buf.append(static_cast< sal_Unicode >(encoded));
+ } else {
+ buf.append(static_cast< sal_Unicode >(
+ (encoded >> 10) | 0xD800));
+ buf.append(static_cast< sal_Unicode >(
+ (encoded & 0x3FF) | 0xDC00));
+ }
+ } else {
+ break;
+ }
+ *index = i;
+ } else {
+ buf.append(c);
+ ++*index;
+ }
+ }
+ return buf.makeStringAndClear();
+}
+
+namespace
+{
+ static rtl::OUString encodeNameOrParamFragment( rtl::OUString const & fragment )
+ {
+ static sal_Bool const aCharClass[] =
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* NameOrParamFragment */
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* !"#$%&'()*+,-./*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, /*0123456789:;<=>?*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*@ABCDEFGHIJKLMNO*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, /*PQRSTUVWXYZ[\]^_*/
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*`abcdefghijklmno*/
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0 /*pqrstuvwxyz{|}~ */
+ };
+
+ return rtl::Uri::encode(
+ fragment,
+ aCharClass,
+ rtl_UriEncodeIgnoreEscapes,
+ RTL_TEXTENCODING_UTF8
+ );
+ }
+}
+
+bool parseSchemeSpecificPart(rtl::OUString const & part) {
+ sal_Int32 len = part.getLength();
+ sal_Int32 i = 0;
+ if (parsePart(part, true, &i).getLength() == 0 || part[0] == '/') {
+ return false;
+ }
+ if (i == len) {
+ return true;
+ }
+ for (;;) {
+ ++i; // skip '?' or '&'
+ if (parsePart(part, false, &i).getLength() == 0 || i == len
+ || part[i] != '=')
+ {
+ return false;
+ }
+ ++i;
+ parsePart(part, false, &i);
+ if (i == len) {
+ return true;
+ }
+ if (part[i] != '&') {
+ return false;
+ }
+ }
+}
+
+class UrlReference:
+ public cppu::WeakImplHelper1< css::uri::XVndSunStarScriptUrlReference >
+{
+public:
+ UrlReference(rtl::OUString const & scheme, rtl::OUString const & path):
+ m_base(
+ scheme, false, false, rtl::OUString(), path, false, rtl::OUString())
+ {}
+
+ virtual rtl::OUString SAL_CALL getUriReference()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getUriReference(); }
+
+ virtual sal_Bool SAL_CALL isAbsolute()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.isAbsolute(); }
+
+ virtual rtl::OUString SAL_CALL getScheme()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getScheme(); }
+
+ virtual rtl::OUString SAL_CALL getSchemeSpecificPart()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getSchemeSpecificPart(); }
+
+ virtual sal_Bool SAL_CALL isHierarchical()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.isHierarchical(); }
+
+ virtual sal_Bool SAL_CALL hasAuthority()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasAuthority(); }
+
+ virtual rtl::OUString SAL_CALL getAuthority()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getAuthority(); }
+
+ virtual rtl::OUString SAL_CALL getPath()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPath(); }
+
+ virtual sal_Bool SAL_CALL hasRelativePath()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasRelativePath(); }
+
+ virtual sal_Int32 SAL_CALL getPathSegmentCount()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPathSegmentCount(); }
+
+ virtual rtl::OUString SAL_CALL getPathSegment(sal_Int32 index)
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getPathSegment(index); }
+
+ virtual sal_Bool SAL_CALL hasQuery()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasQuery(); }
+
+ virtual rtl::OUString SAL_CALL getQuery()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getQuery(); }
+
+ virtual sal_Bool SAL_CALL hasFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.hasFragment(); }
+
+ virtual rtl::OUString SAL_CALL getFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { return m_base.getFragment(); }
+
+ virtual void SAL_CALL setFragment(rtl::OUString const & fragment)
+ throw (com::sun::star::uno::RuntimeException)
+ { m_base.setFragment(fragment); }
+
+ virtual void SAL_CALL clearFragment()
+ throw (com::sun::star::uno::RuntimeException)
+ { m_base.clearFragment(); }
+
+ virtual rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setName(rtl::OUString const & name)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
+
+ virtual sal_Bool SAL_CALL hasParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException);
+
+ virtual rtl::OUString SAL_CALL getParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException);
+
+ virtual void SAL_CALL setParameter(rtl::OUString const & key, rtl::OUString const & value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException);
+
+private:
+ UrlReference(UrlReference &); // not implemented
+ void operator =(UrlReference); // not implemented
+
+ virtual ~UrlReference() {}
+
+ sal_Int32 findParameter(rtl::OUString const & key);
+
+ stoc::uriproc::UriReference m_base;
+};
+
+rtl::OUString UrlReference::getName() throw (css::uno::RuntimeException) {
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = 0;
+ return parsePart(m_base.m_path, true, &i);
+}
+
+void SAL_CALL UrlReference::setName(rtl::OUString const & name) throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
+{
+ if (name.getLength() == 0)
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(), *this, 1);
+
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = 0;
+ parsePart(m_base.m_path, true, &i);
+
+ rtl::OUStringBuffer newPath;
+ newPath.append(encodeNameOrParamFragment(name));
+ newPath.append(m_base.m_path.copy(i));
+ m_base.m_path = newPath.makeStringAndClear();
+}
+
+sal_Bool UrlReference::hasParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_base.m_mutex);
+ return findParameter(key) >= 0;
+}
+
+rtl::OUString UrlReference::getParameter(rtl::OUString const & key)
+ throw (css::uno::RuntimeException)
+{
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = findParameter(key);
+ return i >= 0 ? parsePart(m_base.m_path, false, &i) : rtl::OUString();
+}
+
+void UrlReference::setParameter(rtl::OUString const & key, rtl::OUString const & value)
+ throw (css::uno::RuntimeException, css::lang::IllegalArgumentException)
+{
+ if (key.getLength() == 0)
+ throw css::lang::IllegalArgumentException(
+ ::rtl::OUString(), *this, 1);
+
+ osl::MutexGuard g(m_base.m_mutex);
+ sal_Int32 i = findParameter(key);
+ bool bExistent = ( i>=0 );
+ if (!bExistent) {
+ i = m_base.m_path.getLength();
+ }
+
+ rtl::OUStringBuffer newPath;
+ newPath.append(m_base.m_path.copy(0, i));
+ if (!bExistent) {
+ newPath.append(sal_Unicode(m_base.m_path.indexOf('?') < 0 ? '?' : '&'));
+ newPath.append(encodeNameOrParamFragment(key));
+ newPath.append(sal_Unicode('='));
+ }
+ newPath.append(encodeNameOrParamFragment(value));
+ if (bExistent) {
+ /*oldValue = */
+ parsePart(m_base.m_path, false, &i); // skip key
+ newPath.append(m_base.m_path.copy(i));
+ }
+
+ m_base.m_path = newPath.makeStringAndClear();
+}
+
+sal_Int32 UrlReference::findParameter(rtl::OUString const & key) {
+ sal_Int32 i = 0;
+ parsePart(m_base.m_path, true, &i); // skip name
+ for (;;) {
+ if (i == m_base.m_path.getLength()) {
+ return -1;
+ }
+ ++i; // skip '?' or '&'
+ rtl::OUString k = parsePart(m_base.m_path, false, &i);
+ ++i; // skip '='
+ if (k == key) {
+ return i;
+ }
+ parsePart(m_base.m_path, false, &i); // skip value
+ }
+}
+
+class Parser: public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::uri::XUriSchemeParser >
+{
+public:
+ Parser() {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
+ parse(
+ rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
+ throw (css::uno::RuntimeException);
+
+private:
+ Parser(Parser &); // not implemented
+ void operator =(Parser); // not implemented
+
+ virtual ~Parser() {}
+};
+
+rtl::OUString Parser::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTscript::
+ getImplementationName();
+}
+
+sal_Bool Parser::supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ return stoc::uriproc::supportsService(
+ getSupportedServiceNames(), serviceName);
+}
+
+css::uno::Sequence< rtl::OUString > Parser::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::UriSchemeParser_vndDOTsunDOTstarDOTscript::
+ getSupportedServiceNames();
+}
+
+css::uno::Reference< css::uri::XUriReference >
+Parser::parse(
+ rtl::OUString const & scheme, rtl::OUString const & schemeSpecificPart)
+ throw (css::uno::RuntimeException)
+{
+ if (!parseSchemeSpecificPart(schemeSpecificPart)) {
+ return 0;
+ }
+ try {
+ return new UrlReference(scheme, schemeSpecificPart);
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString::createFromAscii("std::bad_alloc"), 0);
+ }
+}
+
+}
+
+namespace stoc_services {
+namespace UriSchemeParser_vndDOTsunDOTstarDOTscript {
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const &)
+ SAL_THROW((css::uno::Exception))
+{
+ //TODO: single instance
+ try {
+ return static_cast< cppu::OWeakObject * >(new Parser);
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString::createFromAscii("std::bad_alloc"), 0);
+ }
+}
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ css::uno::Sequence< rtl::OUString > s(1);
+ s[0] = rtl::OUString::createFromAscii(
+ "com.sun.star.uri.UriSchemeParser_vndDOTsunDOTstarDOTscript");
+ return s;
+}
+
+} }
diff --git a/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.hxx b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.hxx
new file mode 100644
index 000000000000..00c39ef0e0be
--- /dev/null
+++ b/stoc/source/uriproc/UriSchemeParser_vndDOTsunDOTstarDOTscript.hxx
@@ -0,0 +1,61 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef \
+ INCLUDED_stoc_source_uriproc_UriSchemeParser_vndDOTsunDOTstarDOTscript_hxx
+#define \
+ INCLUDED_stoc_source_uriproc_UriSchemeParser_vndDOTsunDOTstarDOTscript_hxx
+
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+ class XInterface;
+} } } }
+namespace rtl { class OUString; }
+
+namespace stoc { namespace uriproc {
+
+namespace UriSchemeParser_vndDOTsunDOTstarDOTscript {
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+ create(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ const &)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ rtl::OUString SAL_CALL getImplementationName();
+
+ com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames();
+}
+
+} }
+
+#endif
diff --git a/stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.cxx b/stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.cxx
new file mode 100644
index 000000000000..0422bad6a770
--- /dev/null
+++ b/stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.cxx
@@ -0,0 +1,167 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "stocservices.hxx"
+
+#include "supportsService.hxx"
+
+#include "com/sun/star/lang/XServiceInfo.hpp"
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/RuntimeException.hpp"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "com/sun/star/uno/XComponentContext.hpp"
+#include "com/sun/star/uno/XInterface.hpp"
+#include "com/sun/star/uri/UriReferenceFactory.hpp"
+#include "com/sun/star/uri/XUriReference.hpp"
+#include "com/sun/star/uri/XUriReferenceFactory.hpp"
+#include "com/sun/star/uri/XVndSunStarPkgUrlReferenceFactory.hpp"
+#include "cppuhelper/implbase2.hxx"
+#include "cppuhelper/weak.hxx"
+#include "rtl/string.h"
+#include "rtl/textenc.h"
+#include "rtl/uri.h"
+#include "rtl/uri.hxx"
+#include "rtl/ustrbuf.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+#include <new>
+
+namespace css = com::sun::star;
+
+namespace {
+
+class Factory: public cppu::WeakImplHelper2<
+ css::lang::XServiceInfo, css::uri::XVndSunStarPkgUrlReferenceFactory >
+{
+public:
+ explicit Factory(
+ css::uno::Reference< css::uno::XComponentContext > const & context):
+ m_context(context) {}
+
+ virtual rtl::OUString SAL_CALL getImplementationName()
+ throw (css::uno::RuntimeException);
+
+ virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException);
+
+ virtual css::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames() throw (css::uno::RuntimeException);
+
+ virtual css::uno::Reference< css::uri::XUriReference > SAL_CALL
+ createVndSunStarPkgUrlReference(
+ css::uno::Reference< css::uri::XUriReference > const & authority)
+ throw (css::uno::RuntimeException);
+
+private:
+ Factory(Factory &); // not implemented
+ void operator =(Factory); // not implemented
+
+ virtual ~Factory() {}
+
+ css::uno::Reference< css::uno::XComponentContext > m_context;
+};
+
+rtl::OUString Factory::getImplementationName()
+ throw (css::uno::RuntimeException)
+{
+ return
+ stoc_services::VndSunStarPkgUrlReferenceFactory::
+ getImplementationName();
+}
+
+sal_Bool Factory::supportsService(rtl::OUString const & serviceName)
+ throw (css::uno::RuntimeException)
+{
+ return stoc::uriproc::supportsService(
+ getSupportedServiceNames(), serviceName);
+}
+
+css::uno::Sequence< rtl::OUString > Factory::getSupportedServiceNames()
+ throw (css::uno::RuntimeException)
+{
+ return stoc_services::VndSunStarPkgUrlReferenceFactory::
+ getSupportedServiceNames();
+}
+
+css::uno::Reference< css::uri::XUriReference >
+Factory::createVndSunStarPkgUrlReference(
+ css::uno::Reference< css::uri::XUriReference > const & authority)
+ throw (css::uno::RuntimeException)
+{
+ OSL_ASSERT(authority.is());
+ if (authority->isAbsolute() && !authority->hasFragment()) {
+ rtl::OUStringBuffer buf;
+ buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("vnd.sun.star.pkg://"));
+ buf.append(
+ rtl::Uri::encode(
+ authority->getUriReference(), rtl_UriCharClassRegName,
+ rtl_UriEncodeIgnoreEscapes, RTL_TEXTENCODING_UTF8));
+ css::uno::Reference< css::uri::XUriReference > uriRef(
+ css::uri::UriReferenceFactory::create(m_context)->parse(
+ buf.makeStringAndClear()));
+ OSL_ASSERT(uriRef.is());
+ return uriRef;
+ } else {
+ return css::uno::Reference< css::uri::XUriReference >();
+ }
+}
+
+}
+
+namespace stoc_services { namespace VndSunStarPkgUrlReferenceFactory
+{
+
+css::uno::Reference< css::uno::XInterface > create(
+ css::uno::Reference< css::uno::XComponentContext > const & context)
+ SAL_THROW((css::uno::Exception))
+{
+ try {
+ return static_cast< cppu::OWeakObject * >(new Factory(context));
+ } catch (std::bad_alloc &) {
+ throw css::uno::RuntimeException(
+ rtl::OUString::createFromAscii("std::bad_alloc"), 0);
+ }
+}
+
+rtl::OUString getImplementationName() {
+ return rtl::OUString::createFromAscii(
+ "com.sun.star.comp.uri.VndSunStarPkgUrlReferenceFactory");
+}
+
+css::uno::Sequence< rtl::OUString > getSupportedServiceNames() {
+ css::uno::Sequence< rtl::OUString > s(1);
+ s[0] = rtl::OUString::createFromAscii(
+ "com.sun.star.uri.VndSunStarPkgUrlReferenceFactory");
+ return s;
+}
+
+} }
diff --git a/stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.hxx b/stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.hxx
new file mode 100644
index 000000000000..2e869d4e2648
--- /dev/null
+++ b/stoc/source/uriproc/VndSunStarPkgUrlReferenceFactory.hxx
@@ -0,0 +1,59 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_uriproc_VndSunStarPkgUrlReferenceFactory_hxx
+#define INCLUDED_stoc_source_uriproc_VndSunStarPkgUrlReferenceFactory_hxx
+
+#include "com/sun/star/uno/Exception.hpp"
+#include "com/sun/star/uno/Reference.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "sal/types.h"
+
+namespace com { namespace sun { namespace star { namespace uno {
+ class XComponentContext;
+ class XInterface;
+} } } }
+namespace rtl { class OUString; }
+
+namespace stoc { namespace uriproc {
+
+namespace VndSunStarPkgUrlReferenceFactory {
+ com::sun::star::uno::Reference< com::sun::star::uno::XInterface > SAL_CALL
+ create(
+ com::sun::star::uno::Reference< com::sun::star::uno::XComponentContext >
+ const & context)
+ SAL_THROW((com::sun::star::uno::Exception));
+
+ rtl::OUString SAL_CALL getImplementationName();
+
+ com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL
+ getSupportedServiceNames();
+}
+
+} }
+
+#endif
diff --git a/stoc/source/uriproc/makefile.mk b/stoc/source/uriproc/makefile.mk
new file mode 100644
index 000000000000..194da2219b6b
--- /dev/null
+++ b/stoc/source/uriproc/makefile.mk
@@ -0,0 +1,53 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2000, 2010 Oracle and/or its affiliates.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=stoc
+TARGET=uriproc
+ENABLE_EXCEPTIONS := TRUE
+
+# --- openoffice.org.orig/Settings -----------------------------------------------------
+
+.INCLUDE: settings.mk
+DLLPRE =
+
+# ------------------------------------------------------------------
+
+.INCLUDE : ..$/cppumaker.mk
+
+SLOFILES = \
+ $(SLO)$/ExternalUriReferenceTranslator.obj \
+ $(SLO)$/UriReference.obj \
+ $(SLO)$/UriReferenceFactory.obj \
+ $(SLO)$/UriSchemeParser_vndDOTsunDOTstarDOTexpand.obj \
+ $(SLO)$/UriSchemeParser_vndDOTsunDOTstarDOTscript.obj \
+ $(SLO)$/VndSunStarPkgUrlReferenceFactory.obj \
+ $(SLO)$/supportsService.obj
+
+# ------------------------------------------------------------------
+
+.INCLUDE: target.mk
diff --git a/stoc/source/uriproc/supportsService.cxx b/stoc/source/uriproc/supportsService.cxx
new file mode 100644
index 000000000000..77b55252bd4d
--- /dev/null
+++ b/stoc/source/uriproc/supportsService.cxx
@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_stoc.hxx"
+
+#include "supportsService.hxx"
+
+#include "com/sun/star/uno/Sequence.hxx"
+#include "rtl/ustring.hxx"
+#include "sal/types.h"
+
+namespace stoc { namespace uriproc {
+
+bool supportsService(
+ com::sun::star::uno::Sequence< rtl::OUString > const & serviceNames,
+ rtl::OUString const & serviceName)
+{
+ for (sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {
+ if (serviceNames[i] == serviceName) {
+ return true;
+ }
+ }
+ return false;
+}
+
+} }
diff --git a/stoc/source/uriproc/supportsService.hxx b/stoc/source/uriproc/supportsService.hxx
new file mode 100644
index 000000000000..35b2ed662195
--- /dev/null
+++ b/stoc/source/uriproc/supportsService.hxx
@@ -0,0 +1,43 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_stoc_source_uriproc_supportsService_hxx
+#define INCLUDED_stoc_source_uriproc_supportsService_hxx
+
+#include "com/sun/star/uno/Sequence.hxx"
+
+namespace rtl { class OUString; }
+
+namespace stoc { namespace uriproc {
+
+bool supportsService(
+ com::sun::star::uno::Sequence< rtl::OUString > const & serviceNames,
+ rtl::OUString const & serviceName);
+
+} }
+
+#endif