update dev300-m58
[ooovba.git] / remotebridges / source / dynamicloader / dynamicloader.cxx
blobec87b5212b112fda029d6ff942cc969d19bb247d
2 #include <stdio.h>
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;
33 OUString _link;
34 OUString _resolver;
36 Reference<XSingleServiceFactory> getRemoteFactory() throw(Exception, RuntimeException);
38 public:
40 SingleServiceFactory(const Reference<XMultiServiceFactory > & xServiceManager,
41 const OUString & serviceName,
42 const OUString & link,
43 const OUString & resolver)
44 : _xServiceManager(xServiceManager),
45 _serviceName(serviceName),
46 _link(link),
47 _resolver(resolver)
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);
56 // XServiceInfo
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);
65 if(!xResolver.is()) {
66 OUString message(RTL_CONSTASCII_USTRINGPARAM("dynamic_loader::singleServiceFactory.createInstance - couldn't create resolver: "));
67 message += _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: "));
75 message += _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: "));
83 message += _link;
85 throw Exception(message, Reference<XInterface>());
88 return remoteFactory;
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);
106 // XServiceInfo
107 OUString SAL_CALL SingleServiceFactory::getImplementationName() throw(RuntimeException) {
108 return _link;
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;
124 protected:
125 DynamicLoader(const Reference<XMultiServiceFactory> & rXSMgr) throw(RuntimeException);
126 ~DynamicLoader() throw();
128 public:
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);
137 // XServiceInfo
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;
162 try {
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());
175 return xRet;
178 DynamicLoader::DynamicLoader(const Reference<XMultiServiceFactory> & xSMgr) throw(RuntimeException)
179 : _xSMgr(xSMgr)
184 DynamicLoader::~DynamicLoader() throw() {
187 // XServiceInfo
188 OUString SAL_CALL DynamicLoader::getImplementationName() throw(RuntimeException) {
189 return implname;
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;
200 return bSupport;
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());
212 #endif
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("=")));
223 sal_Int32 index = 0;
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();
229 OUString token;
230 OUString attribute;
232 while(index <= locationUrl.getLength()) {
233 if(index >= locationUrl.getLength() || (raw_url[index] == separator.getStr()[0] && !quote && !inString)) { // a separator or end?
234 OUString value;
236 if(left)
237 attribute = token.trim();
239 else
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());
247 #endif
249 if(attribute.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("servicename"))))
250 *serviceName = value;
252 else if(attribute.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("link"))))
253 *link = value;
255 else if(attribute.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("resolver"))))
256 *resolver = value;
258 else {
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
277 token = emptyString;
279 else if(raw_url[index] == bSlash.getStr()[0] && !quote) // a back slash?
280 quote = sal_True;
282 else if(raw_url[index] == equalSign.getStr()[0] && !quote && !inString) { // equalSign (switch from left to right)?
283 left = sal_False;
285 attribute = token.trim();
286 token = emptyString;
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);
293 quote = sal_False;
296 ++ index;
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;
323 OUString link;
324 OUString resolver;
326 try {
327 parseUrl(locationUrl, &serviceName, &link, &resolver);
329 catch(RuntimeException & runtimeException) {
330 throw CannotRegisterImplementationException(runtimeException.Message, Reference<XInterface>());
333 // create the keys
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;
345 return bSuccess;
348 Reference<XInterface> SAL_CALL DynamicLoader::activate(const OUString &,
349 const OUString &,
350 const OUString & locationUrl,
351 const Reference<XRegistryKey> &)
352 throw(CannotActivateFactoryException, RuntimeException)
354 OSL_TRACE("DynamicLoader::activate");
356 OUString serviceName;
357 OUString link;
358 OUString resolver;
360 parseUrl(locationUrl, &serviceName, &link, &resolver);
362 XSingleServiceFactory * xFactory = (XSingleServiceFactory *)new SingleServiceFactory(_xSMgr,
363 serviceName,
364 link,
365 resolver);
367 Reference<XInterface> xReturn;
369 if(xFactory)
370 xReturn = Reference<XInterface>::query(xFactory);
372 return xReturn;
379 extern "C" {
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;
387 if (pRegistryKey) {
388 try {
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]);
402 bRes = sal_True;
404 catch (InvalidRegistryException &) {
405 OSL_ENSURE( sal_False, "### InvalidRegistryException!" );
409 return bRes;
412 void * SAL_CALL component_getFactory(const sal_Char * pImplName, XMultiServiceFactory * pServiceManager, XRegistryKey *) {
413 void * pRet = 0;
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()));
421 if (xFactory.is()) {
422 xFactory->acquire();
423 pRet = xFactory.get();
426 else
427 OSL_TRACE("DynamicLoader - warning - given wrong implName: %s", pImplName);
429 return pRet;