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