1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include "codemaker/commoncpp.hxx" 29 30 #include "skeletoncommon.hxx" 31 #include "skeletoncpp.hxx" 32 33 #include <iostream> 34 35 using namespace ::rtl; 36 using namespace ::codemaker::cpp; 37 38 namespace skeletonmaker { namespace cpp { 39 40 void generateIncludes(std::ostream & o, 41 const std::hash_set< OString, OStringHash >& interfaces, 42 const AttributeInfo& /*properties*/, 43 OString propertyhelper, bool serviceobject, 44 bool supportxcomponent) 45 { 46 o << "#include \"sal/config.h\"\n"; 47 if (serviceobject) { 48 o << "#include \"cppuhelper/factory.hxx\"\n" 49 << "#include \"cppuhelper/implementationentry.hxx\"\n"; 50 } else { 51 o << "#include \"com/sun/star/uno/XComponentContext.hpp\"\n"; 52 } 53 if (supportxcomponent) { 54 o << "#include \"cppuhelper/compbase" << interfaces.size() << ".hxx\"\n"; 55 o << "#include \"cppuhelper/basemutex.hxx\"\n"; 56 } else { 57 o << "#include \"cppuhelper/implbase" << interfaces.size() << ".hxx\"\n"; 58 } 59 60 if (propertyhelper.getLength() > 1) { 61 if (propertyhelper.equals("_")) 62 o << "#include \"cppuhelper/rpopshlp.hxx\"\n"; 63 else 64 o << "#include \"cppuhelper/propertysetmixin.hxx\"\n"; 65 } 66 67 std::hash_set< OString, OStringHash >::const_iterator iter = interfaces.begin(); 68 while (iter != interfaces.end()) 69 { 70 o << "#include \"" 71 << ((*iter).replace('.', '/').getStr()) 72 << ".hpp\"\n"; 73 iter++; 74 } 75 } 76 77 short generateNamespace(std::ostream & o, 78 const OString & implname, 79 bool serviceobject, 80 OString & nm) 81 { 82 short count=0; 83 sal_Int32 index = implname.lastIndexOf('.'); 84 if (serviceobject) { 85 o << "\n\n// component helper namespace\n"; 86 } else { 87 o << "\n"; 88 } 89 OStringBuffer buf; 90 if (index == -1) { 91 if (serviceobject) { 92 buf.append("comp_"); 93 buf.append(implname); 94 nm = buf.makeStringAndClear(); 95 o << "namespace comp_" << implname << " {\n\n"; 96 count=1; 97 } else { 98 nm = OString(); 99 } 100 } else { 101 sal_Int32 nPos=0; 102 do { 103 OString token(implname.getToken(0, '.', nPos)); 104 if (nPos < 0 && serviceobject) { 105 buf.append("::comp_"); 106 buf.append(token); 107 o << "namespace comp_" << token << " { "; 108 count++; 109 } else { 110 buf.append("::"); 111 buf.append(token); 112 o << "namespace " << token << " { "; 113 count++; 114 } 115 } while( nPos <= index ); 116 nm = buf.makeStringAndClear(); 117 o << "\n\n"; 118 } 119 return count; 120 } 121 122 OString generateCompHelperDeclaration(std::ostream & o, 123 const OString & implname) 124 { 125 OString nm; 126 short nbrackets = generateNamespace(o, implname, true, nm); 127 128 o << "namespace css = ::com::sun::star;\n\n"; 129 130 // generate component/service helper functions 131 o << "// component and service helper functions:\n" 132 "::rtl::OUString SAL_CALL _getImplementationName();\n" 133 "css::uno::Sequence< ::rtl::OUString > SAL_CALL " 134 "_getSupportedServiceNames();\n" 135 "css::uno::Reference< css::uno::XInterface > SAL_CALL _create(" 136 " css::uno::Reference< css::uno::XComponentContext > const & " 137 "context );\n\n"; 138 139 // close namepsace 140 for (short i=0; i < nbrackets; i++) 141 o << "} "; 142 o << "// closing component helper namespace\n\n"; 143 144 return nm; 145 } 146 147 void generateCompHelperDefinition(std::ostream & o, 148 const OString & implname, 149 const OString & classname, 150 const std::hash_set< OString, OStringHash >& services) 151 { 152 OString nm; 153 short nbrackets = generateNamespace(o, implname, true, nm); 154 155 o << "::rtl::OUString SAL_CALL _getImplementationName() {\n" 156 << " return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\n" 157 << " \"" << implname << "\"));\n}\n\n"; 158 159 o << "css::uno::Sequence< ::rtl::OUString > SAL_CALL " 160 "_getSupportedServiceNames()\n{\n css::uno::Sequence< " 161 << "::rtl::OUString >" << " s(" << services.size() << ");\n"; 162 163 std::hash_set< OString, OStringHash >::const_iterator iter = services.begin(); 164 short i=0; 165 while (iter != services.end()) 166 { 167 o << " s[" << i++ << "] = ::rtl::OUString(" 168 << "RTL_CONSTASCII_USTRINGPARAM(\n \"" 169 << (*iter).replace('/','.') << "\"));\n"; 170 iter++; 171 } 172 o << " return s;\n}\n\n"; 173 174 o << "css::uno::Reference< css::uno::XInterface > SAL_CALL _create(" 175 << "\n const css::uno::Reference< css::uno::XComponentContext > & " 176 << "context)\n SAL_THROW((css::uno::Exception))\n{\n" 177 << " return static_cast< ::cppu::OWeakObject * >(new " 178 << classname << "(context));\n}\n\n"; 179 180 // close namepsace 181 for (short j=0; j < nbrackets; j++) 182 o << "} "; 183 o << "// closing component helper namespace\n\n"; 184 185 } 186 187 void generateCompFunctions(std::ostream & o, const OString & nmspace) 188 { 189 o << "static ::cppu::ImplementationEntry const entries[] = {\n" 190 << " { &" << nmspace << "::_create,\n &" 191 << nmspace << "::_getImplementationName,\n &" 192 << nmspace << "::_getSupportedServiceNames,\n" 193 << " &::cppu::createSingleComponentFactory, 0, 0 },\n" 194 << " { 0, 0, 0, 0, 0, 0 }\n};\n\n"; 195 196 o << "extern \"C\" void SAL_CALL component_getImplementationEnvironment(\n" 197 << " const char ** envTypeName, uno_Environment **)\n{\n" 198 << " *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;\n}\n\n"; 199 200 o << "extern \"C\" void * SAL_CALL component_getFactory(\n" 201 << " const char * implName, void * serviceManager, void * registryKey)\n{\n" 202 << " return ::cppu::component_getFactoryHelper(\n" 203 << " implName, serviceManager, registryKey, entries);\n}\n\n"; 204 205 o << "extern \"C\" sal_Bool SAL_CALL component_writeInfo(\n" 206 << " void * serviceManager, void * registryKey)\n{\n" 207 << " return ::cppu::component_writeInfoHelper(" 208 << "serviceManager, registryKey, entries);\n}\n"; 209 } 210 211 void generateXPropertySetBodies(std::ostream& o, 212 const OString & classname, 213 const OString & propertyhelper) 214 { 215 o << "// com.sun.star.beans.XPropertySet:\n"; 216 217 o << "css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL " 218 << classname << "getPropertySetInfo() throw (" 219 "css::uno::RuntimeException)\n{\n return ::cppu::PropertySetMixin< " 220 << propertyhelper 221 << " >::getPropertySetInfo();\n}\n\n"; 222 223 o << "void SAL_CALL " << classname << "setPropertyValue(const ::rtl::OUString" 224 " & aPropertyName, const css::uno::Any & aValue) throw (" 225 "css::uno::RuntimeException, css::beans::UnknownPropertyException, " 226 "css::beans::PropertyVetoException, css::lang::IllegalArgumentException, " 227 "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " 228 << propertyhelper << " >::setPropertyValue(aPropertyName, aValue);\n}\n\n"; 229 230 231 o << "css::uno::Any SAL_CALL " << classname << "getPropertyValue(const " 232 "::rtl::OUString & aPropertyName) throw (css::uno::RuntimeException, " 233 "css::beans::UnknownPropertyException, css::lang::WrappedTargetException)" 234 "\n{\n return ::cppu::PropertySetMixin< " 235 << propertyhelper << " >::getPropertyValue(aPropertyName);\n}\n\n"; 236 237 o << "void SAL_CALL " << classname << "addPropertyChangeListener(const " 238 "::rtl::OUString & aPropertyName, const css::uno::Reference< " 239 "css::beans::XPropertyChangeListener > & xListener) throw (" 240 "css::uno::RuntimeException, css::beans::UnknownPropertyException, " 241 "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " 242 << propertyhelper 243 << " >::addPropertyChangeListener(aPropertyName, xListener);\n}\n\n"; 244 245 o << "void SAL_CALL " << classname << "removePropertyChangeListener(const " 246 "::rtl::OUString & aPropertyName, const css::uno::Reference< " 247 "css::beans::XPropertyChangeListener > & xListener) throw (" 248 "css::uno::RuntimeException, css::beans::UnknownPropertyException, " 249 "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " 250 << propertyhelper 251 << " >::removePropertyChangeListener(aPropertyName, xListener);\n}\n\n"; 252 253 o << "void SAL_CALL " << classname << "addVetoableChangeListener(const " 254 "::rtl::OUString & aPropertyName, const css::uno::Reference< " 255 "css::beans::XVetoableChangeListener > & xListener) throw (" 256 "css::uno::RuntimeException, css::beans::UnknownPropertyException, " 257 "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " 258 << propertyhelper 259 << " >::addVetoableChangeListener(aPropertyName, xListener);\n}\n\n"; 260 261 o << "void SAL_CALL " << classname << "removeVetoableChangeListener(const " 262 "::rtl::OUString & aPropertyName, const css::uno::Reference< " 263 "css::beans::XVetoableChangeListener > & xListener) throw (" 264 "css::uno::RuntimeException, css::beans::UnknownPropertyException, " 265 "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " 266 << propertyhelper 267 << " >::removeVetoableChangeListener(aPropertyName, xListener);\n}\n\n"; 268 } 269 270 void generateXFastPropertySetBodies(std::ostream& o, 271 const OString & classname, 272 const OString & propertyhelper) 273 { 274 o << "// com.sun.star.beans.XFastPropertySet:\n"; 275 276 o << "void SAL_CALL " << classname << "setFastPropertyValue( ::sal_Int32 " 277 "nHandle, const css::uno::Any& aValue ) throw (" 278 "css::beans::UnknownPropertyException, css::beans::PropertyVetoException, " 279 "css::lang::IllegalArgumentException, css::lang::WrappedTargetException, " 280 "css::uno::RuntimeException)\n{\n ::cppu::PropertySetMixin< " 281 << propertyhelper << " >::setFastPropertyValue(nHandle, aValue);\n}\n\n"; 282 283 284 o << "css::uno::Any SAL_CALL " << classname << "getFastPropertyValue( " 285 "::sal_Int32 nHandle ) throw (css::beans::UnknownPropertyException, " 286 "css::lang::WrappedTargetException, css::uno::RuntimeException)\n{\n" 287 " return ::cppu::PropertySetMixin< " 288 << propertyhelper << " >::getFastPropertyValue(nHandle);\n}\n\n"; 289 } 290 291 void generateXPropertyAccessBodies(std::ostream& o, 292 const OString & classname, 293 const OString & propertyhelper) 294 { 295 o << " // com.sun.star.beans.XPropertyAccess:\n"; 296 297 o << "css::uno::Sequence< css::beans::PropertyValue > SAL_CALL " 298 << classname << "getPropertyValues( ) throw (" 299 "::com::sun::star::uno::RuntimeException)\n{\n" 300 " return ::cppu::PropertySetMixin< " 301 << propertyhelper << " >::getPropertyValues();\n}\n\n"; 302 303 o << "void SAL_CALL " << classname << "setPropertyValues( const " 304 "css::uno::Sequence< css::beans::PropertyValue >& aProps ) throw (" 305 "css::beans::UnknownPropertyException, css::beans::PropertyVetoException, " 306 "css::lang::IllegalArgumentException, css::lang::WrappedTargetException, " 307 "css::uno::RuntimeException)\n{\n" 308 " ::cppu::PropertySetMixin< " 309 << propertyhelper << " >::setPropertyValues(aProps);\n}\n\n"; 310 } 311 312 void generateXLocalizable(std::ostream& o, const OString & classname) 313 { 314 o << "// ::com::sun::star::lang::XLocalizable:\n" 315 "void SAL_CALL " << classname << "setLocale(const css::lang::" 316 "Locale & eLocale) throw (css::uno::RuntimeException)\n{\n" 317 " m_locale = eLocale;\n}\n\n" 318 "css::lang::Locale SAL_CALL " << classname << "getLocale() " 319 "throw (css::uno::RuntimeException)\n{\n return m_locale;\n}\n\n"; 320 } 321 322 void generateXAddInBodies(std::ostream& o, const OString & classname) 323 { 324 o << "// ::com::sun::star::sheet::XAddIn:\n"; 325 326 o << "::rtl::OUString SAL_CALL " << classname << "getProgrammaticFuntionName(" 327 "const ::rtl::OUString & aDisplayName) throw (css::uno::RuntimeException)" 328 "\n{\n ::rtl::OUString ret;\n try {\n css::uno::Reference< " 329 "css::container::XNameAccess > xNAccess(m_xHAccess, css::uno::UNO_QUERY);\n" 330 " css::uno::Sequence< ::rtl::OUString > functions = " 331 "xNAccess->getElementNames();\n sal_Int32 len = functions." 332 "getLength();\n ::rtl::OUString sDisplayName;\n" 333 " for (sal_Int32 i=0; i < len; ++i) {\n" 334 " sDisplayName = getAddinProperty(functions[i], " 335 "::rtl::OUString(),\n " 336 "sDISPLAYNAME);\n if (sDisplayName.equals(aDisplayName))\n" 337 " return functions[i];\n }\n }\n" 338 " catch ( css::uno::RuntimeException & e ) {\n throw e;\n }\n" 339 " catch ( css::uno::Exception & ) {\n }\n return ret;\n}\n\n"; 340 341 o << "::rtl::OUString SAL_CALL " << classname << "getDisplayFunctionName(const " 342 "::rtl::OUString & aProgrammaticName) throw (css::uno::RuntimeException)\n" 343 "{\n return getAddinProperty(aProgrammaticName, ::rtl::OUString(), " 344 "sDISPLAYNAME);\n}\n\n"; 345 346 o << "::rtl::OUString SAL_CALL " << classname << "getFunctionDescription(const " 347 "::rtl::OUString & aProgrammaticName) throw (css::uno::RuntimeException)\n" 348 "{\n return getAddinProperty(aProgrammaticName, ::rtl::OUString(), " 349 "sDESCRIPTION);\n}\n\n"; 350 351 o << "::rtl::OUString SAL_CALL " << classname << "getDisplayArgumentName(const " 352 "::rtl::OUString & aProgrammaticFunctionName, ::sal_Int32 nArgument) throw " 353 "(css::uno::RuntimeException)\n{\n return getAddinProperty(" 354 "aProgrammaticFunctionName,\n m_functionMap[" 355 "aProgrammaticFunctionName][nArgument],\n" 356 " sDISPLAYNAME);\n}\n\n"; 357 358 o << "::rtl::OUString SAL_CALL " << classname << "getArgumentDescription(const " 359 "::rtl::OUString & aProgrammaticFunctionName, ::sal_Int32 nArgument) throw " 360 "(css::uno::RuntimeException)\n{\n return getAddinProperty(" 361 "aProgrammaticFunctionName,\n " 362 "m_functionMap[aProgrammaticFunctionName][nArgument],\n" 363 " sDESCRIPTION);\n}\n\n"; 364 365 o << "::rtl::OUString SAL_CALL " << classname << "getProgrammaticCategoryName(" 366 "const ::rtl::OUString & aProgrammaticFunctionName) throw (" 367 "css::uno::RuntimeException)\n{\n return getAddinProperty(" 368 "aProgrammaticFunctionName, ::rtl::OUString(), sCATEGORY);\n}\n\n"; 369 370 o << "::rtl::OUString SAL_CALL " << classname << "getDisplayCategoryName(const " 371 "::rtl::OUString & aProgrammaticFunctionName) throw (" 372 "css::uno::RuntimeException)\n{\n return getAddinProperty(" 373 "aProgrammaticFunctionName, ::rtl::OUString(), " 374 "sCATEGORYDISPLAYNAME);\n}\n\n"; 375 } 376 377 void generateXCompatibilityNamesBodies(std::ostream& o, const OString & classname) 378 { 379 o << "// ::com::sun::star::sheet::XCompatibilityNames:\n" 380 "css::uno::Sequence< css::sheet::LocalizedName > SAL_CALL " << classname 381 << "getCompatibilityNames(const ::rtl::OUString & aProgrammaticName) throw " 382 "(css::uno::RuntimeException)\n{\n css::uno::Sequence< " 383 "css::sheet::LocalizedName > seqLocalizedNames;\n try {\n " 384 "::rtl::OUStringBuffer buf(" 385 "aProgrammaticName);\n buf.appendAscii(\"/CompatibilityName\");\n" 386 " ::rtl::OUString hname(buf.makeStringAndClear());\n\n " 387 "if ( m_xCompAccess->hasByHierarchicalName(hname) ) {\n" 388 " css::uno::Reference< css::container::XNameAccess > " 389 "xNameAccess(\n" 390 " m_xCompAccess->getByHierarchicalName(hname), " 391 "css::uno::UNO_QUERY);\n\n css::uno::Sequence< ::rtl::OUString" 392 " > elems = \n xNameAccess->getElementNames();" 393 "\n ::sal_Int32 len = elems.getLength();\n\n " 394 "seqLocalizedNames.realloc(len);\n\n ::rtl::OUString " 395 "sCompatibilityName;\n for (::sal_Int32 i=0; i < len; ++i) {\n" 396 " ::rtl::OUString sLocale(elems[i]);\n " 397 "xNameAccess->getByName(sLocale) >>= sCompatibilityName;\n\n" 398 " css::lang::Locale aLocale;\n " 399 "::sal_Int32 nIndex = 0, nToken = 0;\n " 400 "do {\n ::rtl::OUString aToken = sLocale.getToken(0, '-', " 401 "nIndex);\n switch (nToken++) {\n " 402 "case 0:\n aLocale.Language = aToken;\n" 403 " break;\n case 1:\n" 404 " aLocale.Country = aToken;\n " 405 " break;\n default:\n " 406 "aLocale.Variant = sLocale.copy(nIndex-aToken.getLength()-1);\n" 407 " nIndex = -1;\n }\n" 408 " } while ( nIndex >= 0 );\n\n " 409 "seqLocalizedNames[i].Locale = aLocale;\n " 410 "seqLocalizedNames[i].Name = sCompatibilityName;\n }" 411 "\n }\n }\n catch ( css::uno::RuntimeException & e ) {\n " 412 "throw e;\n }\n catch ( css::uno::Exception & ) {\n }\n\n" 413 " return seqLocalizedNames;\n}\n\n"; 414 } 415 416 void generateXInitialization(std::ostream& o, const OString & classname) 417 { 418 o << "// ::com::sun::star::lang::XInitialization:\n" 419 "void SAL_CALL " << classname << "initialize( const css::uno::Sequence< " 420 "css::uno::Any >& aArguments ) " 421 "throw (css::uno::Exception, css::uno::RuntimeException)\n{\n" 422 " css::uno::Reference < css::frame::XFrame > xFrame;\n" 423 " if ( aArguments.getLength() ) {\n aArguments[0] >>= xFrame;\n" 424 " m_xFrame = xFrame;\n }\n}\n\n"; 425 } 426 427 void generateXDispatch(std::ostream& o, 428 const OString & classname, 429 const ProtocolCmdMap & protocolCmdMap) 430 { 431 // com.sun.star.frame.XDispatch 432 // dispatch 433 o << "// ::com::sun::star::frame::XDispatch:\n" 434 "void SAL_CALL " << classname << "dispatch( const css::util::URL& aURL, const " 435 "css::uno::Sequence< css::beans::PropertyValue >& aArguments ) throw" 436 "(css::uno::RuntimeException)\n{\n"; 437 438 ProtocolCmdMap::const_iterator iter = protocolCmdMap.begin(); 439 while (iter != protocolCmdMap.end()) { 440 o << " if ( aURL.Protocol.equalsAscii(\"" << (*iter).first 441 << "\") == 0 )\n {\n"; 442 443 for (std::vector< OString >::const_iterator i = (*iter).second.begin(); 444 i != (*iter).second.end(); ++i) { 445 o << " if ( aURL.Path.equalsAscii(\"" << (*i) << "\") )\n" 446 " {\n // add your own code here\n" 447 " return;\n }\n"; 448 } 449 450 o << " }\n"; 451 iter++; 452 } 453 o << "}\n\n"; 454 455 // addStatusListener 456 o << "void SAL_CALL " << classname << "addStatusListener( const css::uno::Reference< " 457 "css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) " 458 "throw (css::uno::RuntimeException)\n{\n" 459 " // add your own code here\n}\n\n"; 460 461 // removeStatusListener 462 o << "void SAL_CALL " << classname << "removeStatusListener( const css::uno::Reference" 463 "< css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) " 464 "throw (css::uno::RuntimeException)\n{\n" 465 " // add your own code here\n}\n\n"; 466 } 467 468 void generateXDispatchProvider(std::ostream& o, 469 const OString & classname, 470 const ProtocolCmdMap & protocolCmdMap) 471 { 472 473 // com.sun.star.frame.XDispatchProvider 474 // queryDispatch 475 o << "// ::com::sun::star::frame::XDispatchProvider:\n" 476 "css::uno::Reference< css::frame::XDispatch > SAL_CALL " << classname 477 << "queryDispatch( const css::util::URL& aURL," 478 " const ::rtl::OUString& sTargetFrameName, sal_Int32 nSearchFlags ) " 479 "throw(css::uno::RuntimeException)\n{\n css::uno::Reference< " 480 "css::frame::XDispatch > xRet;\n" 481 " if ( !m_xFrame.is() )\n return 0;\n\n"; 482 483 ProtocolCmdMap::const_iterator iter = protocolCmdMap.begin(); 484 while (iter != protocolCmdMap.end()) { 485 o << " if ( aURL.Protocol.equalsAscii(\"" << (*iter).first 486 << "\") == 0 )\n {\n"; 487 488 for (std::vector< OString >::const_iterator i = (*iter).second.begin(); 489 i != (*iter).second.end(); ++i) { 490 o << " if ( aURL.Path.equalsAscii(\"" << (*i) << "\") == 0 )\n" 491 " xRet = this;\n"; 492 } 493 494 o << " }\n"; 495 iter++; 496 } 497 o << " return xRet;\n}\n\n"; 498 499 // queryDispatches 500 o << "css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL " 501 << classname << "queryDispatches( const css::uno::Sequence< " 502 "css::frame::DispatchDescriptor >& seqDescripts ) throw(" 503 "css::uno::RuntimeException)\n{\n" 504 " sal_Int32 nCount = seqDescripts.getLength();\n" 505 " css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > " 506 "lDispatcher(nCount);\n\n" 507 " for( sal_Int32 i=0; i<nCount; ++i ) {\n" 508 " lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL,\n" 509 " seqDescripts[i].FrameName,\n" 510 " seqDescripts[i].SearchFlags );\n" 511 " }\n\n return lDispatcher;\n}\n\n"; 512 } 513 514 void generateAddinConstructorAndHelper(std::ostream& o, 515 ProgramOptions const & options, 516 TypeManager const & manager, const OString & classname, 517 const std::hash_set< OString, OStringHash >& interfaces) 518 { 519 o << classname << "::" << classname 520 << "(css::uno::Reference< css::uno::XComponentContext > const & context) :\n" 521 << " m_xContext(context), m_locale()\n{\n"; 522 523 if (options.backwardcompatible) { 524 o << " try {\n"; 525 526 generateFunctionParameterMap(o, options, manager, interfaces); 527 528 o << " css::uno::Reference< css::lang::XMultiServiceFactory > xProvider" 529 "(\n m_xContext->getServiceManager()->createInstanceWithContext" 530 "(\n ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\n " 531 " \"com.sun.star.configuration.ConfigurationProvider\"))," 532 "\n m_xContext ), css::uno::UNO_QUERY );\n\n"; 533 534 o << " ::rtl::OUString sReadOnlyView(\n" 535 " RTL_CONSTASCII_USTRINGPARAM(\n" 536 " \"com.sun.star.configuration.ConfigurationAccess\"));\n\n"; 537 538 o << " ::rtl::OUStringBuffer sPath(::rtl::OUString::createFromAscii(\n" 539 " \"/org.openoffice.Office.CalcAddIns/AddInInfo/\"));\n" 540 " sPath.appendAscii(sADDIN_SERVICENAME);\n" 541 " sPath.appendAscii(\"/AddInFunctions\");\n\n" 542 " // create arguments: nodepath\n" 543 " css::beans::PropertyValue aArgument;\n" 544 " aArgument.Name = ::rtl::OUString::createFromAscii(\"nodepath\");\n" 545 " aArgument.Value <<= sPath.makeStringAndClear();\n\n" 546 " css::uno::Sequence< css::uno::Any > aArguments(1);\n" 547 " aArguments[0] <<= aArgument;\n\n"; 548 549 o << " // create the default view using default UI locale\n" 550 " css::uno::Reference< css::uno::XInterface > xIface =\n" 551 " xProvider->createInstanceWithArguments(sReadOnlyView, " 552 "aArguments);\n\n" 553 " m_xHAccess = css::uno::Reference<\n " 554 "css::container::XHierarchicalNameAccess >(xIface, css::uno::UNO_QUERY);" 555 "\n\n"; 556 557 o << " // extend arguments to create a view for all locales to get " 558 "simple\n // access to the compatibilityname property\n" 559 " aArgument.Name = ::rtl::OUString::createFromAscii(\"locale\");\n" 560 " aArgument.Value <<= ::rtl::OUString::createFromAscii(\"*\");\n" 561 " aArguments.realloc(2);\n" 562 " aArguments[1] <<= aArgument;\n\n" 563 " // create view for all locales\n" 564 " xIface = xProvider->createInstanceWithArguments(sReadOnlyView, " 565 "aArguments);\n\n" 566 " m_xCompAccess = css::uno::Reference<\n " 567 "css::container::XHierarchicalNameAccess >(xIface, css::uno::UNO_QUERY);\n"; 568 569 o << " }\n catch ( css::uno::Exception & ) {\n }\n}\n\n"; 570 571 o << "// addin configuration property helper function:\n::rtl::OUString " 572 "SAL_CALL " << classname << "::getAddinProperty(const ::rtl::OUString &" 573 " funcName, const ::rtl::OUString & paramName, const char * propName) " 574 "throw (css::uno::RuntimeException)\n{\n" 575 " ::rtl::OUString ret;\n try {\n " 576 "::rtl::OUStringBuffer buf(funcName);\n" 577 " if (paramName.getLength() > 0) {\n" 578 " buf.appendAscii(\"/Parameters/\");\n" 579 " buf.append(paramName);\n }\n\n" 580 " css::uno::Reference< css::beans::XPropertySet > xPropSet(\n" 581 " m_xHAccess->getByHierarchicalName(\n" 582 " buf.makeStringAndClear()), css::uno::UNO_QUERY);\n" 583 " xPropSet->getPropertyValue(\n " 584 "::rtl::OUString::createFromAscii(propName)) >>= ret;\n }\n" 585 " catch ( css::uno::RuntimeException & e ) {\n throw e;\n }\n" 586 " catch ( css::uno::Exception & ) {\n }\n return ret;\n"; 587 } 588 o <<"}\n\n"; 589 } 590 591 void generateMemberInitialization(std::ostream& o, 592 ProgramOptions const & options, 593 TypeManager const & manager, 594 AttributeInfo const & members) 595 { 596 if (!members.empty()) { 597 for (AttributeInfo::const_iterator i(members.begin()); 598 i != members.end(); ++i) 599 { 600 RTTypeClass typeClass; 601 OString type(i->second.first.replace('.','/')); 602 OString name; 603 sal_Int32 rank; 604 std::vector< OString > arguments; 605 codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( 606 manager, type, true, true, true, &typeClass, &name, &rank, 607 &arguments); 608 609 if (sort <= codemaker::UnoType::SORT_CHAR && rank == 0) { 610 o << ",\n m_" << i->first << "("; 611 printType(o, options, manager, type, 16, true); 612 o << ")"; 613 } 614 } 615 } 616 } 617 618 void generateMemberDeclaration(std::ostream& o, 619 ProgramOptions const & options, 620 TypeManager const & manager, 621 AttributeInfo const & members) 622 { 623 for (AttributeInfo::const_iterator i(members.begin()); 624 i != members.end(); ++i) 625 { 626 o << " "; 627 printType(o, options, manager, i->second.first.replace('.','/'), 628 1, false); 629 o << " m_" << i->first << ";\n"; 630 } 631 } 632 633 OString generateClassDefinition(std::ostream& o, 634 ProgramOptions const & options, 635 TypeManager const & manager, 636 OString const & classname, 637 std::hash_set< OString, OStringHash > const & interfaces, 638 AttributeInfo const & properties, 639 AttributeInfo const & attributes, 640 std::hash_set< OString, OStringHash > const & propinterfaces, 641 OString const & propertyhelper, bool supportxcomponent) 642 { 643 OStringBuffer parentname(64); 644 o << "class " << classname << ":\n"; 645 646 if (!interfaces.empty()) { 647 if (supportxcomponent) { 648 parentname.append("::cppu::WeakComponentImplHelper"); 649 parentname.append(static_cast<sal_Int32>(interfaces.size())); 650 o << " private ::cppu::BaseMutex,\n" 651 << " public ::cppu::WeakComponentImplHelper" 652 << interfaces.size() << "<"; 653 } else { 654 parentname.append("::cppu::WeakImplHelper"); 655 parentname.append(static_cast<sal_Int32>(interfaces.size())); 656 o << " public ::cppu::WeakImplHelper" << interfaces.size() << "<"; 657 } 658 659 std::hash_set< OString, OStringHash >::const_iterator iter = 660 interfaces.begin(); 661 while (iter != interfaces.end()) 662 { 663 o << "\n " << scopedCppName(*iter, false, true); 664 iter++; 665 if (iter != interfaces.end()) 666 o << ","; 667 else 668 o << ">"; 669 } 670 } 671 672 if (propertyhelper.getLength() > 1) { 673 o << ",\n public ::cppu::PropertySetMixin< " 674 << scopedCppName(propertyhelper, false, true) << " >"; 675 } 676 677 o << "\n{\npublic:\n" 678 << " explicit " << classname << "(" 679 << "css::uno::Reference< css::uno::XComponentContext > const & context);\n\n"; 680 681 // generate component/service helper functions 682 // o << " // component and service helper functions:\n" 683 // << " static ::rtl::OUString SAL_CALL _getImplementationName();\n" 684 // << " static css::uno::Sequence< ::rtl::OUString > SAL_CALL " 685 // << "_getSupportedServiceNames();\n" 686 // << " static css::uno::Reference< css::uno::XInterface > SAL_CALL _create(" 687 // << "\n css::uno::Reference< css::uno::XComponentContext > const & " 688 // << "context);\n\n"; 689 690 // overload queryInterface 691 if (propertyhelper.getLength() > 1) { 692 o << " // ::com::sun::star::uno::XInterface:\n" 693 " virtual css::uno::Any SAL_CALL queryInterface(" 694 "css::uno::Type const & type) throw (" 695 "css::uno::RuntimeException);\n"; 696 697 OStringBuffer buffer(256); 698 buffer.append(parentname); 699 buffer.append("< "); 700 std::hash_set< OString, OStringHash >::const_iterator iter = 701 interfaces.begin(); 702 while (iter != interfaces.end()) 703 { 704 buffer.append(scopedCppName(*iter, false, true)); 705 iter++; 706 if (iter != interfaces.end()) 707 buffer.append(", "); 708 else 709 buffer.append(" >"); 710 } 711 OString parent(buffer.makeStringAndClear()); 712 o << " virtual void SAL_CALL acquire() throw ()\n { " 713 << parent << "::acquire(); }\n"; 714 o << " virtual void SAL_CALL release() throw ()\n { " 715 << parent << "::release(); }\n\n"; 716 } 717 718 std::hash_set< OString, OStringHash >::const_iterator it = 719 interfaces.begin(); 720 codemaker::GeneratedTypeSet generated; 721 while (it != interfaces.end()) 722 { 723 typereg::Reader reader(manager.getTypeReader((*it).replace('.','/'))); 724 printMethods(o, options, manager, reader, generated, "", "", " ", 725 true, propertyhelper); 726 it++; 727 } 728 729 o << "private:\n " << classname << "(const " << classname << " &); // not defined\n" 730 << " " << classname << "& operator=(const " << classname << " &); // not defined\n\n" 731 << " // destructor is private and will be called indirectly by the release call" 732 << " virtual ~" << classname << "() {}\n\n"; 733 734 if (options.componenttype == 2) { 735 o << " typedef std::hash_map< ::sal_Int32, rtl::OUString, " 736 "std::hash<::sal_Int32> > ParamMap;\n" 737 " typedef std::hash_map< rtl::OUString, ParamMap, " 738 "rtl::OUStringHash > FunctionMap;\n\n" 739 " ::rtl::OUString SAL_CALL getAddinProperty(const ::rtl::OUString & " 740 "funcName, const ::rtl::OUString & paramName, const char * propName) " 741 "throw (css::uno::RuntimeException);\n\n"; 742 } 743 744 if (supportxcomponent) { 745 o << " // overload WeakComponentImplHelperBase::disposing()\n" 746 " // This function is called upon disposing the component,\n" 747 " // if your component needs special work when it becomes\n" 748 " // disposed, do it here.\n" 749 " virtual void SAL_CALL disposing();\n\n"; 750 } 751 752 // members 753 o << " css::uno::Reference< css::uno::XComponentContext > m_xContext;\n"; 754 if (!supportxcomponent && !attributes.empty()) 755 o << " mutable ::osl::Mutex m_aMutex;\n"; 756 757 // additional member for add-ons 758 if (options.componenttype == 3) { 759 o << " css::uno::Reference< css::frame::XFrame > m_xFrame;\n"; 760 } 761 762 if (options.componenttype == 2) { 763 if (options.backwardcompatible) { 764 o <<" css::uno::Reference< css::container::XHierarchicalNameAccess > " 765 "m_xHAccess;\n" 766 " css::uno::Reference< css::container::XHierarchicalNameAccess > " 767 "m_xCompAccess;\n" 768 " FunctionMap m_functionMap;\n"; 769 } 770 o << " css::lang::Locale m_locale;\n"; 771 } 772 773 generateMemberDeclaration(o, options, manager, properties); 774 generateMemberDeclaration(o, options, manager, attributes); 775 776 // if (!properties.empty()) 777 // { 778 // AttributeInfo::const_iterator iter = properties.begin(); 779 // while (iter != properties.end()) 780 // { 781 // o << " "; 782 // printType(o, options, manager, iter->second.first.replace('.','/'), 783 // 1, false); 784 // o << " m_" << iter->first << ";\n"; 785 // iter++; 786 // } 787 // } 788 // if (!attributes.empty()) 789 // { 790 // AttributeInfo::const_iterator iter = attributes.begin(); 791 // while (iter != attributes.end()) 792 // { 793 // o << " "; 794 // printType(o, options, manager, iter->second.first.replace('.','/'), 795 // 1, false); 796 // o << " m_" << iter->first << ";\n"; 797 // iter++; 798 // } 799 // } 800 801 o << "};\n\n"; 802 803 // generate constructor 804 if (options.componenttype == 2) { 805 generateAddinConstructorAndHelper(o, options, manager, 806 classname, interfaces); 807 } else { 808 o << classname << "::" << classname 809 << "(css::uno::Reference< css::uno::XComponentContext > const & context) :\n"; 810 if (supportxcomponent) { 811 o << " ::cppu::WeakComponentImplHelper" << interfaces.size() << "<"; 812 std::hash_set< OString, OStringHash >::const_iterator iter = 813 interfaces.begin(); 814 while (iter != interfaces.end()) { 815 o << "\n " << scopedCppName(*iter, false, true); 816 iter++; 817 if (iter != interfaces.end()) 818 o << ","; 819 else 820 o << ">(m_aMutex),\n"; 821 } 822 } 823 if (propertyhelper.getLength() > 1) { 824 o << " ::cppu::PropertySetMixin< " 825 << scopedCppName(propertyhelper, false, true) << " >(\n" 826 << " context, static_cast< Implements >(\n "; 827 OStringBuffer buffer(128); 828 if (propinterfaces.find("com/sun/star/beans/XPropertySet") 829 != propinterfaces.end()) { 830 buffer.append("IMPLEMENTS_PROPERTY_SET"); 831 } 832 if (propinterfaces.find("com/sun/star/beans/XFastPropertySet") 833 != propinterfaces.end()) { 834 if (buffer.getLength() > 0) 835 buffer.append(" | IMPLEMENTS_FAST_PROPERTY_SET"); 836 else 837 buffer.append("IMPLEMENTS_FAST_PROPERTY_SET"); 838 } 839 if (propinterfaces.find("com/sun/star/beans/XPropertyAccess") 840 != propinterfaces.end()) { 841 if (buffer.getLength() > 0) 842 buffer.append(" | IMPLEMENTS_PROPERTY_ACCESS"); 843 else 844 buffer.append("IMPLEMENTS_PROPERTY_ACCESS"); 845 } 846 o << buffer.makeStringAndClear() 847 << "), css::uno::Sequence< ::rtl::OUString >()),\n"; 848 } 849 o << " m_xContext(context)"; 850 851 generateMemberInitialization(o, options, manager, properties); 852 generateMemberInitialization(o, options, manager, attributes); 853 854 o << "\n{}\n\n"; 855 } 856 857 // generate service/component helper function implementations 858 // generateServiceHelper(o, options.implname, classname, services); 859 860 if (supportxcomponent) { 861 o << "// overload WeakComponentImplHelperBase::disposing()\n" 862 "// This function is called upon disposing the component,\n" 863 "// if your component needs special work when it becomes\n" 864 "// disposed, do it here.\n" 865 "void SAL_CALL " << classname << "::disposing()\n{\n\n}\n\n"; 866 } 867 868 return parentname.makeStringAndClear(); 869 } 870 871 void generateXServiceInfoBodies(std::ostream& o, 872 OString const & classname, 873 OString const & comphelpernamespace) 874 { 875 o << "// com.sun.star.uno.XServiceInfo:\n" 876 << "::rtl::OUString SAL_CALL " << classname << "getImplementationName() " 877 << "throw (css::uno::RuntimeException)\n{\n " 878 << "return " << comphelpernamespace << "::_getImplementationName();\n}\n\n"; 879 880 o << "::sal_Bool SAL_CALL " << classname 881 << "supportsService(::rtl::OUString const & " 882 << "serviceName) throw (css::uno::RuntimeException)\n{\n " 883 << "css::uno::Sequence< ::rtl::OUString > serviceNames = " 884 << comphelpernamespace << "::_getSupportedServiceNames();\n " 885 << "for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {\n " 886 << " if (serviceNames[i] == serviceName)\n return sal_True;\n" 887 << " }\n return sal_False;\n}\n\n"; 888 889 o << "css::uno::Sequence< ::rtl::OUString > SAL_CALL " << classname 890 << "getSupportedServiceNames() throw (css::uno::RuntimeException)\n{\n " 891 << "return " << comphelpernamespace 892 << "::_getSupportedServiceNames();\n}\n\n"; 893 } 894 895 896 void generateMethodBodies(std::ostream& o, 897 ProgramOptions const & options, 898 TypeManager const & manager, 899 std::hash_set< OString, OStringHash > const & interfaces, 900 OString const & classname, 901 OString const & comphelpernamespace, 902 OString const & propertyhelper) 903 { 904 OString name(classname.concat("::")); 905 std::hash_set< OString, OStringHash >::const_iterator iter = 906 interfaces.begin(); 907 codemaker::GeneratedTypeSet generated; 908 while (iter != interfaces.end()) { 909 if ( (*iter).equals("com.sun.star.lang.XServiceInfo") ) { 910 generateXServiceInfoBodies(o, name, comphelpernamespace); 911 generated.add(*iter); 912 } else { 913 typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/'))); 914 printMethods(o, options, manager, reader, generated, "_", 915 name, "", true, propertyhelper); 916 } 917 iter++; 918 } 919 } 920 921 void generateQueryInterface(std::ostream& o, 922 ProgramOptions const & options, 923 TypeManager const & manager, 924 const std::hash_set< OString, OStringHash >& interfaces, 925 OString const & parentname, 926 OString const & classname, 927 OString const & propertyhelper) 928 { 929 if (propertyhelper.getLength() == 0) 930 return; 931 932 o << "css::uno::Any " << classname 933 << "::queryInterface(css::uno::Type const & type) throw (" 934 "css::uno::RuntimeException)\n{\n "; 935 936 if (propertyhelper.getLength() >= 1) 937 o << "return "; 938 else 939 o << "css::uno::Any a("; 940 941 o << parentname << "<"; 942 std::hash_set< OString, OStringHash >::const_iterator iter = 943 interfaces.begin(); 944 while (iter != interfaces.end()) 945 { 946 o << "\n " << scopedCppName(*iter, false, true); 947 iter++; 948 if (iter != interfaces.end()) 949 o << ","; 950 else 951 o << ">"; 952 } 953 954 if (propertyhelper.getLength() >= 1) { 955 o << "::queryInterface(type);\n"; 956 } else { 957 o << "::queryInterface(type));\n"; 958 o << " return a.hasValue() ? a\n : ("; 959 if (propertyhelper.equals("_")) { 960 o << "::cppu::OPropertySetHelper::queryInterface(type));\n"; 961 } else { 962 o << "::cppu::PropertySetMixin<\n "; 963 printType(o, options, manager, propertyhelper.replace('.', '/'), 964 0, false); 965 o << " >::queryInterface(\n type));\n"; 966 } 967 } 968 o << "}\n\n"; 969 } 970 971 void generateSkeleton(ProgramOptions const & options, 972 TypeManager const & manager, 973 std::vector< OString > const & types, 974 OString const & /*delegate*/) 975 { 976 // special handling of calc add-ins 977 if (options.componenttype == 2) { 978 generateCalcAddin(options, manager, types); 979 return; 980 } 981 982 std::hash_set< OString, OStringHash > interfaces; 983 std::hash_set< OString, OStringHash > services; 984 AttributeInfo properties; 985 AttributeInfo attributes; 986 std::hash_set< OString, OStringHash > propinterfaces; 987 bool serviceobject = false; 988 bool supportxcomponent = false; 989 990 std::vector< OString >::const_iterator iter = types.begin(); 991 while (iter != types.end()) { 992 checkType(manager, *iter, interfaces, services, properties); 993 iter++; 994 } 995 996 if (options.componenttype == 3) { 997 // the Protocolhandler service is mandatory for an protocol handler add-on, 998 // so it is defaulted. The XDispatchProvider provides Dispatch objects for 999 // certain functions and the generated impl object implements XDispatch 1000 // directly for simplicity reasons. 1001 checkType(manager, "com.sun.star.frame.ProtocolHandler", 1002 interfaces, services, properties); 1003 checkType(manager, "com.sun.star.frame.XDispatch", 1004 interfaces, services, properties); 1005 } 1006 1007 // check if service object or simple UNO object 1008 if (!services.empty()) 1009 serviceobject = true; 1010 1011 OString propertyhelper = checkPropertyHelper( 1012 options, manager, services, interfaces, attributes, propinterfaces); 1013 1014 checkDefaultInterfaces(interfaces, services, propertyhelper); 1015 1016 if (interfaces.size() > 12) 1017 throw CannotDumpException( 1018 "the skeletonmaker supports components with 12 interfaces " 1019 "only (limitation of the UNO implementation helpers)!"); 1020 1021 1022 supportxcomponent = checkXComponentSupport(manager, interfaces); 1023 1024 OString compFileName; 1025 OString tmpFileName; 1026 std::ostream* pofs = NULL; 1027 bool standardout = getOutputStream(options, ".cxx", 1028 &pofs, compFileName, tmpFileName); 1029 1030 try { 1031 if (!standardout && options.license) { 1032 printLicenseHeader(*pofs, compFileName); 1033 } 1034 1035 generateIncludes(*pofs, interfaces, properties, propertyhelper, 1036 serviceobject, supportxcomponent); 1037 1038 if (options.componenttype == 3) { 1039 *pofs << "#include \"com/sun/star/frame/XFrame.hpp\"\n"; 1040 } 1041 1042 // namespace 1043 OString nmspace; 1044 short nm = 0; 1045 1046 if (serviceobject) { 1047 nmspace = generateCompHelperDeclaration(*pofs, options.implname); 1048 1049 *pofs << 1050 "\n\n/// anonymous implementation namespace\nnamespace {\n\n" 1051 "namespace css = ::com::sun::star;\n\n"; 1052 } else { 1053 nm = generateNamespace(*pofs, options.implname, false, nmspace); 1054 *pofs << "namespace css = ::com::sun::star;\n\n"; 1055 } 1056 1057 sal_Int32 index = 0; 1058 OString classname(options.implname); 1059 if ((index = classname.lastIndexOf('.')) > 0) 1060 classname = classname.copy(index+1); 1061 1062 OString parentname( 1063 generateClassDefinition(*pofs, 1064 options, manager, classname, interfaces, properties, 1065 attributes, propinterfaces, propertyhelper, supportxcomponent)); 1066 1067 generateQueryInterface(*pofs, options, manager, interfaces, parentname, 1068 classname, propertyhelper); 1069 1070 generateMethodBodies(*pofs, options, manager, interfaces, classname, 1071 nmspace, propertyhelper); 1072 1073 if (serviceobject) { 1074 // close namepsace 1075 *pofs << "} // closing anonymous implementation namespace\n\n"; 1076 1077 generateCompHelperDefinition(*pofs, options.implname, 1078 classname, services); 1079 generateCompFunctions(*pofs, nmspace); 1080 } else { 1081 // close namepsace 1082 for (short i=0; i < nm; i++) 1083 *pofs << "} "; 1084 *pofs << (nm > 0 ? "// closing namespace\n\n" : "\n"); 1085 } 1086 1087 if ( !standardout && pofs && ((std::ofstream*)pofs)->is_open()) { 1088 ((std::ofstream*)pofs)->close(); 1089 delete pofs; 1090 OSL_VERIFY(makeValidTypeFile(compFileName, tmpFileName, sal_False)); 1091 } 1092 } catch(CannotDumpException& e) { 1093 1094 std::cerr << "ERROR: " << e.m_message.getStr() << "\n"; 1095 if ( !standardout ) { 1096 if (pofs && ((std::ofstream*)pofs)->is_open()) { 1097 ((std::ofstream*)pofs)->close(); 1098 delete pofs; 1099 } 1100 // remove existing type file if something goes wrong to ensure 1101 // consistency 1102 if (fileExists(compFileName)) 1103 removeTypeFile(compFileName); 1104 1105 // remove tmp file if something goes wrong 1106 removeTypeFile(tmpFileName); 1107 } 1108 } 1109 } 1110 1111 void generateCalcAddin(ProgramOptions const & options, 1112 TypeManager const & manager, 1113 std::vector< OString > const & types) 1114 { 1115 std::hash_set< OString, OStringHash > interfaces; 1116 std::hash_set< OString, OStringHash > services; 1117 AttributeInfo properties; 1118 AttributeInfo attributes; 1119 std::hash_set< OString, OStringHash > propinterfaces; 1120 bool serviceobject = false; 1121 bool supportxcomponent = false; 1122 1123 1124 std::vector< OString >::const_iterator iter = types.begin(); 1125 while (iter != types.end()) { 1126 checkType(manager, *iter, interfaces, services, properties); 1127 iter++; 1128 } 1129 1130 OString sAddinService; 1131 if (services.size() != 1) { 1132 throw CannotDumpException( 1133 "for calc add-in components one and only one service type is necessary!" 1134 " Please reference a valid type with the '-t' option."); 1135 } 1136 1137 1138 // get the one and only add-in service for later use 1139 std::hash_set< OString, OStringHash >::const_iterator iter2 = services.begin(); 1140 sAddinService = (*iter2).replace('/', '.'); 1141 if (sAddinService.equals("com.sun.star.sheet.AddIn")) { 1142 sAddinService = (*(++iter2)).replace('/', '.'); 1143 } 1144 1145 // if backwardcompatible==true the AddIn service needs to be added to the 1146 // suported service list, the necessary intefaces are mapped to the add-in 1147 // configuration. Since OO.org 2.0.4 this is obsolete and the add-in is 1148 // take form the configuration from Calc directly, this simplifies the 1149 // add-in code 1150 if (options.backwardcompatible) { 1151 checkType(manager, "com.sun.star.sheet.AddIn", 1152 interfaces, services, properties); 1153 } else { 1154 // special case for the optional XLocalization interface. It should be 1155 // implemented always. But it is parent of the XAddIn and we need it only 1156 // if backwardcompatible is false. 1157 if (interfaces.find("com.sun.star.lang.XLocalizable") == interfaces.end()) { 1158 interfaces.insert("com.sun.star.lang.XLocalizable"); 1159 } 1160 } 1161 1162 OString propertyhelper = checkPropertyHelper( 1163 options, manager, services, interfaces, attributes, propinterfaces); 1164 1165 if (propertyhelper.getLength() > 0) 1166 std::cerr << "WARNING: interfaces specifying calc add-in functions " 1167 "shouldn't support attributes!\n"; 1168 1169 checkDefaultInterfaces(interfaces, services, propertyhelper); 1170 1171 if (interfaces.size() > 12) { 1172 throw CannotDumpException( 1173 "the skeletonmaker supports components with 12 interfaces " 1174 "only (limitation of the UNO implementation helpers)!"); 1175 } 1176 1177 // check if service object or simple UNO object 1178 if (!services.empty()) 1179 serviceobject = true; 1180 1181 supportxcomponent = checkXComponentSupport(manager, interfaces); 1182 if (supportxcomponent) 1183 std::cerr << "WARNING: add-ins shouldn't support " 1184 "com.sun.star.uno.XComponent!\n"; 1185 1186 OString compFileName; 1187 OString tmpFileName; 1188 std::ostream* pofs = NULL; 1189 bool standardout = getOutputStream(options, ".cxx", 1190 &pofs, compFileName, tmpFileName); 1191 1192 try { 1193 if (!standardout && options.license) { 1194 printLicenseHeader(*pofs, compFileName); 1195 } 1196 1197 generateIncludes(*pofs, interfaces, properties, propertyhelper, 1198 serviceobject, supportxcomponent); 1199 1200 *pofs << 1201 "#include \"com/sun/star/beans/PropertyValue.hpp\"\n" 1202 "#include \"com/sun/star/beans/XPropertySet.hpp\"\n" 1203 "#include \"com/sun/star/container/XNameAccess.hpp\"\n" 1204 "#include \"com/sun/star/container/XHierarchicalNameAccess.hpp\"\n\n" 1205 "#include \"rtl/ustrbuf.hxx\"\n\n" 1206 "#include <hash_map>\n" 1207 "#include <set>\n"; 1208 1209 // namespace 1210 OString nmspace(generateCompHelperDeclaration(*pofs, options.implname)); 1211 1212 *pofs << 1213 "\n\n// anonymous implementation namespace\nnamespace {\n\n" 1214 "namespace css = ::com::sun::star;\n\n"; 1215 1216 sal_Int32 index = 0; 1217 OString classname(options.implname); 1218 if ((index = classname.lastIndexOf('.')) > 0) { 1219 classname = classname.copy(index+1); 1220 } 1221 1222 if (options.backwardcompatible) { 1223 *pofs << "static const char * sADDIN_SERVICENAME = \"" 1224 << sAddinService << "\";\n\n"; 1225 *pofs << "static const char * sDISPLAYNAME = \"DisplayName\";\n" 1226 "static const char * sDESCRIPTION = \"Description\";\n" 1227 "static const char * sCATEGORY = \"Category\";\n" 1228 "static const char * sCATEGORYDISPLAYNAME = \"CategoryDisplayName\";" 1229 "\n\n"; 1230 } 1231 1232 OString parentname( 1233 generateClassDefinition(*pofs, 1234 options, manager, classname, interfaces, properties, 1235 attributes, propinterfaces, propertyhelper, supportxcomponent)); 1236 1237 generateQueryInterface(*pofs, options, manager, interfaces, parentname, 1238 classname, propertyhelper); 1239 1240 generateMethodBodies(*pofs, options, manager, interfaces, classname, 1241 nmspace, propertyhelper); 1242 1243 // close namepsace 1244 *pofs << "} // closing anonymous implementation namespace\n\n"; 1245 1246 generateCompHelperDefinition(*pofs, options.implname, classname, 1247 services); 1248 1249 generateCompFunctions(*pofs, nmspace); 1250 1251 if ( !standardout && pofs && ((std::ofstream*)pofs)->is_open()) { 1252 ((std::ofstream*)pofs)->close(); 1253 delete pofs; 1254 OSL_VERIFY(makeValidTypeFile(compFileName, tmpFileName, sal_False)); 1255 } 1256 } catch(CannotDumpException& e) { 1257 1258 std::cerr << "ERROR: " << e.m_message.getStr() << "\n"; 1259 if ( !standardout ) { 1260 if (pofs && ((std::ofstream*)pofs)->is_open()) { 1261 ((std::ofstream*)pofs)->close(); 1262 delete pofs; 1263 } 1264 // remove existing type file if something goes wrong to ensure 1265 // consistency 1266 if (fileExists(compFileName)) 1267 removeTypeFile(compFileName); 1268 1269 // remove tmp file if something goes wrong 1270 removeTypeFile(tmpFileName); 1271 } 1272 } 1273 } 1274 1275 } } 1276 1277 1278