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 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 51*76f5c358SAndrew Rist o << "/**************************************************************\n" 52cdf0e10cSrcweir " * \n" 53*76f5c358SAndrew Rist " * Licensed to the Apache Software Foundation (ASF) under one\n" 54*76f5c358SAndrew Rist " * or more contributor license agreements. See the NOTICE file\n" 55*76f5c358SAndrew Rist " * distributed with this work for additional information\n" 56*76f5c358SAndrew Rist " * regarding copyright ownership. The ASF licenses this file\n" 57*76f5c358SAndrew Rist " * to you under the Apache License, Version 2.0 (the\n" 58*76f5c358SAndrew Rist " * \"License\"); you may not use this file except in compliance\n" 59*76f5c358SAndrew Rist " * with the License. You may obtain a copy of the License at\n" 60cdf0e10cSrcweir " * \n" 61*76f5c358SAndrew Rist " * http://www.apache.org/licenses/LICENSE-2.0\n" 62cdf0e10cSrcweir " * \n" 63*76f5c358SAndrew Rist " * Unless required by applicable law or agreed to in writing,\n" 64*76f5c358SAndrew Rist " * software distributed under the License is distributed on an\n" 65*76f5c358SAndrew Rist " * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n" 66*76f5c358SAndrew Rist " * KIND, either express or implied. See the License for the\n" 67*76f5c358SAndrew Rist " * specific language governing permissions and limitations\n" 68*76f5c358SAndrew Rist " * under the License.\n" 69cdf0e10cSrcweir " * \n" 70*76f5c358SAndrew Rist " *************************************************************/\n\n" 71cdf0e10cSrcweir } 72cdf0e10cSrcweir 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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