1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sfx2.hxx" 26 #include "sfx2/sfxmodelfactory.hxx" 27 28 /** === begin UNO includes === **/ 29 #include <com/sun/star/lang/XServiceInfo.hpp> 30 #include <com/sun/star/beans/NamedValue.hpp> 31 #include <com/sun/star/lang/XInitialization.hpp> 32 /** === end UNO includes === **/ 33 34 #include <comphelper/namedvaluecollection.hxx> 35 #include <cppuhelper/implbase2.hxx> 36 37 #include <algorithm> 38 #include <functional> 39 40 //........................................................................ 41 namespace sfx2 42 { 43 //........................................................................ 44 45 /** === begin UNO using === **/ 46 using ::com::sun::star::uno::Reference; 47 using ::com::sun::star::uno::XInterface; 48 using ::com::sun::star::uno::UNO_QUERY; 49 using ::com::sun::star::uno::UNO_QUERY_THROW; 50 using ::com::sun::star::uno::UNO_SET_THROW; 51 using ::com::sun::star::uno::Exception; 52 using ::com::sun::star::uno::RuntimeException; 53 using ::com::sun::star::uno::Any; 54 using ::com::sun::star::uno::makeAny; 55 using ::com::sun::star::lang::XMultiServiceFactory; 56 using ::com::sun::star::uno::Sequence; 57 using ::com::sun::star::lang::XSingleServiceFactory; 58 using ::com::sun::star::lang::XServiceInfo; 59 using ::com::sun::star::beans::NamedValue; 60 using ::com::sun::star::beans::PropertyValue; 61 using ::com::sun::star::lang::XInitialization; 62 /** === end UNO using === **/ 63 64 //==================================================================== 65 //= SfxModelFactory - declaration 66 //==================================================================== 67 typedef ::cppu::WeakImplHelper2 < XSingleServiceFactory 68 , XServiceInfo 69 > SfxModelFactory_Base; 70 /** implements a XSingleServiceFactory which can be used to created instances 71 of classes derived from SfxBaseModel 72 73 In opposite to the default implementations from module cppuhelper, this 74 factory evaluates certain creation arguments (passed to createInstanceWithArguments) 75 and passes them to the factory function of the derived class. 76 */ 77 class SfxModelFactory : public SfxModelFactory_Base 78 { 79 public: 80 SfxModelFactory( 81 const Reference< XMultiServiceFactory >& _rxServiceFactory, 82 const ::rtl::OUString& _rImplementationName, 83 const SfxModelFactoryFunc _pComponentFactoryFunc, 84 const Sequence< ::rtl::OUString >& _rServiceNames 85 ); 86 87 // XSingleServiceFactory 88 virtual Reference< XInterface > SAL_CALL createInstance( ) throw (Exception, RuntimeException); 89 virtual Reference< XInterface > SAL_CALL createInstanceWithArguments( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException); 90 91 // XServiceInfo 92 virtual ::rtl::OUString SAL_CALL getImplementationName( ) throw (RuntimeException); 93 virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException); 94 virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames( ) throw (RuntimeException); 95 96 protected: 97 virtual ~SfxModelFactory(); 98 99 private: 100 Reference< XInterface > impl_createInstance( const sal_uInt64 _nCreationFlags ) const; 101 102 private: 103 const Reference< XMultiServiceFactory > m_xServiceFactory; 104 const ::rtl::OUString m_sImplementationName; 105 const Sequence< ::rtl::OUString > m_aServiceNames; 106 const SfxModelFactoryFunc m_pComponentFactoryFunc; 107 }; 108 109 //==================================================================== 110 //= SfxModelFactory - implementation 111 //==================================================================== 112 //-------------------------------------------------------------------- SfxModelFactory(const Reference<XMultiServiceFactory> & _rxServiceFactory,const::rtl::OUString & _rImplementationName,const SfxModelFactoryFunc _pComponentFactoryFunc,const Sequence<::rtl::OUString> & _rServiceNames)113 SfxModelFactory::SfxModelFactory( const Reference< XMultiServiceFactory >& _rxServiceFactory, 114 const ::rtl::OUString& _rImplementationName, const SfxModelFactoryFunc _pComponentFactoryFunc, 115 const Sequence< ::rtl::OUString >& _rServiceNames ) 116 :m_xServiceFactory( _rxServiceFactory ) 117 ,m_sImplementationName( _rImplementationName ) 118 ,m_aServiceNames( _rServiceNames ) 119 ,m_pComponentFactoryFunc( _pComponentFactoryFunc ) 120 { 121 } 122 123 //-------------------------------------------------------------------- ~SfxModelFactory()124 SfxModelFactory::~SfxModelFactory() 125 { 126 } 127 128 //-------------------------------------------------------------------- impl_createInstance(const sal_uInt64 _nCreationFlags) const129 Reference< XInterface > SfxModelFactory::impl_createInstance( const sal_uInt64 _nCreationFlags ) const 130 { 131 return (*m_pComponentFactoryFunc)( m_xServiceFactory, _nCreationFlags ); 132 } 133 134 //-------------------------------------------------------------------- createInstance()135 Reference< XInterface > SAL_CALL SfxModelFactory::createInstance( ) throw (Exception, RuntimeException) 136 { 137 return createInstanceWithArguments( Sequence< Any >() ); 138 } 139 140 //-------------------------------------------------------------------- 141 namespace 142 { 143 struct IsSpecialArgument : public ::std::unary_function< Any, bool > 144 { isSpecialArgumentNamesfx2::__anon163f98690111::IsSpecialArgument145 static bool isSpecialArgumentName( const ::rtl::OUString& _rValueName ) 146 { 147 return _rValueName.equalsAscii( "EmbeddedObject" ) 148 || _rValueName.equalsAscii( "EmbeddedScriptSupport" ) 149 || _rValueName.equalsAscii( "DocumentRecoverySupport" ); 150 } 151 operator ()sfx2::__anon163f98690111::IsSpecialArgument152 bool operator()( const Any& _rArgument ) const 153 { 154 NamedValue aNamedValue; 155 if ( ( _rArgument >>= aNamedValue ) && isSpecialArgumentName( aNamedValue.Name ) ) 156 return true; 157 PropertyValue aPropertyValue; 158 if ( ( _rArgument >>= aPropertyValue ) && isSpecialArgumentName( aPropertyValue.Name ) ) 159 return true; 160 return false; 161 } 162 }; 163 } 164 165 //-------------------------------------------------------------------- createInstanceWithArguments(const Sequence<Any> & _rArguments)166 Reference< XInterface > SAL_CALL SfxModelFactory::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException) 167 { 168 ::comphelper::NamedValueCollection aArgs( _rArguments ); 169 const sal_Bool bEmbeddedObject = aArgs.getOrDefault( "EmbeddedObject", sal_False ); 170 const sal_Bool bScriptSupport = aArgs.getOrDefault( "EmbeddedScriptSupport", sal_True ); 171 const sal_Bool bDocRecoverySupport = aArgs.getOrDefault( "DocumentRecoverySupport", sal_True ); 172 173 sal_uInt64 nCreationFlags = 174 ( bEmbeddedObject ? SFXMODEL_EMBEDDED_OBJECT : 0 ) 175 | ( bScriptSupport ? 0 : SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) 176 | ( bDocRecoverySupport ? 0 : SFXMODEL_DISABLE_DOCUMENT_RECOVERY ); 177 178 Reference< XInterface > xInstance( impl_createInstance( nCreationFlags ) ); 179 180 // to mimic the behaviour of the default factory's createInstanceWithArguments, we initialize 181 // the object with the given arguments, stripped by the three special ones 182 Sequence< Any > aStrippedArguments( _rArguments.getLength() ); 183 Any* pStrippedArgs = aStrippedArguments.getArray(); 184 Any* pStrippedArgsEnd = ::std::remove_copy_if( 185 _rArguments.getConstArray(), 186 _rArguments.getConstArray() + _rArguments.getLength(), 187 pStrippedArgs, 188 IsSpecialArgument() 189 ); 190 aStrippedArguments.realloc( pStrippedArgsEnd - pStrippedArgs ); 191 192 if ( aStrippedArguments.getLength() ) 193 { 194 Reference< XInitialization > xModelInit( xInstance, UNO_QUERY ); 195 OSL_ENSURE( xModelInit.is(), "SfxModelFactory::createInstanceWithArguments: no XInitialization!" ); 196 if ( xModelInit.is() ) 197 xModelInit->initialize( aStrippedArguments ); 198 } 199 200 return xInstance; 201 } 202 203 //-------------------------------------------------------------------- getImplementationName()204 ::rtl::OUString SAL_CALL SfxModelFactory::getImplementationName( ) throw (RuntimeException) 205 { 206 return m_sImplementationName; 207 } 208 209 //-------------------------------------------------------------------- supportsService(const::rtl::OUString & _rServiceName)210 ::sal_Bool SAL_CALL SfxModelFactory::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException) 211 { 212 return ::std::find( 213 m_aServiceNames.getConstArray(), 214 m_aServiceNames.getConstArray() + m_aServiceNames.getLength(), 215 _rServiceName 216 ) != m_aServiceNames.getConstArray() + m_aServiceNames.getLength(); 217 } 218 219 //-------------------------------------------------------------------- getSupportedServiceNames()220 Sequence< ::rtl::OUString > SAL_CALL SfxModelFactory::getSupportedServiceNames( ) throw (RuntimeException) 221 { 222 return m_aServiceNames; 223 } 224 225 //-------------------------------------------------------------------- createSfxModelFactory(const Reference<XMultiServiceFactory> & _rxServiceFactory,const::rtl::OUString & _rImplementationName,const SfxModelFactoryFunc _pComponentFactoryFunc,const Sequence<::rtl::OUString> & _rServiceNames)226 Reference< XSingleServiceFactory > createSfxModelFactory( const Reference< XMultiServiceFactory >& _rxServiceFactory, 227 const ::rtl::OUString& _rImplementationName, const SfxModelFactoryFunc _pComponentFactoryFunc, 228 const Sequence< ::rtl::OUString >& _rServiceNames ) 229 { 230 return new SfxModelFactory( _rxServiceFactory, _rImplementationName, _pComponentFactoryFunc, _rServiceNames ); 231 } 232 233 //........................................................................ 234 } // namespace sfx2 235 //........................................................................ 236