1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sfx2.hxx"
30 #include "sfx2/sfxmodelfactory.hxx"
31 
32 /** === begin UNO includes === **/
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/beans/NamedValue.hpp>
35 #include <com/sun/star/lang/XInitialization.hpp>
36 /** === end UNO includes === **/
37 
38 #include <comphelper/namedvaluecollection.hxx>
39 #include <cppuhelper/implbase2.hxx>
40 
41 #include <algorithm>
42 #include <functional>
43 
44 //........................................................................
45 namespace sfx2
46 {
47 //........................................................................
48 
49 	/** === begin UNO using === **/
50 	using ::com::sun::star::uno::Reference;
51 	using ::com::sun::star::uno::XInterface;
52 	using ::com::sun::star::uno::UNO_QUERY;
53 	using ::com::sun::star::uno::UNO_QUERY_THROW;
54 	using ::com::sun::star::uno::UNO_SET_THROW;
55 	using ::com::sun::star::uno::Exception;
56 	using ::com::sun::star::uno::RuntimeException;
57 	using ::com::sun::star::uno::Any;
58 	using ::com::sun::star::uno::makeAny;
59     using ::com::sun::star::lang::XMultiServiceFactory;
60     using ::com::sun::star::uno::Sequence;
61     using ::com::sun::star::lang::XSingleServiceFactory;
62     using ::com::sun::star::lang::XServiceInfo;
63     using ::com::sun::star::beans::NamedValue;
64     using ::com::sun::star::beans::PropertyValue;
65     using ::com::sun::star::lang::XInitialization;
66 	/** === end UNO using === **/
67 
68 	//====================================================================
69 	//= SfxModelFactory - declaration
70 	//====================================================================
71     typedef ::cppu::WeakImplHelper2 <   XSingleServiceFactory
72                                     ,   XServiceInfo
73                                     >   SfxModelFactory_Base;
74     /** implements a XSingleServiceFactory which can be used to created instances
75         of classes derived from SfxBaseModel
76 
77         In opposite to the default implementations from module cppuhelper, this
78         factory evaluates certain creation arguments (passed to createInstanceWithArguments)
79         and passes them to the factory function of the derived class.
80     */
81     class SfxModelFactory : public SfxModelFactory_Base
82 	{
83     public:
84         SfxModelFactory(
85             const Reference< XMultiServiceFactory >& _rxServiceFactory,
86             const ::rtl::OUString& _rImplementationName,
87             const SfxModelFactoryFunc _pComponentFactoryFunc,
88             const Sequence< ::rtl::OUString >& _rServiceNames
89         );
90 
91         // XSingleServiceFactory
92         virtual Reference< XInterface > SAL_CALL createInstance(  ) throw (Exception, RuntimeException);
93         virtual Reference< XInterface > SAL_CALL createInstanceWithArguments( const Sequence< Any >& aArguments ) throw (Exception, RuntimeException);
94 
95         // XServiceInfo
96         virtual ::rtl::OUString SAL_CALL getImplementationName(  ) throw (RuntimeException);
97         virtual ::sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) throw (RuntimeException);
98         virtual Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames(  ) throw (RuntimeException);
99 
100     protected:
101         virtual ~SfxModelFactory();
102 
103     private:
104         Reference< XInterface > impl_createInstance( const sal_uInt64 _nCreationFlags ) const;
105 
106     private:
107         const Reference< XMultiServiceFactory >     m_xServiceFactory;
108         const ::rtl::OUString                       m_sImplementationName;
109         const Sequence< ::rtl::OUString >           m_aServiceNames;
110         const SfxModelFactoryFunc                   m_pComponentFactoryFunc;
111 	};
112 
113 	//====================================================================
114 	//= SfxModelFactory - implementation
115 	//====================================================================
116 	//--------------------------------------------------------------------
117     SfxModelFactory::SfxModelFactory( const Reference< XMultiServiceFactory >& _rxServiceFactory,
118             const ::rtl::OUString& _rImplementationName, const SfxModelFactoryFunc _pComponentFactoryFunc,
119             const Sequence< ::rtl::OUString >& _rServiceNames )
120         :m_xServiceFactory( _rxServiceFactory )
121         ,m_sImplementationName( _rImplementationName )
122         ,m_aServiceNames( _rServiceNames )
123         ,m_pComponentFactoryFunc( _pComponentFactoryFunc )
124     {
125     }
126 
127 	//--------------------------------------------------------------------
128     SfxModelFactory::~SfxModelFactory()
129     {
130     }
131 
132     //--------------------------------------------------------------------
133     Reference< XInterface > SfxModelFactory::impl_createInstance( const sal_uInt64 _nCreationFlags ) const
134     {
135         return (*m_pComponentFactoryFunc)( m_xServiceFactory, _nCreationFlags );
136     }
137 
138     //--------------------------------------------------------------------
139     Reference< XInterface > SAL_CALL SfxModelFactory::createInstance(  ) throw (Exception, RuntimeException)
140     {
141         return createInstanceWithArguments( Sequence< Any >() );
142     }
143 
144     //--------------------------------------------------------------------
145     namespace
146     {
147         struct IsSpecialArgument : public ::std::unary_function< Any, bool >
148         {
149             static bool isSpecialArgumentName( const ::rtl::OUString& _rValueName )
150             {
151                 return  _rValueName.equalsAscii( "EmbeddedObject" )
152                     ||  _rValueName.equalsAscii( "EmbeddedScriptSupport" )
153                     ||  _rValueName.equalsAscii( "DocumentRecoverySupport" );
154             }
155 
156             bool operator()( const Any& _rArgument ) const
157             {
158                 NamedValue aNamedValue;
159                 if ( ( _rArgument >>= aNamedValue ) && isSpecialArgumentName( aNamedValue.Name ) )
160                     return true;
161                 PropertyValue aPropertyValue;
162                 if ( ( _rArgument >>= aPropertyValue ) && isSpecialArgumentName( aPropertyValue.Name ) )
163                     return true;
164                 return false;
165             }
166         };
167     }
168 
169     //--------------------------------------------------------------------
170     Reference< XInterface > SAL_CALL SfxModelFactory::createInstanceWithArguments( const Sequence< Any >& _rArguments ) throw (Exception, RuntimeException)
171     {
172         ::comphelper::NamedValueCollection aArgs( _rArguments );
173         const sal_Bool bEmbeddedObject = aArgs.getOrDefault( "EmbeddedObject", sal_False );
174         const sal_Bool bScriptSupport = aArgs.getOrDefault( "EmbeddedScriptSupport", sal_True );
175         const sal_Bool bDocRecoverySupport = aArgs.getOrDefault( "DocumentRecoverySupport", sal_True );
176 
177         sal_uInt64 nCreationFlags =
178                 ( bEmbeddedObject ? SFXMODEL_EMBEDDED_OBJECT : 0 )
179             |   ( bScriptSupport ? 0 : SFXMODEL_DISABLE_EMBEDDED_SCRIPTS )
180             |   ( bDocRecoverySupport ? 0 : SFXMODEL_DISABLE_DOCUMENT_RECOVERY );
181 
182         Reference< XInterface > xInstance( impl_createInstance( nCreationFlags ) );
183 
184         // to mimic the bahaviour of the default factory's createInstanceWithArguments, we initialize
185         // the object with the given arguments, stripped by the three special ones
186         Sequence< Any > aStrippedArguments( _rArguments.getLength() );
187         Any* pStrippedArgs = aStrippedArguments.getArray();
188         Any* pStrippedArgsEnd = ::std::remove_copy_if(
189             _rArguments.getConstArray(),
190             _rArguments.getConstArray() + _rArguments.getLength(),
191             pStrippedArgs,
192             IsSpecialArgument()
193         );
194         aStrippedArguments.realloc( pStrippedArgsEnd - pStrippedArgs );
195 
196         if ( aStrippedArguments.getLength() )
197         {
198             Reference< XInitialization > xModelInit( xInstance, UNO_QUERY );
199             OSL_ENSURE( xModelInit.is(), "SfxModelFactory::createInstanceWithArguments: no XInitialization!" );
200             if ( xModelInit.is() )
201                 xModelInit->initialize( aStrippedArguments );
202         }
203 
204         return xInstance;
205     }
206 
207     //--------------------------------------------------------------------
208     ::rtl::OUString SAL_CALL SfxModelFactory::getImplementationName(  ) throw (RuntimeException)
209     {
210         return m_sImplementationName;
211     }
212 
213     //--------------------------------------------------------------------
214     ::sal_Bool SAL_CALL SfxModelFactory::supportsService( const ::rtl::OUString& _rServiceName ) throw (RuntimeException)
215     {
216         return ::std::find(
217             m_aServiceNames.getConstArray(),
218             m_aServiceNames.getConstArray() + m_aServiceNames.getLength(),
219             _rServiceName
220         )  != m_aServiceNames.getConstArray() + m_aServiceNames.getLength();
221     }
222 
223     //--------------------------------------------------------------------
224     Sequence< ::rtl::OUString > SAL_CALL SfxModelFactory::getSupportedServiceNames(  ) throw (RuntimeException)
225     {
226         return m_aServiceNames;
227     }
228 
229     //--------------------------------------------------------------------
230     Reference< XSingleServiceFactory > createSfxModelFactory( const Reference< XMultiServiceFactory >& _rxServiceFactory,
231             const ::rtl::OUString& _rImplementationName, const SfxModelFactoryFunc _pComponentFactoryFunc,
232             const Sequence< ::rtl::OUString >& _rServiceNames )
233     {
234         return new SfxModelFactory( _rxServiceFactory, _rImplementationName, _pComponentFactoryFunc, _rServiceNames );
235     }
236 
237 //........................................................................
238 } // namespace sfx2
239 //........................................................................
240