diff options
Diffstat (limited to 'unodevtools/source/skeletonmaker')
-rw-r--r-- | unodevtools/source/skeletonmaker/cppcompskeleton.cxx | 1277 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/cpptypemaker.cxx | 971 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/javacompskeleton.cxx | 997 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/javatypemaker.cxx | 876 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/makefile.mk | 57 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/skeletoncommon.cxx | 722 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/skeletoncommon.hxx | 168 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/skeletoncpp.hxx | 142 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/skeletonjava.hxx | 116 | ||||
-rw-r--r-- | unodevtools/source/skeletonmaker/skeletonmaker.cxx | 352 |
10 files changed, 5678 insertions, 0 deletions
diff --git a/unodevtools/source/skeletonmaker/cppcompskeleton.cxx b/unodevtools/source/skeletonmaker/cppcompskeleton.cxx new file mode 100644 index 000000000000..1c74e4b1ad2b --- /dev/null +++ b/unodevtools/source/skeletonmaker/cppcompskeleton.cxx @@ -0,0 +1,1277 @@ +/************************************************************************* + * + * 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 std::hash_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"; + } + + std::hash_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 std::hash_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"; + + std::hash_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\" void SAL_CALL component_getImplementationEnvironment(\n" + << " const char ** envTypeName, uno_Environment **)\n{\n" + << " *envTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;\n}\n\n"; + + o << "extern \"C\" 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 std::hash_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::createFromAscii(\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::createFromAscii(\"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::createFromAscii(\"locale\");\n" + " aArgument.Value <<= ::rtl::OUString::createFromAscii(\"*\");\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::createFromAscii(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, + std::hash_set< OString, OStringHash > const & interfaces, + AttributeInfo const & properties, + AttributeInfo const & attributes, + std::hash_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() << "<"; + } + + std::hash_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("< "); + std::hash_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"; + } + + std::hash_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 std::hash_map< ::sal_Int32, rtl::OUString, " + "std::hash<::sal_Int32> > ParamMap;\n" + " typedef std::hash_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() << "<"; + std::hash_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, + std::hash_set< OString, OStringHash > const & interfaces, + OString const & classname, + OString const & comphelpernamespace, + OString const & propertyhelper) +{ + OString name(classname.concat("::")); + std::hash_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 std::hash_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 << "<"; + std::hash_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; + } + + std::hash_set< OString, OStringHash > interfaces; + std::hash_set< OString, OStringHash > services; + AttributeInfo properties; + AttributeInfo attributes; + std::hash_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) +{ + std::hash_set< OString, OStringHash > interfaces; + std::hash_set< OString, OStringHash > services; + AttributeInfo properties; + AttributeInfo attributes; + std::hash_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 + std::hash_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 <hash_map>\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); + } + } +} + +} } + + diff --git a/unodevtools/source/skeletonmaker/cpptypemaker.cxx b/unodevtools/source/skeletonmaker/cpptypemaker.cxx new file mode 100644 index 000000000000..66ef981e8978 --- /dev/null +++ b/unodevtools/source/skeletonmaker/cpptypemaker.cxx @@ -0,0 +1,971 @@ +/************************************************************************* + * + * 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::createFromAscii(" + "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; + } + } +} + +} } + + diff --git a/unodevtools/source/skeletonmaker/javacompskeleton.cxx b/unodevtools/source/skeletonmaker/javacompskeleton.cxx new file mode 100644 index 000000000000..ebc8ffe10d59 --- /dev/null +++ b/unodevtools/source/skeletonmaker/javacompskeleton.cxx @@ -0,0 +1,997 @@ +/************************************************************************* + * + * 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 std::hash_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"; + } + } + + +// std::hash_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 std::hash_set< OString, OStringHash >& interfaces, + const OString& indentation, bool usepropertymixin) +{ + std::hash_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 std::hash_set< OString, OStringHash >& services, + const std::hash_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 + std::hash_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 std::hash_set< OString, OStringHash >& services, + const std::hash_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 "; + std::hash_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"; + std::hash_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*/) +{ + std::hash_set< OString, OStringHash > interfaces; + std::hash_set< OString, OStringHash > services; + AttributeInfo properties; + AttributeInfo attributes; + std::hash_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); + } + } +} + +} } + + diff --git a/unodevtools/source/skeletonmaker/javatypemaker.cxx b/unodevtools/source/skeletonmaker/javatypemaker.cxx new file mode 100644 index 000000000000..36501555bc68 --- /dev/null +++ b/unodevtools/source/skeletonmaker/javatypemaker.cxx @@ -0,0 +1,876 @@ +/************************************************************************* + * + * 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() + << "()"; + + #if 0 + // DEBUG + sal_uInt16 mc = reader.getMethodCount(); + RTMethodMode mm = reader.getMethodFlags(method); + #endif + 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; + } + } +} + +} } + + diff --git a/unodevtools/source/skeletonmaker/makefile.mk b/unodevtools/source/skeletonmaker/makefile.mk new file mode 100644 index 000000000000..72ac80ec9bda --- /dev/null +++ b/unodevtools/source/skeletonmaker/makefile.mk @@ -0,0 +1,57 @@ +#************************************************************************* +# +# 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 +.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 = $(REGLIB) $(SALLIB) $(SALHELPERLIB) $(CPPULIB) $(CPPUHELPERLIB) \ + $(UNODEVTOOLSLIBST) $(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..95c53760687c --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletoncommon.cxx @@ -0,0 +1,722 @@ +/************************************************************************* + * + * 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, + std::hash_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, + std::hash_set< OString, OStringHash >& interfaceTypes, + std::hash_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( + std::hash_set< OString, OStringHash >& interfaces, + const std::hash_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 std::hash_set< OString, OStringHash >& services, + const std::hash_set< OString, OStringHash >& interfaces, + AttributeInfo& attributes, + std::hash_set< OString, OStringHash >& propinterfaces) +{ + std::hash_set< OString, OStringHash >::const_iterator iter; + std::hash_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, + std::hash_set< OString, OStringHash >& interfaces) +{ + if ( interfaces.empty() ) + return false; + + std::hash_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::createFromAscii(\"" + << 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::createFromAscii(\"" + << 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 std::hash_set< OString, OStringHash >& interfaces) +{ + ::codemaker::GeneratedTypeSet generated; + bool bFirst = true; + std::hash_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++; + } +} + +} + diff --git a/unodevtools/source/skeletonmaker/skeletoncommon.hxx b/unodevtools/source/skeletonmaker/skeletoncommon.hxx new file mode 100644 index 000000000000..13516fc75617 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletoncommon.hxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * 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 <hash_set> +#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, + std::hash_set< rtl::OString, rtl::OStringHash >& interfaceTypes, + std::hash_set< rtl::OString, rtl::OStringHash >& serviceTypes, + AttributeInfo& properties); + +void checkDefaultInterfaces( + std::hash_set< rtl::OString, rtl::OStringHash >& interfaces, + const std::hash_set< rtl::OString, rtl::OStringHash >& services, + const rtl::OString & propertyhelper); + +rtl::OString checkPropertyHelper( + ProgramOptions const & options, TypeManager const & manager, + const std::hash_set< rtl::OString, rtl::OStringHash >& services, + const std::hash_set< rtl::OString, rtl::OStringHash >& interfaces, + AttributeInfo& attributes, + std::hash_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, + std::hash_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 std::hash_set< ::rtl::OString, ::rtl::OStringHash >& interfaces); + +} + +#endif // INCLUDED_UNODEVTOOLS_SOURCE_SKELETONMAKER_SKELETONCOMMON_HXX + diff --git a/unodevtools/source/skeletonmaker/skeletoncpp.hxx b/unodevtools/source/skeletonmaker/skeletoncpp.hxx new file mode 100644 index 000000000000..2c7ec5c4c629 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletoncpp.hxx @@ -0,0 +1,142 @@ +/************************************************************************* + * + * 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 + diff --git a/unodevtools/source/skeletonmaker/skeletonjava.hxx b/unodevtools/source/skeletonmaker/skeletonjava.hxx new file mode 100644 index 000000000000..6b35818a9744 --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletonjava.hxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * 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 + diff --git a/unodevtools/source/skeletonmaker/skeletonmaker.cxx b/unodevtools/source/skeletonmaker/skeletonmaker.cxx new file mode 100644 index 000000000000..50cb6ed1f34c --- /dev/null +++ b/unodevtools/source/skeletonmaker/skeletonmaker.cxx @@ -0,0 +1,352 @@ +/************************************************************************* + * + * 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" +" Sun Microsystems (R) "; + +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; +} |