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