xref: /AOO41X/main/unodevtools/source/skeletonmaker/cppcompskeleton.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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