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