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