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 	//--------------------------------------------------------------------
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 	//--------------------------------------------------------------------
124     SfxModelFactory::~SfxModelFactory()
125     {
126     }
127 
128     //--------------------------------------------------------------------
129     Reference< XInterface > SfxModelFactory::impl_createInstance( const sal_uInt64 _nCreationFlags ) const
130     {
131         return (*m_pComponentFactoryFunc)( m_xServiceFactory, _nCreationFlags );
132     }
133 
134     //--------------------------------------------------------------------
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         {
145             static bool isSpecialArgumentName( const ::rtl::OUString& _rValueName )
146             {
147                 return  _rValueName.equalsAscii( "EmbeddedObject" )
148                     ||  _rValueName.equalsAscii( "EmbeddedScriptSupport" )
149                     ||  _rValueName.equalsAscii( "DocumentRecoverySupport" );
150             }
151 
152             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     //--------------------------------------------------------------------
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 bahaviour 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     //--------------------------------------------------------------------
204     ::rtl::OUString SAL_CALL SfxModelFactory::getImplementationName(  ) throw (RuntimeException)
205     {
206         return m_sImplementationName;
207     }
208 
209     //--------------------------------------------------------------------
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     //--------------------------------------------------------------------
220     Sequence< ::rtl::OUString > SAL_CALL SfxModelFactory::getSupportedServiceNames(  ) throw (RuntimeException)
221     {
222         return m_aServiceNames;
223     }
224 
225     //--------------------------------------------------------------------
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