xref: /AOO41X/main/unodevtools/source/skeletonmaker/skeletoncommon.cxx (revision 7ceddb922c36bc48f0711c90dec62c8f86ce5272)
1*7ceddb92SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*7ceddb92SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*7ceddb92SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*7ceddb92SAndrew Rist  * distributed with this work for additional information
6*7ceddb92SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*7ceddb92SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*7ceddb92SAndrew Rist  * "License"); you may not use this file except in compliance
9*7ceddb92SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*7ceddb92SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*7ceddb92SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*7ceddb92SAndrew Rist  * software distributed under the License is distributed on an
15*7ceddb92SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*7ceddb92SAndrew Rist  * KIND, either express or implied.  See the License for the
17*7ceddb92SAndrew Rist  * specific language governing permissions and limitations
18*7ceddb92SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*7ceddb92SAndrew Rist  *************************************************************/
21*7ceddb92SAndrew Rist 
22*7ceddb92SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir #include "osl/thread.hxx"
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "codemaker/commonjava.hxx"
27cdf0e10cSrcweir #include "codemaker/commoncpp.hxx"
28cdf0e10cSrcweir #include "codemaker/generatedtypeset.hxx"
29cdf0e10cSrcweir 
30cdf0e10cSrcweir #include "skeletoncommon.hxx"
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <iostream>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir using namespace ::rtl;
35cdf0e10cSrcweir using namespace ::codemaker::cpp;
36cdf0e10cSrcweir 
37cdf0e10cSrcweir namespace skeletonmaker {
38cdf0e10cSrcweir 
39cdf0e10cSrcweir void printLicenseHeader(std::ostream& o, rtl::OString const & filename)
40cdf0e10cSrcweir {
41cdf0e10cSrcweir     sal_Int32 index = -1;
42cdf0e10cSrcweir #ifdef SAL_UNX
43cdf0e10cSrcweir 	index = filename.lastIndexOf('/');
44cdf0e10cSrcweir #else
45cdf0e10cSrcweir 	index = filename.lastIndexOf('\\');
46cdf0e10cSrcweir #endif
47cdf0e10cSrcweir     OString shortfilename(filename);
48cdf0e10cSrcweir     if ( index != -1 )
49cdf0e10cSrcweir         shortfilename = filename.copy(index+1);
50cdf0e10cSrcweir 
51cdf0e10cSrcweir     o << "/*************************************************************************\n"
52cdf0e10cSrcweir         " *\n"
53cdf0e10cSrcweir         " * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n"
54cdf0e10cSrcweir         " * \n"
55cdf0e10cSrcweir         " * Copyright 2000, 2010 Oracle and/or its affiliates.\n"
56cdf0e10cSrcweir         " *\n"
57cdf0e10cSrcweir         " * OpenOffice.org - a multi-platform office productivity suite\n"
58cdf0e10cSrcweir         " *\n"
59cdf0e10cSrcweir         " * This file is part of OpenOffice.org.\n"
60cdf0e10cSrcweir         " *\n"
61cdf0e10cSrcweir         " * OpenOffice.org is free software: you can redistribute it and/or modify\n"
62cdf0e10cSrcweir         " * it under the terms of the GNU Lesser General Public License version 3\n"
63cdf0e10cSrcweir         " * only, as published by the Free Software Foundation.\n"
64cdf0e10cSrcweir         " *\n"
65cdf0e10cSrcweir         " * OpenOffice.org is distributed in the hope that it will be useful,\n"
66cdf0e10cSrcweir         " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
67cdf0e10cSrcweir         " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"
68cdf0e10cSrcweir         " * GNU Lesser General Public License version 3 for more details\n"
69cdf0e10cSrcweir         " * (a copy is included in the LICENSE file that accompanied this code).\n"
70cdf0e10cSrcweir         " *\n"
71cdf0e10cSrcweir         " * You should have received a copy of the GNU Lesser General Public License\n"
72cdf0e10cSrcweir         " * version 3 along with OpenOffice.org.  If not, see\n"
73cdf0e10cSrcweir         " * <http://www.openoffice.org/license.html>\n"
74cdf0e10cSrcweir         " * for a copy of the LGPLv3 License.\n"
75cdf0e10cSrcweir         " *\n"
76cdf0e10cSrcweir         " ************************************************************************/\n\n";
77cdf0e10cSrcweir }
78cdf0e10cSrcweir 
79cdf0e10cSrcweir bool getOutputStream(ProgramOptions const & options,
80cdf0e10cSrcweir                      OString const & extension,
81cdf0e10cSrcweir                      std::ostream** ppOutputStream,
82cdf0e10cSrcweir                      OString & targetSourceFileName,
83cdf0e10cSrcweir                      OString & tmpSourceFileName)
84cdf0e10cSrcweir {
85cdf0e10cSrcweir     bool bStandardout = false;
86cdf0e10cSrcweir     if ( options.outputpath.equals("stdout") )
87cdf0e10cSrcweir     {
88cdf0e10cSrcweir         bStandardout = true;
89cdf0e10cSrcweir         *ppOutputStream = &std::cout;
90cdf0e10cSrcweir         return bStandardout;
91cdf0e10cSrcweir     }
92cdf0e10cSrcweir 
93cdf0e10cSrcweir     targetSourceFileName = createFileNameFromType(
94cdf0e10cSrcweir         options.outputpath, options.implname.replace('.','/'), extension);
95cdf0e10cSrcweir 
96cdf0e10cSrcweir     OString tmpDir = getTempDir(targetSourceFileName);
97cdf0e10cSrcweir     FileStream file;
98cdf0e10cSrcweir     file.createTempFile(tmpDir);
99cdf0e10cSrcweir 
100cdf0e10cSrcweir     if( !file.isValid() )
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir         OString message("cannot open ");
103cdf0e10cSrcweir         message += targetSourceFileName + " for writing";
104cdf0e10cSrcweir         throw CannotDumpException(message);
105cdf0e10cSrcweir     } else {
106cdf0e10cSrcweir         tmpSourceFileName = file.getName();
107cdf0e10cSrcweir     }
108cdf0e10cSrcweir     file.close();
109cdf0e10cSrcweir     *ppOutputStream = new std::ofstream(tmpSourceFileName.getStr(),
110cdf0e10cSrcweir                                         std::ios_base::binary);
111cdf0e10cSrcweir 
112cdf0e10cSrcweir     return bStandardout;
113cdf0e10cSrcweir }
114cdf0e10cSrcweir 
115cdf0e10cSrcweir codemaker::UnoType::Sort decomposeResolveAndCheck(
116cdf0e10cSrcweir     TypeManager const & manager, OString const & type,
117cdf0e10cSrcweir     bool resolveTypedefs, bool allowVoid, bool allowExtraEntities,
118cdf0e10cSrcweir     RTTypeClass * typeClass, OString * name, sal_Int32 * rank,
119cdf0e10cSrcweir     std::vector< OString > * arguments)
120cdf0e10cSrcweir {
121cdf0e10cSrcweir     codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
122cdf0e10cSrcweir         manager, type, resolveTypedefs, allowVoid, allowExtraEntities,
123cdf0e10cSrcweir         typeClass, name, rank, arguments);
124cdf0e10cSrcweir     for ( std::vector< OString >::iterator i(arguments->begin());
125cdf0e10cSrcweir           i != arguments->end(); ++i )
126cdf0e10cSrcweir     {
127cdf0e10cSrcweir         RTTypeClass typeClass2;
128cdf0e10cSrcweir         OString name2;
129cdf0e10cSrcweir         sal_Int32 rank2;
130cdf0e10cSrcweir         std::vector< OString > arguments2;
131cdf0e10cSrcweir         decomposeResolveAndCheck(
132cdf0e10cSrcweir             manager, *i, true, false, false, &typeClass2, &name2, &rank2,
133cdf0e10cSrcweir             &arguments2);
134cdf0e10cSrcweir     }
135cdf0e10cSrcweir     return sort;
136cdf0e10cSrcweir }
137cdf0e10cSrcweir 
138cdf0e10cSrcweir bool containsAttribute(AttributeInfo& attributes, OString const & attrname)
139cdf0e10cSrcweir {
140cdf0e10cSrcweir     for ( AttributeInfo::const_iterator i(attributes.begin());
141cdf0e10cSrcweir           i != attributes.end(); ++i ) {
142cdf0e10cSrcweir         if ( (*i).first == attrname ) {
143cdf0e10cSrcweir             return true;
144cdf0e10cSrcweir         }
145cdf0e10cSrcweir     }
146cdf0e10cSrcweir     return false;
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir // collect attributes including inherited attributes
150cdf0e10cSrcweir void checkAttributes(TypeManager const & manager,
151cdf0e10cSrcweir                      const typereg::Reader& reader,
152cdf0e10cSrcweir                      AttributeInfo& attributes,
153cdf0e10cSrcweir                      std::hash_set< OString, OStringHash >& propinterfaces)
154cdf0e10cSrcweir {
155cdf0e10cSrcweir     OString typeName = codemaker::convertString(reader.getTypeName());
156cdf0e10cSrcweir     if ( typeName.equals("com/sun/star/beans/XPropertySet") ||
157cdf0e10cSrcweir          typeName.equals("com/sun/star/beans/XFastPropertySet") ||
158cdf0e10cSrcweir //        typeName.equals("com/sun/star/beans/XMultiPropertySet") ||
159cdf0e10cSrcweir          typeName.equals("com/sun/star/beans/XPropertyAccess") )
160cdf0e10cSrcweir     {
161cdf0e10cSrcweir         propinterfaces.insert(typeName);
162cdf0e10cSrcweir     }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
165cdf0e10cSrcweir         typereg::Reader supertype(manager.getTypeReader(
166cdf0e10cSrcweir                                   codemaker::convertString(
167cdf0e10cSrcweir                                       reader.getSuperTypeName(i))));
168cdf0e10cSrcweir         if ( !supertype.isValid() ) {
169cdf0e10cSrcweir             throw CannotDumpException(
170cdf0e10cSrcweir                 "Bad type library entity "
171cdf0e10cSrcweir                 + codemaker::convertString(reader.getSuperTypeName(i)));
172cdf0e10cSrcweir         }
173cdf0e10cSrcweir         checkAttributes(manager, supertype, attributes, propinterfaces);
174cdf0e10cSrcweir     }
175cdf0e10cSrcweir 
176cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
177cdf0e10cSrcweir         OString fieldName(
178cdf0e10cSrcweir             codemaker::convertString(reader.getFieldName(i)).
179cdf0e10cSrcweir             replace('/', '.'));
180cdf0e10cSrcweir 
181cdf0e10cSrcweir         if ( !containsAttribute(attributes, fieldName) ) {
182cdf0e10cSrcweir             OString fieldType(
183cdf0e10cSrcweir                 codemaker::convertString(reader.getFieldTypeName(i)).
184cdf0e10cSrcweir                 replace('/', '.'));
185cdf0e10cSrcweir             attributes.push_back(AttributeInfo::value_type(
186cdf0e10cSrcweir                                      fieldName, std::pair<OString, sal_Int16>(
187cdf0e10cSrcweir                                          fieldType, reader.getFieldFlags(i))));
188cdf0e10cSrcweir         }
189cdf0e10cSrcweir     }
190cdf0e10cSrcweir }
191cdf0e10cSrcweir 
192cdf0e10cSrcweir void checkType(TypeManager const & manager,
193cdf0e10cSrcweir                OString const & type,
194cdf0e10cSrcweir                std::hash_set< OString, OStringHash >& interfaceTypes,
195cdf0e10cSrcweir                std::hash_set< OString, OStringHash >& serviceTypes,
196cdf0e10cSrcweir                AttributeInfo& properties)
197cdf0e10cSrcweir {
198cdf0e10cSrcweir 
199cdf0e10cSrcweir     OString binType(type.replace('.', '/'));
200cdf0e10cSrcweir     typereg::Reader reader(manager.getTypeReader(binType));
201cdf0e10cSrcweir     if ( !reader.isValid() ) {
202cdf0e10cSrcweir         throw CannotDumpException("Bad type library entity " + binType);
203cdf0e10cSrcweir     }
204cdf0e10cSrcweir 
205cdf0e10cSrcweir     switch ( reader.getTypeClass() )
206cdf0e10cSrcweir     {
207cdf0e10cSrcweir     case RT_TYPE_INTERFACE:
208cdf0e10cSrcweir     {
209cdf0e10cSrcweir         // com/sun/star/lang/XComponent should be also not in the list
210cdf0e10cSrcweir         // but it will be used for checking the impl helper and will be
211cdf0e10cSrcweir         // removed later if necessary.
212cdf0e10cSrcweir         if ( binType.equals("com/sun/star/lang/XTypeProvider") ||
213cdf0e10cSrcweir              binType.equals("com/sun/star/uno/XWeak") )
214cdf0e10cSrcweir             return;
215cdf0e10cSrcweir         if (interfaceTypes.find(type) == interfaceTypes.end()) {
216cdf0e10cSrcweir             interfaceTypes.insert(type);
217cdf0e10cSrcweir         }
218cdf0e10cSrcweir     }
219cdf0e10cSrcweir         break;
220cdf0e10cSrcweir     case RT_TYPE_SERVICE:
221cdf0e10cSrcweir         if ( serviceTypes.find(binType) == serviceTypes.end() ) {
222cdf0e10cSrcweir             serviceTypes.insert(binType);
223cdf0e10cSrcweir 
224cdf0e10cSrcweir             if ( reader.getSuperTypeCount() > 0 ) {
225cdf0e10cSrcweir                 OString supername(codemaker::convertString(
226cdf0e10cSrcweir                     reader.getSuperTypeName(0).replace('/', '.')));
227cdf0e10cSrcweir 				if ( interfaceTypes.find(supername) == interfaceTypes.end() ) {
228cdf0e10cSrcweir                     interfaceTypes.insert(supername);
229cdf0e10cSrcweir 
230cdf0e10cSrcweir 					typereg::Reader supertype(manager.getTypeReader(
231cdf0e10cSrcweir                                   codemaker::convertString(
232cdf0e10cSrcweir                                       reader.getSuperTypeName(0))));
233cdf0e10cSrcweir 					if ( !supertype.isValid() ) {
234cdf0e10cSrcweir 						throw CannotDumpException(
235cdf0e10cSrcweir 							"Bad type library entity "
236cdf0e10cSrcweir 							+ codemaker::convertString(reader.getSuperTypeName(0)));
237cdf0e10cSrcweir 					}
238cdf0e10cSrcweir 				}
239cdf0e10cSrcweir 
240cdf0e10cSrcweir                 // check if constructors are specified, if yes automatically
241cdf0e10cSrcweir                 // support of XInitialization. We will take care of the default
242cdf0e10cSrcweir                 // constructor because in this case XInitialization is not called.
243cdf0e10cSrcweir                 if ( reader.getMethodCount() > 1 ||
244cdf0e10cSrcweir                      ( reader.getMethodCount() == 1 &&
245cdf0e10cSrcweir                        reader.getMethodName(0).getLength() > 0 ) )
246cdf0e10cSrcweir                 {
247cdf0e10cSrcweir                     OString s("com.sun.star.lang.XInitialization");
248cdf0e10cSrcweir                     if ( interfaceTypes.find(s) == interfaceTypes.end() )
249cdf0e10cSrcweir                         interfaceTypes.insert(s);
250cdf0e10cSrcweir                 }
251cdf0e10cSrcweir             } else {
252cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
253cdf0e10cSrcweir                     OString referenceType(
254cdf0e10cSrcweir                         codemaker::convertString(
255cdf0e10cSrcweir                             reader.getReferenceTypeName(i)).replace('/', '.'));
256cdf0e10cSrcweir 
257cdf0e10cSrcweir                     if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) {
258cdf0e10cSrcweir                         checkType(manager, referenceType, interfaceTypes,
259cdf0e10cSrcweir                                   serviceTypes, properties);
260cdf0e10cSrcweir                     } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
261cdf0e10cSrcweir                         checkType(manager, referenceType, interfaceTypes,
262cdf0e10cSrcweir                                   serviceTypes, properties);
263cdf0e10cSrcweir                     }
264cdf0e10cSrcweir                 }
265cdf0e10cSrcweir 
266cdf0e10cSrcweir                 for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) {
267cdf0e10cSrcweir                     OString fieldName(
268cdf0e10cSrcweir                         codemaker::convertString(reader.getFieldName(i)).
269cdf0e10cSrcweir                         replace('/', '.'));
270cdf0e10cSrcweir                     OString fieldType(
271cdf0e10cSrcweir                         codemaker::convertString(reader.getFieldTypeName(i)).
272cdf0e10cSrcweir                         replace('/', '.'));
273cdf0e10cSrcweir 
274cdf0e10cSrcweir                     properties.push_back(AttributeInfo::value_type(
275cdf0e10cSrcweir                         fieldName, std::pair<OString, sal_Int16>(
276cdf0e10cSrcweir                             fieldType, reader.getFieldFlags(i))));
277cdf0e10cSrcweir                 }
278cdf0e10cSrcweir             }
279cdf0e10cSrcweir         }
280cdf0e10cSrcweir         break;
281cdf0e10cSrcweir     default:
282cdf0e10cSrcweir         OSL_ASSERT(false);
283cdf0e10cSrcweir         break;
284cdf0e10cSrcweir     }
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir void checkDefaultInterfaces(
288cdf0e10cSrcweir          std::hash_set< OString, OStringHash >& interfaces,
289cdf0e10cSrcweir          const std::hash_set< OString, OStringHash >& services,
290cdf0e10cSrcweir        const OString & propertyhelper)
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     if ( services.empty() ) {
293cdf0e10cSrcweir         if (interfaces.find("com.sun.star.lang.XServiceInfo") != interfaces.end())
294cdf0e10cSrcweir             interfaces.erase("com.sun.star.lang.XServiceInfo");
295cdf0e10cSrcweir     } else {
296cdf0e10cSrcweir         if (interfaces.find("com.sun.star.lang.XServiceInfo") == interfaces.end())
297cdf0e10cSrcweir             interfaces.insert("com.sun.star.lang.XServiceInfo");
298cdf0e10cSrcweir     }
299cdf0e10cSrcweir 
300cdf0e10cSrcweir     if ( propertyhelper.equals("_") ) {
301cdf0e10cSrcweir         if (interfaces.find("com.sun.star.beans.XPropertySet")
302cdf0e10cSrcweir             != interfaces.end())
303cdf0e10cSrcweir             interfaces.erase("com.sun.star.beans.XPropertySet");
304cdf0e10cSrcweir         if (interfaces.find("com.sun.star.beans.XFastPropertySet")
305cdf0e10cSrcweir             != interfaces.end())
306cdf0e10cSrcweir             interfaces.erase("com.sun.star.beans.XFastPropertySet");
307cdf0e10cSrcweir         if (interfaces.find("com.sun.star.beans.XPropertyAccess")
308cdf0e10cSrcweir             != interfaces.end())
309cdf0e10cSrcweir             interfaces.erase("com.sun.star.beans.XPropertyAccess");
310cdf0e10cSrcweir     }
311cdf0e10cSrcweir }
312cdf0e10cSrcweir 
313cdf0e10cSrcweir bool checkServiceProperties(TypeManager const & manager,
314cdf0e10cSrcweir                             const typereg::Reader & reader)
315cdf0e10cSrcweir {
316cdf0e10cSrcweir     if ( reader.getFieldCount() > 0 )
317cdf0e10cSrcweir         return true;
318cdf0e10cSrcweir 
319cdf0e10cSrcweir     if ( reader.getReferenceCount() > 0 ) {
320cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) {
321cdf0e10cSrcweir             if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) {
322cdf0e10cSrcweir                 typereg::Reader refreader(
323cdf0e10cSrcweir                     manager.getTypeReader(
324cdf0e10cSrcweir                         codemaker::convertString(reader.getReferenceTypeName(i))));
325cdf0e10cSrcweir 
326cdf0e10cSrcweir                 if ( checkServiceProperties(manager, refreader) )
327cdf0e10cSrcweir                     return true;
328cdf0e10cSrcweir             }
329cdf0e10cSrcweir         }
330cdf0e10cSrcweir     }
331cdf0e10cSrcweir     return false;
332cdf0e10cSrcweir }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir 
335cdf0e10cSrcweir OString checkPropertyHelper(
336cdf0e10cSrcweir     ProgramOptions const & options,
337cdf0e10cSrcweir     TypeManager const & manager,
338cdf0e10cSrcweir     const std::hash_set< OString, OStringHash >& services,
339cdf0e10cSrcweir     const std::hash_set< OString, OStringHash >& interfaces,
340cdf0e10cSrcweir     AttributeInfo& attributes,
341cdf0e10cSrcweir     std::hash_set< OString, OStringHash >& propinterfaces)
342cdf0e10cSrcweir {
343cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator iter;
344cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator end;
345cdf0e10cSrcweir 
346cdf0e10cSrcweir     if ( !services.empty() ) {
347cdf0e10cSrcweir         iter = services.begin();
348cdf0e10cSrcweir         end = services.end();
349cdf0e10cSrcweir     } else {
350cdf0e10cSrcweir         iter = interfaces.begin();
351cdf0e10cSrcweir         end = interfaces.end();
352cdf0e10cSrcweir     }
353cdf0e10cSrcweir 
354cdf0e10cSrcweir     bool oldStyleWithProperties = false;
355cdf0e10cSrcweir     while ( iter != end ) {
356cdf0e10cSrcweir         typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));
357cdf0e10cSrcweir 
358cdf0e10cSrcweir         if ( !services.empty() ) {
359cdf0e10cSrcweir             if ( options.supportpropertysetmixin && reader.getSuperTypeCount() > 0 )
360cdf0e10cSrcweir             {
361cdf0e10cSrcweir                 typereg::Reader supertype(
362cdf0e10cSrcweir                     manager.getTypeReader(
363cdf0e10cSrcweir                         codemaker::convertString(
364cdf0e10cSrcweir                             reader.getSuperTypeName(0))));
365cdf0e10cSrcweir                 if ( !supertype.isValid() ) {
366cdf0e10cSrcweir                     throw CannotDumpException(
367cdf0e10cSrcweir                         "Bad type library entity "
368cdf0e10cSrcweir                         + codemaker::convertString(
369cdf0e10cSrcweir                             reader.getSuperTypeName(0)));
370cdf0e10cSrcweir                 }
371cdf0e10cSrcweir 
372cdf0e10cSrcweir                 checkAttributes(manager, supertype, attributes, propinterfaces);
373cdf0e10cSrcweir 
374cdf0e10cSrcweir                 if ( !(attributes.empty() || propinterfaces.empty()) ) {
375cdf0e10cSrcweir                     return OUStringToOString(
376cdf0e10cSrcweir                         supertype.getTypeName().replace('/', '.'),
377cdf0e10cSrcweir                         osl_getThreadTextEncoding());
378cdf0e10cSrcweir                 }
379cdf0e10cSrcweir             } else {
380cdf0e10cSrcweir                 oldStyleWithProperties = checkServiceProperties(manager, reader);
381cdf0e10cSrcweir             }
382cdf0e10cSrcweir         } else {
383cdf0e10cSrcweir             checkAttributes(manager, reader, attributes, propinterfaces);
384cdf0e10cSrcweir             if ( !(attributes.empty() || propinterfaces.empty()) ) {
385cdf0e10cSrcweir                 return OUStringToOString(
386cdf0e10cSrcweir                     reader.getTypeName().replace('/', '.'),
387cdf0e10cSrcweir                     osl_getThreadTextEncoding());
388cdf0e10cSrcweir             }
389cdf0e10cSrcweir         }
390cdf0e10cSrcweir         iter++;
391cdf0e10cSrcweir     }
392cdf0e10cSrcweir 
393cdf0e10cSrcweir     return (oldStyleWithProperties ? "_" : "");
394cdf0e10cSrcweir }
395cdf0e10cSrcweir 
396cdf0e10cSrcweir bool checkXComponentSupport(TypeManager const & manager,
397cdf0e10cSrcweir                             typereg::Reader const & reader)
398cdf0e10cSrcweir {
399cdf0e10cSrcweir     static OUString s(RTL_CONSTASCII_USTRINGPARAM(
400cdf0e10cSrcweir                                "com/sun/star/lang/XComponent"));
401cdf0e10cSrcweir     if ( reader.getTypeName().equals(s) )
402cdf0e10cSrcweir         return true;
403cdf0e10cSrcweir 
404cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
405cdf0e10cSrcweir         typereg::Reader super(
406cdf0e10cSrcweir             manager.getTypeReader(
407cdf0e10cSrcweir                 codemaker::convertString(
408cdf0e10cSrcweir                     reader.getSuperTypeName(i))));
409cdf0e10cSrcweir         if ( !super.isValid() ) {
410cdf0e10cSrcweir             throw CannotDumpException(
411cdf0e10cSrcweir                 "Bad type library entity "
412cdf0e10cSrcweir                 + codemaker::convertString(
413cdf0e10cSrcweir                     reader.getSuperTypeName(i)));
414cdf0e10cSrcweir         }
415cdf0e10cSrcweir         if ( checkXComponentSupport(manager, super) )
416cdf0e10cSrcweir             return true;
417cdf0e10cSrcweir     }
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     return false;
420cdf0e10cSrcweir }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir 
423cdf0e10cSrcweir // if XComponent is directly specified, return true and remove it from the
424cdf0e10cSrcweir // supported interfaces list
425cdf0e10cSrcweir bool checkXComponentSupport(TypeManager const & manager,
426cdf0e10cSrcweir          std::hash_set< OString, OStringHash >& interfaces)
427cdf0e10cSrcweir {
428cdf0e10cSrcweir     if ( interfaces.empty() )
429cdf0e10cSrcweir         return false;
430cdf0e10cSrcweir 
431cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator iter =
432cdf0e10cSrcweir         interfaces.begin();
433cdf0e10cSrcweir     while ( iter != interfaces.end() ) {
434cdf0e10cSrcweir         if ( (*iter).equals("com.sun.star.lang.XComponent") ) {
435cdf0e10cSrcweir             interfaces.erase("com.sun.star.lang.XComponent");
436cdf0e10cSrcweir             return true;
437cdf0e10cSrcweir         }
438cdf0e10cSrcweir         typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/')));
439cdf0e10cSrcweir         if ( checkXComponentSupport(manager, reader) )
440cdf0e10cSrcweir             return true;
441cdf0e10cSrcweir         iter++;
442cdf0e10cSrcweir     }
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     return false;
445cdf0e10cSrcweir }
446cdf0e10cSrcweir 
447cdf0e10cSrcweir sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader,
448cdf0e10cSrcweir                                         sal_uInt16 field, sal_uInt16 method)
449cdf0e10cSrcweir {
450cdf0e10cSrcweir     sal_uInt16 flags = 0;
451cdf0e10cSrcweir     bool getterSupportsUnknown = false;
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     OUString su(RTL_CONSTASCII_USTRINGPARAM(
454cdf0e10cSrcweir                    "com/sun/star/beans/UnknownPropertyException"));
455cdf0e10cSrcweir     if ( method < reader.getMethodCount()
456cdf0e10cSrcweir          && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET
457cdf0e10cSrcweir          && reader.getMethodName(method) == reader.getFieldName(field) )
458cdf0e10cSrcweir     {
459cdf0e10cSrcweir         if ( reader.getMethodExceptionCount(method) > 0 ) {
460cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
461cdf0e10cSrcweir                   ++i )
462cdf0e10cSrcweir             {
463cdf0e10cSrcweir                 if (su.equals(reader.getMethodExceptionTypeName(method, i)))
464cdf0e10cSrcweir                     getterSupportsUnknown = true;
465cdf0e10cSrcweir             }
466cdf0e10cSrcweir         }
467cdf0e10cSrcweir         method++;
468cdf0e10cSrcweir     }
469cdf0e10cSrcweir     if ( method < reader.getMethodCount()
470cdf0e10cSrcweir          && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET
471cdf0e10cSrcweir          && reader.getMethodName(method) == reader.getFieldName(field) )
472cdf0e10cSrcweir     {
473cdf0e10cSrcweir         if ( reader.getMethodExceptionCount(method) > 0 ) {
474cdf0e10cSrcweir             OUString s(RTL_CONSTASCII_USTRINGPARAM(
475cdf0e10cSrcweir                            "com/sun/star/beans/PropertyVetoException"));
476cdf0e10cSrcweir             for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method);
477cdf0e10cSrcweir                   ++i )
478cdf0e10cSrcweir             {
479cdf0e10cSrcweir                 if ( s.equals(reader.getMethodExceptionTypeName(method, i)) )
480cdf0e10cSrcweir                     flags |= RT_ACCESS_CONSTRAINED;
481cdf0e10cSrcweir                 if ( getterSupportsUnknown &&
482cdf0e10cSrcweir                      su.equals(reader.getMethodExceptionTypeName(method, i)) )
483cdf0e10cSrcweir                     flags |= RT_ACCESS_OPTIONAL;
484cdf0e10cSrcweir             }
485cdf0e10cSrcweir         }
486cdf0e10cSrcweir     }
487cdf0e10cSrcweir     return flags;
488cdf0e10cSrcweir }
489cdf0e10cSrcweir 
490cdf0e10cSrcweir // This function checks if the specified types for paramters and return
491cdf0e10cSrcweir // types are allowed add-in types, for more info see the com.sun.star.sheet.AddIn
492cdf0e10cSrcweir // service description
493cdf0e10cSrcweir bool checkAddinType(TypeManager const & manager,
494cdf0e10cSrcweir                     OString const & type, bool & bLastAny,
495cdf0e10cSrcweir                     bool & bHasXPropertySet, bool bIsReturn)
496cdf0e10cSrcweir {
497cdf0e10cSrcweir     RTTypeClass typeClass;
498cdf0e10cSrcweir     OString name;
499cdf0e10cSrcweir     sal_Int32 rank;
500cdf0e10cSrcweir     std::vector< OString > arguments;
501cdf0e10cSrcweir     codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve(
502cdf0e10cSrcweir         manager, type, true, true, true, &typeClass, &name, &rank, &arguments);
503cdf0e10cSrcweir 
504cdf0e10cSrcweir     if ( sort == codemaker::UnoType::SORT_LONG ||
505cdf0e10cSrcweir          sort == codemaker::UnoType::SORT_DOUBLE ||
506cdf0e10cSrcweir          sort == codemaker::UnoType::SORT_STRING )
507cdf0e10cSrcweir     {
508cdf0e10cSrcweir         if ( rank == 0 || rank ==2 )
509cdf0e10cSrcweir             return true;
510cdf0e10cSrcweir     }
511cdf0e10cSrcweir     if ( sort == codemaker::UnoType::SORT_ANY )
512cdf0e10cSrcweir     {
513cdf0e10cSrcweir         if ( rank <= 2 ) {
514cdf0e10cSrcweir             if ( rank ==1 ) {
515cdf0e10cSrcweir                 if ( bIsReturn )
516cdf0e10cSrcweir                     return false;
517cdf0e10cSrcweir                 bLastAny = true;
518cdf0e10cSrcweir             }
519cdf0e10cSrcweir 
520cdf0e10cSrcweir             return true;
521cdf0e10cSrcweir         }
522cdf0e10cSrcweir     }
523cdf0e10cSrcweir     if ( sort == codemaker::UnoType::SORT_COMPLEX &&
524cdf0e10cSrcweir          typeClass == RT_TYPE_INTERFACE )
525cdf0e10cSrcweir     {
526cdf0e10cSrcweir         if ( bIsReturn && type.equals("com/sun/star/sheet/XVolatileResult") )
527cdf0e10cSrcweir             return true;
528cdf0e10cSrcweir         if ( !bIsReturn && type.equals("com/sun/star/table/XCellRange") )
529cdf0e10cSrcweir             return true;
530cdf0e10cSrcweir         if ( !bIsReturn && type.equals("com/sun/star/beans/XPropertySet") )
531cdf0e10cSrcweir         {
532cdf0e10cSrcweir             if ( bHasXPropertySet ) {
533cdf0e10cSrcweir                 return false;
534cdf0e10cSrcweir             } else {
535cdf0e10cSrcweir                 bHasXPropertySet = true;
536cdf0e10cSrcweir                 return true;
537cdf0e10cSrcweir             }
538cdf0e10cSrcweir         }
539cdf0e10cSrcweir     }
540cdf0e10cSrcweir     return false;
541cdf0e10cSrcweir }
542cdf0e10cSrcweir 
543cdf0e10cSrcweir void checkAddInTypes(TypeManager const & manager,
544cdf0e10cSrcweir                      typereg::Reader const & reader)
545cdf0e10cSrcweir {
546cdf0e10cSrcweir     OString sType(codemaker::convertString(reader.getTypeName()).replace('/', '.'));
547cdf0e10cSrcweir     bool bLastAny = false;
548cdf0e10cSrcweir     bool bHasXPropertySet = false;
549cdf0e10cSrcweir     for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
550cdf0e10cSrcweir         OString sMethod(codemaker::convertString(reader.getMethodName(m)));
551cdf0e10cSrcweir 
552cdf0e10cSrcweir         OString sReturnType(codemaker::convertString(
553cdf0e10cSrcweir                                 reader.getMethodReturnTypeName(m)));
554cdf0e10cSrcweir         if ( !checkAddinType(
555cdf0e10cSrcweir                  manager, sReturnType, bLastAny, bHasXPropertySet, true) )
556cdf0e10cSrcweir         {
557cdf0e10cSrcweir             OStringBuffer msg("the return type of the calc add-in function '");
558cdf0e10cSrcweir             msg.append(sType);
559cdf0e10cSrcweir             msg.append(":");
560cdf0e10cSrcweir             msg.append(sMethod);
561cdf0e10cSrcweir             msg.append("' is invalid. Please check your IDL defintion.");
562cdf0e10cSrcweir             throw CannotDumpException(msg.makeStringAndClear());
563cdf0e10cSrcweir         }
564cdf0e10cSrcweir 
565cdf0e10cSrcweir         bHasXPropertySet = false;
566cdf0e10cSrcweir         for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
567cdf0e10cSrcweir             bLastAny = false;
568cdf0e10cSrcweir             OString sParamType(codemaker::convertString(
569cdf0e10cSrcweir                                    reader.getMethodParameterTypeName(m, p)));
570cdf0e10cSrcweir             if ( !checkAddinType(manager, sParamType,
571cdf0e10cSrcweir                                 bLastAny, bHasXPropertySet, false) ||
572cdf0e10cSrcweir                  bLastAny )
573cdf0e10cSrcweir             {
574cdf0e10cSrcweir                 OStringBuffer msg("the type of the ");
575cdf0e10cSrcweir                 msg.append((sal_Int32)p+1);
576cdf0e10cSrcweir                 msg.append(". parameter of the calc add-in function '");
577cdf0e10cSrcweir                 msg.append(sType);
578cdf0e10cSrcweir                 msg.append(":");
579cdf0e10cSrcweir                 msg.append(sMethod);
580cdf0e10cSrcweir                 msg.append("' is invalid.");
581cdf0e10cSrcweir                 if ( bLastAny )
582cdf0e10cSrcweir                     msg.append(" The type 'sequence<any>' is allowed as last "
583cdf0e10cSrcweir                                "parameter only.");
584cdf0e10cSrcweir                 if ( bHasXPropertySet )
585cdf0e10cSrcweir                     msg.append(" The type 'XPropertySet' is allowed only once.");
586cdf0e10cSrcweir 
587cdf0e10cSrcweir                 msg.append(" Please check your IDL definition.");
588cdf0e10cSrcweir                 throw CannotDumpException(msg.makeStringAndClear());
589cdf0e10cSrcweir             }
590cdf0e10cSrcweir         }
591cdf0e10cSrcweir     }
592cdf0e10cSrcweir }
593cdf0e10cSrcweir 
594cdf0e10cSrcweir void generateFunctionParamterMap(std::ostream& o,
595cdf0e10cSrcweir                                  ProgramOptions const & options,
596cdf0e10cSrcweir                                  TypeManager const & manager,
597cdf0e10cSrcweir                                  typereg::Reader const & reader,
598cdf0e10cSrcweir                                  ::codemaker::GeneratedTypeSet & generated,
599cdf0e10cSrcweir                                  bool bFirst)
600cdf0e10cSrcweir {
601cdf0e10cSrcweir     OString sType(codemaker::convertString(reader.getTypeName()));
602cdf0e10cSrcweir     if ( sType.equals("com/sun/star/uno/XInterface") ||
603cdf0e10cSrcweir          sType.equals("com/sun/star/lang/XLocalizable") ||
604cdf0e10cSrcweir          sType.equals("com/sun/star/lang/XServiceInfo") ||
605cdf0e10cSrcweir          // the next three checks becomes obsolete when configuration is used
606cdf0e10cSrcweir          sType.equals("com/sun/star/sheet/XAddIn") ||
607cdf0e10cSrcweir          sType.equals("com/sun/star/sheet/XCompatibilityNames") ||
608cdf0e10cSrcweir          sType.equals("com/sun/star/lang/XServiceName") )
609cdf0e10cSrcweir     {
610cdf0e10cSrcweir         return;
611cdf0e10cSrcweir     }
612cdf0e10cSrcweir 
613cdf0e10cSrcweir     // check if the specified add-in functions supports valid types
614cdf0e10cSrcweir     checkAddInTypes(manager, reader);
615cdf0e10cSrcweir 
616cdf0e10cSrcweir     for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) {
617cdf0e10cSrcweir         typereg::Reader super(
618cdf0e10cSrcweir             manager.getTypeReader(
619cdf0e10cSrcweir                 codemaker::convertString(
620cdf0e10cSrcweir                     reader.getSuperTypeName(i))));
621cdf0e10cSrcweir         if ( !super.isValid() ) {
622cdf0e10cSrcweir             throw CannotDumpException(
623cdf0e10cSrcweir                 "Bad type library entity "
624cdf0e10cSrcweir                 + codemaker::convertString(
625cdf0e10cSrcweir                     reader.getSuperTypeName(i)));
626cdf0e10cSrcweir         }
627cdf0e10cSrcweir         generateFunctionParamterMap(o, options, manager, super, generated, bFirst);
628cdf0e10cSrcweir     }
629cdf0e10cSrcweir 
630cdf0e10cSrcweir     OString type(codemaker::convertString(reader.getTypeName()));
631cdf0e10cSrcweir     if ( generated.contains(type) )
632cdf0e10cSrcweir         return;
633cdf0e10cSrcweir     else
634cdf0e10cSrcweir         generated.add(type);
635cdf0e10cSrcweir 
636cdf0e10cSrcweir     for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) {
637cdf0e10cSrcweir         OString sMethod(codemaker::convertString(reader.getMethodName(m)));
638cdf0e10cSrcweir 
639cdf0e10cSrcweir         if ( bFirst ) {
640cdf0e10cSrcweir             if (options.language == 2) {
641cdf0e10cSrcweir                 o << "        ParamMap fpm;\n";
642cdf0e10cSrcweir             }
643cdf0e10cSrcweir             else {
644cdf0e10cSrcweir                 if ( options.java5 )
645cdf0e10cSrcweir                     o << "        java.util.Hashtable< Integer, String > fpm = "
646cdf0e10cSrcweir                         "new java.util.Hashtable< Integer, String >();\n";
647cdf0e10cSrcweir                 else
648cdf0e10cSrcweir                     o << "        java.util.Hashtable fpm = "
649cdf0e10cSrcweir                         "new java.util.Hashtable();\n";
650cdf0e10cSrcweir             }
651cdf0e10cSrcweir             bFirst = false;
652cdf0e10cSrcweir         } else
653cdf0e10cSrcweir             if ( options.language == 2 ) {
654cdf0e10cSrcweir                 o << "        fpm = ParamMap();\n";
655cdf0e10cSrcweir             }
656cdf0e10cSrcweir             else {
657cdf0e10cSrcweir                 if ( options.java5 )
658cdf0e10cSrcweir                     o << "        fpm = new java.util.Hashtable< "
659cdf0e10cSrcweir                         "Integer, String >();\n";
660cdf0e10cSrcweir                 else
661cdf0e10cSrcweir                     o << "        fpm = new java.util.Hashtable();\n";
662cdf0e10cSrcweir             }
663cdf0e10cSrcweir 
664cdf0e10cSrcweir         for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) {
665cdf0e10cSrcweir             if ( options.language == 2 ) {
666cdf0e10cSrcweir                 o << "        fpm[" << p
667cdf0e10cSrcweir                   << "] = ::rtl::OUString::createFromAscii(\""
668cdf0e10cSrcweir                   << codemaker::convertString(reader.getMethodParameterName(m, p))
669cdf0e10cSrcweir                   << "\");\n";
670cdf0e10cSrcweir             }
671cdf0e10cSrcweir             else {
672cdf0e10cSrcweir                 if ( options.java5 )
673cdf0e10cSrcweir                     o << "        fpm.put(" << p << ", \""
674cdf0e10cSrcweir                       << codemaker::convertString(
675cdf0e10cSrcweir                           reader.getMethodParameterName(m, p))
676cdf0e10cSrcweir                       << "\");\n";
677cdf0e10cSrcweir                 else
678cdf0e10cSrcweir                     o << "       fpm.put(new Integer(" << p << "), \""
679cdf0e10cSrcweir                       << codemaker::convertString(
680cdf0e10cSrcweir                           reader.getMethodParameterName(m, p))
681cdf0e10cSrcweir                       << "\");\n";
682cdf0e10cSrcweir             }
683cdf0e10cSrcweir         }
684cdf0e10cSrcweir 
685cdf0e10cSrcweir         if ( options.language == 2 ) {
686cdf0e10cSrcweir             o << "        m_functionMap[::rtl::OUString::createFromAscii(\""
687cdf0e10cSrcweir               << sMethod << "\")] = fpm;\n\n";
688cdf0e10cSrcweir         }
689cdf0e10cSrcweir         else {
690cdf0e10cSrcweir             o << "        m_functionMap.put(\"" << sMethod << "\", fpm);\n\n";
691cdf0e10cSrcweir         }
692cdf0e10cSrcweir     }
693cdf0e10cSrcweir }
694cdf0e10cSrcweir 
695cdf0e10cSrcweir void generateFunctionParameterMap(std::ostream& o,
696cdf0e10cSrcweir          ProgramOptions const & options,
697cdf0e10cSrcweir          TypeManager const & manager,
698cdf0e10cSrcweir          const std::hash_set< OString, OStringHash >& interfaces)
699cdf0e10cSrcweir {
700cdf0e10cSrcweir     ::codemaker::GeneratedTypeSet generated;
701cdf0e10cSrcweir     bool bFirst = true;
702cdf0e10cSrcweir     std::hash_set< OString, OStringHash >::const_iterator iter = interfaces.begin();
703cdf0e10cSrcweir     while ( iter != interfaces.end() ) {
704cdf0e10cSrcweir         typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/')));
705cdf0e10cSrcweir         if (!reader.isValid()) {
706cdf0e10cSrcweir             throw CannotDumpException(
707cdf0e10cSrcweir                 "Bad type library entity "
708cdf0e10cSrcweir                 + codemaker::convertString(
709cdf0e10cSrcweir                     reader.getTypeName()));
710cdf0e10cSrcweir         }
711cdf0e10cSrcweir 
712cdf0e10cSrcweir         generateFunctionParamterMap(o, options, manager, reader, generated, bFirst);
713cdf0e10cSrcweir         iter++;
714cdf0e10cSrcweir     }
715cdf0e10cSrcweir }
716cdf0e10cSrcweir 
717cdf0e10cSrcweir }
718cdf0e10cSrcweir 
719