1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_stoc.hxx" 26 27 #include "com/sun/star/container/XHierarchicalNameAccess.hpp" 28 #include "com/sun/star/container/XSet.hpp" 29 #include "com/sun/star/lang/XMain.hpp" 30 #include "com/sun/star/lang/XSingleComponentFactory.hpp" 31 #include "com/sun/star/lang/IllegalArgumentException.hpp" 32 #include "com/sun/star/reflection/XIndirectTypeDescription.hpp" 33 #include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp" 34 #include "com/sun/star/reflection/XPublished.hpp" 35 #include "com/sun/star/reflection/XStructTypeDescription.hpp" 36 #include "com/sun/star/reflection/XTypeDescription.hpp" 37 #include "com/sun/star/registry/InvalidRegistryException.hpp" 38 #include "com/sun/star/registry/XRegistryKey.hpp" 39 #include "com/sun/star/registry/XSimpleRegistry.hpp" 40 #include "com/sun/star/uno/Exception.hpp" 41 #include "com/sun/star/uno/Reference.hxx" 42 #include "com/sun/star/uno/RuntimeException.hpp" 43 #include "com/sun/star/uno/Sequence.hxx" 44 #include "com/sun/star/uno/TypeClass.hpp" 45 #include "com/sun/star/uno/XComponentContext.hpp" 46 #include "com/sun/star/uno/XInterface.hpp" 47 #include "cppuhelper/factory.hxx" 48 #include "cppuhelper/implbase1.hxx" 49 #include "cppuhelper/weak.hxx" 50 #include "osl/file.h" 51 #include "osl/thread.h" 52 #include "rtl/textenc.h" 53 #include "rtl/ustring.h" 54 #include "rtl/ustring.hxx" 55 #include "sal/types.h" 56 #include "uno/environment.h" 57 #include "uno/lbnames.h" 58 59 #include /*MSVC trouble: <cstdlib>*/ <stdlib.h> 60 #include <iostream> 61 #include <ostream> 62 63 namespace css = com::sun::star; 64 65 namespace { 66 67 class Service: public cppu::WeakImplHelper1< css::lang::XMain > { 68 public: 69 virtual sal_Int32 SAL_CALL 70 run(css::uno::Sequence< rtl::OUString > const & arguments) 71 throw (css::uno::RuntimeException); 72 73 static rtl::OUString getImplementationName(); 74 75 static css::uno::Sequence< rtl::OUString > getSupportedServiceNames(); 76 77 static css::uno::Reference< css::uno::XInterface > SAL_CALL createInstance( 78 css::uno::Reference< css::uno::XComponentContext > const & context) 79 throw (css::uno::Exception); 80 81 private: 82 explicit Service( 83 css::uno::Reference< css::uno::XComponentContext > const & context): 84 m_context(context) 85 {} 86 87 css::uno::Reference< css::uno::XComponentContext > m_context; 88 }; 89 90 } 91 92 namespace { 93 94 std::ostream & operator <<(std::ostream & out, rtl::OUString const & value) { 95 return out << rtl::OUStringToOString(value, RTL_TEXTENCODING_UTF8).getStr(); 96 } 97 98 void assertTrue(bool argument) { 99 if (!argument) { 100 std::cerr 101 << "assertTrue(" << argument << ") failed" << std::endl; 102 /*MSVC trouble: std::*/abort(); 103 } 104 } 105 106 void assertFalse(bool argument) { 107 if (argument) { 108 std::cerr 109 << "assertFalse(" << argument << ") failed" << std::endl; 110 /*MSVC trouble: std::*/abort(); 111 } 112 } 113 114 template< typename T > void assertEqual(T const & value, T const & argument) { 115 if (argument != value) { 116 std::cerr 117 << "assertEqual(" << value << ", " << argument << ") failed" 118 << std::endl; 119 /*MSVC trouble: std::*/abort(); 120 } 121 } 122 123 } 124 125 sal_Int32 Service::run(css::uno::Sequence< rtl::OUString > const & arguments) 126 throw (css::uno::RuntimeException) 127 { 128 css::uno::Reference< css::lang::XMultiComponentFactory > factory( 129 m_context->getServiceManager()); 130 assertTrue(factory.is()); 131 css::uno::Reference< css::container::XHierarchicalNameAccess > manager( 132 m_context->getValueByName( 133 rtl::OUString( 134 RTL_CONSTASCII_USTRINGPARAM( 135 "/singletons/" 136 "com.sun.star.reflection.theTypeDescriptionManager"))), 137 css::uno::UNO_QUERY_THROW); 138 139 //////////////////////////////////////// 140 // test: add cmd line rdbs to manager 141 //////////////////////////////////////// 142 143 OSL_ASSERT( arguments.getLength() > 0 ); 144 css::uno::Reference<css::container::XSet> xSet( 145 manager, css::uno::UNO_QUERY_THROW ); 146 for ( sal_Int32 argPos = 0; argPos < arguments.getLength(); ++argPos ) { 147 rtl::OUString url; 148 OSL_VERIFY( osl_File_E_None == osl_getFileURLFromSystemPath( 149 arguments[argPos].pData, &url.pData ) ); 150 bool supposedToBeCompatible = ! url.endsWithIgnoreAsciiCaseAsciiL( 151 RTL_CONSTASCII_STRINGPARAM("_incomp.rdb") ); 152 153 css::uno::Reference<css::registry::XSimpleRegistry> xReg( 154 m_context->getServiceManager()->createInstanceWithContext( 155 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 156 "com.sun.star.registry.SimpleRegistry") ), 157 m_context ), css::uno::UNO_QUERY_THROW ); 158 xReg->open( url, true /* read-only */, false /* ! create */ ); 159 css::uno::Any arg( css::uno::makeAny(xReg) ); 160 css::uno::Reference<css::container::XHierarchicalNameAccess> xTDprov( 161 m_context->getServiceManager()-> 162 createInstanceWithArgumentsAndContext( 163 rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( 164 "com.sun.star.comp.stoc." 165 "RegistryTypeDescriptionProvider") ), 166 css::uno::Sequence<css::uno::Any>( &arg, 1 ), m_context ), 167 css::uno::UNO_QUERY_THROW ); 168 try { 169 xSet->insert( css::uno::makeAny(xTDprov) ); 170 if (! supposedToBeCompatible) 171 std::cerr << "current rdb file: " << 172 rtl::OUStringToOString( 173 url, osl_getThreadTextEncoding()).getStr() << std::endl; 174 assertTrue(supposedToBeCompatible); 175 } catch (css::lang::IllegalArgumentException &) { 176 if (supposedToBeCompatible) 177 throw; 178 assertFalse(supposedToBeCompatible); 179 } 180 } 181 182 /////// 183 184 css::uno::Reference< css::reflection::XIndirectTypeDescription > sequence( 185 manager->getByHierarchicalName( 186 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[][]boolean"))), 187 css::uno::UNO_QUERY_THROW); 188 assertEqual(css::uno::TypeClass_SEQUENCE, sequence->getTypeClass()); 189 assertEqual( 190 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[][]boolean")), 191 sequence->getName()); 192 assertEqual( 193 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[]boolean")), 194 sequence->getReferencedType()->getName()); 195 196 css::uno::Reference< css::reflection::XStructTypeDescription > structure( 197 manager->getByHierarchicalName( 198 rtl::OUString( 199 RTL_CONSTASCII_USTRINGPARAM( 200 "test.tdmanager.Struct<boolean,test.tdmanager.Struct<" 201 "any,com.sun.star.uno.XInterface>>"))), 202 css::uno::UNO_QUERY_THROW); 203 assertEqual(css::uno::TypeClass_STRUCT, structure->getTypeClass()); 204 assertEqual( 205 rtl::OUString( 206 RTL_CONSTASCII_USTRINGPARAM( 207 "test.tdmanager.Struct<boolean,test.tdmanager.Struct<" 208 "any,com.sun.star.uno.XInterface>>")), 209 structure->getName()); 210 assertEqual< bool >(false, structure->getBaseType().is()); 211 assertEqual< sal_Int32 >(1, structure->getMemberTypes().getLength()); 212 assertEqual( 213 rtl::OUString( 214 RTL_CONSTASCII_USTRINGPARAM( 215 "test.tdmanager.Struct<any,com.sun.star.uno.XInterface>")), 216 structure->getMemberTypes()[0]->getName()); 217 assertEqual< sal_Int32 >(1, structure->getMemberNames().getLength()); 218 assertEqual( 219 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("s")), 220 structure->getMemberNames()[0]); 221 assertEqual< sal_Int32 >(0, structure->getTypeParameters().getLength()); 222 assertEqual< sal_Int32 >(2, structure->getTypeArguments().getLength()); 223 assertEqual( 224 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("boolean")), 225 structure->getTypeArguments()[0]->getName()); 226 assertEqual( 227 rtl::OUString( 228 RTL_CONSTASCII_USTRINGPARAM( 229 "test.tdmanager.Struct<any,com.sun.star.uno.XInterface>")), 230 structure->getTypeArguments()[1]->getName()); 231 232 css::uno::Reference< css::reflection::XInterfaceMethodTypeDescription > 233 method( 234 manager->getByHierarchicalName( 235 rtl::OUString( 236 RTL_CONSTASCII_USTRINGPARAM( 237 "com.sun.star.uno.XComponentContext::getValueByName"))), 238 css::uno::UNO_QUERY_THROW); 239 assertEqual(css::uno::TypeClass_INTERFACE_METHOD, method->getTypeClass()); 240 assertEqual( 241 rtl::OUString( 242 RTL_CONSTASCII_USTRINGPARAM( 243 "com.sun.star.uno.XComponentContext::getValueByName")), 244 method->getName()); 245 assertEqual( 246 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("getValueByName")), 247 method->getMemberName()); 248 assertEqual< sal_Int32 >(3, method->getPosition()); 249 assertEqual( 250 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("any")), 251 method->getReturnType()->getName()); 252 assertEqual< bool >(false, method->isOneway()); 253 assertEqual< sal_Int32 >(1, method->getParameters().getLength()); 254 assertEqual( 255 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Name")), 256 method->getParameters()[0]->getName()); 257 assertEqual( 258 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("string")), 259 method->getParameters()[0]->getType()->getName()); 260 assertEqual< bool >(true, method->getParameters()[0]->isIn()); 261 assertEqual< bool >(false, method->getParameters()[0]->isOut()); 262 assertEqual< sal_Int32 >(0, method->getParameters()[0]->getPosition()); 263 assertEqual< sal_Int32 >(0, method->getExceptions().getLength()); 264 265 assertFalse( 266 css::uno::Reference< css::reflection::XPublished >( 267 css::uno::Reference< css::reflection::XTypeDescription >( 268 manager->getByHierarchicalName( 269 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("[]boolean"))), 270 css::uno::UNO_QUERY_THROW), 271 css::uno::UNO_QUERY).is()); 272 assertFalse( 273 css::uno::Reference< css::reflection::XPublished >( 274 css::uno::Reference< css::reflection::XTypeDescription >( 275 manager->getByHierarchicalName( 276 rtl::OUString( 277 RTL_CONSTASCII_USTRINGPARAM( 278 "com.sun.star.beans.XIntroTest::ObjectName"))), 279 css::uno::UNO_QUERY_THROW), 280 css::uno::UNO_QUERY).is()); 281 assertFalse( 282 css::uno::Reference< css::reflection::XPublished >( 283 css::uno::Reference< css::reflection::XTypeDescription >( 284 manager->getByHierarchicalName( 285 rtl::OUString( 286 RTL_CONSTASCII_USTRINGPARAM( 287 "com.sun.star.beans.XIntroTest::writeln"))), 288 css::uno::UNO_QUERY_THROW), 289 css::uno::UNO_QUERY).is()); 290 //TODO: check that the reflection of a property of an accumulation-based 291 // service does not support XPublished 292 293 return 0; 294 } 295 296 rtl::OUString Service::getImplementationName() { 297 return rtl::OUString::createFromAscii("test.tdmanager.impl"); 298 } 299 300 css::uno::Sequence< rtl::OUString > Service::getSupportedServiceNames() { 301 return css::uno::Sequence< rtl::OUString >(); 302 } 303 304 css::uno::Reference< css::uno::XInterface > Service::createInstance( 305 css::uno::Reference< css::uno::XComponentContext > const & context) 306 throw (css::uno::Exception) 307 { 308 return static_cast< cppu::OWeakObject * >(new Service(context)); 309 } 310 311 extern "C" void SAL_CALL component_getImplementationEnvironment( 312 char const ** envTypeName, uno_Environment **) 313 { 314 if (envTypeName != 0) { 315 *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 316 } 317 } 318 319 extern "C" void * SAL_CALL component_getFactory(char const * implName, 320 void * serviceManager, void *) { 321 void * p = 0; 322 if (serviceManager != 0) { 323 css::uno::Reference< css::lang::XSingleComponentFactory > f; 324 if (Service::getImplementationName().equalsAscii(implName)) { 325 f = cppu::createSingleComponentFactory( 326 &Service::createInstance, Service::getImplementationName(), 327 Service::getSupportedServiceNames()); 328 } 329 if (f.is()) { 330 f->acquire(); 331 p = f.get(); 332 } 333 } 334 return p; 335 } 336 337 namespace { 338 339 bool writeInfo(void * registryKey, rtl::OUString const & implementationName, 340 css::uno::Sequence< rtl::OUString > const & serviceNames) { 341 rtl::OUString keyName(rtl::OUString::createFromAscii("/")); 342 keyName += implementationName; 343 keyName += rtl::OUString::createFromAscii("/UNO/SERVICES"); 344 css::uno::Reference< css::registry::XRegistryKey > key; 345 try { 346 key = static_cast< css::registry::XRegistryKey * >(registryKey)-> 347 createKey(keyName); 348 } catch (css::registry::InvalidRegistryException &) {} 349 if (!key.is()) { 350 return false; 351 } 352 bool success = true; 353 for (sal_Int32 i = 0; i < serviceNames.getLength(); ++i) { 354 try { 355 key->createKey(serviceNames[i]); 356 } catch (css::registry::InvalidRegistryException &) { 357 success = false; 358 break; 359 } 360 } 361 return success; 362 } 363 364 } 365 366 extern "C" sal_Bool SAL_CALL component_writeInfo(void *, void * registryKey) { 367 return registryKey 368 && writeInfo(registryKey, Service::getImplementationName(), 369 Service::getSupportedServiceNames()); 370 } 371