4 #include <cppuhelper/factory.hxx>
6 #include <cppuhelper/implbase1.hxx>
7 #include <cppuhelper/implbase2.hxx>
10 #include <com/sun/star/bridge/XUnoUrlResolver.hpp>
12 #include <com/sun/star/lang/XServiceInfo.hpp>
13 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
14 #include <com/sun/star/loader/XImplementationLoader.hpp>
15 #include <com/sun/star/registry/XRegistryKey.hpp>
18 using namespace ::com::sun::star::bridge
;
19 using namespace ::com::sun::star::lang
;
20 using namespace ::com::sun::star::loader
;
21 using namespace ::com::sun::star::uno
;
22 using namespace ::com::sun::star::registry
;
25 using namespace ::cppu
;
26 using namespace ::rtl
;
28 namespace dynamic_loader
{
30 class SingleServiceFactory
: public WeakImplHelper2
<XServiceInfo
, XSingleServiceFactory
> {
31 Reference
<XMultiServiceFactory
> _xServiceManager
;
32 OUString _serviceName
;
36 Reference
<XSingleServiceFactory
> getRemoteFactory() throw(Exception
, RuntimeException
);
40 SingleServiceFactory(const Reference
<XMultiServiceFactory
> & xServiceManager
,
41 const OUString
& serviceName
,
42 const OUString
& link
,
43 const OUString
& resolver
)
44 : _xServiceManager(xServiceManager
),
45 _serviceName(serviceName
),
50 // XSingleServiceFactory
51 Reference
<XInterface
> SAL_CALL
createInstance() throw(Exception
, RuntimeException
);
52 Reference
<XInterface
> SAL_CALL
createInstanceWithArguments(const Sequence
<Any
>& Arguments
)
53 throw(::com::sun::star::uno::Exception
,
54 ::com::sun::star::uno::RuntimeException
);
57 OUString SAL_CALL
getImplementationName() throw(RuntimeException
);
58 sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) throw(RuntimeException
);
59 Sequence
<OUString
> SAL_CALL
getSupportedServiceNames(void) throw(RuntimeException
);
63 Reference
<XSingleServiceFactory
> SingleServiceFactory::getRemoteFactory() throw(Exception
, RuntimeException
) {
64 Reference
<XUnoUrlResolver
> xResolver(_xServiceManager
->createInstance(_resolver
), UNO_QUERY
);
66 OUString
message(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::singleServiceFactory.createInstance - couldn't create resolver: "));
69 throw Exception(message
, Reference
<XInterface
>());
72 Reference
<XInterface
> remoteObject
= xResolver
->resolve(_link
);
73 if(!remoteObject
.is()) {
74 OUString
message(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::singleServiceFactory.createInstance - couldn't resolve link: "));
77 throw Exception(message
, Reference
<XInterface
>());
80 Reference
<XSingleServiceFactory
> remoteFactory(remoteObject
, UNO_QUERY
);
81 if(!remoteFactory
.is()) {
82 OUString
message(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::singleServiceFactory.createInstance - couldn't get XSingleServiceFactory from: "));
85 throw Exception(message
, Reference
<XInterface
>());
91 // XSingleServiceFactory
92 Reference
<XInterface
> SAL_CALL
SingleServiceFactory::createInstance() throw(Exception
, RuntimeException
) {
93 OSL_TRACE("dynamic_loader::singleServiceFactory::createInstance");
95 return getRemoteFactory()->createInstance();
98 Reference
<XInterface
> SAL_CALL
SingleServiceFactory::createInstanceWithArguments(const Sequence
<Any
>& Arguments
)
99 throw(Exception
, RuntimeException
)
101 OSL_TRACE("dynamic_loader::singleServiceFactory::createInstanceWithArguments");
103 return getRemoteFactory()->createInstanceWithArguments(Arguments
);
107 OUString SAL_CALL
SingleServiceFactory::getImplementationName() throw(RuntimeException
) {
111 sal_Bool SAL_CALL
SingleServiceFactory::supportsService(const OUString
& ServiceName
) throw(RuntimeException
) {
112 return _serviceName
.equals(ServiceName
);
115 Sequence
<OUString
> SAL_CALL
SingleServiceFactory::getSupportedServiceNames(void) throw(RuntimeException
) {
116 return Sequence
<OUString
>(&_serviceName
, 1);
121 class DynamicLoader
: public WeakImplHelper2
<XImplementationLoader
, XServiceInfo
> {
122 Reference
<XMultiServiceFactory
> _xSMgr
;
125 DynamicLoader(const Reference
<XMultiServiceFactory
> & rXSMgr
) throw(RuntimeException
);
126 ~DynamicLoader() throw();
129 static const OUString implname
;
130 static const OUString servname
;
132 static Reference
<XInterface
> SAL_CALL
createInstance(const Reference
<XMultiServiceFactory
> & rSMgr
) throw(Exception
);
133 static Sequence
<OUString
> SAL_CALL
getSupportedServiceNames_Static() throw();
135 static void parseUrl(const OUString
& url
, OUString
* serviceName
, OUString
* link
, OUString
* resolver
) throw(RuntimeException
);
138 virtual OUString SAL_CALL
getImplementationName() throw(RuntimeException
);
139 virtual sal_Bool SAL_CALL
supportsService(const OUString
& ServiceName
) throw(RuntimeException
);
140 virtual Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() throw(RuntimeException
);
142 // XImplementationLoader
143 virtual Reference
<XInterface
> SAL_CALL
activate(const OUString
& implementationName
,
144 const OUString
& implementationLoaderUrl
,
145 const OUString
& locationUrl
,
146 const Reference
<XRegistryKey
>& xKey
) throw(CannotActivateFactoryException
, RuntimeException
);
147 virtual sal_Bool SAL_CALL
writeRegistryInfo(const Reference
<XRegistryKey
>& xKey
,
148 const OUString
& implementationLoaderUrl
,
149 const OUString
& locationUrl
) throw(CannotRegisterImplementationException
, RuntimeException
);
152 const OUString
DynamicLoader::implname
= OUString::createFromAscii("com.sun.star.comp.stoc.DynamicLoader");
153 const OUString
DynamicLoader::servname
= OUString::createFromAscii("com.sun.star.loader.Dynamic");
155 Sequence
<OUString
> SAL_CALL
DynamicLoader::getSupportedServiceNames_Static() throw() {
156 return Sequence
<OUString
>(&servname
, 1);
159 Reference
<XInterface
> SAL_CALL
DynamicLoader::createInstance(const Reference
<XMultiServiceFactory
> & rSMgr
) throw(Exception
) {
160 Reference
<XInterface
> xRet
;
163 XImplementationLoader
*pXLoader
= (XImplementationLoader
*)new DynamicLoader(rSMgr
);
165 xRet
= Reference
<XInterface
>::query(pXLoader
);
167 catch(RuntimeException
& runtimeException
) {
168 OString message
= OUStringToOString(runtimeException
.Message
, RTL_TEXTENCODING_ASCII_US
);
169 osl_trace("dynamic loader - could not init cause of %s", message
.getStr());
172 OSL_TRACE("DynamicLoader - createInstance: %d", xRet
.is());
178 DynamicLoader::DynamicLoader(const Reference
<XMultiServiceFactory
> & xSMgr
) throw(RuntimeException
)
184 DynamicLoader::~DynamicLoader() throw() {
188 OUString SAL_CALL
DynamicLoader::getImplementationName() throw(RuntimeException
) {
192 sal_Bool SAL_CALL
DynamicLoader::supportsService(const OUString
& ServiceName
) throw(RuntimeException
) {
193 sal_Bool bSupport
= sal_False
;
195 Sequence
<OUString
> aSNL
= getSupportedServiceNames();
196 const OUString
* pArray
= aSNL
.getArray();
197 for(sal_Int32 i
= 0; i
< aSNL
.getLength() && !bSupport
; ++ i
)
198 bSupport
= pArray
[i
] == ServiceName
;
203 Sequence
<OUString
> SAL_CALL
DynamicLoader::getSupportedServiceNames() throw(RuntimeException
) {
204 return getSupportedServiceNames_Static();
208 void DynamicLoader::parseUrl(const OUString
& locationUrl
, OUString
* serviceName
, OUString
* link
, OUString
* resolver
) throw(RuntimeException
) {
209 #if OSL_DEBUG_LEVEL > 1
210 OString tmp
= OUStringToOString(locationUrl
, RTL_TEXTENCODING_ASCII_US
);
211 OSL_TRACE("DynamicLoader - locationUrl %s", tmp
.getStr());
214 // This is the default resolver
215 *resolver
= OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.UnoUrlResolver"));
217 const OUString
bSlash(OUString(RTL_CONSTASCII_USTRINGPARAM("\\")));
218 const OUString
tuedle(OUString(RTL_CONSTASCII_USTRINGPARAM("\"")));
219 const OUString
separator(OUString(RTL_CONSTASCII_USTRINGPARAM(",")));
220 const OUString
emptyString(OUString(RTL_CONSTASCII_USTRINGPARAM("")));
221 const OUString
equalSign(OUString(RTL_CONSTASCII_USTRINGPARAM("=")));
224 sal_Bool left
= sal_True
;
225 sal_Bool quote
= sal_False
;
226 sal_Bool inString
= sal_False
;
228 const sal_Unicode
* raw_url
= locationUrl
.getStr();
232 while(index
<= locationUrl
.getLength()) {
233 if(index
>= locationUrl
.getLength() || (raw_url
[index
] == separator
.getStr()[0] && !quote
&& !inString
)) { // a separator or end?
237 attribute
= token
.trim();
240 value
= token
.trim();
242 #if OSL_DEBUG_LEVEL > 1
243 OString attribute_tmp
= OUStringToOString(attribute
, RTL_TEXTENCODING_ASCII_US
);
244 OSL_TRACE("DynamicLoader - attribute %s", attribute_tmp
.getStr());
245 OString value_tmp
= OUStringToOString(value
, RTL_TEXTENCODING_ASCII_US
);
246 OSL_TRACE("DynamicLoader - value %s", value_tmp
.getStr());
249 if(attribute
.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("servicename"))))
250 *serviceName
= value
;
252 else if(attribute
.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("link"))))
255 else if(attribute
.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("resolver"))))
259 OUString
message(RTL_CONSTASCII_USTRINGPARAM("help called"));
261 if(!attribute
.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("help")))) {
262 message
= OUString(RTL_CONSTASCII_USTRINGPARAM("DynamicLoader - unknown attribute: "));
263 message
+= attribute
;
266 fprintf(stdout
, "DynamicLoader - help\n");
267 fprintf(stdout
, "attributes:\n");
268 fprintf(stdout
, "\tservicename: service name of dynamic component\n");
269 fprintf(stdout
, "\tlink: link to a single service factory for dynamic component\n");
270 fprintf(stdout
, "\tresolver: the service which resolves the link\n");
271 fprintf(stdout
, "\thelp: this help\n");
273 throw RuntimeException(message
, Reference
<XInterface
>());
276 left
= sal_True
; // reset state to be left
279 else if(raw_url
[index
] == bSlash
.getStr()[0] && !quote
) // a back slash?
282 else if(raw_url
[index
] == equalSign
.getStr()[0] && !quote
&& !inString
) { // equalSign (switch from left to right)?
285 attribute
= token
.trim();
288 else if(raw_url
[index
] == tuedle
.getStr()[0] && !quote
) // begin or end of string?
289 inString
= !inString
;
291 else { // no special handling
292 token
+= OUString(raw_url
+ index
, 1);
299 // enshure, that attributes are set properly
300 if(!(*serviceName
).getLength())
301 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::DynamicLoader.parseUrl - missing or empty attribute: servicename")),
302 Reference
<XInterface
>());
304 if(!(*link
).getLength())
305 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::DynamicLoader.parseUrl - missing or empty attribute: link")),
306 Reference
<XInterface
>());
308 if(!(*resolver
).getLength())
309 throw RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::DynamicLoader.parseUrl - missing or empty attribute: resolver")),
310 Reference
<XInterface
>());
314 // XImplementationLoader
315 sal_Bool SAL_CALL
DynamicLoader::writeRegistryInfo(const Reference
<XRegistryKey
> & xKey
,
316 const OUString
& implementationLoaderUrl
,
317 const OUString
& locationUrl
)
318 throw(CannotRegisterImplementationException
, RuntimeException
)
320 OSL_TRACE("DynamicLoader::writeRegistryInfo");
322 OUString serviceName
;
327 parseUrl(locationUrl
, &serviceName
, &link
, &resolver
);
329 catch(RuntimeException
& runtimeException
) {
330 throw CannotRegisterImplementationException(runtimeException
.Message
, Reference
<XInterface
>());
334 OUString keyName
= OUString::createFromAscii("/");
335 keyName
+= implementationLoaderUrl
;
336 keyName
+= OUString(RTL_CONSTASCII_USTRINGPARAM("_"));
337 keyName
+= serviceName
;
338 keyName
+= OUString::createFromAscii("/UNO/SERVICES");
340 Reference
<XRegistryKey
> xNewKey(xKey
->createKey(keyName
));
341 xNewKey
->createKey(serviceName
);
343 sal_Bool bSuccess
= sal_True
;
348 Reference
<XInterface
> SAL_CALL
DynamicLoader::activate(const OUString
&,
350 const OUString
& locationUrl
,
351 const Reference
<XRegistryKey
> &)
352 throw(CannotActivateFactoryException
, RuntimeException
)
354 OSL_TRACE("DynamicLoader::activate");
356 OUString serviceName
;
360 parseUrl(locationUrl
, &serviceName
, &link
, &resolver
);
362 XSingleServiceFactory
* xFactory
= (XSingleServiceFactory
*)new SingleServiceFactory(_xSMgr
,
367 Reference
<XInterface
> xReturn
;
370 xReturn
= Reference
<XInterface
>::query(xFactory
);
380 void SAL_CALL
component_getImplementationEnvironment(const sal_Char
** ppEnvTypeName
, uno_Environment
**) {
381 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
384 sal_Bool SAL_CALL
component_writeInfo(XMultiServiceFactory
*, XRegistryKey
* pRegistryKey
) {
385 sal_Bool bRes
= sal_False
;
389 OUString x
= OUString::createFromAscii("/");
390 x
+= ::dynamic_loader::DynamicLoader::implname
;
391 x
+= OUString::createFromAscii("/UNO/SERVICES");
394 Reference
<XRegistryKey
> xNewKey(pRegistryKey
->createKey(x
));
396 const Sequence
<OUString
> rSNL
= ::dynamic_loader::DynamicLoader::getSupportedServiceNames_Static();
397 const OUString
* pArray
= rSNL
.getConstArray();
398 for (sal_Int32 nPos
= rSNL
.getLength(); nPos
--;)
399 xNewKey
->createKey(pArray
[nPos
]);
404 catch (InvalidRegistryException
&) {
405 OSL_ENSURE( sal_False
, "### InvalidRegistryException!" );
412 void * SAL_CALL
component_getFactory(const sal_Char
* pImplName
, XMultiServiceFactory
* pServiceManager
, XRegistryKey
*) {
415 if (pServiceManager
&& OUString::createFromAscii(pImplName
).equals(::dynamic_loader::DynamicLoader::implname
)) {
416 Reference
<XSingleServiceFactory
> xFactory(createOneInstanceFactory(pServiceManager
,
417 ::dynamic_loader::DynamicLoader::implname
,
418 ::dynamic_loader::DynamicLoader::createInstance
,
419 ::dynamic_loader::DynamicLoader::getSupportedServiceNames_Static()));
423 pRet
= xFactory
.get();
427 OSL_TRACE("DynamicLoader - warning - given wrong implName: %s", pImplName
);