diff options
Diffstat (limited to 'unodevtools')
19 files changed, 7180 insertions, 0 deletions
diff --git a/unodevtools/inc/unodevtools/options.hxx b/unodevtools/inc/unodevtools/options.hxx new file mode 100644 index 000000000000..f1fc70bad3fc --- /dev/null +++ b/unodevtools/inc/unodevtools/options.hxx @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_UNODEVTOOLS_OPTIONS_HXX +#define INCLUDED_UNODEVTOOLS_OPTIONS_HXX + +#include <rtl/ustrbuf.hxx> + +namespace com { namespace sun { namespace star { namespace uno { +class RuntimeException; +} } } } + +namespace unodevtools { + +//------------------------------------------------------------------------------- +sal_Bool readOption( rtl::OUString * pValue, const sal_Char * pOpt, + sal_Int32 * pnIndex, const rtl::OUString & aArg) + throw (com::sun::star::uno::RuntimeException); + +//------------------------------------------------------------------------------- +sal_Bool readOption( sal_Bool * pbOpt, const sal_Char * pOpt, + sal_Int32 * pnIndex, const rtl::OUString & aArg); + +} // end of namespace unodevtools + +#endif // INCLUDED_UNODEVTOOLS_OPTIONS_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/inc/unodevtools/typemanager.hxx b/unodevtools/inc/unodevtools/typemanager.hxx new file mode 100644 index 000000000000..603fa4652648 --- /dev/null +++ b/unodevtools/inc/unodevtools/typemanager.hxx @@ -0,0 +1,92 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef INCLUDED_UNODEVTOOLS_TYPEMANAGER_HXX +#define INCLUDED_UNODEVTOOLS_TYPEMANAGER_HXX + +#include <codemaker/typemanager.hxx> +#include <com/sun/star/container/XHierarchicalNameAccess.hpp> + +#include <boost/unordered_map.hpp> +#include <vector> + +class RegistryKey; + +namespace typereg { class Reader; } + +typedef boost::unordered_map +< + ::rtl::OString, // Typename + RTTypeClass, // TypeClass + HashString, + EqualString +> T2TypeClassMap; + +namespace unodevtools { + +struct UnoTypeManagerImpl +{ + UnoTypeManagerImpl() {} + + T2TypeClassMap m_t2TypeClass; + ::com::sun::star::uno::Reference< + ::com::sun::star::container::XHierarchicalNameAccess> m_tdmgr; +}; + +class UnoTypeManager : public TypeManager +{ +public: + UnoTypeManager(); + ~UnoTypeManager(); + + UnoTypeManager( const UnoTypeManager& value ) + : TypeManager(value) + , m_pImpl( value.m_pImpl ) + {} + + sal_Bool init(const ::std::vector< ::rtl::OUString > registries); + + sal_Bool isValidType(const ::rtl::OString& name) const; + ::rtl::OString getTypeName(RegistryKey& rTypeKey) const; + typereg::Reader getTypeReader( + const ::rtl::OString& name, sal_Bool * pIsExtraType = 0 ) const; + typereg::Reader getTypeReader(RegistryKey& rTypeKey) const; + RTTypeClass getTypeClass(const ::rtl::OString& name) const; + RTTypeClass getTypeClass(RegistryKey& rTypeKey) const; + +protected: + void release(); + + UnoTypeManagerImpl* m_pImpl; +}; + +} + +#endif // _UNODEVTOOLS_TYPEMANAGER_HXX_ + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/prj/build.lst b/unodevtools/prj/build.lst new file mode 100644 index 000000000000..37f2ef378a0e --- /dev/null +++ b/unodevtools/prj/build.lst @@ -0,0 +1,8 @@ +udt unodevtools : DESKTOP:codemaker cppuhelper NULL +udt unodevtools usr1 - all udt_mkout NULL +udt unodevtools\inc get - all udt_inc NULL +udt unodevtools\prj get - all udt_prj NULL +udt unodevtools\source\unodevtools nmake - all udt_unodevtools NULL +udt unodevtools\source\skeletonmaker nmake - all udt_skeletonmaker udt_unodevtools NULL + + diff --git a/unodevtools/prj/d.lst b/unodevtools/prj/d.lst new file mode 100644 index 000000000000..f4be609e2b14 --- /dev/null +++ b/unodevtools/prj/d.lst @@ -0,0 +1,5 @@ +..\%__SRC%\bin\uno-skeletonmaker.exe %_DEST%\bin\uno-skeletonmaker.exe +..\%__SRC%\bin\uno-skeletonmaker.pdb %_DEST%\bin\uno-skeletonmaker.pdb + +..\%__SRC%\bin\uno-skeletonmaker %_DEST%\bin\uno-skeletonmaker + diff --git a/unodevtools/source/skeletonmaker/cppcompskeleton.cxx b/unodevtools/source/skeletonmaker/cppcompskeleton.cxx new file mode 100644 index 000000000000..2074efe85ee8 --- /dev/null +++ b/unodevtools/source/skeletonmaker/cppcompskeleton.cxx @@ -0,0 +1,1275 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "codemaker/commoncpp.hxx" + +#include "skeletoncommon.hxx" +#include "skeletoncpp.hxx" + +#include <iostream> + +using namespace ::rtl; +using namespace ::codemaker::cpp; + +namespace skeletonmaker { namespace cpp { + +void generateIncludes(std::ostream & o, + const boost::unordered_set< OString, OStringHash >& interfaces, + const AttributeInfo& /*properties*/, + OString propertyhelper, bool serviceobject, + bool supportxcomponent) +{ + o << "#include \"sal/config.h\"\n"; + if (serviceobject) { + o << "#include \"cppuhelper/factory.hxx\"\n" + << "#include \"cppuhelper/implementationentry.hxx\"\n"; + } else { + o << "#include \"com/sun/star/uno/XComponentContext.hpp\"\n"; + } + if (supportxcomponent) { + o << "#include \"cppuhelper/compbase" << interfaces.size() << ".hxx\"\n"; + o << "#include \"cppuhelper/basemutex.hxx\"\n"; + } else { + o << "#include \"cppuhelper/implbase" << interfaces.size() << ".hxx\"\n"; + } + + if (propertyhelper.getLength() > 1) { + if (propertyhelper.equals("_")) + o << "#include \"cppuhelper/rpopshlp.hxx\"\n"; + else + o << "#include \"cppuhelper/propertysetmixin.hxx\"\n"; + } + + boost::unordered_set< OString, OStringHash >::const_iterator iter = interfaces.begin(); + while (iter != interfaces.end()) + { + o << "#include \"" + << ((*iter).replace('.', '/').getStr()) + << ".hpp\"\n"; + ++iter; + } +} + +short generateNamespace(std::ostream & o, + const OString & implname, + bool serviceobject, + OString & nm) +{ + short count=0; + sal_Int32 index = implname.lastIndexOf('.'); + if (serviceobject) { + o << "\n\n// component helper namespace\n"; + } else { + o << "\n"; + } + OStringBuffer buf; + if (index == -1) { + if (serviceobject) { + buf.append("comp_"); + buf.append(implname); + nm = buf.makeStringAndClear(); + o << "namespace comp_" << implname << " {\n\n"; + count=1; + } else { + nm = OString(); + } + } else { + sal_Int32 nPos=0; + do { + OString token(implname.getToken(0, '.', nPos)); + if (nPos < 0 && serviceobject) { + buf.append("::comp_"); + buf.append(token); + o << "namespace comp_" << token << " { "; + count++; + } else { + buf.append("::"); + buf.append(token); + o << "namespace " << token << " { "; + count++; + } + } while( nPos <= index ); + nm = buf.makeStringAndClear(); + o << "\n\n"; + } + return count; +} + +OString generateCompHelperDeclaration(std::ostream & o, + const OString & implname) +{ + OString nm; + short nbrackets = generateNamespace(o, implname, true, nm); + + o << "namespace css = ::com::sun::star;\n\n"; + + // generate component/service helper functions + o << "// component and service helper functions:\n" + "::rtl::OUString SAL_CALL _getImplementationName();\n" + "css::uno::Sequence< ::rtl::OUString > SAL_CALL " + "_getSupportedServiceNames();\n" + "css::uno::Reference< css::uno::XInterface > SAL_CALL _create(" + " css::uno::Reference< css::uno::XComponentContext > const & " + "context );\n\n"; + + // close namepsace + for (short i=0; i < nbrackets; i++) + o << "} "; + o << "// closing component helper namespace\n\n"; + + return nm; +} + +void generateCompHelperDefinition(std::ostream & o, + const OString & implname, + const OString & classname, + const boost::unordered_set< OString, OStringHash >& services) +{ + OString nm; + short nbrackets = generateNamespace(o, implname, true, nm); + + o << "::rtl::OUString SAL_CALL _getImplementationName() {\n" + << " return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\n" + << " \"" << implname << "\"));\n}\n\n"; + + o << "css::uno::Sequence< ::rtl::OUString > SAL_CALL " + "_getSupportedServiceNames()\n{\n css::uno::Sequence< " + << "::rtl::OUString >" << " s(" << services.size() << ");\n"; + + boost::unordered_set< OString, OStringHash >::const_iterator iter = services.begin(); + short i=0; + while (iter != services.end()) + { + o << " s[" << i++ << "] = ::rtl::OUString(" + << "RTL_CONSTASCII_USTRINGPARAM(\n \"" + << (*iter).replace('/','.') << "\"));\n"; + ++iter; + } + o << " return s;\n}\n\n"; + + o << "css::uno::Reference< css::uno::XInterface > SAL_CALL _create(" + << "\n const css::uno::Reference< css::uno::XComponentContext > & " + << "context)\n SAL_THROW((css::uno::Exception))\n{\n" + << " return static_cast< ::cppu::OWeakObject * >(new " + << classname << "(context));\n}\n\n"; + + // close namepsace + for (short j=0; j < nbrackets; j++) + o << "} "; + o << "// closing component helper namespace\n\n"; + +} + +void generateCompFunctions(std::ostream & o, const OString & nmspace) +{ + o << "static ::cppu::ImplementationEntry const entries[] = {\n" + << " { &" << nmspace << "::_create,\n &" + << nmspace << "::_getImplementationName,\n &" + << nmspace << "::_getSupportedServiceNames,\n" + << " &::cppu::createSingleComponentFactory, 0, 0 },\n" + << " { 0, 0, 0, 0, 0, 0 }\n};\n\n"; + + o << "extern \"C\" SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory(\n" + << " const char * implName, void * serviceManager, void * registryKey)\n{\n" + << " return ::cppu::component_getFactoryHelper(\n" + << " implName, serviceManager, registryKey, entries);\n}\n\n"; + + o << "extern \"C\" sal_Bool SAL_CALL component_writeInfo(\n" + << " void * serviceManager, void * registryKey)\n{\n" + << " return ::cppu::component_writeInfoHelper(" + << "serviceManager, registryKey, entries);\n}\n"; +} + +void generateXPropertySetBodies(std::ostream& o, + const OString & classname, + const OString & propertyhelper) +{ + o << "// com.sun.star.beans.XPropertySet:\n"; + + o << "css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL " + << classname << "getPropertySetInfo() throw (" + "css::uno::RuntimeException)\n{\n return ::cppu::PropertySetMixin< " + << propertyhelper + << " >::getPropertySetInfo();\n}\n\n"; + + o << "void SAL_CALL " << classname << "setPropertyValue(const ::rtl::OUString" + " & aPropertyName, const css::uno::Any & aValue) throw (" + "css::uno::RuntimeException, css::beans::UnknownPropertyException, " + "css::beans::PropertyVetoException, css::lang::IllegalArgumentException, " + "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " + << propertyhelper << " >::setPropertyValue(aPropertyName, aValue);\n}\n\n"; + + + o << "css::uno::Any SAL_CALL " << classname << "getPropertyValue(const " + "::rtl::OUString & aPropertyName) throw (css::uno::RuntimeException, " + "css::beans::UnknownPropertyException, css::lang::WrappedTargetException)" + "\n{\n return ::cppu::PropertySetMixin< " + << propertyhelper << " >::getPropertyValue(aPropertyName);\n}\n\n"; + + o << "void SAL_CALL " << classname << "addPropertyChangeListener(const " + "::rtl::OUString & aPropertyName, const css::uno::Reference< " + "css::beans::XPropertyChangeListener > & xListener) throw (" + "css::uno::RuntimeException, css::beans::UnknownPropertyException, " + "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " + << propertyhelper + << " >::addPropertyChangeListener(aPropertyName, xListener);\n}\n\n"; + + o << "void SAL_CALL " << classname << "removePropertyChangeListener(const " + "::rtl::OUString & aPropertyName, const css::uno::Reference< " + "css::beans::XPropertyChangeListener > & xListener) throw (" + "css::uno::RuntimeException, css::beans::UnknownPropertyException, " + "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " + << propertyhelper + << " >::removePropertyChangeListener(aPropertyName, xListener);\n}\n\n"; + + o << "void SAL_CALL " << classname << "addVetoableChangeListener(const " + "::rtl::OUString & aPropertyName, const css::uno::Reference< " + "css::beans::XVetoableChangeListener > & xListener) throw (" + "css::uno::RuntimeException, css::beans::UnknownPropertyException, " + "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " + << propertyhelper + << " >::addVetoableChangeListener(aPropertyName, xListener);\n}\n\n"; + + o << "void SAL_CALL " << classname << "removeVetoableChangeListener(const " + "::rtl::OUString & aPropertyName, const css::uno::Reference< " + "css::beans::XVetoableChangeListener > & xListener) throw (" + "css::uno::RuntimeException, css::beans::UnknownPropertyException, " + "css::lang::WrappedTargetException)\n{\n ::cppu::PropertySetMixin< " + << propertyhelper + << " >::removeVetoableChangeListener(aPropertyName, xListener);\n}\n\n"; +} + +void generateXFastPropertySetBodies(std::ostream& o, + const OString & classname, + const OString & propertyhelper) +{ + o << "// com.sun.star.beans.XFastPropertySet:\n"; + + o << "void SAL_CALL " << classname << "setFastPropertyValue( ::sal_Int32 " + "nHandle, const css::uno::Any& aValue ) throw (" + "css::beans::UnknownPropertyException, css::beans::PropertyVetoException, " + "css::lang::IllegalArgumentException, css::lang::WrappedTargetException, " + "css::uno::RuntimeException)\n{\n ::cppu::PropertySetMixin< " + << propertyhelper << " >::setFastPropertyValue(nHandle, aValue);\n}\n\n"; + + + o << "css::uno::Any SAL_CALL " << classname << "getFastPropertyValue( " + "::sal_Int32 nHandle ) throw (css::beans::UnknownPropertyException, " + "css::lang::WrappedTargetException, css::uno::RuntimeException)\n{\n" + " return ::cppu::PropertySetMixin< " + << propertyhelper << " >::getFastPropertyValue(nHandle);\n}\n\n"; +} + +void generateXPropertyAccessBodies(std::ostream& o, + const OString & classname, + const OString & propertyhelper) +{ + o << " // com.sun.star.beans.XPropertyAccess:\n"; + + o << "css::uno::Sequence< css::beans::PropertyValue > SAL_CALL " + << classname << "getPropertyValues( ) throw (" + "::com::sun::star::uno::RuntimeException)\n{\n" + " return ::cppu::PropertySetMixin< " + << propertyhelper << " >::getPropertyValues();\n}\n\n"; + + o << "void SAL_CALL " << classname << "setPropertyValues( const " + "css::uno::Sequence< css::beans::PropertyValue >& aProps ) throw (" + "css::beans::UnknownPropertyException, css::beans::PropertyVetoException, " + "css::lang::IllegalArgumentException, css::lang::WrappedTargetException, " + "css::uno::RuntimeException)\n{\n" + " ::cppu::PropertySetMixin< " + << propertyhelper << " >::setPropertyValues(aProps);\n}\n\n"; +} + +void generateXLocalizable(std::ostream& o, const OString & classname) +{ + o << "// ::com::sun::star::lang::XLocalizable:\n" + "void SAL_CALL " << classname << "setLocale(const css::lang::" + "Locale & eLocale) throw (css::uno::RuntimeException)\n{\n" + " m_locale = eLocale;\n}\n\n" + "css::lang::Locale SAL_CALL " << classname << "getLocale() " + "throw (css::uno::RuntimeException)\n{\n return m_locale;\n}\n\n"; +} + +void generateXAddInBodies(std::ostream& o, const OString & classname) +{ + o << "// ::com::sun::star::sheet::XAddIn:\n"; + + o << "::rtl::OUString SAL_CALL " << classname << "getProgrammaticFuntionName(" + "const ::rtl::OUString & aDisplayName) throw (css::uno::RuntimeException)" + "\n{\n ::rtl::OUString ret;\n try {\n css::uno::Reference< " + "css::container::XNameAccess > xNAccess(m_xHAccess, css::uno::UNO_QUERY);\n" + " css::uno::Sequence< ::rtl::OUString > functions = " + "xNAccess->getElementNames();\n sal_Int32 len = functions." + "getLength();\n ::rtl::OUString sDisplayName;\n" + " for (sal_Int32 i=0; i < len; ++i) {\n" + " sDisplayName = getAddinProperty(functions[i], " + "::rtl::OUString(),\n " + "sDISPLAYNAME);\n if (sDisplayName.equals(aDisplayName))\n" + " return functions[i];\n }\n }\n" + " catch ( css::uno::RuntimeException & e ) {\n throw e;\n }\n" + " catch ( css::uno::Exception & ) {\n }\n return ret;\n}\n\n"; + + o << "::rtl::OUString SAL_CALL " << classname << "getDisplayFunctionName(const " + "::rtl::OUString & aProgrammaticName) throw (css::uno::RuntimeException)\n" + "{\n return getAddinProperty(aProgrammaticName, ::rtl::OUString(), " + "sDISPLAYNAME);\n}\n\n"; + + o << "::rtl::OUString SAL_CALL " << classname << "getFunctionDescription(const " + "::rtl::OUString & aProgrammaticName) throw (css::uno::RuntimeException)\n" + "{\n return getAddinProperty(aProgrammaticName, ::rtl::OUString(), " + "sDESCRIPTION);\n}\n\n"; + + o << "::rtl::OUString SAL_CALL " << classname << "getDisplayArgumentName(const " + "::rtl::OUString & aProgrammaticFunctionName, ::sal_Int32 nArgument) throw " + "(css::uno::RuntimeException)\n{\n return getAddinProperty(" + "aProgrammaticFunctionName,\n m_functionMap[" + "aProgrammaticFunctionName][nArgument],\n" + " sDISPLAYNAME);\n}\n\n"; + + o << "::rtl::OUString SAL_CALL " << classname << "getArgumentDescription(const " + "::rtl::OUString & aProgrammaticFunctionName, ::sal_Int32 nArgument) throw " + "(css::uno::RuntimeException)\n{\n return getAddinProperty(" + "aProgrammaticFunctionName,\n " + "m_functionMap[aProgrammaticFunctionName][nArgument],\n" + " sDESCRIPTION);\n}\n\n"; + + o << "::rtl::OUString SAL_CALL " << classname << "getProgrammaticCategoryName(" + "const ::rtl::OUString & aProgrammaticFunctionName) throw (" + "css::uno::RuntimeException)\n{\n return getAddinProperty(" + "aProgrammaticFunctionName, ::rtl::OUString(), sCATEGORY);\n}\n\n"; + + o << "::rtl::OUString SAL_CALL " << classname << "getDisplayCategoryName(const " + "::rtl::OUString & aProgrammaticFunctionName) throw (" + "css::uno::RuntimeException)\n{\n return getAddinProperty(" + "aProgrammaticFunctionName, ::rtl::OUString(), " + "sCATEGORYDISPLAYNAME);\n}\n\n"; +} + +void generateXCompatibilityNamesBodies(std::ostream& o, const OString & classname) +{ + o << "// ::com::sun::star::sheet::XCompatibilityNames:\n" + "css::uno::Sequence< css::sheet::LocalizedName > SAL_CALL " << classname + << "getCompatibilityNames(const ::rtl::OUString & aProgrammaticName) throw " + "(css::uno::RuntimeException)\n{\n css::uno::Sequence< " + "css::sheet::LocalizedName > seqLocalizedNames;\n try {\n " + "::rtl::OUStringBuffer buf(" + "aProgrammaticName);\n buf.appendAscii(\"/CompatibilityName\");\n" + " ::rtl::OUString hname(buf.makeStringAndClear());\n\n " + "if ( m_xCompAccess->hasByHierarchicalName(hname) ) {\n" + " css::uno::Reference< css::container::XNameAccess > " + "xNameAccess(\n" + " m_xCompAccess->getByHierarchicalName(hname), " + "css::uno::UNO_QUERY);\n\n css::uno::Sequence< ::rtl::OUString" + " > elems = \n xNameAccess->getElementNames();" + "\n ::sal_Int32 len = elems.getLength();\n\n " + "seqLocalizedNames.realloc(len);\n\n ::rtl::OUString " + "sCompatibilityName;\n for (::sal_Int32 i=0; i < len; ++i) {\n" + " ::rtl::OUString sLocale(elems[i]);\n " + "xNameAccess->getByName(sLocale) >>= sCompatibilityName;\n\n" + " css::lang::Locale aLocale;\n " + "::sal_Int32 nIndex = 0, nToken = 0;\n " + "do {\n ::rtl::OUString aToken = sLocale.getToken(0, '-', " + "nIndex);\n switch (nToken++) {\n " + "case 0:\n aLocale.Language = aToken;\n" + " break;\n case 1:\n" + " aLocale.Country = aToken;\n " + " break;\n default:\n " + "aLocale.Variant = sLocale.copy(nIndex-aToken.getLength()-1);\n" + " nIndex = -1;\n }\n" + " } while ( nIndex >= 0 );\n\n " + "seqLocalizedNames[i].Locale = aLocale;\n " + "seqLocalizedNames[i].Name = sCompatibilityName;\n }" + "\n }\n }\n catch ( css::uno::RuntimeException & e ) {\n " + "throw e;\n }\n catch ( css::uno::Exception & ) {\n }\n\n" + " return seqLocalizedNames;\n}\n\n"; +} + +void generateXInitialization(std::ostream& o, const OString & classname) +{ + o << "// ::com::sun::star::lang::XInitialization:\n" + "void SAL_CALL " << classname << "initialize( const css::uno::Sequence< " + "css::uno::Any >& aArguments ) " + "throw (css::uno::Exception, css::uno::RuntimeException)\n{\n" + " css::uno::Reference < css::frame::XFrame > xFrame;\n" + " if ( aArguments.getLength() ) {\n aArguments[0] >>= xFrame;\n" + " m_xFrame = xFrame;\n }\n}\n\n"; +} + +void generateXDispatch(std::ostream& o, + const OString & classname, + const ProtocolCmdMap & protocolCmdMap) +{ + // com.sun.star.frame.XDispatch + // dispatch + o << "// ::com::sun::star::frame::XDispatch:\n" + "void SAL_CALL " << classname << "dispatch( const css::util::URL& aURL, const " + "css::uno::Sequence< css::beans::PropertyValue >& aArguments ) throw" + "(css::uno::RuntimeException)\n{\n"; + + ProtocolCmdMap::const_iterator iter = protocolCmdMap.begin(); + while (iter != protocolCmdMap.end()) { + o << " if ( aURL.Protocol.equalsAscii(\"" << (*iter).first + << "\") == 0 )\n {\n"; + + for (std::vector< OString >::const_iterator i = (*iter).second.begin(); + i != (*iter).second.end(); ++i) { + o << " if ( aURL.Path.equalsAscii(\"" << (*i) << "\") )\n" + " {\n // add your own code here\n" + " return;\n }\n"; + } + + o << " }\n"; + ++iter; + } + o << "}\n\n"; + + // addStatusListener + o << "void SAL_CALL " << classname << "addStatusListener( const css::uno::Reference< " + "css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) " + "throw (css::uno::RuntimeException)\n{\n" + " // add your own code here\n}\n\n"; + + // removeStatusListener + o << "void SAL_CALL " << classname << "removeStatusListener( const css::uno::Reference" + "< css::frame::XStatusListener >& xControl, const css::util::URL& aURL ) " + "throw (css::uno::RuntimeException)\n{\n" + " // add your own code here\n}\n\n"; +} + +void generateXDispatchProvider(std::ostream& o, + const OString & classname, + const ProtocolCmdMap & protocolCmdMap) +{ + + // com.sun.star.frame.XDispatchProvider + // queryDispatch + o << "// ::com::sun::star::frame::XDispatchProvider:\n" + "css::uno::Reference< css::frame::XDispatch > SAL_CALL " << classname + << "queryDispatch( const css::util::URL& aURL," + " const ::rtl::OUString& sTargetFrameName, sal_Int32 nSearchFlags ) " + "throw(css::uno::RuntimeException)\n{\n css::uno::Reference< " + "css::frame::XDispatch > xRet;\n" + " if ( !m_xFrame.is() )\n return 0;\n\n"; + + ProtocolCmdMap::const_iterator iter = protocolCmdMap.begin(); + while (iter != protocolCmdMap.end()) { + o << " if ( aURL.Protocol.equalsAscii(\"" << (*iter).first + << "\") == 0 )\n {\n"; + + for (std::vector< OString >::const_iterator i = (*iter).second.begin(); + i != (*iter).second.end(); ++i) { + o << " if ( aURL.Path.equalsAscii(\"" << (*i) << "\") == 0 )\n" + " xRet = this;\n"; + } + + o << " }\n"; + ++iter; + } + o << " return xRet;\n}\n\n"; + + // queryDispatches + o << "css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > SAL_CALL " + << classname << "queryDispatches( const css::uno::Sequence< " + "css::frame::DispatchDescriptor >& seqDescripts ) throw(" + "css::uno::RuntimeException)\n{\n" + " sal_Int32 nCount = seqDescripts.getLength();\n" + " css::uno::Sequence< css::uno::Reference< css::frame::XDispatch > > " + "lDispatcher(nCount);\n\n" + " for( sal_Int32 i=0; i<nCount; ++i ) {\n" + " lDispatcher[i] = queryDispatch( seqDescripts[i].FeatureURL,\n" + " seqDescripts[i].FrameName,\n" + " seqDescripts[i].SearchFlags );\n" + " }\n\n return lDispatcher;\n}\n\n"; +} + +void generateAddinConstructorAndHelper(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, const OString & classname, + const boost::unordered_set< OString, OStringHash >& interfaces) +{ + o << classname << "::" << classname + << "(css::uno::Reference< css::uno::XComponentContext > const & context) :\n" + << " m_xContext(context), m_locale()\n{\n"; + + if (options.backwardcompatible) { + o << " try {\n"; + + generateFunctionParameterMap(o, options, manager, interfaces); + + o << " css::uno::Reference< css::lang::XMultiServiceFactory > xProvider" + "(\n m_xContext->getServiceManager()->createInstanceWithContext" + "(\n ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\n " + " \"com.sun.star.configuration.ConfigurationProvider\"))," + "\n m_xContext ), css::uno::UNO_QUERY );\n\n"; + + o << " ::rtl::OUString sReadOnlyView(\n" + " RTL_CONSTASCII_USTRINGPARAM(\n" + " \"com.sun.star.configuration.ConfigurationAccess\"));\n\n"; + + o << " ::rtl::OUStringBuffer sPath(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\n" + " \"/org.openoffice.Office.CalcAddIns/AddInInfo/\")));\n" + " sPath.appendAscii(sADDIN_SERVICENAME);\n" + " sPath.appendAscii(\"/AddInFunctions\");\n\n" + " // create arguments: nodepath\n" + " css::beans::PropertyValue aArgument;\n" + " aArgument.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"nodepath\"));\n" + " aArgument.Value <<= sPath.makeStringAndClear();\n\n" + " css::uno::Sequence< css::uno::Any > aArguments(1);\n" + " aArguments[0] <<= aArgument;\n\n"; + + o << " // create the default view using default UI locale\n" + " css::uno::Reference< css::uno::XInterface > xIface =\n" + " xProvider->createInstanceWithArguments(sReadOnlyView, " + "aArguments);\n\n" + " m_xHAccess = css::uno::Reference<\n " + "css::container::XHierarchicalNameAccess >(xIface, css::uno::UNO_QUERY);" + "\n\n"; + + o << " // extend arguments to create a view for all locales to get " + "simple\n // access to the compatibilityname property\n" + " aArgument.Name = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"locale\"));\n" + " aArgument.Value <<= ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"*\"));\n" + " aArguments.realloc(2);\n" + " aArguments[1] <<= aArgument;\n\n" + " // create view for all locales\n" + " xIface = xProvider->createInstanceWithArguments(sReadOnlyView, " + "aArguments);\n\n" + " m_xCompAccess = css::uno::Reference<\n " + "css::container::XHierarchicalNameAccess >(xIface, css::uno::UNO_QUERY);\n"; + + o << " }\n catch ( css::uno::Exception & ) {\n }\n}\n\n"; + + o << "// addin configuration property helper function:\n::rtl::OUString " + "SAL_CALL " << classname << "::getAddinProperty(const ::rtl::OUString &" + " funcName, const ::rtl::OUString & paramName, const char * propName) " + "throw (css::uno::RuntimeException)\n{\n" + " ::rtl::OUString ret;\n try {\n " + "::rtl::OUStringBuffer buf(funcName);\n" + " if (paramName.getLength() > 0) {\n" + " buf.appendAscii(\"/Parameters/\");\n" + " buf.append(paramName);\n }\n\n" + " css::uno::Reference< css::beans::XPropertySet > xPropSet(\n" + " m_xHAccess->getByHierarchicalName(\n" + " buf.makeStringAndClear()), css::uno::UNO_QUERY);\n" + " xPropSet->getPropertyValue(\n " + "::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(propName))) >>= ret;\n }\n" + " catch ( css::uno::RuntimeException & e ) {\n throw e;\n }\n" + " catch ( css::uno::Exception & ) {\n }\n return ret;\n"; + } + o <<"}\n\n"; +} + +void generateMemberInitialization(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + AttributeInfo const & members) +{ + if (!members.empty()) { + for (AttributeInfo::const_iterator i(members.begin()); + i != members.end(); ++i) + { + RTTypeClass typeClass; + OString type(i->second.first.replace('.','/')); + OString name; + sal_Int32 rank; + std::vector< OString > arguments; + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, type, true, true, true, &typeClass, &name, &rank, + &arguments); + + if (sort <= codemaker::UnoType::SORT_CHAR && rank == 0) { + o << ",\n m_" << i->first << "("; + printType(o, options, manager, type, 16, true); + o << ")"; + } + } + } +} + +void generateMemberDeclaration(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + AttributeInfo const & members) +{ + for (AttributeInfo::const_iterator i(members.begin()); + i != members.end(); ++i) + { + o << " "; + printType(o, options, manager, i->second.first.replace('.','/'), + 1, false); + o << " m_" << i->first << ";\n"; + } +} + +OString generateClassDefinition(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + OString const & classname, + boost::unordered_set< OString, OStringHash > const & interfaces, + AttributeInfo const & properties, + AttributeInfo const & attributes, + boost::unordered_set< OString, OStringHash > const & propinterfaces, + OString const & propertyhelper, bool supportxcomponent) +{ + OStringBuffer parentname(64); + o << "class " << classname << ":\n"; + + if (!interfaces.empty()) { + if (supportxcomponent) { + parentname.append("::cppu::WeakComponentImplHelper"); + parentname.append(static_cast<sal_Int32>(interfaces.size())); + o << " private ::cppu::BaseMutex,\n" + << " public ::cppu::WeakComponentImplHelper" + << interfaces.size() << "<"; + } else { + parentname.append("::cppu::WeakImplHelper"); + parentname.append(static_cast<sal_Int32>(interfaces.size())); + o << " public ::cppu::WeakImplHelper" << interfaces.size() << "<"; + } + + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + while (iter != interfaces.end()) + { + o << "\n " << scopedCppName(*iter, false, true); + ++iter; + if (iter != interfaces.end()) + o << ","; + else + o << ">"; + } + } + + if (propertyhelper.getLength() > 1) { + o << ",\n public ::cppu::PropertySetMixin< " + << scopedCppName(propertyhelper, false, true) << " >"; + } + + o << "\n{\npublic:\n" + << " explicit " << classname << "(" + << "css::uno::Reference< css::uno::XComponentContext > const & context);\n\n"; + + // generate component/service helper functions +// o << " // component and service helper functions:\n" +// << " static ::rtl::OUString SAL_CALL _getImplementationName();\n" +// << " static css::uno::Sequence< ::rtl::OUString > SAL_CALL " +// << "_getSupportedServiceNames();\n" +// << " static css::uno::Reference< css::uno::XInterface > SAL_CALL _create(" +// << "\n css::uno::Reference< css::uno::XComponentContext > const & " +// << "context);\n\n"; + + // overload queryInterface + if (propertyhelper.getLength() > 1) { + o << " // ::com::sun::star::uno::XInterface:\n" + " virtual css::uno::Any SAL_CALL queryInterface(" + "css::uno::Type const & type) throw (" + "css::uno::RuntimeException);\n"; + + OStringBuffer buffer(256); + buffer.append(parentname); + buffer.append("< "); + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + while (iter != interfaces.end()) + { + buffer.append(scopedCppName(*iter, false, true)); + ++iter; + if (iter != interfaces.end()) + buffer.append(", "); + else + buffer.append(" >"); + } + OString parent(buffer.makeStringAndClear()); + o << " virtual void SAL_CALL acquire() throw ()\n { " + << parent << "::acquire(); }\n"; + o << " virtual void SAL_CALL release() throw ()\n { " + << parent << "::release(); }\n\n"; + } + + boost::unordered_set< OString, OStringHash >::const_iterator it = + interfaces.begin(); + codemaker::GeneratedTypeSet generated; + while (it != interfaces.end()) + { + typereg::Reader reader(manager.getTypeReader((*it).replace('.','/'))); + printMethods(o, options, manager, reader, generated, "", "", " ", + true, propertyhelper); + ++it; + } + + o << "private:\n " << classname << "(const " << classname << " &); // not defined\n" + << " " << classname << "& operator=(const " << classname << " &); // not defined\n\n" + << " // destructor is private and will be called indirectly by the release call" + << " virtual ~" << classname << "() {}\n\n"; + + if (options.componenttype == 2) { + o << " typedef boost::unordered_map< ::sal_Int32, rtl::OUString, " + "boost::hash<::sal_Int32> > ParamMap;\n" + " typedef boost::unordered_map< rtl::OUString, ParamMap, " + "rtl::OUStringHash > FunctionMap;\n\n" + " ::rtl::OUString SAL_CALL getAddinProperty(const ::rtl::OUString & " + "funcName, const ::rtl::OUString & paramName, const char * propName) " + "throw (css::uno::RuntimeException);\n\n"; + } + + if (supportxcomponent) { + o << " // overload WeakComponentImplHelperBase::disposing()\n" + " // This function is called upon disposing the component,\n" + " // if your component needs special work when it becomes\n" + " // disposed, do it here.\n" + " virtual void SAL_CALL disposing();\n\n"; + } + + // members + o << " css::uno::Reference< css::uno::XComponentContext > m_xContext;\n"; + if (!supportxcomponent && !attributes.empty()) + o << " mutable ::osl::Mutex m_aMutex;\n"; + + // additional member for add-ons + if (options.componenttype == 3) { + o << " css::uno::Reference< css::frame::XFrame > m_xFrame;\n"; + } + + if (options.componenttype == 2) { + if (options.backwardcompatible) { + o <<" css::uno::Reference< css::container::XHierarchicalNameAccess > " + "m_xHAccess;\n" + " css::uno::Reference< css::container::XHierarchicalNameAccess > " + "m_xCompAccess;\n" + " FunctionMap m_functionMap;\n"; + } + o << " css::lang::Locale m_locale;\n"; + } + + generateMemberDeclaration(o, options, manager, properties); + generateMemberDeclaration(o, options, manager, attributes); + +// if (!properties.empty()) +// { +// AttributeInfo::const_iterator iter = properties.begin(); +// while (iter != properties.end()) +// { +// o << " "; +// printType(o, options, manager, iter->second.first.replace('.','/'), +// 1, false); +// o << " m_" << iter->first << ";\n"; +// iter++; +// } +// } +// if (!attributes.empty()) +// { +// AttributeInfo::const_iterator iter = attributes.begin(); +// while (iter != attributes.end()) +// { +// o << " "; +// printType(o, options, manager, iter->second.first.replace('.','/'), +// 1, false); +// o << " m_" << iter->first << ";\n"; +// iter++; +// } +// } + + o << "};\n\n"; + + // generate constructor + if (options.componenttype == 2) { + generateAddinConstructorAndHelper(o, options, manager, + classname, interfaces); + } else { + o << classname << "::" << classname + << "(css::uno::Reference< css::uno::XComponentContext > const & context) :\n"; + if (supportxcomponent) { + o << " ::cppu::WeakComponentImplHelper" << interfaces.size() << "<"; + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + while (iter != interfaces.end()) { + o << "\n " << scopedCppName(*iter, false, true); + ++iter; + if (iter != interfaces.end()) + o << ","; + else + o << ">(m_aMutex),\n"; + } + } + if (propertyhelper.getLength() > 1) { + o << " ::cppu::PropertySetMixin< " + << scopedCppName(propertyhelper, false, true) << " >(\n" + << " context, static_cast< Implements >(\n "; + OStringBuffer buffer(128); + if (propinterfaces.find("com/sun/star/beans/XPropertySet") + != propinterfaces.end()) { + buffer.append("IMPLEMENTS_PROPERTY_SET"); + } + if (propinterfaces.find("com/sun/star/beans/XFastPropertySet") + != propinterfaces.end()) { + if (buffer.getLength() > 0) + buffer.append(" | IMPLEMENTS_FAST_PROPERTY_SET"); + else + buffer.append("IMPLEMENTS_FAST_PROPERTY_SET"); + } + if (propinterfaces.find("com/sun/star/beans/XPropertyAccess") + != propinterfaces.end()) { + if (buffer.getLength() > 0) + buffer.append(" | IMPLEMENTS_PROPERTY_ACCESS"); + else + buffer.append("IMPLEMENTS_PROPERTY_ACCESS"); + } + o << buffer.makeStringAndClear() + << "), css::uno::Sequence< ::rtl::OUString >()),\n"; + } + o << " m_xContext(context)"; + + generateMemberInitialization(o, options, manager, properties); + generateMemberInitialization(o, options, manager, attributes); + + o << "\n{}\n\n"; + } + + // generate service/component helper function implementations +// generateServiceHelper(o, options.implname, classname, services); + + if (supportxcomponent) { + o << "// overload WeakComponentImplHelperBase::disposing()\n" + "// This function is called upon disposing the component,\n" + "// if your component needs special work when it becomes\n" + "// disposed, do it here.\n" + "void SAL_CALL " << classname << "::disposing()\n{\n\n}\n\n"; + } + + return parentname.makeStringAndClear(); +} + +void generateXServiceInfoBodies(std::ostream& o, + OString const & classname, + OString const & comphelpernamespace) +{ + o << "// com.sun.star.uno.XServiceInfo:\n" + << "::rtl::OUString SAL_CALL " << classname << "getImplementationName() " + << "throw (css::uno::RuntimeException)\n{\n " + << "return " << comphelpernamespace << "::_getImplementationName();\n}\n\n"; + + o << "::sal_Bool SAL_CALL " << classname + << "supportsService(::rtl::OUString const & " + << "serviceName) throw (css::uno::RuntimeException)\n{\n " + << "css::uno::Sequence< ::rtl::OUString > serviceNames = " + << comphelpernamespace << "::_getSupportedServiceNames();\n " + << "for (::sal_Int32 i = 0; i < serviceNames.getLength(); ++i) {\n " + << " if (serviceNames[i] == serviceName)\n return sal_True;\n" + << " }\n return sal_False;\n}\n\n"; + + o << "css::uno::Sequence< ::rtl::OUString > SAL_CALL " << classname + << "getSupportedServiceNames() throw (css::uno::RuntimeException)\n{\n " + << "return " << comphelpernamespace + << "::_getSupportedServiceNames();\n}\n\n"; +} + + +void generateMethodBodies(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + boost::unordered_set< OString, OStringHash > const & interfaces, + OString const & classname, + OString const & comphelpernamespace, + OString const & propertyhelper) +{ + OString name(classname.concat("::")); + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + codemaker::GeneratedTypeSet generated; + while (iter != interfaces.end()) { + if ( (*iter).equals("com.sun.star.lang.XServiceInfo") ) { + generateXServiceInfoBodies(o, name, comphelpernamespace); + generated.add(*iter); + } else { + typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/'))); + printMethods(o, options, manager, reader, generated, "_", + name, "", true, propertyhelper); + } + ++iter; + } +} + +void generateQueryInterface(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + const boost::unordered_set< OString, OStringHash >& interfaces, + OString const & parentname, + OString const & classname, + OString const & propertyhelper) +{ + if (propertyhelper.getLength() == 0) + return; + + o << "css::uno::Any " << classname + << "::queryInterface(css::uno::Type const & type) throw (" + "css::uno::RuntimeException)\n{\n "; + + if (propertyhelper.getLength() >= 1) + o << "return "; + else + o << "css::uno::Any a("; + + o << parentname << "<"; + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + while (iter != interfaces.end()) + { + o << "\n " << scopedCppName(*iter, false, true); + ++iter; + if (iter != interfaces.end()) + o << ","; + else + o << ">"; + } + + if (propertyhelper.getLength() >= 1) { + o << "::queryInterface(type);\n"; + } else { + o << "::queryInterface(type));\n"; + o << " return a.hasValue() ? a\n : ("; + if (propertyhelper.equals("_")) { + o << "::cppu::OPropertySetHelper::queryInterface(type));\n"; + } else { + o << "::cppu::PropertySetMixin<\n "; + printType(o, options, manager, propertyhelper.replace('.', '/'), + 0, false); + o << " >::queryInterface(\n type));\n"; + } + } + o << "}\n\n"; +} + +void generateSkeleton(ProgramOptions const & options, + TypeManager const & manager, + std::vector< OString > const & types, + OString const & /*delegate*/) +{ + // special handling of calc add-ins + if (options.componenttype == 2) { + generateCalcAddin(options, manager, types); + return; + } + + boost::unordered_set< OString, OStringHash > interfaces; + boost::unordered_set< OString, OStringHash > services; + AttributeInfo properties; + AttributeInfo attributes; + boost::unordered_set< OString, OStringHash > propinterfaces; + bool serviceobject = false; + bool supportxcomponent = false; + + std::vector< OString >::const_iterator iter = types.begin(); + while (iter != types.end()) { + checkType(manager, *iter, interfaces, services, properties); + ++iter; + } + + if (options.componenttype == 3) { + // the Protocolhandler service is mandatory for an protocol handler add-on, + // so it is defaulted. The XDispatchProvider provides Dispatch objects for + // certain functions and the generated impl object implements XDispatch + // directly for simplicity reasons. + checkType(manager, "com.sun.star.frame.ProtocolHandler", + interfaces, services, properties); + checkType(manager, "com.sun.star.frame.XDispatch", + interfaces, services, properties); + } + + // check if service object or simple UNO object + if (!services.empty()) + serviceobject = true; + + OString propertyhelper = checkPropertyHelper( + options, manager, services, interfaces, attributes, propinterfaces); + + checkDefaultInterfaces(interfaces, services, propertyhelper); + + if (interfaces.size() > 12) + throw CannotDumpException( + "the skeletonmaker supports components with 12 interfaces " + "only (limitation of the UNO implementation helpers)!"); + + + supportxcomponent = checkXComponentSupport(manager, interfaces); + + OString compFileName; + OString tmpFileName; + std::ostream* pofs = NULL; + bool standardout = getOutputStream(options, ".cxx", + &pofs, compFileName, tmpFileName); + + try { + if (!standardout && options.license) { + printLicenseHeader(*pofs, compFileName); + } + + generateIncludes(*pofs, interfaces, properties, propertyhelper, + serviceobject, supportxcomponent); + + if (options.componenttype == 3) { + *pofs << "#include \"com/sun/star/frame/XFrame.hpp\"\n"; + } + + // namespace + OString nmspace; + short nm = 0; + + if (serviceobject) { + nmspace = generateCompHelperDeclaration(*pofs, options.implname); + + *pofs << + "\n\n/// anonymous implementation namespace\nnamespace {\n\n" + "namespace css = ::com::sun::star;\n\n"; + } else { + nm = generateNamespace(*pofs, options.implname, false, nmspace); + *pofs << "namespace css = ::com::sun::star;\n\n"; + } + + sal_Int32 index = 0; + OString classname(options.implname); + if ((index = classname.lastIndexOf('.')) > 0) + classname = classname.copy(index+1); + + OString parentname( + generateClassDefinition(*pofs, + options, manager, classname, interfaces, properties, + attributes, propinterfaces, propertyhelper, supportxcomponent)); + + generateQueryInterface(*pofs, options, manager, interfaces, parentname, + classname, propertyhelper); + + generateMethodBodies(*pofs, options, manager, interfaces, classname, + nmspace, propertyhelper); + + if (serviceobject) { + // close namepsace + *pofs << "} // closing anonymous implementation namespace\n\n"; + + generateCompHelperDefinition(*pofs, options.implname, + classname, services); + generateCompFunctions(*pofs, nmspace); + } else { + // close namepsace + for (short i=0; i < nm; i++) + *pofs << "} "; + *pofs << (nm > 0 ? "// closing namespace\n\n" : "\n"); + } + + if ( !standardout && pofs && ((std::ofstream*)pofs)->is_open()) { + ((std::ofstream*)pofs)->close(); + delete pofs; + OSL_VERIFY(makeValidTypeFile(compFileName, tmpFileName, sal_False)); + } + } catch(CannotDumpException& e) { + + std::cerr << "ERROR: " << e.m_message.getStr() << "\n"; + if ( !standardout ) { + if (pofs && ((std::ofstream*)pofs)->is_open()) { + ((std::ofstream*)pofs)->close(); + delete pofs; + } + // remove existing type file if something goes wrong to ensure + // consistency + if (fileExists(compFileName)) + removeTypeFile(compFileName); + + // remove tmp file if something goes wrong + removeTypeFile(tmpFileName); + } + } +} + +void generateCalcAddin(ProgramOptions const & options, + TypeManager const & manager, + std::vector< OString > const & types) +{ + boost::unordered_set< OString, OStringHash > interfaces; + boost::unordered_set< OString, OStringHash > services; + AttributeInfo properties; + AttributeInfo attributes; + boost::unordered_set< OString, OStringHash > propinterfaces; + bool serviceobject = false; + bool supportxcomponent = false; + + + std::vector< OString >::const_iterator iter = types.begin(); + while (iter != types.end()) { + checkType(manager, *iter, interfaces, services, properties); + ++iter; + } + + OString sAddinService; + if (services.size() != 1) { + throw CannotDumpException( + "for calc add-in components one and only one service type is necessary!" + " Please reference a valid type with the '-t' option."); + } + + + // get the one and only add-in service for later use + boost::unordered_set< OString, OStringHash >::const_iterator iter2 = services.begin(); + sAddinService = (*iter2).replace('/', '.'); + if (sAddinService.equals("com.sun.star.sheet.AddIn")) { + sAddinService = (*(++iter2)).replace('/', '.'); + } + + // if backwardcompatible==true the AddIn service needs to be added to the + // suported service list, the necessary intefaces are mapped to the add-in + // configuration. Since OO.org 2.0.4 this is obsolete and the add-in is + // take form the configuration from Calc directly, this simplifies the + // add-in code + if (options.backwardcompatible) { + checkType(manager, "com.sun.star.sheet.AddIn", + interfaces, services, properties); + } else { + // special case for the optional XLocalization interface. It should be + // implemented always. But it is parent of the XAddIn and we need it only + // if backwardcompatible is false. + if (interfaces.find("com.sun.star.lang.XLocalizable") == interfaces.end()) { + interfaces.insert("com.sun.star.lang.XLocalizable"); + } + } + + OString propertyhelper = checkPropertyHelper( + options, manager, services, interfaces, attributes, propinterfaces); + + if (propertyhelper.getLength() > 0) + std::cerr << "WARNING: interfaces specifying calc add-in functions " + "shouldn't support attributes!\n"; + + checkDefaultInterfaces(interfaces, services, propertyhelper); + + if (interfaces.size() > 12) { + throw CannotDumpException( + "the skeletonmaker supports components with 12 interfaces " + "only (limitation of the UNO implementation helpers)!"); + } + + // check if service object or simple UNO object + if (!services.empty()) + serviceobject = true; + + supportxcomponent = checkXComponentSupport(manager, interfaces); + if (supportxcomponent) + std::cerr << "WARNING: add-ins shouldn't support " + "com.sun.star.uno.XComponent!\n"; + + OString compFileName; + OString tmpFileName; + std::ostream* pofs = NULL; + bool standardout = getOutputStream(options, ".cxx", + &pofs, compFileName, tmpFileName); + + try { + if (!standardout && options.license) { + printLicenseHeader(*pofs, compFileName); + } + + generateIncludes(*pofs, interfaces, properties, propertyhelper, + serviceobject, supportxcomponent); + + *pofs << + "#include \"com/sun/star/beans/PropertyValue.hpp\"\n" + "#include \"com/sun/star/beans/XPropertySet.hpp\"\n" + "#include \"com/sun/star/container/XNameAccess.hpp\"\n" + "#include \"com/sun/star/container/XHierarchicalNameAccess.hpp\"\n\n" + "#include \"rtl/ustrbuf.hxx\"\n\n" + "#include <boost/unordered_map.hpp>\n" + "#include <set>\n"; + + // namespace + OString nmspace(generateCompHelperDeclaration(*pofs, options.implname)); + + *pofs << + "\n\n// anonymous implementation namespace\nnamespace {\n\n" + "namespace css = ::com::sun::star;\n\n"; + + sal_Int32 index = 0; + OString classname(options.implname); + if ((index = classname.lastIndexOf('.')) > 0) { + classname = classname.copy(index+1); + } + + if (options.backwardcompatible) { + *pofs << "static const char * sADDIN_SERVICENAME = \"" + << sAddinService << "\";\n\n"; + *pofs << "static const char * sDISPLAYNAME = \"DisplayName\";\n" + "static const char * sDESCRIPTION = \"Description\";\n" + "static const char * sCATEGORY = \"Category\";\n" + "static const char * sCATEGORYDISPLAYNAME = \"CategoryDisplayName\";" + "\n\n"; + } + + OString parentname( + generateClassDefinition(*pofs, + options, manager, classname, interfaces, properties, + attributes, propinterfaces, propertyhelper, supportxcomponent)); + + generateQueryInterface(*pofs, options, manager, interfaces, parentname, + classname, propertyhelper); + + generateMethodBodies(*pofs, options, manager, interfaces, classname, + nmspace, propertyhelper); + + // close namepsace + *pofs << "} // closing anonymous implementation namespace\n\n"; + + generateCompHelperDefinition(*pofs, options.implname, classname, + services); + + generateCompFunctions(*pofs, nmspace); + + if ( !standardout && pofs && ((std::ofstream*)pofs)->is_open()) { + ((std::ofstream*)pofs)->close(); + delete pofs; + OSL_VERIFY(makeValidTypeFile(compFileName, tmpFileName, sal_False)); + } + } catch(CannotDumpException& e) { + + std::cerr << "ERROR: " << e.m_message.getStr() << "\n"; + if ( !standardout ) { + if (pofs && ((std::ofstream*)pofs)->is_open()) { + ((std::ofstream*)pofs)->close(); + delete pofs; + } + // remove existing type file if something goes wrong to ensure + // consistency + if (fileExists(compFileName)) + removeTypeFile(compFileName); + + // remove tmp file if something goes wrong + removeTypeFile(tmpFileName); + } + } +} + +} } + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/cpptypemaker.cxx b/unodevtools/source/skeletonmaker/cpptypemaker.cxx new file mode 100644 index 000000000000..ce9f4b8d95a6 --- /dev/null +++ b/unodevtools/source/skeletonmaker/cpptypemaker.cxx @@ -0,0 +1,973 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "codemaker/commoncpp.hxx" + +#include "skeletoncommon.hxx" +#include "skeletoncpp.hxx" + +using namespace ::rtl; +using namespace ::codemaker::cpp; + +namespace skeletonmaker { namespace cpp { + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + OString const & name, sal_Int32 rank, + std::vector< OString > const & arguments, short referenceType, + bool defaultvalue) +{ + if (defaultvalue && rank == 0 && sort <= codemaker::UnoType::SORT_CHAR) { + switch (sort) + { + case codemaker::UnoType::SORT_BOOLEAN: + o << "sal_False"; + return; + case codemaker::UnoType::SORT_CHAR: + case codemaker::UnoType::SORT_BYTE: + case codemaker::UnoType::SORT_SHORT: + case codemaker::UnoType::SORT_UNSIGNED_SHORT: + case codemaker::UnoType::SORT_LONG: + case codemaker::UnoType::SORT_UNSIGNED_LONG: + case codemaker::UnoType::SORT_HYPER: + case codemaker::UnoType::SORT_UNSIGNED_HYPER: + case codemaker::UnoType::SORT_FLOAT: + case codemaker::UnoType::SORT_DOUBLE: + o << "0"; + return; + case codemaker::UnoType::SORT_VOID: + case codemaker::UnoType::SORT_STRING: + case codemaker::UnoType::SORT_TYPE: + case codemaker::UnoType::SORT_ANY: + case codemaker::UnoType::SORT_COMPLEX: + break; + } + } + + if (defaultvalue && referenceType == 16) { + if (typeClass == RT_TYPE_ENUM) { + typereg::Reader reader(manager.getTypeReader(name)); + o << name.copy(name.lastIndexOf('/')) + << "_" + << codemaker::convertString(reader.getFieldName(0)); + } + return; + } + bool bReference = false; + if (((sort > codemaker::UnoType::SORT_CHAR || + rank > 0) && referenceType != 8 && + !(typeClass == RT_TYPE_ENUM && referenceType == 4 && rank == 0)) || + (sort <= codemaker::UnoType::SORT_CHAR && referenceType == 2)) + { + bReference = true; + } + + if (bReference && referenceType == 4) + o << "const "; + + for (sal_Int32 i = 0; i < rank; ++i) { + o << ((options.shortnames) ? "css::uno::Sequence< " : + "::com::sun::star::uno::Sequence< "); + } + if (typeClass == RT_TYPE_INTERFACE && referenceType > 0) { + o << ((options.shortnames) ? "css::uno::Reference< " : + "::com::sun::star::uno::Reference< "); + } + + o << scopedCppName(codemaker::cpp::translateUnoToCppType( + sort, typeClass, name, false), + false, options.shortnames && referenceType > 0); + + if (typeClass == RT_TYPE_INTERFACE && referenceType > 0) + o << " >"; + + if (!arguments.empty()) { + o << "< "; + for (std::vector< OString >::const_iterator i(arguments.begin()); + i != arguments.end(); ++i) + { + if (i != arguments.begin()) + o << ", "; + + printType(o, options, manager, *i, 1, false); + } + o << " >"; + } + + for (sal_Int32 i = 0; i < rank; ++i) + o << " >"; + + if (bReference && referenceType > 1) + o << " &"; + + if (referenceType == 8 && (sort > codemaker::UnoType::SORT_CHAR || rank > 0)) + o << "()"; +} + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + OString const & type, short referenceType, bool defaultvalue) +{ + RTTypeClass typeClass; + OString name; + sal_Int32 rank; + std::vector< OString > arguments; + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, type, true, true, true, &typeClass, &name, &rank, &arguments); + printType(o, + options, manager, sort, typeClass, name, rank, arguments, + referenceType, defaultvalue); +} + +bool printConstructorParameters(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, typereg::Reader const & outerReader, + std::vector< OString > const & arguments) +{ + bool previous = false; + if (reader.getSuperTypeCount() != 0) { + OString super( + codemaker::convertString(reader.getSuperTypeName(0))); + typereg::Reader superReader(manager.getTypeReader(super)); + if (!superReader.isValid()) + throw CannotDumpException("Bad type library entity " + super); + + previous = printConstructorParameters(o, + options, manager, superReader, outerReader, arguments); + } + for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) { + if (previous) + o << ", "; + else + previous = true; + + if ((reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) == 0) { + printType(o, options, manager, + codemaker::convertString(reader.getFieldTypeName(i)), 4); + } else if (arguments.empty()) { + // ToDo ! + // o << "com::sun::star::uno::Any"; + } else { + sal_uInt16 tparam = 0; + while (outerReader.getReferenceTypeName(tparam) + != reader.getFieldTypeName(i)) + { + ++tparam; + OSL_ASSERT(tparam < outerReader.getReferenceCount()); + } + // assume std::vector< OString >::size_type is at least as + // large as sal_uInt16: + printType(o, options, manager, arguments[tparam], 4); + } + o << ' ' + << (codemaker::cpp::translateUnoToCppIdentifier( + codemaker::convertString(reader.getFieldName(i)), + "param"). + getStr()); + } + return previous; +} + +void printConstructor(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, + std::vector< OString > const & arguments) +{ + OString type(codemaker::convertString(reader.getTypeName())); + o << "public "; + o << type.copy(type.lastIndexOf('/') + 1) << '('; + printConstructorParameters(o, options, manager, reader, reader, + arguments); + o << ");\n"; +} + +void printMethodParameters(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, sal_uInt16 method, bool previous, + bool withtype) +{ + short referenceType = 4; + for (sal_uInt16 i = 0; i < reader.getMethodParameterCount(method); ++i) { + if (previous) + o << ", "; + + previous = true; + + if (reader.getMethodParameterFlags(method, i) == RT_PARAM_OUT + || reader.getMethodParameterFlags(method, i) == RT_PARAM_INOUT) + { + referenceType = 2; + } else { + referenceType = 4; + } + + if (withtype) { + printType(o, options, manager, + codemaker::convertString( + reader.getMethodParameterTypeName(method, i)), + referenceType); + o << ' '; + } + + o << (codemaker::cpp::translateUnoToCppIdentifier( + codemaker::convertString( + reader.getMethodParameterName(method, i)), + "param"). + getStr()); + } +} + +void printExceptionSpecification(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, sal_uInt16 method) +{ + o << ((options.shortnames) ? " throw (css::uno::RuntimeException" : + " throw (::com::sun::star::uno::RuntimeException"); + if (reader.getMethodExceptionCount(method) > 0) { + for (sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method); ++i) { + o << ", "; + printType(o, options, manager, + codemaker::convertString( + reader.getMethodExceptionTypeName(method, i)), 1); + } + } + o << ")"; +} + +void printSetPropertyMixinBody(std::ostream & o, + typereg::Reader const & reader, + sal_uInt16 field, + sal_uInt16 method) +{ + RTFieldAccess propFlags = checkAdditionalPropertyFlags(reader, field, method); + OString fieldname = codemaker::convertString(reader.getFieldName(field)); + bool bound = (reader.getFieldFlags(field) & RT_ACCESS_BOUND ? true : false); + + o << "\n{\n"; + + if (bound) + o << " BoundListeners l;\n"; + + if (propFlags & RT_ACCESS_CONSTRAINED) { + OString fieldtype = codemaker::convertString( + reader.getFieldTypeName(field)); + + sal_Int32 index = fieldtype.lastIndexOf('<'); + sal_Int32 nPos=0; + bool single = true; + bool optional = false; + OStringBuffer buffer1(64); + OStringBuffer buffer2(64); + do + { + OString s(fieldtype.getToken(0, '<', nPos)); + OString t = s.copy(s.lastIndexOf('/')+1); + + if (t.equals("Optional")) { + optional=true; + if (single) { + single=false; + buffer1.append("the_value.IsPresent"); + buffer2.append("the_value.Value"); + } else { + buffer1.insert(0, t); + buffer1.append(".IsPresent"); + buffer2.insert(0, t); + buffer2.append(".Value"); + } + } else { + if (single) { + single=false; + if (!optional) + buffer1.append("the_value.Value"); + + buffer2.append("the_value.Value"); + } else { + if (!optional) { + buffer1.insert(0, t); + buffer1.append(".Value"); + } + buffer2.insert(0, t); + buffer2.append(".Value"); + } + } + } while( nPos <= index ); + + o << " css::uno::Any v;\n"; + if (optional) { + o << " if(" << buffer1.makeStringAndClear() << ")\n {\n" + << " v <<= " << buffer2.makeStringAndClear() << ";\n }\n"; + } else { + o << " v <<= " << buffer2.makeStringAndClear() << ";\n\n"; + } + + o << " prepareSet(\n rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"" + << fieldname << "\")),\n css::uno::Any(), v, "; + } else { + o << " prepareSet(\n rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"" + << fieldname << "\")),\n css::uno::Any(), css::uno::Any(), "; + } + + if (bound) + o << "&l);\n"; + else + o << "0);\n"; + + o << " {\n osl::MutexGuard g(m_aMutex);\n m_" + << fieldname << " = the_value;\n }\n"; + + if (bound) + o << " l.notify();\n"; + + o << "}\n\n"; +} + +void generateXPropertySetBodies(std::ostream& o, + const OString & classname, + const OString & interfaceName); +void generateXFastPropertySetBodies(std::ostream& o, + const OString & classname, + const OString & interfaceName); +void generateXPropertyAccessBodies(std::ostream& o, + const OString & classname, + const OString & interfaceName); + +void generateXAddInBodies(std::ostream& o, const OString & classname); + +void generateXLocalizable(std::ostream& o, const OString & classname); + +void generateXCompatibilityNamesBodies(std::ostream& o, const OString & classname); + +void generateXInitialization(std::ostream& o, const OString & classname); + +void generateXDispatch(std::ostream& o, + const OString & classname, + const ProtocolCmdMap & protocolCmdMap); + +void generateXDispatchProvider(std::ostream& o, + const OString & classname, + const ProtocolCmdMap & protocolCmdMap); + + +void printMethods(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, codemaker::GeneratedTypeSet & generated, + OString const & delegate, OString const & classname, + OString const & indentation, bool defaultvalue, + OString const & propertyhelper) +{ + OString type(codemaker::convertString(reader.getTypeName())); + if (generated.contains(type) || type.equals("com/sun/star/uno/XInterface") || + (defaultvalue && + ( type.equals("com/sun/star/lang/XComponent") || + type.equals("com/sun/star/lang/XTypeProvider") || + type.equals("com/sun/star/uno/XWeak")) ) ) + { + return; + } + + static OString sd(RTL_CONSTASCII_STRINGPARAM("_")); + bool body = ((delegate.getLength() > 0) ? true : false); + bool defaultbody = ((delegate.equals(sd)) ? true : false); + + if (body && propertyhelper.getLength() > 1) { + if ( type.equals("com/sun/star/beans/XPropertySet")) { + generated.add(type); + generateXPropertySetBodies( + o, classname, scopedCppName(propertyhelper, false, true)); + return; + } else if ( type.equals("com/sun/star/beans/XFastPropertySet")) { + generated.add(type); + generateXFastPropertySetBodies( + o, classname, scopedCppName(propertyhelper, false, true)); + return; + } else if ( type.equals("com/sun/star/beans/XPropertyAccess")) { + generated.add(type); + generateXPropertyAccessBodies( + o, classname, scopedCppName(propertyhelper, false, true)); + return; + } + } + + if (body && options.componenttype == 2) { + if (type.equals("com/sun/star/lang/XServiceName")) { + o << "// ::com::sun::star::lang::XServiceName:\n" + "::rtl::OUString SAL_CALL " << classname << "getServiceName() " + "throw (css::uno::RuntimeException)\n{\n " + "return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" + "sADDIN_SERVICENAME));\n}\n"; + generated.add(type); + return; + } else if (type.equals("com/sun/star/sheet/XAddIn")) { + generateXAddInBodies(o, classname); + generated.add(type); + + // special handling of XLocalizable -> parent of XAddIn + if (!generated.contains("com/sun/star/lang/XLocalizable")) { + generateXLocalizable(o, classname); + generated.add("com/sun/star/lang/XLocalizable"); + } + return; + } else if (type.equals("com/sun/star/lang/XLocalizable")) { + generateXLocalizable(o, classname); + generated.add(type); + return; + } else if (type.equals("com/sun/star/sheet/XCompatibilityNames")) { + generateXCompatibilityNamesBodies(o, classname); + generated.add(type); + return; + } + } + + if (body && options.componenttype == 3) { + if (type.equals("com/sun/star/lang/XInitialization")) { + generateXInitialization(o, classname); + generated.add(type); + return; + } else if (type.equals("com/sun/star/frame/XDispatch")) { + generateXDispatch(o, classname, options.protocolCmdMap); + generated.add(type); + return; + } else if (type.equals("com/sun/star/frame/XDispatchProvider")) { + generateXDispatchProvider(o, classname, options.protocolCmdMap); + generated.add(type); + return; + } + } + + generated.add(type); + if (options.all || defaultvalue) { + for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) { + typereg::Reader super( + manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(i)))); + if (!super.isValid()) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString( + reader.getSuperTypeName(i))); + } + + OString stype(codemaker::convertString(super.getTypeName())); + printMethods(o, options, manager, super, generated, delegate, + classname, indentation, defaultvalue, propertyhelper); + } + + if (reader.getFieldCount() > 0 || reader.getMethodCount() > 0) { + o << indentation << "// "; + printType(o, options, manager, type, 0); + o << ":\n"; + } + } + sal_uInt16 method = 0; + for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) { + o << indentation; + if (!body) + o << "virtual "; + + printType(o, options, manager, + codemaker::convertString(reader.getFieldTypeName(i)), 1); + o << " SAL_CALL "; + if (classname.getLength() > 0) + o << classname; + + o << "get" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << "()"; + if (method < reader.getMethodCount() + && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET + && reader.getMethodName(method) == reader.getFieldName(i)) + { + printExceptionSpecification(o, options, manager, reader, method++); + } else { + o << ((options.shortnames) ? " throw (css::uno::RuntimeException)" : + " throw (::com::sun::star::uno::RuntimeException)"); + } + if (body) { + if (defaultbody) { + if (propertyhelper.getLength() > 0) { + o << "\n{\n osl::MutexGuard g(m_aMutex);\n return m_" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << ";\n}\n\n"; + } else { + o << "\n{\n return "; + if (options.componenttype == 1) { + o << "m_" + << codemaker::convertString( + reader.getFieldName(i)).getStr(); + } else { + printType(o, options, manager, + codemaker::convertString( + reader.getFieldTypeName(i)), + 8, true); + } + o << ";\n}\n\n"; + } + } else { + o << "\n" << indentation << "{\n" << indentation << " return " + << delegate.getStr() << "get" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << "();\n" << indentation << "}\n\n"; + } + } else { + o << ";\n"; + } + + if ((reader.getFieldFlags(i) & RT_ACCESS_READONLY) == 0) { + o << indentation; + if (!body) + o << "virtual "; + + o << "void SAL_CALL "; + if (classname.getLength() > 0) + o << classname; + + o << "set" + << (codemaker::convertString(reader.getFieldName(i)).getStr()) + << '('; + printType(o, options, manager, + codemaker::convertString(reader.getFieldTypeName(i)), 4); + o << " the_value)"; + if (method < reader.getMethodCount() + && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET + && reader.getMethodName(method) == reader.getFieldName(i)) + { + printExceptionSpecification(o, options, manager, reader, method++); + } else { + o << ((options.shortnames) ? " throw (css::uno::RuntimeException)" : + " throw (::com::sun::star::uno::RuntimeException)"); + } + if (body) { + if (defaultbody) { + if (propertyhelper.getLength() > 0) { + printSetPropertyMixinBody(o, reader, i, method); + } else { + if (options.componenttype == 1) { + o << "\n{\n m_" + << codemaker::convertString( + reader.getFieldName(i)).getStr() + << " = the_value;\n}\n\n"; + } else { + o << "\n{\n\n}\n\n"; + } + } + } else { + o << "\n" << indentation << "{\n" << indentation << " " + << delegate.getStr() << "set" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << "(the_value);\n" << indentation << "}\n\n"; + } + } else { + o << ";\n"; + } + } + } + for (; method < reader.getMethodCount(); ++method) { + o << indentation; + if (!body) + o << "virtual "; + + printType(o, options, manager, + codemaker::convertString( + reader.getMethodReturnTypeName(method)), 1); + o << " SAL_CALL "; + if (classname.getLength() > 0) + o << classname; + + const OString methodName(codemaker::convertString(reader.getMethodName(method))); + + o << methodName << '('; + printMethodParameters(o, options, manager, reader, method, false, true); + o << ')'; + printExceptionSpecification(o, options, manager, reader, method); + if (body) { + static OUString s(RTL_CONSTASCII_USTRINGPARAM("void")); + if (defaultbody) { + o << "\n{\n"; + if (!reader.getMethodReturnTypeName(method).equals(s)) { + o << " // TODO: Exchange the default return implementation for \"" + << methodName << "\" !!!\n"; + o << " // Exchange the default return implementation.\n" + " // NOTE: Default initialized polymorphic structs " + "can cause problems because of\n // missing default " + "initialization of primitive types of some C++ compilers or" + "\n // different Any initialization in Java and C++ " + "polymorphic structs.\n return "; + printType(o, options, manager, + codemaker::convertString( + reader.getMethodReturnTypeName(method)), 8, true); + o << ";"; + } else { + o << " // TODO: Insert your implementation for \"" + << methodName << "\" here."; + } + o << "\n}\n\n"; + } else { + o << "\n" << indentation << "{\n" << indentation << " "; + if (!reader.getMethodReturnTypeName(method).equals(s)) + o << "return "; + + o << delegate.getStr() + << (codemaker::convertString( + reader.getMethodName(method)).getStr()) + << '('; + printMethodParameters(o, options, manager, reader, method, + false, false); + o << ");\n" << indentation << "}\n\n"; + } + } else { + o << ";\n"; + } + } + + if (method > 0 && !body) + o << "\n"; +} + +void printConstructionMethods(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader) +{ + for (sal_uInt16 i = 0; i < reader.getMethodCount(); ++i) { + o << "static "; + printType(o, + options, manager, + codemaker::convertString(reader.getSuperTypeName(0)), 1); + o << ' '; + if (reader.getMethodName(i).getLength() == 0) { + o << "create"; + } else { + o << (codemaker::cpp::translateUnoToCppIdentifier( + codemaker::convertString(reader.getMethodName(i)), + "method"). + getStr()); + } + o << ((options.shortnames) ? "(css::uno::Reference< css" : + "(::com::sun::star::uno::Reference< ::com::sun::star") + << "::uno::XComponentContext > const & the_context"; + printMethodParameters(o, options, manager, reader, i, + true, true); + o << ')'; + printExceptionSpecification(o, options, manager, reader, i); + o << ";\n"; + } +} + +void printServiceMembers(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, OString const & type, + OString const & delegate) +{ + for (sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i) { + OString referenceType( + codemaker::convertString( + reader.getReferenceTypeName(i)).replace('/', '.')); + + if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) { + o << "\n// supported interface " << referenceType.getStr() << "\n"; + generateDocumentation(o, options, manager, referenceType, delegate); + } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) { + o << "\n// exported service " << referenceType.getStr() << "\n"; + generateDocumentation(o, options, manager, referenceType, delegate); + o << "\n// end of exported service " << referenceType.getStr() << "\n"; + } + } + + if (delegate.getLength() == 0) { + o << "\n// properties of service \""<< type.getStr() << "\"\n"; + for (sal_uInt16 i = 0; i < reader.getFieldCount(); ++i) { + OString fieldName( + codemaker::convertString(reader.getFieldName(i))); + OString fieldType( + codemaker::convertString(reader.getFieldTypeName(i))); + + o << "// private "; + printType(o, options, manager, fieldType, 1); + o << " " + << codemaker::cpp::translateUnoToCppIdentifier( + fieldName, "property").getStr() + << ";\n"; + } + } +} + +void printMapsToCppType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + OString const & name, sal_Int32 rank, + std::vector< OString > const & arguments, const char * cppTypeSort) +{ + o << "maps to C++ "; + if (cppTypeSort != 0) + o << cppTypeSort << ' '; + + o << "type \""; + if (rank == 0 && name == "com/sun/star/uno/XInterface") { + o << "Reference< com::sun::star::uno::XInterface >"; + } else { + printType(o, options, manager, sort, typeClass, name, rank, arguments, 0); + } + o << '"'; +} + +void generateDocumentation(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + OString const & type, OString const & delegate) +{ + if (type.indexOf('/') >= 0) + throw CannotDumpException("Illegal type name " + type); + + OString binType(type.replace('.', '/')); + RTTypeClass typeClass; + OString name; + sal_Int32 rank; + std::vector< OString > arguments; + codemaker::UnoType::Sort sort = decomposeResolveAndCheck( + manager, binType, false, true, true, &typeClass, &name, &rank, + &arguments); + + bool comment=true; + if (delegate.getLength() > 0) { + if (typeClass != RT_TYPE_INTERFACE && + typeClass != RT_TYPE_SERVICE ) + { + return; + } + comment=false; + } + + if (comment) { + o << "\n// UNO"; + if (rank > 0) { + o << " sequence type"; + } else if (sort != codemaker::UnoType::SORT_COMPLEX) { + o << " simple type"; + } else { + typereg::Reader reader(manager.getTypeReader(name)); + if (!reader.isValid()) + throw CannotDumpException("Bad type library entity " + name); + + switch (typeClass) + { + case RT_TYPE_INTERFACE: + o << " interface type"; + break; + + case RT_TYPE_MODULE: + o << "IDL module"; + break; + + case RT_TYPE_STRUCT: + if (reader.getReferenceCount() == 0) + o << " simple struct type"; + else if (arguments.empty()) + o << " polymorphic struct type template"; + else + o << " instantiated polymorphic struct type"; + break; + + case RT_TYPE_ENUM: + o << " enum type"; + break; + + case RT_TYPE_EXCEPTION: + o << " exception type"; + break; + + case RT_TYPE_TYPEDEF: + o << "IDL typedef"; + break; + + case RT_TYPE_SERVICE: + if (reader.getSuperTypeCount() > 0) + o << " single-inheritance--based service"; + else + o << "IDL accumulation-based service"; + break; + + case RT_TYPE_SINGLETON: + if ((manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(0))).getTypeClass()) + == RT_TYPE_INTERFACE) + o << " inheritance-based singleton"; + else + o << "IDL service-based singleton"; + break; + + case RT_TYPE_CONSTANTS: + o << "IDL constant group"; + break; + + default: + OSL_ASSERT(false); + break; + } + } + o << " \"" << type.getStr() << "\" "; + } + sort = codemaker::decomposeAndResolve( + manager, binType, true, true, true, &typeClass, &name, &rank, + &arguments); + if (rank > 0) { + if (comment) { + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, "array"); + o << '\n'; + } + } else if (sort != codemaker::UnoType::SORT_COMPLEX) { + if (comment) { + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, 0); + o << '\n'; + } + } else { + typereg::Reader reader(manager.getTypeReader(name)); + if (!reader.isValid()) + throw CannotDumpException("Bad type library entity " + name); + + switch (typeClass) + { + case RT_TYPE_INTERFACE: + if (comment) + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + "interface"); + if (name == "com/sun/star/uno/XInterface") { + if (comment) + o << '\n'; + } else { + if (comment) + o << "; " << (options.all ? "all" : "direct") << " methods:\n"; + + codemaker::GeneratedTypeSet generated; + printMethods(o, options, manager, reader, generated, + delegate, options.implname, ""); + } + break; + + case RT_TYPE_MODULE: + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + "namespace"); + o << '\n'; + break; + + case RT_TYPE_STRUCT: + if (reader.getReferenceCount() == 0) { + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + "class"); + } else if (arguments.empty()) { + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + options.java5 ? "generic class" : "class"); + } else { + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + options.java5 ? "generic class instantiation" : "class"); + } + o << "; full constructor:\n"; + printConstructor(o, options, manager, reader, arguments); + break; + + case RT_TYPE_ENUM: + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + "enum"); + o << '\n'; + break; + + case RT_TYPE_CONSTANTS: + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + "namespace"); + o << '\n'; + break; + + case RT_TYPE_EXCEPTION: + printMapsToCppType(o, + options, manager, sort, typeClass, name, rank, arguments, + "exception class"); + o << "; full constructor:\n"; + printConstructor(o, options, manager, reader, arguments); + break; + + case RT_TYPE_SERVICE: + if (reader.getSuperTypeCount() > 0) { + if (comment) { + printMapsToCppType(o, options, manager, sort, typeClass, + name, rank, arguments, "class"); + o << "; construction methods:\n"; + printConstructionMethods(o, options, manager, reader); + } + + OString super( + codemaker::convertString( + reader.getSuperTypeName(0)).replace('/', '.')); + generateDocumentation(o, options, manager, super, delegate); + } else { + if (comment) + o << ("does not map to C++\n" + "// the service members are generated instead\n"); + printServiceMembers(o, options, manager, reader, type, delegate); + } + break; + + case RT_TYPE_SINGLETON: + if (reader.getSuperTypeCount() > 0 && + ((manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(0))). + getTypeClass()) == RT_TYPE_INTERFACE) ) + { + printMapsToCppType(o, options, manager, sort, typeClass, + name, rank, arguments, + "class"); + o << "; get method:\nstatic "; + printType(o, options, manager, + codemaker::convertString(reader.getSuperTypeName(0)), 1); + o << " get(::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > const & context);\n"; + } else { + o << "does not map to C++\n"; + } + break; + + default: + OSL_ASSERT(false); + break; + } + } +} + +} } + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/javacompskeleton.cxx b/unodevtools/source/skeletonmaker/javacompskeleton.cxx new file mode 100644 index 000000000000..33b99676f8e1 --- /dev/null +++ b/unodevtools/source/skeletonmaker/javacompskeleton.cxx @@ -0,0 +1,999 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "codemaker/commonjava.hxx" + +#include "skeletoncommon.hxx" +#include "skeletonjava.hxx" + +#include <iostream> + +using namespace ::rtl; +using namespace ::codemaker::java; + +namespace skeletonmaker { namespace java { + +void generatePackage(std::ostream & o, const OString & implname) +{ + sal_Int32 index = implname.lastIndexOf('.'); + if (index != -1) + o << "package " << implname.copy(0, index) << ";\n\n"; +} + +void generateImports(std::ostream & o, ProgramOptions const & options, + const boost::unordered_set< OString, OStringHash >& /*interfaces*/, + const OString & propertyhelper, + bool serviceobject, bool supportxcomponent) +{ + if (options.componenttype == 3) + o << "import com.sun.star.uno.UnoRuntime;\n"; + o << "import com.sun.star.uno.XComponentContext;\n"; + if (serviceobject) { + o << "import com.sun.star.lib.uno.helper.Factory;\n"; + o << "import com.sun.star.lang.XSingleComponentFactory;\n"; + o << "import com.sun.star.registry.XRegistryKey;\n"; + } + + if (!propertyhelper.equals("_")) { + if (supportxcomponent) + o << "import com.sun.star.lib.uno.helper.ComponentBase;\n"; + else + o << "import com.sun.star.lib.uno.helper.WeakBase;\n"; + } + if (propertyhelper.getLength() > 0) { + if (propertyhelper.equals("_")) { + o << "import com.sun.star.lib.uno.helper.PropertySet;\n"; + o << "import com.sun.star.beans.PropertyAttribute;\n"; + } else { + o << "import com.sun.star.uno.Type;\n"; + o << "import com.sun.star.uno.Any;\n"; + o << "import com.sun.star.beans.Ambiguous;\n"; + o << "import com.sun.star.beans.Defaulted;\n"; + o << "import com.sun.star.beans.Optional;\n"; + o << "import com.sun.star.lib.uno.helper.PropertySetMixin;\n"; + } + } + + +// boost::unordered_set< OString, OStringHash >::const_iterator iter = +// interfaces.begin(); +// while (iter != interfaces.end()) +// { +// o << "import " << ((*iter).getStr()) << ";\n"; +// iter++; +// } +} + +void generateCompFunctions(std::ostream & o, const OString & classname) +{ + o << " public static XSingleComponentFactory __getComponentFactory(" + " String sImplementationName ) {\n" + " XSingleComponentFactory xFactory = null;\n\n" + " if ( sImplementationName.equals( m_implementationName ) )\n" + " xFactory = Factory.createComponentFactory(" + << classname << ".class, m_serviceNames);\n" + " return xFactory;\n }\n\n"; + + o << " public static boolean __writeRegistryServiceInfo(" + " XRegistryKey xRegistryKey ) {\n" + " return Factory.writeRegistryServiceInfo(m_implementationName,\n" + " m_serviceNames,\n" + " xRegistryKey);\n" + " }\n\n"; +} + +void generateXServiceInfoBodies(std::ostream& o) +{ + o << " // com.sun.star.lang.XServiceInfo:\n"; + o << " public String getImplementationName() {\n" + << " return m_implementationName;\n }\n\n"; + + o << " public boolean supportsService( String sService ) {\n" + << " int len = m_serviceNames.length;\n\n" + << " for( int i=0; i < len; i++) {\n" + << " if (sService.equals(m_serviceNames[i]))\n" + << " return true;\n" + << " }\n return false;\n }\n\n"; + + o << " public String[] getSupportedServiceNames() {\n" + << " return m_serviceNames;\n }\n\n"; +} + +void generateXPropertySetBodies(std::ostream& o) +{ + o << " // com.sun.star.beans.XPropertySet:\n"; + o << " public com.sun.star.beans.XPropertySetInfo getPropertySetInfo()\n" + " {\n return m_prophlp.getPropertySetInfo();\n }\n\n"; + + o << " public void setPropertyValue(String aPropertyName, " + "Object aValue) throws " + "com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.beans.PropertyVetoException, " + "com.sun.star.lang.IllegalArgumentException," + "com.sun.star.lang.WrappedTargetException\n {\n " + "m_prophlp.setPropertyValue(aPropertyName, aValue);\n }\n\n"; + + o << " public Object getPropertyValue(String " + "aPropertyName) throws com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.lang.WrappedTargetException\n {\n return " + "m_prophlp.getPropertyValue(aPropertyName);\n }\n\n"; + + o << " public void addPropertyChangeListener(String aPropertyName" + ", com.sun.star.beans.XPropertyChangeListener xListener) throws " + "com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.lang.WrappedTargetException\n {\n " + "m_prophlp.addPropertyChangeListener(aPropertyName, xListener);\n }\n\n"; + + o << " public void removePropertyChangeListener(String " + "aPropertyName, com.sun.star.beans.XPropertyChangeListener xListener) " + "throws com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.lang.WrappedTargetException\n {\n " + "m_prophlp.removePropertyChangeListener(aPropertyName, xListener);\n" + " }\n\n"; + + o << " public void addVetoableChangeListener(String aPropertyName" + ", com.sun.star.beans.XVetoableChangeListener xListener) throws " + "com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.lang.WrappedTargetException\n {\n " + "m_prophlp.addVetoableChangeListener(aPropertyName, xListener);\n }\n\n"; + + o << " public void removeVetoableChangeListener(String " + "aPropertyName, com.sun.star.beans.XVetoableChangeListener xListener) " + "throws com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.lang.WrappedTargetException\n {\n " + "m_prophlp.removeVetoableChangeListener(aPropertyName, xListener);\n }\n\n"; +} + +void generateXFastPropertySetBodies(std::ostream& o) +{ + o << " // com.sun.star.beans.XFastPropertySet:\n"; + + o << " public void setFastPropertyValue(int nHandle, Object " + "aValue) throws com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.beans.PropertyVetoException, " + "com.sun.star.lang.IllegalArgumentException, " + "com.sun.star.lang.WrappedTargetException\n {\n " + "m_prophlp.setFastPropertyValue(nHandle, aValue);\n }\n\n"; + + o << " public Object getFastPropertyValue(int nHandle) throws " + "com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.lang.WrappedTargetException\n {\n return " + "m_prophlp.getFastPropertyValue(nHandle);\n }\n\n"; +} + +void generateXPropertyAccessBodies(std::ostream& o) +{ + o << " // com.sun.star.beans.XPropertyAccess:\n"; + + o << " public com.sun.star.beans.PropertyValue[] getPropertyValues()\n" + " {\n return m_prophlp.getPropertyValues();\n }\n\n"; + + o << " public void setPropertyValues(com.sun.star.beans.PropertyValue[] " + "aProps) throws com.sun.star.beans.UnknownPropertyException, " + "com.sun.star.beans.PropertyVetoException, " + "com.sun.star.lang.IllegalArgumentException, " + "com.sun.star.lang.WrappedTargetException\n {\n " + "m_prophlp.setPropertyValues(aProps);\n }\n\n"; +} + + +bool checkAttribute(OStringBuffer& attributeValue, sal_uInt16 attribute) +{ + bool cast = false; + sal_uInt16 attributes[9] = { + /* com::sun::star::beans::PropertyValue::MAYBEVOID */ 1, + /* com::sun::star::beans::PropertyValue::BOUND */ 2, + /* com::sun::star::beans::PropertyValue::CONSTRAINED */ 4, + /* com::sun::star::beans::PropertyValue::TRANSIENT */ 8, + /* com::sun::star::beans::PropertyValue::READONLY */ 16, + /* com::sun::star::beans::PropertyValue::MAYBEAMBIGIOUS */ 32, + /* com::sun::star::beans::PropertyValue::MAYBEDEFAULT */ 64, + /* com::sun::star::beans::PropertyValue::REMOVEABLE */ 128, + /* com::sun::star::beans::PropertyValue::OPTIONAL */ 256 }; + + for (sal_uInt16 i = 0; i < 9; i++) + { + if (attribute & attributes[i]) { + if (attributeValue.getLength() > 0) { + cast |= true; + attributeValue.append("|"); + } + switch (attributes[i]) + { + case 1: + attributeValue.append("PropertyAttribute.MAYBEVOID"); + break; + case 2: + attributeValue.append("PropertyAttribute.BOUND"); + break; + case 4: + attributeValue.append("PropertyAttribute.CONSTRAINED"); + break; + case 8: + attributeValue.append("PropertyAttribute.TRANSIENT"); + break; + case 16: + attributeValue.append("PropertyAttribute.READONLY"); + break; + case 32: + attributeValue.append("PropertyAttribute.MAYBEAMBIGIOUS"); + break; + case 64: + attributeValue.append("PropertyAttribute.MAYBEDEFAULT"); + break; + case 128: + attributeValue.append("PropertyAttribute.REMOVEABLE"); + break; + case 256: + attributeValue.append("PropertyAttribute.OPTIONAL"); + break; + } + } + } + if (cast) { + attributeValue.insert(0, '('); + attributeValue.append(')'); + } + + return cast; +} + +void registerProperties(std::ostream& o, + TypeManager const & /*manager*/, + const AttributeInfo& properties, + const OString& indentation) +{ + if (!properties.empty()) { + bool cast = false; + OStringBuffer attributeValue; + for (AttributeInfo::const_iterator i(properties.begin()); + i != properties.end(); ++i) + { + if (i->second.second > 0) { + cast = checkAttribute(attributeValue, i->second.second); + } else { + cast = true; + attributeValue.append('0'); + } + + o << indentation << "registerProperty(\"" << i->first + << "\", \"m_" << i->first << "\",\n" + << indentation << " "; + if (cast) + o << "(short)"; + + o << attributeValue.makeStringAndClear() << ");\n"; + } + } +} + +void generateXLocalizableBodies(std::ostream& o) { + // com.sun.star.lang.XLocalizable: + // setLocale + o << " // com.sun.star.lang.XLocalizable:\n" + " public void setLocale(com.sun.star.lang.Locale eLocale)\n {\n" + " m_locale = eLocale;\n }\n\n"; + + // getLocale + o << " public com.sun.star.lang.Locale getLocale()\n {\n" + " return m_locale;\n }\n\n"; +} + +void generateXAddInBodies(std::ostream& o, ProgramOptions const & options) +{ + // com.sun.star.sheet.XAddIn: + // getProgrammaticFuntionName + o << " // com.sun.star.sheet.XAddIn:\n" + " public String getProgrammaticFuntionName(String " + "aDisplayName)\n {\n" + " try {\n" + " com.sun.star.container.XNameAccess xNAccess =\n" + " (com.sun.star.container.XNameAccess)UnoRuntime." + "queryInterface(\n" + " com.sun.star.container.XNameAccess.class, m_xHAccess);" + "\n String functions[] = xNAccess.getElementNames();\n" + " String sDisplayName = \"\";\n" + " int len = functions.length;\n" + " for (int i=0; i < len; ++i) {\n" + " sDisplayName = com.sun.star.uno.AnyConverter.toString(\n" + " getAddinProperty(functions[i], \"\", sDISPLAYNAME));\n" + " if (sDisplayName.equals(aDisplayName))\n" + " return functions[i];\n }\n" + " }\n catch ( com.sun.star.uno.RuntimeException e ) {\n" + " throw e;\n }\n" + " catch ( com.sun.star.uno.Exception e ) {\n }\n\n" + " return \"\";\n }\n\n"; + + // getDisplayFunctionName + o << " public String getDisplayFunctionName(String " + "aProgrammaticName)\n {\n" + " return getAddinProperty(aProgrammaticName, \"\", sDISPLAYNAME);\n" + " }\n\n"; + + // getFunctionDescription + o << " public String getFunctionDescription(String " + "aProgrammaticName)\n {\n" + " return getAddinProperty(aProgrammaticName, \"\", sDESCRIPTION);\n" + " }\n\n"; + + // getDisplayArgumentName + o << " public String getDisplayArgumentName(String " + "aProgrammaticFunctionName, int nArgument)\n {\n"; + if (options.java5) { + o << " return getAddinProperty(aProgrammaticFunctionName,\n" + " m_functionMap.get(\n" + " aProgrammaticFunctionName).get(" + "nArgument),\n" + " sDISPLAYNAME);\n }\n\n"; + } else { + o << " return getAddinProperty(aProgrammaticFunctionName, (String)\n" + " ((java.util.Hashtable)m_functionMap." + "get(\n aProgrammaticFunctionName))." + "get(\n new Integer(nArgument))" + ", sDISPLAYNAME);\n }\n\n"; + } + + // getArgumentDescription + o << " public String getArgumentDescription(String " + "aProgrammaticFunctionName, int nArgument)\n {\n"; + if (options.java5) { + o << " return getAddinProperty(aProgrammaticFunctionName,\n" + " m_functionMap.get(\n" + " aProgrammaticFunctionName).get(" + "nArgument),\n" + " sDESCRIPTION);\n }\n\n"; + } else { + o << " return getAddinProperty(aProgrammaticFunctionName, (String)\n" + " ((java.util.Hashtable)m_functionMap." + "get(\n aProgrammaticFunctionName))." + "get(\n new Integer(nArgument))" + ", sDESCRIPTION);\n }\n\n"; + } + // getProgrammaticCategoryName + o << " public String getProgrammaticCategoryName(String " + "aProgrammaticFunctionName)\n {\n" + " return getAddinProperty(aProgrammaticFunctionName, \"\", " + "sCATEGORY);\n }\n\n"; + + // getDisplayCategoryName + o << " public String getDisplayCategoryName(String " + "aProgrammaticFunctionName)\n {\n" + " return getAddinProperty(aProgrammaticFunctionName, \"\", " + "sCATEGORYDISPLAYNAME);\n }\n\n"; +} + +void generateXCompatibilityNamesBodies(std::ostream& o) +{ + o << " // com.sun.star.sheet.XCompatibilityNames:\n" + " public com.sun.star.sheet.LocalizedName[] getCompatibilityNames(" + "String aProgrammaticName)\n {\n" + " com.sun.star.sheet.LocalizedName[] seqLocalizedNames =\n" + " new com.sun.star.sheet.LocalizedName[0];\n\n try {\n"; + + o << " StringBuffer path = new StringBuffer(aProgrammaticName);\n" + " path.append(\"/CompatibilityName\");\n" + " String hname = path.toString();\n\n"; + + o << " if ( m_xCompAccess.hasByHierarchicalName(hname) ) {\n" + " com.sun.star.container.XNameAccess xNameAccess =\n" + " (com.sun.star.container.XNameAccess)UnoRuntime." + "queryInterface(\n" + " com.sun.star.container.XNameAccess.class,\n" + " m_xCompAccess.getByHierarchicalName(hname));\n\n" + " String elems[] = xNameAccess.getElementNames();\n" + " int len = elems.length;\n" + " seqLocalizedNames = new com.sun.star.sheet.LocalizedName" + "[len];\n String sCompatibilityName = \"\";\n\n"; + + o << " for (int i=0; i < len; ++i) {\n" + " String sLocale = elems[i];\n" + " sCompatibilityName = com.sun.star.uno.AnyConverter." + "toString(\n xNameAccess.getByName(sLocale));\n\n" + " com.sun.star.lang.Locale aLocale = \n" + " new com.sun.star.lang.Locale();\n\n" + " String tokens[] = sLocale.split(\"-\");\n" + " int nToken = tokens.length;\n" + " if (nToken >= 1) aLocale.Language = tokens[0];\n" + " if (nToken >= 2) aLocale.Country = tokens[1];\n" + " if (nToken >= 3) {\n" + " StringBuffer buf = \n" + " new StringBuffer(tokens[2]);\n" + " for (int t=3; t < nToken; ++t)\n" + " buf.append(tokens[t]);\n\n" + " aLocale.Variant = buf.toString();\n" + " }\n\n" + " seqLocalizedNames[i].Locale = aLocale;\n" + " seqLocalizedNames[i].Name = sCompatibilityName;\n" + " }\n }\n }\n" + " catch ( com.sun.star.uno.RuntimeException e ) {\n" + " throw e;\n }\n" + " catch ( com.sun.star.uno.Exception e ) {\n }\n\n" + " return seqLocalizedNames;\n }\n\n"; +} + +void generateXInitializationBodies(std::ostream& o) +{ + o << " // com.sun.star.lang.XInitialization:\n" + " public void initialize( Object[] object )\n" + " throws com.sun.star.uno.Exception\n {\n" + " if ( object.length > 0 )\n {\n" + " m_xFrame = (com.sun.star.frame.XFrame)UnoRuntime.queryInterface(\n" + " com.sun.star.frame.XFrame.class, object[0]);\n }\n }\n\n"; +} + +void generateXDispatchBodies(std::ostream& o, ProgramOptions const & options) +{ + // com.sun.star.frame.XDispatch + // dispatch + o << " // com.sun.star.frame.XDispatch:\n" + " public void dispatch( com.sun.star.util.URL aURL,\n" + " com.sun.star.beans.PropertyValue[] aArguments )\n {\n"; + + ProtocolCmdMap::const_iterator iter = options.protocolCmdMap.begin(); + while (iter != options.protocolCmdMap.end()) { + o << " if ( aURL.Protocol.compareTo(\"" << (*iter).first + << "\") == 0 )\n {\n"; + + for (std::vector< OString >::const_iterator i = (*iter).second.begin(); + i != (*iter).second.end(); ++i) { + o << " if ( aURL.Path.compareTo(\"" << (*i) << "\") == 0 )\n" + " {\n // add your own code here\n" + " return;\n }\n"; + } + + o << " }\n"; + ++iter; + } + o << " }\n\n"; + + // addStatusListener + o << " public void addStatusListener( com.sun.star.frame.XStatusListener xControl,\n" + " com.sun.star.util.URL aURL )\n {\n" + " // add your own code here\n }\n\n"; + + // com.sun.star.frame.XDispatch + o << " public void removeStatusListener( com.sun.star.frame.XStatusListener xControl,\n" + " com.sun.star.util.URL aURL )\n {\n" + " // add your own code here\n }\n\n"; +} + +void generateXDispatchProviderBodies(std::ostream& o, ProgramOptions const & options) +{ + // com.sun.star.frame.XDispatchProvider + // queryDispatch + o << " // com.sun.star.frame.XDispatchProvider:\n" + " public com.sun.star.frame.XDispatch queryDispatch( com.sun.star.util.URL aURL,\n" + " String sTargetFrameName,\n" + " int iSearchFlags )\n {\n"; + + ProtocolCmdMap::const_iterator iter = options.protocolCmdMap.begin(); + while (iter != options.protocolCmdMap.end()) { + o << " if ( aURL.Protocol.compareTo(\"" << (*iter).first + << "\") == 0 )\n {\n"; + + for (std::vector< OString >::const_iterator i = (*iter).second.begin(); + i != (*iter).second.end(); ++i) { + o << " if ( aURL.Path.compareTo(\"" << (*i) << "\") == 0 )\n" + " return this;\n"; + } + + o << " }\n"; + ++iter; + } + o << " return null;\n }\n\n"; + + // queryDispatches + o << " // com.sun.star.frame.XDispatchProvider:\n" + " public com.sun.star.frame.XDispatch[] queryDispatches(\n" + " com.sun.star.frame.DispatchDescriptor[] seqDescriptors )\n {\n" + " int nCount = seqDescriptors.length;\n" + " com.sun.star.frame.XDispatch[] seqDispatcher =\n" + " new com.sun.star.frame.XDispatch[seqDescriptors.length];\n\n" + " for( int i=0; i < nCount; ++i )\n {\n" + " seqDispatcher[i] = queryDispatch(seqDescriptors[i].FeatureURL,\n" + " seqDescriptors[i].FrameName,\n" + " seqDescriptors[i].SearchFlags );\n" + " }\n return seqDispatcher;\n }\n\n"; +} + +void generateMethodBodies(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + const boost::unordered_set< OString, OStringHash >& interfaces, + const OString& indentation, bool usepropertymixin) +{ + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + codemaker::GeneratedTypeSet generated; + while (iter != interfaces.end()) { + OString type(*iter); + ++iter; + if (type.equals("com.sun.star.lang.XServiceInfo")) { + generateXServiceInfoBodies(o); + generated.add(type); + } else { + if (options.componenttype == 2) { + if (type.equals("com.sun.star.lang.XServiceName")) { + o << " // com.sun.star.lang.XServiceName:\n" + " public String getServiceName() {\n" + " return sADDIN_SERVICENAME;\n }\n"; + generated.add(type); + continue; + } else if (type.equals("com.sun.star.sheet.XAddIn")) { + generateXAddInBodies(o, options); + generated.add(type); + + // special handling of XLocalizable -> parent of XAddIn + if (!generated.contains("com.sun.star.lang.XLocalizable")) { + generateXLocalizableBodies(o); + generated.add("com.sun.star.lang.XLocalizable"); + } + continue; + } else if (type.equals("com.sun.star.lang.XLocalizable")) { + generateXLocalizableBodies(o); + generated.add(type); + continue; + } else if (type.equals("com.sun.star.sheet.XCompatibilityNames")) { + generateXCompatibilityNamesBodies(o); + generated.add(type); + continue; + } + } + if (options.componenttype == 3) { + if (type.equals("com.sun.star.lang.XInitialization")) { + generateXInitializationBodies(o); + generated.add(type); + continue; + } else if (type.equals("com.sun.star.frame.XDispatch")) { + generateXDispatchBodies(o, options); + generated.add(type); + continue; + } else if (type.equals("com.sun.star.frame.XDispatchProvider")) { + generateXDispatchProviderBodies(o, options); + generated.add(type); + continue; + } + } + typereg::Reader reader(manager.getTypeReader(type.replace('.','/'))); + printMethods(o, options, manager, reader, generated, "_", + indentation, true, usepropertymixin); + } + } +} + +static const char* propcomment= +" // use the last parameter of the PropertySetMixin constructor\n" +" // for your optional attributes if necessary. See the documentation\n" +" // of the PropertySetMixin helper for further information.\n" +" // Ensure that your attributes are initialized correctly!\n"; + + +void generateAddinConstructorAndHelper(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, const OString & classname, + const boost::unordered_set< OString, OStringHash >& services, + const boost::unordered_set< OString, OStringHash >& interfaces) +{ + o << " private com.sun.star.lang.Locale m_locale = " + "new com.sun.star.lang.Locale();\n"; + + if (!options.backwardcompatible) { + // Constructor + o << "\n public " << classname << "( XComponentContext context )\n" + " {\n m_xContext = context;\n }\n\n"; + return; + } + + + // get the one and only add-in service for later use + boost::unordered_set< OString, OStringHash >::const_iterator iter = services.begin(); + OString sAddinService = (*iter).replace('/', '.'); + if (sAddinService.equals("com.sun.star.sheet.AddIn")) { + sAddinService = (*(++iter)).replace('/', '.'); + } + + + // add-in specific fields + o << "\n private static final String sADDIN_SERVICENAME = \"" + << sAddinService << "\";\n\n"; + o << " private static final String sDISPLAYNAME = " + "\"DisplayName\";\n" + " private static final String sDESCRIPTION = " + "\"Description\";\n" + " private static final String sCATEGORY = \"Category\";\n" + " private static final String sCATEGORYDISPLAYNAME = " + "\"CategoryDisplayName\";\n\n"; + + o << " private com.sun.star.container.XHierarchicalNameAccess " + "m_xHAccess = null;\n" + " private com.sun.star.container.XHierarchicalNameAccess " + "m_xCompAccess = null;\n"; + if (options.java5) { + o << " private java.util.Hashtable<\n String, " + "java.util.Hashtable< Integer, String> > m_functionMap = null;\n\n"; + } else { + o << " private java.util.Hashtable m_functionMap = null;\n\n"; + } + // Constructor + o << "\n public " << classname << "( XComponentContext context )\n {\n" + " m_xContext = context;\n\n" + " try {\n"; + + if (options.java5) { + o << " m_functionMap = new java.util.Hashtable<\n" + " String, java.util.Hashtable< Integer, " + "String > >();\n\n"; + } else { + o << " m_functionMap = new java.util.Hashtable();\n\n"; + } + + generateFunctionParameterMap(o, options, manager, interfaces); + + o << " com.sun.star.lang.XMultiServiceFactory xProvider = \n" + " (com.sun.star.lang.XMultiServiceFactory)UnoRuntime." + "queryInterface(\n" + " com.sun.star.lang.XMultiServiceFactory.class,\n" + " m_xContext.getServiceManager().createInstanceWithContext(" + "\n \"com.sun.star.configuration.ConfigurationProvider\"" + ",\n m_xContext));\n\n"; + + o << " String sReadOnlyView = " + "\"com.sun.star.configuration.ConfigurationAccess\";\n\n"; + + o << " StringBuffer sPath = new StringBuffer(\n" + " \"/org.openoffice.Office.CalcAddIns/AddInInfo/\");\n" + " sPath.append(sADDIN_SERVICENAME);\n" + " sPath.append(\"/AddInFunctions\");\n\n"; + + o << " // create arguments: nodepath\n" + " com.sun.star.beans.PropertyValue aArgument = \n" + " new com.sun.star.beans.PropertyValue();\n" + " aArgument.Name = \"nodepath\";\n" + " aArgument.Value = new com.sun.star.uno.Any(\n" + " com.sun.star.uno.Type.STRING, sPath.toString());\n\n"; + + o << " Object aArguments[] = new Object[1];\n" + " aArguments[0] = new com.sun.star.uno.Any(" + " new com.sun.star.uno.Type(\n" + " com.sun.star.beans.PropertyValue.class), aArgument);\n\n"; + + o << " // create the default view using default UI locale\n" + " Object xIface = \n" + " xProvider.createInstanceWithArguments(sReadOnlyView, " + "aArguments);\n\n"; + + o << " m_xHAccess = (com.sun.star.container.XHierarchicalNameAccess)\n" + " UnoRuntime.queryInterface(\n" + " com.sun.star.container.XHierarchicalNameAccess.class, " + "xIface);\n\n"; + + o << " // extends arguments to create a view for all locales to get " + "simple\n // access to the compatibilityname property\n" + " aArguments = new Object[2];\n" + " aArguments[0] = new com.sun.star.uno.Any( " + "new com.sun.star.uno.Type(\n" + " com.sun.star.beans.PropertyValue.class), aArgument);\n" + " aArgument.Name = \"locale\";\n" + " aArgument.Value = new com.sun.star.uno.Any(\n" + " com.sun.star.uno.Type.STRING, \"*\");\n" + " aArguments[1] = new com.sun.star.uno.Any( " + " new com.sun.star.uno.Type(\n" + " com.sun.star.beans.PropertyValue.class), aArgument);\n\n"; + + o << " // create view for all locales\n" + " xIface = xProvider.createInstanceWithArguments(sReadOnlyView, " + "aArguments);\n\n" + " m_xCompAccess = (com.sun.star.container.XHierarchicalNameAccess)\n" + " UnoRuntime.queryInterface(\n" + " com.sun.star.container.XHierarchicalNameAccess.class, " + "xIface);\n }\n" + " catch ( com.sun.star.uno.Exception e ) {\n }\n }\n\n"; + + // add-in helper function + o << " // addin configuration property helper function:\n" + " String getAddinProperty(String funcName, " + "String paramName, String propName)\n {\n" + " try {\n StringBuffer buf = " + "new StringBuffer(funcName);\n\n" + " if (paramName.length() > 0) {\n" + " buf.append(\"/Parameters/\");\n" + " buf.append(paramName);\n }\n\n"; + + o << " com.sun.star.beans.XPropertySet xPropSet =\n" + " (com.sun.star.beans.XPropertySet)UnoRuntime." + "queryInterface(\n" + " com.sun.star.beans.XPropertySet.class,\n" + " m_xHAccess.getByHierarchicalName(buf.toString()));\n\n" + " return com.sun.star.uno.AnyConverter.toString(\n" + " xPropSet.getPropertyValue(propName));\n }\n" + " catch ( com.sun.star.uno.RuntimeException e ) {\n" + " throw e;\n }\n" + " catch ( com.sun.star.uno.Exception e ) {\n }\n" + " return \"\";\n }\n\n"; +} + + +void generateClassDefinition(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + const OString & classname, + const boost::unordered_set< OString, OStringHash >& services, + const boost::unordered_set< OString, OStringHash >& interfaces, + const AttributeInfo& properties, + const AttributeInfo& attributes, + const OString& propertyhelper, bool supportxcomponent) +{ + o << "\n\npublic final class " << classname << " extends "; + + if (!interfaces.empty()) { + if (propertyhelper.equals("_")) { + o << "PropertySet\n"; + } else { + if (supportxcomponent) + o << "ComponentBase\n"; + else + o << "WeakBase\n"; + } + o << " implements "; + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + while (iter != interfaces.end()) { + o << (*iter); + ++iter; + if (iter != interfaces.end()) + o << ",\n "; + } + } + o << "\n{\n"; + + o << " private final XComponentContext m_xContext;\n"; + + // additional member for add-ons + if (options.componenttype == 3) { + o << " private com.sun.star.frame.XFrame m_xFrame;\n"; + } + + // check property helper + if (propertyhelper.getLength() > 1) + o << " private final PropertySetMixin m_prophlp;\n"; + + o << " private static final String m_implementationName = " + << classname << ".class.getName();\n"; + + if (!services.empty()) { + o << " private static final String[] m_serviceNames = {\n"; + boost::unordered_set< OString, OStringHash >::const_iterator iter = + services.begin(); + while (iter != services.end()) { + o << " \"" << (*iter).replace('/','.') << "\""; + ++iter; + if (iter != services.end()) + o << ",\n"; + else + o << " };\n\n"; + } + } + + // attribute/property members + if (!properties.empty()) { + AttributeInfo::const_iterator iter = + properties.begin(); + o << " // properties\n"; + while (iter != properties.end()) { + o << " protected "; + printType(o, options, manager, iter->second.first.replace('.','/'), + false, false); + o << " m_" << iter->first << ";\n"; + ++iter; + } + } else if (!attributes.empty()) { + AttributeInfo::const_iterator iter = + attributes.begin(); + o << " // attributes\n"; + while (iter != attributes.end()) { + o << " private "; + printType(o, options, manager, iter->second.first.replace('.','/'), + false, false); + o << " m_" << iter->first << " = "; + printType(o, options, manager, iter->second.first.replace('.','/'), + false, true); + o <<";\n"; + ++iter; + } + } + + // special handling of calc add-ins + if (options.componenttype == 2) + { + generateAddinConstructorAndHelper(o, options, manager, classname, + services, interfaces); + } else { + o << "\n public " << classname << "( XComponentContext context )\n" + " {\n m_xContext = context;\n"; + if (propertyhelper.equals("_")) { + registerProperties(o, manager, properties, " "); + } else { + if (propertyhelper.getLength() > 1) { + o << propcomment + << " m_prophlp = new PropertySetMixin(m_xContext, this,\n" + << " new Type(" << propertyhelper + << ".class), null);\n"; + } + } + o << " };\n\n"; + + } + + if (!services.empty()) + generateCompFunctions(o, classname); + + generateMethodBodies(o, options, manager, interfaces, + " ", propertyhelper.getLength() > 1); + + // end of class definition + o << "}\n"; +} + +void generateSkeleton(ProgramOptions const & options, + TypeManager const & manager, + std::vector< OString > const & types, + OString const & /*delegate*/) +{ + boost::unordered_set< OString, OStringHash > interfaces; + boost::unordered_set< OString, OStringHash > services; + AttributeInfo properties; + AttributeInfo attributes; + boost::unordered_set< OString, OStringHash > propinterfaces; + bool serviceobject = false; + bool supportxcomponent = false; + + std::vector< OString >::const_iterator iter = types.begin(); + while (iter != types.end()) { + checkType(manager, *iter, interfaces, services, properties); + ++iter; + } + + if (options.componenttype == 3) { + // the Protocolhandler service is mandatory for an protocol handler add-on, + // so it is defaulted. The XDispatchProvider provides Dispatch objects for + // certain functions and the generated impl object implements XDispatch + // directly for simplicity reasons. + checkType(manager, "com.sun.star.frame.ProtocolHandler", + interfaces, services, properties); + checkType(manager, "com.sun.star.frame.XDispatch", + interfaces, services, properties); + + +// ProtocolCmdMap::const_iterator iter2 = options.protocolCmdMap.begin(); +// while (iter2 != options.protocolCmdMap.end()) { +// fprintf(stdout, "prt=%s\n", (*iter2).first.getStr()); + +// for (std::vector< OString >::const_iterator i = (*iter2).second.begin(); +// i != (*iter2).second.end(); ++i) { +// fprintf(stdout, "cmd=%s\n", (*i).getStr()); +// } +// iter2++; +// } +// return; + } + + if (options.componenttype == 2) { + if (services.size() != 1) { + throw CannotDumpException( + "for calc add-in components one and only one service type is " + "necessary! Please reference a valid type with the '-t' option."); + } + + // if backwardcompatible==true the AddIn service needs to be added to the + // suported service list, the necessary intefaces are mapped to the add-in + // configuration. Since OO.org 2.0.4 this is obsolete and the add-in is + // take form the configuration from Calc directly, this simplifies the + // add-in code + if (options.backwardcompatible) { + checkType(manager, "com.sun.star.sheet.AddIn", + interfaces, services, properties); + } else { + // special case for the optional XLocalization interface. It should be + // implemented always. But it is parent of the XAddIn and we need it only + // if backwardcompatible is false. + if (interfaces.find("com.sun.star.lang.XLocalizable") == interfaces.end()) { + interfaces.insert("com.sun.star.lang.XLocalizable"); + } + } + } + + + // check if service object or simple UNO object + if (!services.empty()) + serviceobject = true; + + OString propertyhelper = checkPropertyHelper( + options, manager, services, interfaces, attributes, propinterfaces); + checkDefaultInterfaces(interfaces, services, propertyhelper); + + if (options.componenttype == 2) { + if (propertyhelper.getLength() > 0) + std::cerr << "WARNING: interfaces specifying calc add-in functions " + "shouldn't support attributes!\n"; + } + + supportxcomponent = checkXComponentSupport(manager, interfaces); + + OString compFileName; + OString tmpFileName; + std::ostream* pofs = NULL; + bool standardout = getOutputStream(options, ".java", + &pofs, compFileName, tmpFileName); + + try { + if (!standardout && options.license) { + printLicenseHeader(*pofs, compFileName); + } + + generatePackage(*pofs, options.implname); + + generateImports(*pofs, options, interfaces, propertyhelper, + serviceobject, supportxcomponent); + + OString classname(options.implname); + sal_Int32 index = 0; + if ((index = classname.lastIndexOf('.')) > 0) + classname = classname.copy(index+1); + + generateClassDefinition(*pofs, options, manager, classname, services, + interfaces, properties, attributes, propertyhelper, + supportxcomponent); + + if ( !standardout && pofs && ((std::ofstream*)pofs)->is_open()) { + ((std::ofstream*)pofs)->close(); + delete pofs; + OSL_VERIFY(makeValidTypeFile(compFileName, tmpFileName, sal_False)); + } + } catch(CannotDumpException& e) { + + std::cerr << "ERROR: " << e.m_message.getStr() << "\n"; + if ( !standardout ) { + if (pofs && ((std::ofstream*)pofs)->is_open()) { + ((std::ofstream*)pofs)->close(); + delete pofs; + } + // remove existing type file if something goes wrong to ensure + // consistency + if (fileExists(compFileName)) + removeTypeFile(compFileName); + + // remove tmp file if something goes wrong + removeTypeFile(tmpFileName); + } + } +} + +} } + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/javatypemaker.cxx b/unodevtools/source/skeletonmaker/javatypemaker.cxx new file mode 100644 index 000000000000..9f49f66a8785 --- /dev/null +++ b/unodevtools/source/skeletonmaker/javatypemaker.cxx @@ -0,0 +1,873 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "codemaker/commonjava.hxx" + +#include "skeletoncommon.hxx" +#include "skeletonjava.hxx" + +using namespace ::rtl; + +namespace skeletonmaker { namespace java { + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + OString const & type, bool referenceType, + bool defaultvalue); + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + OString const & name, sal_Int32 rank, + std::vector< OString > const & arguments, bool referenceType, + bool defaultvalue) +{ + if ( defaultvalue && rank == 0 && sort <= codemaker::UnoType::SORT_CHAR ) { + switch (sort) + { + case codemaker::UnoType::SORT_BOOLEAN: + o << "false"; + return; + case codemaker::UnoType::SORT_CHAR: + case codemaker::UnoType::SORT_BYTE: + case codemaker::UnoType::SORT_SHORT: + case codemaker::UnoType::SORT_UNSIGNED_SHORT: + case codemaker::UnoType::SORT_LONG: + case codemaker::UnoType::SORT_UNSIGNED_LONG: + case codemaker::UnoType::SORT_HYPER: + case codemaker::UnoType::SORT_UNSIGNED_HYPER: + case codemaker::UnoType::SORT_FLOAT: + case codemaker::UnoType::SORT_DOUBLE: + o << "0"; + return; + case codemaker::UnoType::SORT_VOID: + case codemaker::UnoType::SORT_STRING: + case codemaker::UnoType::SORT_TYPE: + case codemaker::UnoType::SORT_ANY: + case codemaker::UnoType::SORT_COMPLEX: + break; + } + } + + if ( defaultvalue ) { + if ( sort == codemaker::UnoType::SORT_COMPLEX && + typeClass == RT_TYPE_INTERFACE ) { + o << "null"; + return; + } else if ( sort == codemaker::UnoType::SORT_ANY && rank==0 ) { + o << "com.sun.star.uno.Any.VOID"; + return; + } else if ( sort == codemaker::UnoType::SORT_TYPE && rank==0 ) { + o << "com.sun.star.uno.Type.VOID"; + return; + } else + if ( typeClass != RT_TYPE_ENUM || rank > 0 ) + o << "new "; + } + + OString sType(codemaker::java::translateUnoToJavaType( + sort, typeClass, name, referenceType && rank==0).replace('/', '.')); + if ( sType.indexOf("java.lang.") == 0 ) + sType = sType.copy(10); + o << sType.getStr(); + if ( !arguments.empty() && options.java5 ) { + o << '<'; + for ( std::vector< OString >::const_iterator i(arguments.begin()); + i != arguments.end(); ++i ) + { + if ( i != arguments.begin() ) { + o << ", "; + } + + printType(o, options, manager, *i, true, false); + } + o << '>'; + } + for ( sal_Int32 i = 0; i < rank; ++i ) { + if ( defaultvalue ) + o << "[0]"; + else + o << "[]"; + } + + if ( defaultvalue && sort > codemaker::UnoType::SORT_CHAR && rank == 0 ) { + if ( typeClass == RT_TYPE_ENUM ) + o << ".getDefault()"; + else + o << "()"; + } +} + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + OString const & type, bool referenceType, bool defaultvalue) +{ + RTTypeClass typeClass; + OString name; + sal_Int32 rank; + std::vector< OString > arguments; + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, type, true, true, true, &typeClass, &name, &rank, &arguments); + printType(o, + options, manager, sort, typeClass, name, rank, arguments, + referenceType, defaultvalue); +} + +bool printConstructorParameters(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, typereg::Reader const & outerReader, + std::vector< OString > const & arguments) +{ + bool previous = false; + if ( reader.getSuperTypeCount() != 0 ) { + OString super( + codemaker::convertString(reader.getSuperTypeName(0))); + typereg::Reader superReader(manager.getTypeReader(super)); + if ( !superReader.isValid() ) { + throw CannotDumpException("Bad type library entity " + super); + } + previous = printConstructorParameters(o, + options, manager, superReader, outerReader, arguments); + } + for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) { + if ( previous ) { + o << ", "; + } + previous = true; + if ( (reader.getFieldFlags(i) & RT_ACCESS_PARAMETERIZED_TYPE) == 0 ) { + printType(o, + options, manager, + codemaker::convertString(reader.getFieldTypeName(i)), + false); + } else if ( arguments.empty() ) { + o << "java.lang.Object"; + } else { + sal_uInt16 tparam = 0; + while ( outerReader.getReferenceTypeName(tparam) + != reader.getFieldTypeName(i) ) + { + ++tparam; + OSL_ASSERT(tparam < outerReader.getReferenceCount()); + } + // assume std::vector< OString >::size_type is at least as + // large as sal_uInt16: + printType(o, options, manager, arguments[tparam], true); + } + o + << ' ' + << (codemaker::java::translateUnoToJavaIdentifier( + codemaker::convertString(reader.getFieldName(i)), + "param"). + getStr()); + } + return previous; +} + +void printConstructor(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, + std::vector< OString > const & arguments) +{ + OString type(codemaker::convertString(reader.getTypeName())); + o << "public " << type.copy(type.lastIndexOf('/') + 1) << '('; + printConstructorParameters(o, options, manager, reader, reader, arguments); + o << ");\n"; +} + +void printMethodParameters(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, sal_uInt16 method, bool previous, + bool withtype, bool /*shortname*/) +{ + for ( sal_uInt16 i = 0; i < reader.getMethodParameterCount(method); ++i ) { + if ( previous ) + o << ", "; + else + previous = true; + + if ( withtype ) { + printType(o, options, manager, + codemaker::convertString( + reader.getMethodParameterTypeName(method, i)), + false); + if ( reader.getMethodParameterFlags(method, i) == RT_PARAM_OUT + || reader.getMethodParameterFlags(method, i) == RT_PARAM_INOUT ) + { + o << "[]"; + } else if ( (reader.getMethodParameterFlags(method, i) & RT_PARAM_REST ) + != 0) + { + o << (options.java5 ? "..." : "[]"); + } + o << ' '; + } + o << (codemaker::java::translateUnoToJavaIdentifier( + codemaker::convertString( + reader.getMethodParameterName(method, i)), + "param"). + getStr()); + } +} + +void printExceptionSpecification(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, sal_uInt16 method) +{ + if ( reader.getMethodExceptionCount(method) > 0 ) { + o << " throws "; + for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method); ++i ) + { + if ( i != 0 ) { + o << ", "; + } + printType(o, + options, manager, + codemaker::convertString( + reader.getMethodExceptionTypeName(method, i)), + false); + } + } +} + + +void printSetPropertyMixinBody(std::ostream & o, + typereg::Reader const & reader, + sal_uInt16 field, + sal_uInt16 method, + OString const & indentation) +{ + RTFieldAccess propFlags = checkAdditionalPropertyFlags(reader, field, method); + OString fieldname = codemaker::convertString(reader.getFieldName(field)); + bool bound = (reader.getFieldFlags(field) & RT_ACCESS_BOUND ? true : false); + + o << "\n" << indentation << "{\n"; + + if ( bound ) { + o << indentation << " PropertySetMixin.BoundListeners l = " + "new PropertySetMixin.BoundListeners();\n\n"; + } + + o << indentation << " m_prophlp.prepareSet(\"" + << fieldname << "\", "; + if ( propFlags & RT_ACCESS_CONSTRAINED ) { + OString fieldtype = codemaker::convertString(reader.getFieldTypeName(field)); + + sal_Int32 index = fieldtype.lastIndexOf('<'); + sal_Int32 nPos=0; + bool single = true; + bool optional = false; + OStringBuffer buffer1(64); + OStringBuffer buffer2(64); + do + { + OString s(fieldtype.getToken(0, '<', nPos)); + OStringBuffer buffer(16); + buffer.append("(("); + buffer.append(s.copy(s.lastIndexOf('/')+1)); + buffer.append(')'); + OString t = buffer.makeStringAndClear(); + + if ( t.equals("((Optional)") ) { + optional=true; + if (single) { + single=false; + buffer1.append("the_value.IsPresent"); + buffer2.append("the_value.Value"); + } else { + buffer1.insert(0, t); + buffer1.append(").IsPresent"); + buffer2.insert(0, t); + buffer2.append(").Value"); + } + } else { + if ( single ) { + single=false; + if ( !optional ) { + buffer1.append("the_value.Value"); + } + buffer2.append("the_value.Value"); + } else { + if ( !optional ) { + buffer1.insert(0, t); + buffer1.append(").Value"); + } + buffer2.insert(0, t); + buffer2.append(").Value"); + } + } + } while( nPos <= index ); + + o << "Any.VOID,\n" << indentation << " "; + if ( optional ) + o << "("; + o << buffer1.makeStringAndClear(); + if ( optional ) + o << ") ? " << buffer2.makeStringAndClear() << " : Any.VOID,\n" + << indentation << " "; + else + o << ", "; + } + + if ( bound ) + o << "l"; + else + o << "null"; + o << ");\n"; + + o << indentation << " synchronized (this) {\n" + << indentation << " m_" << fieldname + << " = the_value;\n" << indentation << " }\n"; + + if ( bound ) { + o << indentation << " l.notifyListeners();\n"; + } + o << indentation << "}\n\n"; +} + +void generateXPropertySetBodies(std::ostream& o); +void generateXFastPropertySetBodies(std::ostream& o); +void generateXPropertyAccessBodies(std::ostream& o); + +void printMethods(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, + codemaker::GeneratedTypeSet & generated, + OString const & delegate, OString const & indentation, + bool defaultvalue, bool usepropertymixin) +{ + OString type(codemaker::convertString(reader.getTypeName())); + if ( generated.contains(type) || type == "com/sun/star/uno/XInterface" || + ( defaultvalue && + ( type.equals("com/sun/star/lang/XComponent") || + type.equals("com/sun/star/lang/XTypeProvider") || + type.equals("com/sun/star/uno/XWeak") ) ) ) { + return; + } + + if ( usepropertymixin ) { + if ( type.equals("com/sun/star/beans/XPropertySet") ) { + generated.add(type); + generateXPropertySetBodies(o); + return; + } else if ( type.equals("com/sun/star/beans/XFastPropertySet") ) { + generated.add(type); + generateXFastPropertySetBodies(o); + return; + } else if ( type.equals("com/sun/star/beans/XPropertyAccess") ) { + generated.add(type); + generateXPropertyAccessBodies(o); + return; + } + } + + static OString sd(RTL_CONSTASCII_STRINGPARAM("_")); + bool body = ((delegate.getLength() > 0) ? true : false); + bool defaultbody = ((delegate.equals(sd)) ? true : false); + + generated.add(type); + if ( options.all || defaultvalue ) { + for (sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i) { + typereg::Reader super( + manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(i)))); + if ( !super.isValid() ) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString( + reader.getSuperTypeName(i))); + } + printMethods(o, options, manager, super, generated, delegate, + indentation, defaultvalue, usepropertymixin); + } + if ( reader.getFieldCount() > 0 || reader.getMethodCount() > 0 ) { + o << indentation << "// "; + printType(o, options, manager, type, false); + o << ":\n"; + } + } + sal_uInt16 method = 0; + for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) { +// OString fieldName( +// codemaker::convertString(reader.getFieldName(i)). +// replace('/', '.')); +// OString fieldType( +// codemaker::convertString(reader.getFieldTypeName(i)). +// replace('/', '.')); +// attributes.insert(StringPairHashMap::value_type(fieldName, +// std::pair<OString, sal_Int16>( +// fieldType, reader.getFieldFlags(i)))); + + o << indentation << "public "; + printType(o, + options, manager, + codemaker::convertString(reader.getFieldTypeName(i)), false); + o << " get" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << "()"; + + OUString mn = reader.getMethodName(method); + OUString fn = reader.getFieldName(i); + + if ( method < reader.getMethodCount() + && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET + && reader.getMethodName(method) == reader.getFieldName(i) ) + { + printExceptionSpecification(o, options, manager, reader, method++); + } + if ( body ) { + if ( defaultbody ) { + if ( usepropertymixin ) { + o << "\n" << indentation << "{\n" << indentation + << " return m_" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << ";\n" << indentation << "}\n\n"; + } else { + o << "\n" << indentation << "{\n" << indentation + << " return "; + printType(o, + options, manager, + codemaker::convertString(reader.getFieldTypeName(i)), + false, true); + o << ";\n" << indentation << "}\n\n"; + } + } else { + o << "\n" << indentation << "{\n" << indentation << + " return " + << delegate.getStr() << "get" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << "();\n" << indentation << "}\n\n"; + } + } else { + o << ";\n"; + } + + // REMOVE next line + OUString tmp = reader.getFieldName(i); + bool setAttrMethod = false; + if ( (reader.getFieldFlags(i) & RT_ACCESS_READONLY) == 0 ) { + o << indentation << "public void set" + << (codemaker::convertString(reader.getFieldName(i)). + getStr()) + << '('; + printType(o, + options, manager, + codemaker::convertString(reader.getFieldTypeName(i)), + false); + o << " the_value)"; + if ( method < reader.getMethodCount() + && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET + && reader.getMethodName(method) == reader.getFieldName(i) ) + { + setAttrMethod=true; + printExceptionSpecification(o, options, manager, reader, method); + } + if ( body ) { + if ( defaultbody ) { + if ( usepropertymixin ) { + printSetPropertyMixinBody(o, reader, i, method, + indentation); + } else { + o << "\n" << indentation << "{\n\n" << indentation + << "}\n\n"; + } + } else { + o << "\n" << indentation << "{\n" << indentation + << " " << delegate.getStr() << "set" + << codemaker::convertString(reader.getFieldName(i)).getStr() + << "(the_value);\n" << indentation << "}\n\n"; + } + } else { + o << ";\n"; + } + if (setAttrMethod) ++method; + } + } + for ( ; method < reader.getMethodCount(); ++method ) { + o << indentation << "public "; + printType(o, + options, manager, + codemaker::convertString( + reader.getMethodReturnTypeName(method)), + false); + + const OString methodName(codemaker::convertString(reader.getMethodName(method))); + + o << ' ' << methodName.getStr() << '('; + printMethodParameters(o, options, manager, reader, method, false, true); + o << ')'; + printExceptionSpecification(o, options, manager, reader, method); + if ( body ) { + static OUString s(RTL_CONSTASCII_USTRINGPARAM("void")); + if ( defaultbody ) { + o << "\n" << indentation << "{\n"; + if ( !reader.getMethodReturnTypeName(method).equals(s) ) { + o << indentation << " // TODO: Exchange the default return " + << "implementation for \"" << methodName << "\" !!!\n"; + o << indentation << " // NOTE: " + "Default initialized polymorphic structs can cause problems" + "\n" << indentation << " // because of missing default " + "initialization of primitive types of\n" << indentation + << " // some C++ compilers or different Any initialization" + " in Java and C++\n" << indentation + << " // polymorphic structs.\n" << indentation + << " return "; + printType(o, + options, manager, + codemaker::convertString( + reader.getMethodReturnTypeName(method)), + false, true); + o << ";"; + } else { + o << indentation << " // TODO: Insert your implementation for \"" + << methodName << "\" here."; + } + o << "\n" << indentation << "}\n\n"; + } else { + o << "\n" << indentation << "{\n" << indentation << " "; + if ( !reader.getMethodReturnTypeName(method).equals(s) ) + o << "return "; + o << delegate.getStr() + << (codemaker::convertString( + reader.getMethodName(method)).getStr()) + << '('; + printMethodParameters(o, options, manager, reader, method, + false, false); + o << ");\n" << indentation << "}\n\n"; + } + } else { + o << ";\n"; + } + } +} + +void printConstructionMethods(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader) +{ + for ( sal_uInt16 i = 0; i < reader.getMethodCount(); ++i ) { + o << "public static "; + printType(o, + options, manager, + codemaker::convertString(reader.getSuperTypeName(0)), false); + o << ' '; + if ( reader.getMethodName(i).getLength() == 0 ) { + o << "create"; + } else { + o << (codemaker::java::translateUnoToJavaIdentifier( + codemaker::convertString(reader.getMethodName(i)), + "method").getStr()); + } + o << "(com.sun.star.uno.XComponentContext the_context"; + printMethodParameters(o, options, manager, reader, i, true, true); + o << ')'; + printExceptionSpecification(o, options, manager, reader, i); + o << ";\n"; + } +} + +void generateDocumentation(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + OString const & type); + +void printServiceMembers(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, OString const & type, + OString const & delegate) +{ + for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) { + OString referenceType( + codemaker::convertString( + reader.getReferenceTypeName(i)).replace('/', '.')); + + if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) { + o << "\n// supported interface " << referenceType.getStr() << "\n"; + generateDocumentation(o, options, manager, referenceType, delegate); + } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) { + o << "\n// exported service " << referenceType.getStr() << "\n"; + generateDocumentation(o, options, manager, referenceType, delegate); + } + } + + o << "\n// properties of service \""<< type.getStr() << "\"\n"; + for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) { + OString fieldName( + codemaker::convertString(reader.getFieldName(i))); + OString fieldType( + codemaker::convertString(reader.getFieldTypeName(i))); + + o << "// private "; + printType(o, options, manager, fieldType, false); + o << " " + << codemaker::java::translateUnoToJavaIdentifier( + fieldName, "property").getStr() + << ";\n"; + } +} + +void printMapsToJavaType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + OString const & name, sal_Int32 rank, + std::vector< OString > const & arguments, const char * javaTypeSort) +{ + o << "maps to Java " << (options.java5 ? "1.5" : "1.4") << " "; + if ( javaTypeSort != 0 ) { + o << javaTypeSort << ' '; + } + o << "type \""; + if ( rank == 0 && name == "com/sun/star/uno/XInterface" ) { + o << "com.sun.star.uno.XInterface"; + } else { + printType(o, + options, manager, sort, typeClass, name, rank, arguments, false); + } + o << '"'; +} + +void generateDocumentation(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + OString const & type, OString const & delegate) +{ + if ( type.indexOf('/') >= 0 ) { + throw CannotDumpException("Illegal type name " + type); + } + OString binType(type.replace('.', '/')); + RTTypeClass typeClass; + OString name; + sal_Int32 rank; + std::vector< OString > arguments; + codemaker::UnoType::Sort sort = decomposeResolveAndCheck( + manager, binType, false, true, true, &typeClass, &name, &rank, + &arguments); + + bool comment=true; + if ( delegate.getLength() > 0 ) { + if ( typeClass != RT_TYPE_INTERFACE && typeClass != RT_TYPE_SERVICE ) + return; + + comment=false; + } + + if ( comment ) { + o << "\n// UNO"; + if ( rank > 0 ) { + o << " sequence type"; + } else if ( sort != codemaker::UnoType::SORT_COMPLEX ) { + o << " simple type"; + } else { + typereg::Reader reader(manager.getTypeReader(name)); + if ( !reader.isValid() ) { + throw CannotDumpException("Bad type library entity " + name); + } + switch ( typeClass ) { + case RT_TYPE_INTERFACE: + o << " interface type"; + break; + + case RT_TYPE_MODULE: + o << "IDL module"; + break; + + case RT_TYPE_STRUCT: + if ( reader.getReferenceCount() == 0 ) { + o << " simple struct type"; + } else if ( arguments.empty() ) { + o << " polymorphic struct type template"; + } else { + o << " instantiated polymorphic struct type"; + } + break; + + case RT_TYPE_ENUM: + o << " enum type"; + break; + + case RT_TYPE_EXCEPTION: + o << " exception type"; + break; + + case RT_TYPE_TYPEDEF: + o << "IDL typedef"; + break; + + case RT_TYPE_SERVICE: + if ( reader.getSuperTypeCount() > 0 ) { + o << " single-inheritance--based service"; + } else { + o << "IDL accumulation-based service"; + } + break; + + case RT_TYPE_SINGLETON: + if ( (manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(0))).getTypeClass()) + == RT_TYPE_INTERFACE ) + { + o << " inheritance-based singleton"; + } else { + o << "IDL service-based singleton"; + } + break; + + case RT_TYPE_CONSTANTS: + o << "IDL constant group"; + break; + + default: + OSL_ASSERT(false); + break; + } + } + o << " \"" << type.getStr() << "\" "; + } + sort = codemaker::decomposeAndResolve( + manager, binType, true, true, true, &typeClass, &name, &rank, + &arguments); + if ( rank > 0 ) { + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, "array"); + o << '\n'; + } else if ( sort != codemaker::UnoType::SORT_COMPLEX ) { + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, 0); + o << '\n'; + } else { + typereg::Reader reader(manager.getTypeReader(name)); + if ( !reader.isValid() ) { + throw CannotDumpException("Bad type library entity " + name); + } + switch ( typeClass ) { + case RT_TYPE_INTERFACE: + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + "interface"); + if ( name == "com/sun/star/uno/XInterface" ) { + o << '\n'; + } else { + o + << "; " << (options.all ? "all" : "direct") + << " methods:\n"; + codemaker::GeneratedTypeSet generated; + printMethods(o, options, manager, reader, generated, + delegate, ""); + } + break; + + case RT_TYPE_MODULE: + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + "package"); + o << '\n'; + break; + + case RT_TYPE_STRUCT: + if ( reader.getReferenceCount() == 0 ) { + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + "class"); + } else if ( arguments.empty() ) { + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + options.java5 ? "generic class" : "class"); + } else { + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + options.java5 ? "generic class instantiation" : "class"); + } + o << "; full constructor:\n"; + printConstructor(o, options, manager, reader, arguments); + break; + + case RT_TYPE_ENUM: + case RT_TYPE_CONSTANTS: + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + "class"); + o << '\n'; + break; + + case RT_TYPE_EXCEPTION: + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + "exception class"); + o << "; full constructor:\n"; + printConstructor(o, options, manager, reader, arguments); + break; + + case RT_TYPE_SERVICE: + if ( reader.getSuperTypeCount() > 0 ) { + printMapsToJavaType(o, + options, manager, sort, typeClass, name, rank, arguments, + "class"); + o << "; construction methods:\n"; + printConstructionMethods(o, options, manager, reader); + + OString super( + codemaker::convertString( + reader.getSuperTypeName(0)).replace('/', '.')); + + generateDocumentation(o, options, manager, super, delegate); + } else { + o << ("does not map to Java\n" + "// the service members are generated instead\n"); + printServiceMembers(o, options, manager, reader, type, delegate); + } + break; + + case RT_TYPE_SINGLETON: + if ( reader.getSuperTypeCount() > 0 && + ((manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(0))).getTypeClass()) + == RT_TYPE_INTERFACE) ) { + printMapsToJavaType(o, options, manager, sort, typeClass, + name, rank, arguments, "class"); + o << "; get method:\npublic static "; + printType(o, options, manager, + codemaker::convertString(reader.getSuperTypeName(0)), + false); + o + << " get(com.sun.star.uno.XComponentContext context);\n"; + } else { + o << "does not map to Java\n"; + } + break; + + default: + OSL_ASSERT(false); + break; + } + } +} + +} } + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/makefile.mk b/unodevtools/source/skeletonmaker/makefile.mk new file mode 100644 index 000000000000..ec0a382134d3 --- /dev/null +++ b/unodevtools/source/skeletonmaker/makefile.mk @@ -0,0 +1,63 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ := ..$/.. +PRJNAME := unodevtools + +TARGET := uno-skeletonmaker +TARGETTYPE := CUI +LIBTARGET := NO + +ENABLE_EXCEPTIONS := TRUE + +.INCLUDE: settings.mk + +.IF "$(OS)" == "IOS" +all: + @echo No point in build-time executables for this platform +.ENDIF + +.INCLUDE : $(PRJ)$/unodevtools.pmk + +APP1TARGET = $(TARGET) +APP1RPATH=SDK + +APP1OBJS = $(OBJ)$/skeletonmaker.obj \ + $(OBJ)$/skeletoncommon.obj \ + $(OBJ)$/javatypemaker.obj \ + $(OBJ)$/cpptypemaker.obj \ + $(OBJ)$/javacompskeleton.obj \ + $(OBJ)$/cppcompskeleton.obj + +APP1DEPN= $(OUT)$/lib$/$(UNODEVTOOLSLIBDEPN) $(SOLARLIBDIR)$/$(CODEMAKERLIBDEPN) \ + $(SOLARLIBDIR)$/$(COMMONCPPLIBDEPN) $(SOLARLIBDIR)$/$(COMMONJAVALIBDEPN) +APP1STDLIBS = $(UNODEVTOOLSLIBST) $(REGLIB) $(SALLIB) $(SALHELPERLIB) $(CPPULIB) $(CPPUHELPERLIB) \ + $(CODEMAKERLIBST) $(COMMONCPPLIBST) $(COMMONJAVALIBST) + +OBJFILES = $(APP1OBJS) + +.INCLUDE: target.mk diff --git a/unodevtools/source/skeletonmaker/skeletoncommon.cxx b/unodevtools/source/skeletonmaker/skeletoncommon.cxx new file mode 100644 index 000000000000..7329b793ab54 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletoncommon.cxx @@ -0,0 +1,724 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "osl/thread.hxx" + +#include "codemaker/commonjava.hxx" +#include "codemaker/commoncpp.hxx" +#include "codemaker/generatedtypeset.hxx" + +#include "skeletoncommon.hxx" + +#include <iostream> + +using namespace ::rtl; +using namespace ::codemaker::cpp; + +namespace skeletonmaker { + +void printLicenseHeader(std::ostream& o, rtl::OString const & filename) +{ + sal_Int32 index = -1; +#ifdef SAL_UNX + index = filename.lastIndexOf('/'); +#else + index = filename.lastIndexOf('\\'); +#endif + OString shortfilename(filename); + if ( index != -1 ) + shortfilename = filename.copy(index+1); + + o << "/*************************************************************************\n" + " *\n" + " * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n" + " * \n" + " * Copyright 2000, 2010 Oracle and/or its affiliates.\n" + " *\n" + " * OpenOffice.org - a multi-platform office productivity suite\n" + " *\n" + " * This file is part of OpenOffice.org.\n" + " *\n" + " * OpenOffice.org is free software: you can redistribute it and/or modify\n" + " * it under the terms of the GNU Lesser General Public License version 3\n" + " * only, as published by the Free Software Foundation.\n" + " *\n" + " * OpenOffice.org is distributed in the hope that it will be useful,\n" + " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n" + " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" + " * GNU Lesser General Public License version 3 for more details\n" + " * (a copy is included in the LICENSE file that accompanied this code).\n" + " *\n" + " * You should have received a copy of the GNU Lesser General Public License\n" + " * version 3 along with OpenOffice.org. If not, see\n" + " * <http://www.openoffice.org/license.html>\n" + " * for a copy of the LGPLv3 License.\n" + " *\n" + " ************************************************************************/\n\n"; +} + +bool getOutputStream(ProgramOptions const & options, + OString const & extension, + std::ostream** ppOutputStream, + OString & targetSourceFileName, + OString & tmpSourceFileName) +{ + bool bStandardout = false; + if ( options.outputpath.equals("stdout") ) + { + bStandardout = true; + *ppOutputStream = &std::cout; + return bStandardout; + } + + targetSourceFileName = createFileNameFromType( + options.outputpath, options.implname.replace('.','/'), extension); + + OString tmpDir = getTempDir(targetSourceFileName); + FileStream file; + file.createTempFile(tmpDir); + + if( !file.isValid() ) + { + OString message("cannot open "); + message += targetSourceFileName + " for writing"; + throw CannotDumpException(message); + } else { + tmpSourceFileName = file.getName(); + } + file.close(); + *ppOutputStream = new std::ofstream(tmpSourceFileName.getStr(), + std::ios_base::binary); + + return bStandardout; +} + +codemaker::UnoType::Sort decomposeResolveAndCheck( + TypeManager const & manager, OString const & type, + bool resolveTypedefs, bool allowVoid, bool allowExtraEntities, + RTTypeClass * typeClass, OString * name, sal_Int32 * rank, + std::vector< OString > * arguments) +{ + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, type, resolveTypedefs, allowVoid, allowExtraEntities, + typeClass, name, rank, arguments); + for ( std::vector< OString >::iterator i(arguments->begin()); + i != arguments->end(); ++i ) + { + RTTypeClass typeClass2; + OString name2; + sal_Int32 rank2; + std::vector< OString > arguments2; + decomposeResolveAndCheck( + manager, *i, true, false, false, &typeClass2, &name2, &rank2, + &arguments2); + } + return sort; +} + +bool containsAttribute(AttributeInfo& attributes, OString const & attrname) +{ + for ( AttributeInfo::const_iterator i(attributes.begin()); + i != attributes.end(); ++i ) { + if ( (*i).first == attrname ) { + return true; + } + } + return false; +} + +// collect attributes including inherited attributes +void checkAttributes(TypeManager const & manager, + const typereg::Reader& reader, + AttributeInfo& attributes, + boost::unordered_set< OString, OStringHash >& propinterfaces) +{ + OString typeName = codemaker::convertString(reader.getTypeName()); + if ( typeName.equals("com/sun/star/beans/XPropertySet") || + typeName.equals("com/sun/star/beans/XFastPropertySet") || +// typeName.equals("com/sun/star/beans/XMultiPropertySet") || + typeName.equals("com/sun/star/beans/XPropertyAccess") ) + { + propinterfaces.insert(typeName); + } + + for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) { + typereg::Reader supertype(manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(i)))); + if ( !supertype.isValid() ) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString(reader.getSuperTypeName(i))); + } + checkAttributes(manager, supertype, attributes, propinterfaces); + } + + for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) { + OString fieldName( + codemaker::convertString(reader.getFieldName(i)). + replace('/', '.')); + + if ( !containsAttribute(attributes, fieldName) ) { + OString fieldType( + codemaker::convertString(reader.getFieldTypeName(i)). + replace('/', '.')); + attributes.push_back(AttributeInfo::value_type( + fieldName, std::pair<OString, sal_Int16>( + fieldType, reader.getFieldFlags(i)))); + } + } +} + +void checkType(TypeManager const & manager, + OString const & type, + boost::unordered_set< OString, OStringHash >& interfaceTypes, + boost::unordered_set< OString, OStringHash >& serviceTypes, + AttributeInfo& properties) +{ + + OString binType(type.replace('.', '/')); + typereg::Reader reader(manager.getTypeReader(binType)); + if ( !reader.isValid() ) { + throw CannotDumpException("Bad type library entity " + binType); + } + + switch ( reader.getTypeClass() ) + { + case RT_TYPE_INTERFACE: + { + // com/sun/star/lang/XComponent should be also not in the list + // but it will be used for checking the impl helper and will be + // removed later if necessary. + if ( binType.equals("com/sun/star/lang/XTypeProvider") || + binType.equals("com/sun/star/uno/XWeak") ) + return; + if (interfaceTypes.find(type) == interfaceTypes.end()) { + interfaceTypes.insert(type); + } + } + break; + case RT_TYPE_SERVICE: + if ( serviceTypes.find(binType) == serviceTypes.end() ) { + serviceTypes.insert(binType); + + if ( reader.getSuperTypeCount() > 0 ) { + OString supername(codemaker::convertString( + reader.getSuperTypeName(0).replace('/', '.'))); + if ( interfaceTypes.find(supername) == interfaceTypes.end() ) { + interfaceTypes.insert(supername); + + typereg::Reader supertype(manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(0)))); + if ( !supertype.isValid() ) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString(reader.getSuperTypeName(0))); + } + } + + // check if constructors are specified, if yes automatically + // support of XInitialization. We will take care of the default + // constructor because in this case XInitialization is not called. + if ( reader.getMethodCount() > 1 || + ( reader.getMethodCount() == 1 && + reader.getMethodName(0).getLength() > 0 ) ) + { + OString s("com.sun.star.lang.XInitialization"); + if ( interfaceTypes.find(s) == interfaceTypes.end() ) + interfaceTypes.insert(s); + } + } else { + for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) { + OString referenceType( + codemaker::convertString( + reader.getReferenceTypeName(i)).replace('/', '.')); + + if ( reader.getReferenceSort(i) == RT_REF_SUPPORTS ) { + checkType(manager, referenceType, interfaceTypes, + serviceTypes, properties); + } else if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) { + checkType(manager, referenceType, interfaceTypes, + serviceTypes, properties); + } + } + + for ( sal_uInt16 i = 0; i < reader.getFieldCount(); ++i ) { + OString fieldName( + codemaker::convertString(reader.getFieldName(i)). + replace('/', '.')); + OString fieldType( + codemaker::convertString(reader.getFieldTypeName(i)). + replace('/', '.')); + + properties.push_back(AttributeInfo::value_type( + fieldName, std::pair<OString, sal_Int16>( + fieldType, reader.getFieldFlags(i)))); + } + } + } + break; + default: + OSL_ASSERT(false); + break; + } +} + +void checkDefaultInterfaces( + boost::unordered_set< OString, OStringHash >& interfaces, + const boost::unordered_set< OString, OStringHash >& services, + const OString & propertyhelper) +{ + if ( services.empty() ) { + if (interfaces.find("com.sun.star.lang.XServiceInfo") != interfaces.end()) + interfaces.erase("com.sun.star.lang.XServiceInfo"); + } else { + if (interfaces.find("com.sun.star.lang.XServiceInfo") == interfaces.end()) + interfaces.insert("com.sun.star.lang.XServiceInfo"); + } + + if ( propertyhelper.equals("_") ) { + if (interfaces.find("com.sun.star.beans.XPropertySet") + != interfaces.end()) + interfaces.erase("com.sun.star.beans.XPropertySet"); + if (interfaces.find("com.sun.star.beans.XFastPropertySet") + != interfaces.end()) + interfaces.erase("com.sun.star.beans.XFastPropertySet"); + if (interfaces.find("com.sun.star.beans.XPropertyAccess") + != interfaces.end()) + interfaces.erase("com.sun.star.beans.XPropertyAccess"); + } +} + +bool checkServiceProperties(TypeManager const & manager, + const typereg::Reader & reader) +{ + if ( reader.getFieldCount() > 0 ) + return true; + + if ( reader.getReferenceCount() > 0 ) { + for ( sal_uInt16 i = 0; i < reader.getReferenceCount(); ++i ) { + if ( reader.getReferenceSort(i) == RT_REF_EXPORTS ) { + typereg::Reader refreader( + manager.getTypeReader( + codemaker::convertString(reader.getReferenceTypeName(i)))); + + if ( checkServiceProperties(manager, refreader) ) + return true; + } + } + } + return false; +} + + +OString checkPropertyHelper( + ProgramOptions const & options, + TypeManager const & manager, + const boost::unordered_set< OString, OStringHash >& services, + const boost::unordered_set< OString, OStringHash >& interfaces, + AttributeInfo& attributes, + boost::unordered_set< OString, OStringHash >& propinterfaces) +{ + boost::unordered_set< OString, OStringHash >::const_iterator iter; + boost::unordered_set< OString, OStringHash >::const_iterator end; + + if ( !services.empty() ) { + iter = services.begin(); + end = services.end(); + } else { + iter = interfaces.begin(); + end = interfaces.end(); + } + + bool oldStyleWithProperties = false; + while ( iter != end ) { + typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/'))); + + if ( !services.empty() ) { + if ( options.supportpropertysetmixin && reader.getSuperTypeCount() > 0 ) + { + typereg::Reader supertype( + manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(0)))); + if ( !supertype.isValid() ) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString( + reader.getSuperTypeName(0))); + } + + checkAttributes(manager, supertype, attributes, propinterfaces); + + if ( !(attributes.empty() || propinterfaces.empty()) ) { + return OUStringToOString( + supertype.getTypeName().replace('/', '.'), + osl_getThreadTextEncoding()); + } + } else { + oldStyleWithProperties = checkServiceProperties(manager, reader); + } + } else { + checkAttributes(manager, reader, attributes, propinterfaces); + if ( !(attributes.empty() || propinterfaces.empty()) ) { + return OUStringToOString( + reader.getTypeName().replace('/', '.'), + osl_getThreadTextEncoding()); + } + } + ++iter; + } + + return (oldStyleWithProperties ? "_" : ""); +} + +bool checkXComponentSupport(TypeManager const & manager, + typereg::Reader const & reader) +{ + static OUString s(RTL_CONSTASCII_USTRINGPARAM( + "com/sun/star/lang/XComponent")); + if ( reader.getTypeName().equals(s) ) + return true; + + for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) { + typereg::Reader super( + manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(i)))); + if ( !super.isValid() ) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString( + reader.getSuperTypeName(i))); + } + if ( checkXComponentSupport(manager, super) ) + return true; + } + + return false; +} + + +// if XComponent is directly specified, return true and remove it from the +// supported interfaces list +bool checkXComponentSupport(TypeManager const & manager, + boost::unordered_set< OString, OStringHash >& interfaces) +{ + if ( interfaces.empty() ) + return false; + + boost::unordered_set< OString, OStringHash >::const_iterator iter = + interfaces.begin(); + while ( iter != interfaces.end() ) { + if ( (*iter).equals("com.sun.star.lang.XComponent") ) { + interfaces.erase("com.sun.star.lang.XComponent"); + return true; + } + typereg::Reader reader(manager.getTypeReader((*iter).replace('.', '/'))); + if ( checkXComponentSupport(manager, reader) ) + return true; + ++iter; + } + + return false; +} + +sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader, + sal_uInt16 field, sal_uInt16 method) +{ + sal_uInt16 flags = 0; + bool getterSupportsUnknown = false; + + OUString su(RTL_CONSTASCII_USTRINGPARAM( + "com/sun/star/beans/UnknownPropertyException")); + if ( method < reader.getMethodCount() + && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_GET + && reader.getMethodName(method) == reader.getFieldName(field) ) + { + if ( reader.getMethodExceptionCount(method) > 0 ) { + for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method); + ++i ) + { + if (su.equals(reader.getMethodExceptionTypeName(method, i))) + getterSupportsUnknown = true; + } + } + method++; + } + if ( method < reader.getMethodCount() + && reader.getMethodFlags(method) == RT_MODE_ATTRIBUTE_SET + && reader.getMethodName(method) == reader.getFieldName(field) ) + { + if ( reader.getMethodExceptionCount(method) > 0 ) { + OUString s(RTL_CONSTASCII_USTRINGPARAM( + "com/sun/star/beans/PropertyVetoException")); + for ( sal_uInt16 i = 0; i < reader.getMethodExceptionCount(method); + ++i ) + { + if ( s.equals(reader.getMethodExceptionTypeName(method, i)) ) + flags |= RT_ACCESS_CONSTRAINED; + if ( getterSupportsUnknown && + su.equals(reader.getMethodExceptionTypeName(method, i)) ) + flags |= RT_ACCESS_OPTIONAL; + } + } + } + return flags; +} + +// This function checks if the specified types for paramters and return +// types are allowed add-in types, for more info see the com.sun.star.sheet.AddIn +// service description +bool checkAddinType(TypeManager const & manager, + OString const & type, bool & bLastAny, + bool & bHasXPropertySet, bool bIsReturn) +{ + RTTypeClass typeClass; + OString name; + sal_Int32 rank; + std::vector< OString > arguments; + codemaker::UnoType::Sort sort = codemaker::decomposeAndResolve( + manager, type, true, true, true, &typeClass, &name, &rank, &arguments); + + if ( sort == codemaker::UnoType::SORT_LONG || + sort == codemaker::UnoType::SORT_DOUBLE || + sort == codemaker::UnoType::SORT_STRING ) + { + if ( rank == 0 || rank ==2 ) + return true; + } + if ( sort == codemaker::UnoType::SORT_ANY ) + { + if ( rank <= 2 ) { + if ( rank ==1 ) { + if ( bIsReturn ) + return false; + bLastAny = true; + } + + return true; + } + } + if ( sort == codemaker::UnoType::SORT_COMPLEX && + typeClass == RT_TYPE_INTERFACE ) + { + if ( bIsReturn && type.equals("com/sun/star/sheet/XVolatileResult") ) + return true; + if ( !bIsReturn && type.equals("com/sun/star/table/XCellRange") ) + return true; + if ( !bIsReturn && type.equals("com/sun/star/beans/XPropertySet") ) + { + if ( bHasXPropertySet ) { + return false; + } else { + bHasXPropertySet = true; + return true; + } + } + } + return false; +} + +void checkAddInTypes(TypeManager const & manager, + typereg::Reader const & reader) +{ + OString sType(codemaker::convertString(reader.getTypeName()).replace('/', '.')); + bool bLastAny = false; + bool bHasXPropertySet = false; + for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) { + OString sMethod(codemaker::convertString(reader.getMethodName(m))); + + OString sReturnType(codemaker::convertString( + reader.getMethodReturnTypeName(m))); + if ( !checkAddinType( + manager, sReturnType, bLastAny, bHasXPropertySet, true) ) + { + OStringBuffer msg("the return type of the calc add-in function '"); + msg.append(sType); + msg.append(":"); + msg.append(sMethod); + msg.append("' is invalid. Please check your IDL defintion."); + throw CannotDumpException(msg.makeStringAndClear()); + } + + bHasXPropertySet = false; + for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) { + bLastAny = false; + OString sParamType(codemaker::convertString( + reader.getMethodParameterTypeName(m, p))); + if ( !checkAddinType(manager, sParamType, + bLastAny, bHasXPropertySet, false) || + bLastAny ) + { + OStringBuffer msg("the type of the "); + msg.append((sal_Int32)p+1); + msg.append(". parameter of the calc add-in function '"); + msg.append(sType); + msg.append(":"); + msg.append(sMethod); + msg.append("' is invalid."); + if ( bLastAny ) + msg.append(" The type 'sequence<any>' is allowed as last " + "parameter only."); + if ( bHasXPropertySet ) + msg.append(" The type 'XPropertySet' is allowed only once."); + + msg.append(" Please check your IDL definition."); + throw CannotDumpException(msg.makeStringAndClear()); + } + } + } +} + +void generateFunctionParamterMap(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + ::codemaker::GeneratedTypeSet & generated, + bool bFirst) +{ + OString sType(codemaker::convertString(reader.getTypeName())); + if ( sType.equals("com/sun/star/uno/XInterface") || + sType.equals("com/sun/star/lang/XLocalizable") || + sType.equals("com/sun/star/lang/XServiceInfo") || + // the next three checks becomes obsolete when configuration is used + sType.equals("com/sun/star/sheet/XAddIn") || + sType.equals("com/sun/star/sheet/XCompatibilityNames") || + sType.equals("com/sun/star/lang/XServiceName") ) + { + return; + } + + // check if the specified add-in functions supports valid types + checkAddInTypes(manager, reader); + + for ( sal_uInt16 i = 0; i < reader.getSuperTypeCount(); ++i ) { + typereg::Reader super( + manager.getTypeReader( + codemaker::convertString( + reader.getSuperTypeName(i)))); + if ( !super.isValid() ) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString( + reader.getSuperTypeName(i))); + } + generateFunctionParamterMap(o, options, manager, super, generated, bFirst); + } + + OString type(codemaker::convertString(reader.getTypeName())); + if ( generated.contains(type) ) + return; + else + generated.add(type); + + for ( sal_uInt16 m = 0; m < reader.getMethodCount(); ++m ) { + OString sMethod(codemaker::convertString(reader.getMethodName(m))); + + if ( bFirst ) { + if (options.language == 2) { + o << " ParamMap fpm;\n"; + } + else { + if ( options.java5 ) + o << " java.util.Hashtable< Integer, String > fpm = " + "new java.util.Hashtable< Integer, String >();\n"; + else + o << " java.util.Hashtable fpm = " + "new java.util.Hashtable();\n"; + } + bFirst = false; + } else + if ( options.language == 2 ) { + o << " fpm = ParamMap();\n"; + } + else { + if ( options.java5 ) + o << " fpm = new java.util.Hashtable< " + "Integer, String >();\n"; + else + o << " fpm = new java.util.Hashtable();\n"; + } + + for ( sal_uInt16 p = 0; p < reader.getMethodParameterCount(m); ++p ) { + if ( options.language == 2 ) { + o << " fpm[" << p + << "] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"" + << codemaker::convertString(reader.getMethodParameterName(m, p)) + << "\"));\n"; + } + else { + if ( options.java5 ) + o << " fpm.put(" << p << ", \"" + << codemaker::convertString( + reader.getMethodParameterName(m, p)) + << "\");\n"; + else + o << " fpm.put(new Integer(" << p << "), \"" + << codemaker::convertString( + reader.getMethodParameterName(m, p)) + << "\");\n"; + } + } + + if ( options.language == 2 ) { + o << " m_functionMap[::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(\"" + << sMethod << "\"))] = fpm;\n\n"; + } + else { + o << " m_functionMap.put(\"" << sMethod << "\", fpm);\n\n"; + } + } +} + +void generateFunctionParameterMap(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + const boost::unordered_set< OString, OStringHash >& interfaces) +{ + ::codemaker::GeneratedTypeSet generated; + bool bFirst = true; + boost::unordered_set< OString, OStringHash >::const_iterator iter = interfaces.begin(); + while ( iter != interfaces.end() ) { + typereg::Reader reader(manager.getTypeReader((*iter).replace('.','/'))); + if (!reader.isValid()) { + throw CannotDumpException( + "Bad type library entity " + + codemaker::convertString( + reader.getTypeName())); + } + + generateFunctionParamterMap(o, options, manager, reader, generated, bFirst); + ++iter; + } +} + +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/skeletoncommon.hxx b/unodevtools/source/skeletonmaker/skeletoncommon.hxx new file mode 100644 index 000000000000..593b28504ae9 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletoncommon.hxx @@ -0,0 +1,170 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX +#define INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX + +#include "rtl/string.hxx" +#include "registry/reader.hxx" +#include "codemaker/typemanager.hxx" +#include "codemaker/unotype.hxx" + +#include <fstream> +#include <boost/unordered_set.hpp> +#include <map> + +namespace skeletonmaker { + +typedef ::std::map< ::rtl::OString, ::std::vector< ::rtl::OString >, + ::std::less< ::rtl::OString > > ProtocolCmdMap; + +typedef ::std::vector< ::std::pair< rtl::OString, + ::std::pair< rtl::OString, sal_Int16 > > > AttributeInfo; + + +struct ProgramOptions { + ProgramOptions(): java5(true), all(false), dump(false), license(false), + shortnames(false), supportpropertysetmixin(false), + backwardcompatible(false), language(1), componenttype(1) {} + + bool java5; + bool all; + bool dump; + bool license; + bool shortnames; + bool supportpropertysetmixin; + bool backwardcompatible; + // language specifier - is extendable + // 1 = Java + // 2 = C++ + short language; + // component type + // 1 = default UNO component - is extendable + // 2 = calc add-in + // 3 = add-on + short componenttype; + rtl::OString outputpath; + rtl::OString implname; + ProtocolCmdMap protocolCmdMap; +}; + + +/** + print the standard OpenOffice.org license header + + @param o specifies the output stream + @param filename specifies the source file name +*/ +void printLicenseHeader(std::ostream& o, rtl::OString const & filename); + +/** + create dependent on the output path, the implementation name and the + extension a new output file. If output path is equal "stdout" the tool + generates the output to standard out. + + @param options the program options including the output path and the + implementation name + @param extension specifies the file extensions (e.g. .cxx or .java) + @param ppOutputStream out parameter returning the output stream + @param targetSourceFileName out parameter returning the generated file name + constructed on base of the output path, the + implementation name and the extension + @param tmpSourceFileName out parameter returning the temporary file name based + on the output path and a generated temporary file name. + @return true if output is generated to standard out or else false +*/ +bool getOutputStream(ProgramOptions const & options, + rtl::OString const & extension, + std::ostream** ppOutputStream, + rtl::OString & targetSourceFileName, + rtl::OString & tmpSourceFileName); + +codemaker::UnoType::Sort decomposeResolveAndCheck( + TypeManager const & manager, rtl::OString const & type, + bool resolveTypedefs, bool allowVoid, bool allowExtraEntities, + RTTypeClass * typeClass, rtl::OString * name, sal_Int32 * rank, + std::vector< rtl::OString > * arguments); + +void checkType(TypeManager const & manager, + rtl::OString const & type, + boost::unordered_set< rtl::OString, rtl::OStringHash >& interfaceTypes, + boost::unordered_set< rtl::OString, rtl::OStringHash >& serviceTypes, + AttributeInfo& properties); + +void checkDefaultInterfaces( + boost::unordered_set< rtl::OString, rtl::OStringHash >& interfaces, + const boost::unordered_set< rtl::OString, rtl::OStringHash >& services, + const rtl::OString & propertyhelper); + +rtl::OString checkPropertyHelper( + ProgramOptions const & options, TypeManager const & manager, + const boost::unordered_set< rtl::OString, rtl::OStringHash >& services, + const boost::unordered_set< rtl::OString, rtl::OStringHash >& interfaces, + AttributeInfo& attributes, + boost::unordered_set< rtl::OString, rtl::OStringHash >& propinterfaces); + +/** + checks whether the return and parameters types are valid and allowed + calc add-in type. The function throws a CannotDumpException with an + detailed error description which type is wrong + + @param manager a type manager + @param reader a registry type reader of an interface defining + calc add-in functions +*/ +void checkAddInTypes(TypeManager const & manager, + typereg::Reader const & reader); + + +/** + checks if XComponent have to be supported, if yes it removes it from the + supported interfaces list becuase it becmoes implmented by the appropriate + helper + + @param manager a type manager + @param interfaces a list of interfaces which should be implemented + + @return true if XComponent have to be supported +*/ +bool checkXComponentSupport(TypeManager const & manager, + boost::unordered_set< rtl::OString, rtl::OStringHash >& interfaces); + + +sal_uInt16 checkAdditionalPropertyFlags(typereg::Reader const & reader, + sal_uInt16 field, sal_uInt16 method); + + +void generateFunctionParameterMap(std::ostream& o, + ProgramOptions const & options, + TypeManager const & manager, + const boost::unordered_set< ::rtl::OString, ::rtl::OStringHash >& interfaces); + +} + +#endif // INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/skeletoncpp.hxx b/unodevtools/source/skeletonmaker/skeletoncpp.hxx new file mode 100644 index 000000000000..803788cfb3c6 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletoncpp.hxx @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCPP_HXX +#define INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCPP_HXX + +#include <fstream> + +#include "codemaker/generatedtypeset.hxx" +#include "skeletoncommon.hxx" + +namespace skeletonmaker { namespace cpp { + +// referenceType +// 0 = no reference +// 1 = use of css::uno::Reference for interfaces +// 2 = reference (includes css::uno::Reference for interfaces) +// 4 = const reference (includes css::uno::Reference for interfaces) +// 8 = default construction for example for return types, means "return <type>();" +// 16 = default member initialization in a constructor +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + rtl::OString const & name, sal_Int32 rank, + std::vector< rtl::OString > const & arguments, + short referenceType, bool defaultvalue=false); + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + rtl::OString const & type, short referenceType, + bool defaultvalue=false); + + +bool printConstructorParameters(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + typereg::Reader const & outerReader, + std::vector< rtl::OString > const & arguments); + + +void printConstructor(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + std::vector< rtl::OString > const & arguments); + + +void printMethodParameters(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + sal_uInt16 method, bool previous, + bool withtype); + + +void printExceptionSpecification(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + sal_uInt16 method); + + +void printMethods(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, + codemaker::GeneratedTypeSet & generated, + rtl::OString const & delegate, + rtl::OString const & classname=rtl::OString(), + rtl::OString const & indentation=rtl::OString(), + bool defaultvalue=false, + rtl::OString const & propertyhelper=rtl::OString()); + + +void printConstructionMethods(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader); + + +void printServiceMembers(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + rtl::OString const & type, + rtl::OString const & delegate); + + +void printMapsToCppType(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + codemaker::UnoType::Sort sort, + RTTypeClass typeClass, + rtl::OString const & name, + sal_Int32 rank, + std::vector< rtl::OString > const & arguments, + const char * cppTypeSort); + + +void generateDocumentation(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + rtl::OString const & type, + rtl::OString const & delegate); + + +void generateSkeleton(ProgramOptions const & options, + TypeManager const & manager, + std::vector< rtl::OString > const & types, + rtl::OString const & delegate); + +void generateCalcAddin(ProgramOptions const & options, + TypeManager const & manager, + std::vector< rtl::OString > const & types); + +} } + +#endif // INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCPP_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/skeletonjava.hxx b/unodevtools/source/skeletonmaker/skeletonjava.hxx new file mode 100644 index 000000000000..e2c0c9e75539 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletonjava.hxx @@ -0,0 +1,118 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#ifndef INCLUDED_UNODEVTOOLS_SKELETONJAVA_HXX +#define INCLUDED_UNODEVTOOLS_SKELETONJAVA_HXX + +#include <fstream> + +#include "codemaker/generatedtypeset.hxx" +#include "skeletoncommon.hxx" + +namespace skeletonmaker { namespace java { + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + codemaker::UnoType::Sort sort, RTTypeClass typeClass, + rtl::OString const & name, sal_Int32 rank, + std::vector< rtl::OString > const & arguments, + bool referenceType, bool defaultvalue=false); + +void printType(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + rtl::OString const & type, bool referenceType, + bool defaultvalue=false); + +bool printConstructorParameters(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + typereg::Reader const & outerReader, + std::vector< rtl::OString > const & arguments); + +void printConstructor(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, + std::vector< rtl::OString > const & arguments); + +void printMethodParameters(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + sal_uInt16 method, bool previous, + bool withtype, + bool shortname=false); + +void printExceptionSpecification(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + sal_uInt16 method); + +void printMethods(std::ostream & o, + ProgramOptions const & options, TypeManager const & manager, + typereg::Reader const & reader, + codemaker::GeneratedTypeSet & generated, + rtl::OString const & delegate, + rtl::OString const & indentation=rtl::OString(), + bool defaultvalue=false, + bool usepropertymixin=false); + +void printConstructionMethods(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader); + +void printServiceMembers(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + typereg::Reader const & reader, + rtl::OString const & type, + rtl::OString const & delegate); + +void printMapsToJavaType(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + codemaker::UnoType::Sort sort, + RTTypeClass typeClass, + rtl::OString const & name, sal_Int32 rank, + std::vector< rtl::OString > const & arguments, + const char * javaTypeSort); + +void generateDocumentation(std::ostream & o, + ProgramOptions const & options, + TypeManager const & manager, + rtl::OString const & type, + rtl::OString const & delegate); + +void generateSkeleton(ProgramOptions const & options, TypeManager const & manager, std::vector< rtl::OString > const & types, rtl::OString const & delegate); + +} } + +#endif // INCLUDED_UNODEVTOOLS_SKELETONJAVA_HXX + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/skeletonmaker/skeletonmaker.cxx b/unodevtools/source/skeletonmaker/skeletonmaker.cxx new file mode 100644 index 000000000000..127411060105 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletonmaker.cxx @@ -0,0 +1,354 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +#include <iostream> + +#include "sal/main.h" +#include "rtl/process.h" +#include "rtl/ustrbuf.hxx" +#include "unodevtools/typemanager.hxx" +#include "unodevtools/options.hxx" +#include "skeletonjava.hxx" +#include "skeletoncpp.hxx" + +#include "com/sun/star/uno/Reference.hxx" + +using namespace ::rtl; +using namespace ::skeletonmaker; +using namespace ::unodevtools; +using namespace ::com::sun::star::uno; + +namespace { + +static const char usageText[] = +"\n sub-commands:\n" +" dump dump declarations on stdout (e.g. constructors, methods, type\n" +" mapping for properties) or complete method bodies with\n" +" method forwarding.\n" +" component generates language specific code skeleton files using the\n" +" implementation name as the file and class name\n" +" calc-add-in generates a language specific code skeleton for a calc add-in\n" +" using the implementation name as the file and class name. A \n" +" service type is necessary, referencing an interface which defines\n" +" the new add-in functions.\n" +" add-on generates a language specific code skeleton for an add-on compnent\n" +" using the implementation name as the file and class name. The protocol\n" +" name(s) and the corresponding command(s) have to be specified with the\n" +" '-p' option.\n" +"\n options:\n" +" -env:INIFILENAME=<url> url specifies a URL to an UNO ini|rc file of an\n" +" existing UNO environment (URE, office installation).\n" +" -env:UNO_TYPES=<url> url specifies a binary type library file. It can be\n" +" a space separated list of urls.\n" +" -a, --all list all interface methods, not only the direct\n" +" ones\n" +" --(java4|java5|cpp) select the target language\n" +" --java4 generate output for Java 1.4 or earlier\n" +" --java5 generate output for Java 1.5 or later (is \n" +" currently the default)\n" +" --cpp generate output for C++\n" +" -sn, --shortnames using namespace abbreviation 'css:': for\n" +" '::com::sun::star::', only valid for sub-command\n" +" 'dump' and target language 'cpp'. It is default for the\n" +" sub-command 'component'.\n" +" --propertysetmixin the generated skeleton implements the cppu::PropertySetMixin\n" +" helper if a referenced new style service specifies an\n" +" interface which provides attributes (directly or inherited).\n" +" -lh --licenseheader generates a default OpenOffice.org LGPL license\n" +" header at the beginning of a component source file.\n" +" This option is taken into account in 'component' mode\n" +" only and if -o is unequal 'stdout'.\n" +" -bc specifies that the generated calc add-in is backward\n" +" --backward-compatible compatible to older office versions and implement the\n" +" former required add-in interfaces where the implementation\n" +" is mapped on the new add-in configuration. In this case\n" +" the config schema needs to be bundled with the extension\n" +" add-in as well. Default is a minimal add-in component\n" +" skeleton based on the configuration coming with the\n" +" office since OO.org 2.0.4.\n" +" -o <path> path specifies an existing directory where the\n" +" output files are generated to, only valid for\n" +" sub-command 'component'. If path=stdout the generated\n" +" code is generated on standard out instead of a file.\n" +" -l <file> specifies a binary type library (can be used more\n" +" than once). The type library is integrated as an\n" +" additional type provider in the bootstrapped type\n" +" system.\n" +" -n <name> specifies an implementation name for the component\n" +" (used as classname, filename and package|namespace\n" +" name). In 'dump' mode it is used as classname (e.g.\n" +" \"MyBase::\", C++ only) to generate method bodies not\n" +" inline.\n" +" -d <name> specifies a base classname or a delegator.\n" +" In 'dump' mode it is used as a delegator to forward\n" +" methods. It can be used as '<name>::' for base\n" +" forwarding, or '<name>->|.' for composition.\n" +" Using \"_\" means that a default bodies with default\n" +" return values are dumped.\n" +" -t <name> specifies an UNOIDL type name, e.g.\n" +" com.sun.star.text.XText (can be used more than once)\n" +" -p <protocol:cmd(s)> specifies an add-on protocol name and the corresponding\n" +" command names, where the commands are a ',' separated list\n" +" of unique commands. This option is only valid for add-ons.\n" +" -V, --version print version number and exit\n" +" -h, --help print this help and exit\n\n"; + +void printUsageAndExit(const char* programname, const char* version) +{ + std::cerr + << "\n using: " << programname + << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" + << " dump [<options>] -t <type> ...\n" + << " " << programname + << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" + << " component [<options>] -n <name> -t <type> ...\n" + << " " << programname + << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" + << " calc-add-in [<options>] -n <name> -t <add-in_service>\n" + << " " << programname + << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" + << " add-on [<options>] -n <name> -p <protocol_name:command,...>\n" + << " " << programname << " -V, --version\n" + << " " << programname << " -h, --help\n" + << usageText + << programname << " Version " << version << "\n\n"; +} + +} + +SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, /*argv*/) +{ + const char* version = "0.4"; + const char* programname = "uno-skeletonmaker"; + + if ( argc <= 1 ) { + printUsageAndExit(programname, version); + exit(EXIT_FAILURE); + } + + ProgramOptions options; + std::vector< OUString > registries; + std::vector< OString > types; + OString delegate; + + try { + + sal_Int32 nPos = 0; + sal_Int32 nCount = (sal_Int32)rtl_getAppCommandArgCount(); + OUString arg, sOption; + sal_Bool bOption=sal_False; + + // check command + rtl_getAppCommandArg(nPos++, &arg.pData); + if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("dump"))) ) { + options.dump = true; + } else if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("component"))) ) { + options.dump = false; + options.shortnames = true; + } else if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("calc-add-in"))) ) { + options.dump = false; + options.shortnames = true; + options.componenttype = 2; + } else if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("add-on"))) ) { + options.dump = false; + options.shortnames = true; + options.componenttype = 3; + } else if ( readOption( &bOption, "h", &nPos, arg) || + readOption( &bOption, "help", &nPos, arg) ) { + printUsageAndExit(programname, version); + exit(EXIT_SUCCESS); + } else if ( readOption( &bOption, "V", &nPos, arg) || + readOption( &bOption, "version", &nPos, arg) ) { + std::cerr << "\n Sun Microsystems (R) " << programname + << " Version " << version << "\n\n"; + exit(EXIT_SUCCESS); + } else { + std::cerr + << "ERROR: unexpected command \"" + << OUStringToOString(arg, RTL_TEXTENCODING_UTF8).getStr() + << "\"!\n"; + printUsageAndExit(programname, version); + exit(EXIT_FAILURE); + } + + // read up to arguments + while ( nPos < nCount ) + { + rtl_getAppCommandArg(nPos, &arg.pData); + + if ( readOption( &bOption, "a", &nPos, arg) || + readOption( &bOption, "all", &nPos, arg) ) { + options.all = true; + continue; + } + if ( readOption( &bOption, "java4", &nPos, arg) ) { + options.java5 = false; + options.language = 1; + continue; + } + if ( readOption( &bOption, "java5", &nPos, arg) ) { + options.java5 = true; + options.language = 1; + continue; + } + if ( readOption( &bOption, "cpp", &nPos, arg) ) { + options.java5 = false; + options.language = 2; + continue; + } + if ( readOption( &bOption, "sn", &nPos, arg) || + readOption( &bOption, "shortnames", &nPos, arg) ) { + options.shortnames = true; + continue; + } + if ( readOption( &bOption, "lh", &nPos, arg) || + readOption( &bOption, "licenseheader", &nPos, arg) ) { + options.license = true; + continue; + } + if ( readOption( &bOption, "bc", &nPos, arg) || + readOption( &bOption, "backward-compatible", &nPos, arg) ) { + options.backwardcompatible = true; + continue; + } + if ( readOption( &bOption, "propertysetmixin", &nPos, arg) ) { + options.supportpropertysetmixin = true; + continue; + } + if ( readOption( &sOption, "d", &nPos, arg) ) { + delegate = OUStringToOString(sOption, RTL_TEXTENCODING_UTF8); + continue; + } + if ( readOption( &sOption, "n", &nPos, arg) ) { + options.implname = OUStringToOString(sOption, RTL_TEXTENCODING_UTF8); + continue; + } + if ( readOption( &sOption, "o", &nPos, arg) ) { + options.outputpath = OUStringToOString(sOption, RTL_TEXTENCODING_UTF8); + continue; + } + if ( readOption( &sOption, "l", &nPos, arg) ) { + registries.push_back(sOption); + continue; + } + if ( readOption( &sOption, "t", &nPos, arg) ) { + types.push_back(OUStringToOString(sOption, RTL_TEXTENCODING_UTF8)); + continue; + } + if ( readOption( &sOption, "p", &nPos, arg) ) { + OString sTmp(OUStringToOString(sOption, RTL_TEXTENCODING_UTF8)); + sal_Int32 nIndex= sTmp.indexOf(':'); + OString sPrt = sTmp.copy(0, nIndex+1); + OString sCmds = sTmp.copy(nIndex+1); + + nIndex = 0; + std::vector< OString > vCmds; + do { + OString sCmd = sCmds.getToken( 0, ',', nIndex ); + vCmds.push_back(sCmd); + } while ( nIndex >= 0 ); + + options.protocolCmdMap.insert(ProtocolCmdMap::value_type(sPrt, vCmds)); + continue; + } + + + // else illegal argument + OUStringBuffer buf( 64 ); + buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("unexpected parameter \"")); + buf.append(arg); + buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("\"!")); + throw RuntimeException(buf.makeStringAndClear(), + Reference< XInterface >()); + } + + if ( types.empty() && options.componenttype != 3) { + std::cerr + << ("\nError: no type is specified, use the -T option at least once\n"); + printUsageAndExit(programname, version); + exit(EXIT_FAILURE); + } + + UnoTypeManager manager; + if ( !manager.init(registries) ) { + std::cerr + << ("\nError: Using the binary type libraries failed, check the -L" + " options\n"); + exit(EXIT_FAILURE); + } + + if ( options.dump ) { + std::vector< OString >::const_iterator iter = types.begin(); + while (iter != types.end()) { + std::cout << "\n/***************************************************" + "*****************************/\n"; + switch (options.language ) + { + case 1: //Java + java::generateDocumentation(std::cout, options, manager, + *iter, delegate); + break; + case 2: //C++ + cpp::generateDocumentation(std::cout, options, manager, + *iter, delegate); + break; + default: + OSL_ASSERT(false); + break; + } + ++iter; + } + } else { + switch ( options.language ) + { + case 1: //Java + java::generateSkeleton(options, manager, types, delegate); + break; + case 2: //C++ + cpp::generateSkeleton(options, manager, types, delegate); + break; + default: + OSL_ASSERT(false); + break; + } + } + + } catch (CannotDumpException & e) { + std::cout.flush(); + std::cerr << "\nError: " << e.m_message << std::endl; + } catch(Exception& e) { + std::cout.flush(); + std::cerr + << "\nError: " + << OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() + << std::endl; + } + + return 0; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/unodevtools/makefile.mk b/unodevtools/source/unodevtools/makefile.mk new file mode 100644 index 000000000000..d8f0920ad827 --- /dev/null +++ b/unodevtools/source/unodevtools/makefile.mk @@ -0,0 +1,52 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* +PRJ=..$/.. + +PRJNAME=unodevtools +TARGET=unodevtools + + +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- +.INCLUDE : settings.mk + +# ------------------------------------------------------------------ + +SLOFILES= \ + $(SLO)$/typemanager.obj \ + $(SLO)$/typeblob.obj \ + $(SLO)$/options.obj + +LIB1TARGET=$(LB)$/$(TARGET).lib +LIB1ARCHIV=$(LB)$/lib$(TARGET).a +LIB1OBJFILES=$(SLOFILES) + +# ------------------------------------------------------------------ + +.INCLUDE : target.mk + diff --git a/unodevtools/source/unodevtools/options.cxx b/unodevtools/source/unodevtools/options.cxx new file mode 100644 index 000000000000..dbca5cb95f93 --- /dev/null +++ b/unodevtools/source/unodevtools/options.cxx @@ -0,0 +1,128 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include <stdio.h> + +#include "rtl/ustring.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/process.h" + +#include "com/sun/star/uno/RuntimeException.hpp" + +using namespace ::rtl; +using namespace ::com::sun::star::uno; + +namespace unodevtools { + +//------------------------------------------------------------------------------- +#if OSL_DEBUG_LEVEL > 1 +static void out( const sal_Char * pText ) +{ + fprintf( stderr, pText ); +} +#endif + +//------------------------------------------------------------------------------- +sal_Bool readOption( OUString * pValue, const sal_Char * pOpt, + sal_Int32 * pnIndex, const OUString & aArg) + throw (RuntimeException) +{ + const OUString dash = OUString(RTL_CONSTASCII_USTRINGPARAM("-")); + if(aArg.indexOf(dash) != 0) + return sal_False; + + OUString aOpt = OUString::createFromAscii( pOpt ); + + if (aArg.getLength() < aOpt.getLength()) + return sal_False; + + if (aOpt.equalsIgnoreAsciiCase( aArg.copy(1) )) { + // take next argument + ++(*pnIndex); + + rtl_getAppCommandArg(*pnIndex, &pValue->pData); + if (*pnIndex >= (sal_Int32)rtl_getAppCommandArgCount() || + pValue->copy(1).equals(dash)) + { + OUStringBuffer buf( 32 ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("incomplete option \"-") ); + buf.appendAscii( pOpt ); + buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" given!") ); + throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() ); + } else { +#if OSL_DEBUG_LEVEL > 1 + out( "\n> identified option -" ); + out( pOpt ); + out( " = " ); + OString tmp = OUStringToOString(*pValue, RTL_TEXTENCODING_ASCII_US); + out( tmp.getStr() ); +#endif + ++(*pnIndex); + return sal_True; + } + } else if (aArg.indexOf(aOpt) == 1) { + *pValue = aArg.copy(1 + aOpt.getLength()); +#if OSL_DEBUG_LEVEL > 1 + out( "\n> identified option -" ); + out( pOpt ); + out( " = " ); + OString tmp = OUStringToOString(*pValue, RTL_TEXTENCODING_ASCII_US); + out( tmp.getStr() ); +#endif + ++(*pnIndex); + + return sal_True; + } + return sal_False; +} + +//------------------------------------------------------------------------------- +sal_Bool readOption( sal_Bool * pbOpt, const sal_Char * pOpt, + sal_Int32 * pnIndex, const OUString & aArg) +{ + const OUString dashdash(RTL_CONSTASCII_USTRINGPARAM("--")); + const OUString dash(RTL_CONSTASCII_USTRINGPARAM("-")); + OUString aOpt = OUString::createFromAscii(pOpt); + + if((aArg.indexOf(dash) == 0 && aOpt.equalsIgnoreAsciiCase(aArg.copy(1))) || + (aArg.indexOf(dashdash) == 0 && aOpt.equalsIgnoreAsciiCase(aArg.copy(2))) ) + { + ++(*pnIndex); + *pbOpt = sal_True; +#if OSL_DEBUG_LEVEL > 1 + out( "\n> identified option --" ); + out( pOpt ); +#endif + return sal_True; + } + return sal_False; +} + +} // end of namespace unodevtools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/unodevtools/typeblob.cxx b/unodevtools/source/unodevtools/typeblob.cxx new file mode 100644 index 000000000000..9123bf13fff0 --- /dev/null +++ b/unodevtools/source/unodevtools/typeblob.cxx @@ -0,0 +1,810 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "rtl/alloc.h" +#include "registry/writer.hxx" + +#include "com/sun/star/beans/PropertyAttribute.hpp" +#include "com/sun/star/container/XHierarchicalNameAccess.hpp" +#include "com/sun/star/reflection/XPublished.hpp" +#include "com/sun/star/reflection/XInterfaceTypeDescription2.hpp" +#include "com/sun/star/reflection/XSingletonTypeDescription2.hpp" +#include "com/sun/star/reflection/XServiceTypeDescription2.hpp" +#include "com/sun/star/reflection/XStructTypeDescription.hpp" +#include "com/sun/star/reflection/XConstantsTypeDescription.hpp" +#include "com/sun/star/reflection/XConstantTypeDescription.hpp" +#include "com/sun/star/reflection/XModuleTypeDescription.hpp" +#include "com/sun/star/reflection/XInterfaceMethodTypeDescription.hpp" +#include "com/sun/star/reflection/XInterfaceAttributeTypeDescription2.hpp" +#include "com/sun/star/reflection/XMethodParameter.hpp" +#include "com/sun/star/reflection/XCompoundTypeDescription.hpp" +#include "com/sun/star/reflection/XIndirectTypeDescription.hpp" +#include "com/sun/star/reflection/XEnumTypeDescription.hpp" + +#include "codemaker/generatedtypeset.hxx" + +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; +using namespace com::sun::star::reflection; +using namespace codemaker; + +using ::rtl::OUString; +using ::rtl::OString; +using ::rtl::OStringToOUString; +using ::rtl::OUStringToOString; + +namespace unodevtools { + +void writeConstantData(typereg::Writer& rWriter, sal_uInt16 fieldIndex, + const Reference< XConstantTypeDescription >& xConstant) + +{ + RTConstValue constValue; + OUString uConstTypeName; + OUString uConstName = xConstant->getName(); + Any aConstantAny = xConstant->getConstantValue(); + + switch ( aConstantAny.getValueTypeClass() ) + { + case TypeClass_BOOLEAN: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("boolean")); + constValue.m_type = RT_TYPE_BOOL; + aConstantAny >>= constValue.m_value.aBool; + } + break; + case TypeClass_BYTE: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("byte")); + constValue.m_type = RT_TYPE_BYTE; + aConstantAny >>= constValue.m_value.aByte; + } + break; + case TypeClass_SHORT: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("short")); + constValue.m_type = RT_TYPE_INT16; + aConstantAny >>= constValue.m_value.aShort; + } + break; + case TypeClass_UNSIGNED_SHORT: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("unsigned short")); + constValue.m_type = RT_TYPE_UINT16; + aConstantAny >>= constValue.m_value.aUShort; + } + break; + case TypeClass_LONG: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("long")); + constValue.m_type = RT_TYPE_INT32; + aConstantAny >>= constValue.m_value.aLong; + } + break; + case TypeClass_UNSIGNED_LONG: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("unsigned long")); + constValue.m_type = RT_TYPE_UINT32; + aConstantAny >>= constValue.m_value.aULong; + } + break; + case TypeClass_FLOAT: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("float")); + constValue.m_type = RT_TYPE_FLOAT; + aConstantAny >>= constValue.m_value.aFloat; + } + break; + case TypeClass_DOUBLE: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("double")); + constValue.m_type = RT_TYPE_DOUBLE; + aConstantAny >>= constValue.m_value.aDouble; + } + break; + case TypeClass_STRING: + { + uConstTypeName = OUString(RTL_CONSTASCII_USTRINGPARAM("string")); + constValue.m_type = RT_TYPE_STRING; + constValue.m_value.aString = ((OUString*)aConstantAny.getValue())->getStr(); + } + break; + default: + OSL_FAIL( "unsupported constant type" ); + break; + } + + rWriter.setFieldData(fieldIndex, OUString(), OUString(), RT_ACCESS_CONST, + uConstName, uConstTypeName, constValue); +} + +sal_uInt32 getInheritedMemberCount( + GeneratedTypeSet& checkedTypes, + Sequence< Reference< XTypeDescription > >& superTypes) +{ + sal_uInt32 memberCount = 0; + + sal_uInt16 count = (sal_uInt16)superTypes.getLength(); + OString name; + for (sal_uInt16 i=0; i < count; i++) { + name = OString(OUStringToOString(superTypes[i]->getName(), + RTL_TEXTENCODING_UTF8)); + if (!checkedTypes.contains(name)) { + checkedTypes.add(name); + + Reference< XInterfaceTypeDescription2 > xIFace( + superTypes[i], UNO_QUERY); + + Sequence< Reference< XTypeDescription> > baseTypes = + xIFace->getBaseTypes(); + if ( baseTypes.getLength() > 0) + memberCount += getInheritedMemberCount(checkedTypes, baseTypes); + + memberCount += xIFace->getMembers().getLength(); + } + } + + return memberCount; +} + +void writeMethodData( typereg::Writer& rWriter, sal_uInt32 calculatedMemberOffset, + const Reference< XInterfaceMethodTypeDescription >& xMethod ) +{ + RTMethodMode methodMode = RT_MODE_TWOWAY; + if ( xMethod->isOneway() ) + methodMode = RT_MODE_ONEWAY; + + Sequence< Reference< XMethodParameter > > parameters(xMethod->getParameters()); + Sequence< Reference< XTypeDescription > > exceptions(xMethod->getExceptions()); + + OUString name(xMethod->getMemberName()); + sal_uInt16 methodIndex = (sal_uInt16)(xMethod->getPosition() + - calculatedMemberOffset); + sal_uInt16 paramCount = (sal_uInt16)parameters.getLength(); + sal_uInt16 exceptionCount = (sal_uInt16)exceptions.getLength(); + + rWriter.setMethodData(methodIndex, OUString(), methodMode, + xMethod->getMemberName(), + xMethod->getReturnType()->getName().replace('.', '/'), + paramCount, exceptionCount); + + RTParamMode paramMode = RT_PARAM_IN; + sal_uInt16 i; + + for ( i=0; i < paramCount; i++) { + Reference< XMethodParameter > xParam = parameters[i]; + if ( xParam->isIn() && xParam->isOut()) + paramMode = RT_PARAM_INOUT; + else if ( xParam->isIn() ) + paramMode = RT_PARAM_IN; + else if ( xParam->isOut() ) + paramMode = RT_PARAM_OUT; + + rWriter.setMethodParameterData(methodIndex, + (sal_uInt16)xParam->getPosition(), + paramMode, xParam->getName(), + xParam->getType()-> + getName().replace('.', '/')); + } + + for (i=0; i < exceptionCount; i++) { + rWriter.setMethodExceptionTypeName( + methodIndex, i, exceptions[i]->getName().replace('.', '/')); + } +} + +void writeAttributeMethodData( + typereg::Writer& rWriter, sal_uInt16& methodindex, RTMethodMode methodmode, + const Reference<XInterfaceAttributeTypeDescription2>& xAttr) +{ + Sequence<Reference<XCompoundTypeDescription> > seqExcp; + if (methodmode == RT_MODE_ATTRIBUTE_GET) + seqExcp = xAttr->getGetExceptions(); + else + seqExcp = xAttr->getSetExceptions(); + + if (seqExcp.getLength() > 0) { + rWriter.setMethodData(methodindex, OUString(), methodmode, + xAttr->getMemberName(), + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("void")), + 0, (sal_uInt16)seqExcp.getLength()); + + for (sal_Int32 i=0; i < seqExcp.getLength(); i++) { + rWriter.setMethodExceptionTypeName( + methodindex, (sal_uInt16)i, + seqExcp[i]->getName().replace('.', '/')); + } + ++methodindex; + } +} + +RTFieldAccess checkParameterizedTypeFlag(const Sequence< OUString >& typeParams, + const OUString & memberType) +{ + for (sal_uInt16 i=0; i < typeParams.getLength(); i++) { + if (typeParams[i].equals(memberType)) + return RT_ACCESS_PARAMETERIZED_TYPE; + } + + return RT_ACCESS_READWRITE; +} + +RTFieldAccess checkPropertyFlags(short flags) { + RTFieldAccess propertyFlags=RT_ACCESS_INVALID; + switch(flags) { + case PropertyAttribute::MAYBEVOID: + propertyFlags |= RT_ACCESS_MAYBEVOID; + case PropertyAttribute::BOUND: + propertyFlags |= RT_ACCESS_BOUND; + case PropertyAttribute::CONSTRAINED: + propertyFlags |= RT_ACCESS_CONSTRAINED; + case PropertyAttribute::TRANSIENT: + propertyFlags |= RT_ACCESS_TRANSIENT; + case PropertyAttribute::READONLY : + propertyFlags |= RT_ACCESS_READONLY; + case PropertyAttribute::MAYBEAMBIGUOUS: + propertyFlags |= RT_ACCESS_MAYBEAMBIGUOUS; + case PropertyAttribute::MAYBEDEFAULT: + propertyFlags |= RT_ACCESS_MAYBEDEFAULT; + case PropertyAttribute::REMOVEABLE: + propertyFlags |= RT_ACCESS_REMOVEABLE; + case PropertyAttribute::OPTIONAL: + propertyFlags |= RT_ACCESS_OPTIONAL; + } + return propertyFlags; +} + +void* getTypeBlob(Reference< XHierarchicalNameAccess > xTDmgr, + const OString& typeName, sal_uInt32* blobsize) +{ + if ( typeName.getLength() == 0 ) + return NULL; + + OUString uTypeName(OStringToOUString(typeName, RTL_TEXTENCODING_UTF8) + .replace('/', '.')); + + Any aTypeAny( xTDmgr->getByHierarchicalName( uTypeName ) ); + + if ( !aTypeAny.hasValue() ) + return NULL; + + Reference< XTypeDescription > xType; + aTypeAny >>= xType; + + if ( !xType.is() ) + return NULL; + + Reference< XPublished > xPublished(xType, UNO_QUERY); + void* pBlob = NULL; + switch (xType->getTypeClass()) + { + case TypeClass_CONSTANTS: + { + Reference< XConstantsTypeDescription > xCFace(xType, UNO_QUERY); + + if ( !xCFace.is() ) + return NULL; + + Sequence< Reference< XConstantTypeDescription > > constTypes( + xCFace->getConstants()); + sal_uInt16 constCount = (sal_uInt16)constTypes.getLength(); + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_CONSTANTS, xPublished->isPublished(), + uTypeName.replace('.', '/'), + 0, constCount, 0, 0); + + for (sal_uInt16 i=0; i < constCount; i++) + writeConstantData(writer, i, constTypes[i]); + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_MODULE: + { + Reference< XModuleTypeDescription > xMFace(xType, UNO_QUERY); + + if ( !xMFace.is() ) + return NULL; + + Sequence< Reference< XTypeDescription > > memberTypes( + xMFace->getMembers()); + + sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength(); + sal_uInt16 constCount = 0; + sal_Int16 i; + + for ( i=0; i < memberCount; i++) { + if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() ) + constCount++; + } + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_MODULE, xPublished->isPublished(), + uTypeName.replace('.', '/'), + 0, constCount, 0, 0); + + if ( 0 < constCount ) { + Reference< XConstantTypeDescription > xConst; + sal_uInt16 fieldIndex = 0; + for (i=0; i < memberCount; i++) { + if ( TypeClass_CONSTANT == memberTypes[i]->getTypeClass() ) { + xConst = Reference< XConstantTypeDescription >( + memberTypes[i], UNO_QUERY); + + writeConstantData(writer, ++fieldIndex, xConst); + } + } + } + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_INTERFACE: + { + Reference< XInterfaceTypeDescription2 > xIFace(xType, UNO_QUERY); + + if ( !xIFace.is() ) + return NULL; + + Reference< XInterfaceAttributeTypeDescription2 > xAttr; + Reference< XInterfaceMethodTypeDescription > xMethod; + Sequence< Reference< XInterfaceMemberTypeDescription > > memberTypes( + xIFace->getMembers()); + Sequence< Reference< XTypeDescription > > baseTypes = + xIFace->getBaseTypes(); + Sequence< Reference< XTypeDescription > > optBaseTypes = + xIFace->getOptionalBaseTypes(); + + sal_uInt16 baseCount = (sal_uInt16)baseTypes.getLength(); + sal_uInt16 optBaseCount = (sal_uInt16)optBaseTypes.getLength(); + sal_uInt16 memberCount = (sal_uInt16)memberTypes.getLength(); + sal_uInt16 attrCount = 0, attrmethods = 0; + sal_uInt16 inheritedMemberCount = 0; + sal_uInt16 i; + + for (i=0; i < memberCount; i++) { + xAttr = Reference< XInterfaceAttributeTypeDescription2 >( + memberTypes[i], UNO_QUERY); + if ( xAttr.is() ) { + attrCount++; + + if (xAttr->getGetExceptions().getLength() > 0) + attrmethods++; + + if (xAttr->getSetExceptions().getLength() > 0) + attrmethods++; + } + } + + // check inherited members count + if (baseCount > 0) { + GeneratedTypeSet checkedTypes; + inheritedMemberCount = (sal_uInt16)getInheritedMemberCount( + checkedTypes, baseTypes ); + } + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_INTERFACE, xPublished->isPublished(), + uTypeName.replace('.', '/'), + baseCount, attrCount, memberCount-attrCount+attrmethods, + (sal_uInt16)optBaseTypes.getLength()); + + // set super types + for (i=0; i < baseCount; i++) { + writer.setSuperTypeName(i, baseTypes[i]-> + getName().replace('.', '/')); + } + + // set optional super types + RTReferenceType referenceType = RT_REF_SUPPORTS; + RTFieldAccess fieldAccess = RT_ACCESS_OPTIONAL; + for (i=0; i < optBaseCount; i++) { + writer.setReferenceData(i, OUString(), referenceType, + fieldAccess, optBaseTypes[i]-> + getName().replace('.', '/')); + } + + fieldAccess = RT_ACCESS_READWRITE; + // reset attrCount, used for method index calculation + attrCount = 0; + attrmethods = 0; + for (i=0; i < memberCount; i++) { + xAttr = Reference< XInterfaceAttributeTypeDescription2 >( + memberTypes[i], UNO_QUERY); + if ( xAttr.is() ) { + ++attrCount; + if (xAttr->isReadOnly()) + fieldAccess = RT_ACCESS_READONLY; + else + fieldAccess = RT_ACCESS_READWRITE; + + if (xAttr->isBound()) + fieldAccess |= RT_ACCESS_BOUND; + + writer.setFieldData((sal_uInt16)memberTypes[i]->getPosition() + - inheritedMemberCount, + OUString(), OUString(), fieldAccess, + memberTypes[i]->getMemberName(), + xAttr->getType()->getName().replace('.','/'), + RTConstValue()); + + writeAttributeMethodData(writer, attrmethods, + RT_MODE_ATTRIBUTE_GET, xAttr); + if (!xAttr->isReadOnly()) { + writeAttributeMethodData(writer, attrmethods, + RT_MODE_ATTRIBUTE_SET, xAttr); + } + + continue; + } + + xMethod = Reference< XInterfaceMethodTypeDescription >( + memberTypes[i], UNO_QUERY); + if ( xMethod.is() ) { + writeMethodData(writer, attrCount+inheritedMemberCount-attrmethods, + xMethod); + } + } + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_STRUCT: + { + Reference< XStructTypeDescription > xStruct(xType, UNO_QUERY); + + if ( !xStruct.is() ) + return NULL; + + if ( xStruct->getTypeArguments().getLength() > 0) + return NULL; + + + Sequence< OUString > typeParams( xStruct->getTypeParameters()); + Sequence< OUString > memberNames( xStruct->getMemberNames()); + Sequence< Reference< XTypeDescription > > memberTypes( + xStruct->getMemberTypes()); + sal_uInt16 memberCount = (sal_uInt16)memberNames.getLength(); + + OUString uSuperType; + sal_uInt16 superCount=0; + if ( typeParams.getLength() == 0) { + Reference< XTypeDescription > xSuperType = xStruct->getBaseType(); + if ( xSuperType.is() ) { + ++superCount; + uSuperType = xSuperType->getName().replace('.','/'); + } + } + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_STRUCT, xPublished->isPublished(), + uTypeName.replace('.', '/'), + superCount, memberCount, 0, + (sal_uInt16)typeParams.getLength()); + + // set super type + if (superCount > 0) { + writer.setSuperTypeName(0, uSuperType); + } + + sal_uInt16 i=0; + for (i=0; i < memberCount; i++) { + RTFieldAccess fieldAccess = RT_ACCESS_READWRITE; + if (typeParams.getLength() > 0) + fieldAccess |= checkParameterizedTypeFlag( + typeParams, memberTypes[i]->getName()); + + writer.setFieldData(i, OUString(), OUString(), fieldAccess, + memberNames[i], + memberTypes[i]->getName().replace('.', '/'), + RTConstValue()); + } + + for (i=0; i < typeParams.getLength(); i++) { + writer.setReferenceData(i, OUString(), RT_REF_TYPE_PARAMETER, + RT_ACCESS_INVALID, typeParams[i]); + } + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_EXCEPTION: + { + Reference< XCompoundTypeDescription > xComp(xType, UNO_QUERY); + + if ( !xComp.is() ) + return NULL; + + Sequence< OUString > memberNames( xComp->getMemberNames()); + Sequence< Reference< XTypeDescription > > memberTypes( + xComp->getMemberTypes()); + sal_uInt16 memberCount = (sal_uInt16)memberNames.getLength(); + + OUString uSuperType; + sal_uInt16 superCount=0; + Reference< XTypeDescription > xSuperType = xComp->getBaseType(); + if ( xSuperType.is() ) { + ++superCount; + uSuperType = xSuperType->getName().replace('.','/'); + } + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_EXCEPTION, xPublished->isPublished(), + uTypeName.replace('.', '/'), + superCount, memberCount, 0, 0); + + // set super type + if (superCount > 0) { + writer.setSuperTypeName(0, uSuperType); + } + + for (sal_Int16 i=0; i < memberCount; i++) { + writer.setFieldData(i, OUString(), OUString(), RT_ACCESS_READWRITE, + memberNames[i], + memberTypes[i]->getName().replace('.', '/'), + RTConstValue()); + } + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_ENUM: + { + Reference< XEnumTypeDescription > xEnum(xType, UNO_QUERY); + + if ( !xEnum.is() ) + return NULL; + + Sequence< OUString > enumNames( xEnum->getEnumNames()); + Sequence< sal_Int32 > enumValues( xEnum->getEnumValues()); + sal_uInt16 enumCount = (sal_uInt16)enumNames.getLength(); + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_ENUM, xPublished->isPublished(), + uTypeName.replace('.', '/'), + 0, enumCount, 0, 0); + + RTConstValue constValue; + for (sal_Int16 i=0; i < enumCount; i++) { + constValue.m_type = RT_TYPE_INT32; + constValue.m_value.aLong = enumValues[i]; + + writer.setFieldData(i, OUString(), OUString(), + RT_ACCESS_CONST, enumNames[i], + OUString(), constValue); + } + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_TYPEDEF: + { + Reference< XIndirectTypeDescription > xTD(xType, UNO_QUERY); + + if ( !xTD.is() ) + return NULL; + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_TYPEDEF, xPublished->isPublished(), + uTypeName.replace('.', '/'), + 1, 0, 0, 0); + + writer.setSuperTypeName(0, xTD->getReferencedType() + ->getName().replace('.','/')); + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_SERVICE: + { + Reference< XServiceTypeDescription2 > xService(xType, UNO_QUERY); + + if ( !xService.is() ) + return NULL; + + Sequence<Reference<XServiceConstructorDescription> > constructors( + xService->getConstructors()); + Sequence<Reference<XPropertyTypeDescription> > properties; + Sequence<Reference<XServiceTypeDescription> > mandatoryServices; + Sequence<Reference<XServiceTypeDescription> > optionalServices; + Sequence<Reference<XInterfaceTypeDescription> > mandatoryInterfaces; + Sequence<Reference<XInterfaceTypeDescription> > optionalInterfaces; + sal_uInt16 methodCount = (sal_uInt16)constructors.getLength(); + sal_uInt16 referenceCount = 0; + sal_uInt16 propertyCount = 0; + + if ( !xService->isSingleInterfaceBased() ) { + mandatoryServices = xService->getMandatoryServices(); + optionalServices = xService->getOptionalServices(); + mandatoryInterfaces = xService->getMandatoryInterfaces(); + optionalInterfaces = xService->getOptionalInterfaces(); + properties = xService->getProperties(); + referenceCount = (sal_uInt16)( + mandatoryServices.getLength()+ + optionalServices.getLength()+ + mandatoryInterfaces.getLength()+ + optionalInterfaces.getLength()); + propertyCount = (sal_uInt16)properties.getLength(); + } + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_SERVICE, xPublished->isPublished(), + uTypeName.replace('.', '/'), + (xService->isSingleInterfaceBased() ? 1 : 0), + propertyCount, methodCount, referenceCount); + + sal_uInt16 i=0; + if ( xService->isSingleInterfaceBased() ) { + writer.setSuperTypeName(0, xService->getInterface() + ->getName().replace('.','/')); + + sal_uInt16 j=0; + for ( i=0; i<methodCount; i++ ) { + Reference<XServiceConstructorDescription> xConstructor( + constructors[i], UNO_QUERY); + Sequence<Reference<XParameter> > parameters; + Sequence<Reference<XCompoundTypeDescription> > exceptions; + sal_uInt16 parameterCount=0; + sal_uInt16 exceptionCount=0; + if ( !xConstructor->isDefaultConstructor() ) { + parameters = xConstructor->getParameters(); + parameterCount = (sal_uInt16)parameters.getLength(); + } + + writer.setMethodData(i, OUString(), RT_MODE_TWOWAY, + xConstructor->getName(), + OUString( + RTL_CONSTASCII_USTRINGPARAM("void")), + parameterCount, exceptionCount); + + if ( !xConstructor->isDefaultConstructor() ) { + for ( j=0; j<parameterCount; j++ ) { + Reference<XParameter> xParam(parameters[j], UNO_QUERY); + RTParamMode paramMode = RT_PARAM_IN; + if (xParam->isRestParameter()) + paramMode = RT_PARAM_REST; + + writer.setMethodParameterData( + i, (sal_uInt16)xParam->getPosition(), + paramMode, xParam->getName(), + xParam->getType()->getName().replace('.', '/')); + } + + for (j=0; j<exceptionCount; j++) { + Reference<XCompoundTypeDescription> xExcp( + exceptions[j], UNO_QUERY); + + writer.setMethodExceptionTypeName( + i, j, xExcp->getName().replace('.', '/')); + } + } + } + } else + { + for (i=0; i<propertyCount; i++) { + Reference<XPropertyTypeDescription> xProp( + properties[i], UNO_QUERY); + + RTFieldAccess propertyFlags = checkPropertyFlags( + xProp->getPropertyFlags()); + + writer.setFieldData(i, OUString(), OUString(), + propertyFlags, + xProp->getName().copy(xProp->getName().lastIndexOf('.')+1), + xProp->getPropertyTypeDescription() + ->getName().replace('.', '/'), + RTConstValue()); + } + + sal_uInt16 refIndex = 0; + sal_uInt16 length = (sal_uInt16)mandatoryServices.getLength(); + for (i=0; i < length; i++) { + writer.setReferenceData(refIndex++, OUString(), + RT_REF_EXPORTS, RT_ACCESS_INVALID, + mandatoryServices[i]->getName() + .replace('.', '/')); + } + length = (sal_uInt16)optionalServices.getLength(); + for (i=0; i < length; i++) { + writer.setReferenceData(refIndex++, OUString(), + RT_REF_EXPORTS, RT_ACCESS_OPTIONAL, + optionalServices[i]->getName() + .replace('.', '/')); + } + length = (sal_uInt16)mandatoryInterfaces.getLength(); + for (i=0; i < length; i++) { + writer.setReferenceData(refIndex++, OUString(), + RT_REF_SUPPORTS, RT_ACCESS_INVALID, + mandatoryInterfaces[i]->getName() + .replace('.', '/')); + } + length = (sal_uInt16)optionalInterfaces.getLength(); + for (i=0; i < length; i++) { + writer.setReferenceData(refIndex++, OUString(), + RT_REF_SUPPORTS, RT_ACCESS_OPTIONAL, + optionalInterfaces[i]->getName() + .replace('.', '/')); + } + } + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + case TypeClass_SINGLETON: + { + Reference<XSingletonTypeDescription2> xSingleton(xType, UNO_QUERY); + + if ( !xSingleton.is() ) + return NULL; + + typereg::Writer writer(TYPEREG_VERSION_1, OUString(), OUString(), + RT_TYPE_SINGLETON, xPublished->isPublished(), + uTypeName.replace('.', '/'), + 1, 0, 0, 0); + + if (xSingleton->isInterfaceBased()) { + writer.setSuperTypeName(0, xSingleton->getInterface() + ->getName().replace('.','/')); + } else { + writer.setSuperTypeName(0, xSingleton->getService() + ->getName().replace('.','/')); + } + + const void* p = writer.getBlob(blobsize); + pBlob = (sal_uInt8*)rtl_allocateMemory(*blobsize); + rtl_copyMemory(pBlob, p, *blobsize); + } + break; + default: + OSL_FAIL( "unsupported type" ); + break; + } + + return pBlob; +} + +} // end of namespace unodevtools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/source/unodevtools/typemanager.cxx b/unodevtools/source/unodevtools/typemanager.cxx new file mode 100644 index 000000000000..db84a965339b --- /dev/null +++ b/unodevtools/source/unodevtools/typemanager.cxx @@ -0,0 +1,284 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "unodevtools/typemanager.hxx" + +#include "rtl/alloc.h" +#include "registry/reader.hxx" +#include "cppuhelper/bootstrap.hxx" + +#include "com/sun/star/container/XSet.hpp" +#include "com/sun/star/reflection/XTypeDescription.hpp" +#include "com/sun/star/registry/XSimpleRegistry.hpp" +#include "com/sun/star/uno/XComponentContext.hpp" + +using namespace ::rtl; +using namespace ::cppu; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::registry; +using namespace ::com::sun::star::reflection; + +namespace unodevtools { + +static RTTypeClass mapTypeClass(TypeClass typeclass) { + switch(typeclass) { + case TypeClass_ENUM: + return RT_TYPE_ENUM; + case TypeClass_TYPEDEF: + return RT_TYPE_TYPEDEF; + case TypeClass_STRUCT: + return RT_TYPE_STRUCT; + case TypeClass_UNION: + return RT_TYPE_UNION; + case TypeClass_EXCEPTION: + return RT_TYPE_EXCEPTION; + case TypeClass_INTERFACE: + return RT_TYPE_INTERFACE; + case TypeClass_SERVICE: + return RT_TYPE_SERVICE; + case TypeClass_MODULE: + return RT_TYPE_MODULE; + case TypeClass_CONSTANTS: + return RT_TYPE_CONSTANTS; + case TypeClass_SINGLETON: + return RT_TYPE_SINGLETON; + default: + break; + } + return RT_TYPE_INVALID; +} + + +UnoTypeManager::UnoTypeManager() +{ + m_pImpl = new UnoTypeManagerImpl(); + acquire(); +} + +UnoTypeManager::~UnoTypeManager() +{ + release(); +} + +void UnoTypeManager::release() +{ + if (0 == TypeManager::release()) + delete m_pImpl; +} + +sal_Bool UnoTypeManager::init( + const ::std::vector< ::rtl::OUString > registries) +{ + Reference< XComponentContext > xContext= + defaultBootstrap_InitialComponentContext(); + + if ( !xContext.is() ) { + OUString msg(RTL_CONSTASCII_USTRINGPARAM( + "internal UNO problem, can't create initial UNO component context")); + throw RuntimeException( msg, Reference< XInterface >()); + } + Any a = xContext->getValueByName( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "/singletons/com.sun.star.reflection.theTypeDescriptionManager"))); + + a >>= m_pImpl->m_tdmgr; + + if ( !m_pImpl->m_tdmgr.is() ) { + OUString msg(RTL_CONSTASCII_USTRINGPARAM( + "internal UNO problem, can't get TypeDescriptionManager")); + throw RuntimeException( msg, Reference< XInterface >()); + } + + if ( !registries.empty() ) { + + Reference< XMultiComponentFactory > xServiceManager( + xContext->getServiceManager() ); + if ( !xServiceManager.is() ) { + OUString msg(RTL_CONSTASCII_USTRINGPARAM( + "internal UNO problem, can't get ServiceManager")); + throw RuntimeException( msg, Reference< XInterface >()); + } + + Sequence<Any> seqArgs(registries.size()); + + std::vector< OUString >::const_iterator iter = registries.begin(); + int i = 0; + while ( iter != registries.end() ) + { + Reference< XSimpleRegistry > xReg( + xServiceManager->createInstanceWithContext( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.registry.SimpleRegistry")), + xContext), UNO_QUERY); + xReg->open(convertToFileUrl( + OUStringToOString(*iter, RTL_TEXTENCODING_UTF8)), + sal_True, sal_False); + + seqArgs[i++] = makeAny(xReg); + ++iter; + } + + Reference< XHierarchicalNameAccess > xTDProvider( + xServiceManager->createInstanceWithArgumentsAndContext( + OUString(RTL_CONSTASCII_USTRINGPARAM( + "com.sun.star.reflection.TypeDescriptionProvider")), + seqArgs, xContext), + UNO_QUERY); + if ( !xTDProvider.is() ) { + OUString msg(RTL_CONSTASCII_USTRINGPARAM( + "internal UNO problem, can't create local" + " type description provider")); + throw RuntimeException( msg, Reference< XInterface >()); + } + + a = makeAny(xTDProvider); + Reference< XSet > xSet(m_pImpl->m_tdmgr, UNO_QUERY); + xSet->insert(a); + } + + return sal_True; +} + +sal_Bool UnoTypeManager::isValidType(const ::rtl::OString& name) const +{ + return m_pImpl->m_tdmgr->hasByHierarchicalName( + OStringToOUString(name, RTL_TEXTENCODING_UTF8)); +} + +OString UnoTypeManager::getTypeName(RegistryKey& rTypeKey) const +{ + OString typeName = OUStringToOString(rTypeKey.getName(), RTL_TEXTENCODING_UTF8); + static OString sBase("/UCR"); + if (typeName.indexOf(sBase) == 0) { + typeName = typeName.copy(typeName.indexOf('/', 1) + 1); + } else { + typeName = typeName.copy(1); + } + return typeName; +} + +// extern +void* getTypeBlob(Reference< XHierarchicalNameAccess > xTDmgr, + const OString& typeName, sal_uInt32* pBlob); + +typereg::Reader UnoTypeManager::getTypeReader( + const OString& name, sal_Bool * /*pIsExtraType*/ ) const +{ + typereg::Reader reader; + + void* pBlob = NULL; + sal_uInt32 blobsize = 0; + + if ( (pBlob = getTypeBlob(m_pImpl->m_tdmgr, name, &blobsize)) != NULL ) + reader = typereg::Reader(pBlob, blobsize, sal_True, TYPEREG_VERSION_1); + + if ( pBlob ) + rtl_freeMemory(pBlob); + + return reader; +} + +typereg::Reader UnoTypeManager::getTypeReader(RegistryKey& rTypeKey) const +{ + typereg::Reader reader; + + if (rTypeKey.isValid()) { + RegValueType valueType; + sal_uInt32 valueSize; + + if (!rTypeKey.getValueInfo(OUString(), &valueType, &valueSize)) { + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if ( !rTypeKey.getValue(OUString(), pBuffer) ) { + reader = typereg::Reader( + pBuffer, valueSize, true, TYPEREG_VERSION_1); + } + rtl_freeMemory(pBuffer); + } + } + return reader; +} + + +RTTypeClass UnoTypeManager::getTypeClass(const OString& name) const +{ + if ( m_pImpl->m_t2TypeClass.count(name) > 0 ) { + return m_pImpl->m_t2TypeClass[name]; + } else { + Reference< XTypeDescription > xTD; + Any a = m_pImpl->m_tdmgr->getByHierarchicalName( + OStringToOUString(name, RTL_TEXTENCODING_UTF8)); + a >>= xTD; + + if ( xTD.is() ) { + RTTypeClass tc = mapTypeClass(xTD->getTypeClass()); + if (tc != RT_TYPE_INVALID) + m_pImpl->m_t2TypeClass[name] = tc; + return tc; + } + } + + return RT_TYPE_INVALID; +} + +RTTypeClass UnoTypeManager::getTypeClass(RegistryKey& rTypeKey) const +{ + OString name = getTypeName(rTypeKey); + + if ( m_pImpl->m_t2TypeClass.count(name) > 0 ) { + return m_pImpl->m_t2TypeClass[name]; + } else { + if ( rTypeKey.isValid() ) { + RegValueType valueType; + sal_uInt32 valueSize; + + if ( !rTypeKey.getValueInfo(OUString(), &valueType, &valueSize) ) { + sal_uInt8* pBuffer = (sal_uInt8*)rtl_allocateMemory(valueSize); + if ( !rTypeKey.getValue(OUString(), pBuffer) ) { + typereg::Reader reader( + pBuffer, valueSize, false, TYPEREG_VERSION_1); + + RTTypeClass ret = reader.getTypeClass(); + + rtl_freeMemory(pBuffer); + + m_pImpl->m_t2TypeClass[name] = ret; + return ret; + } + rtl_freeMemory(pBuffer); + } + } + } + + return RT_TYPE_INVALID; +} + +} // end of namespace unodevtools + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/unodevtools/unodevtools.pmk b/unodevtools/unodevtools.pmk new file mode 100755 index 000000000000..c2d119c205c7 --- /dev/null +++ b/unodevtools/unodevtools.pmk @@ -0,0 +1,55 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +.IF "$(GUI)"=="WNT" +UNODEVTOOLSLIBDEPN=unodevtools.lib +CODEMAKERLIBDEPN=codemaker.lib +COMMONCPPLIBDEPN=commoncpp.lib +COMMONJAVALIBDEPN=commonjava.lib +.IF "$(COM)"=="GCC" +UNODEVTOOLSLIBST=-lunodevtools +CODEMAKERLIBST=-lcodemaker +COMMONCPPLIBST=-lcommoncpp +COMMONJAVALIBST=-lcommonjava +.ELSE +UNODEVTOOLSLIBST=unodevtools.lib +CODEMAKERLIBST=codemaker.lib +COMMONCPPLIBST=commoncpp.lib +COMMONJAVALIBST=commonjava.lib +.ENDIF + +.ELSE +UNODEVTOOLSLIBDEPN=libunodevtools.a +CODEMAKERLIBDEPN=libcodemaker.a +COMMONCPPLIBDEPN=libcommoncpp.a +COMMONJAVALIBDEPN=libcommonjava.a +UNODEVTOOLSLIBST=-lunodevtools +CODEMAKERLIBST=-lcodemaker +COMMONCPPLIBST=-lcommoncpp +COMMONJAVALIBST=-lcommonjava +.ENDIF + |