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_framework.hxx"
26 #include <uiconfiguration/moduleuicfgsupplier.hxx>
27 #include <threadhelp/resetableguard.hxx>
28 #include <services.h>
29 
30 //_________________________________________________________________________________________________________________
31 //	interface includes
32 //_________________________________________________________________________________________________________________
33 #include <com/sun/star/lang/DisposedException.hpp>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include <com/sun/star/embed/ElementModes.hpp>
37 #include <com/sun/star/io/XOutputStream.hpp>
38 #include <com/sun/star/io/XInputStream.hpp>
39 #include <com/sun/star/io/XSeekable.hpp>
40 #include <com/sun/star/embed/XPackageStructureCreator.hpp>
41 
42 //_________________________________________________________________________________________________________________
43 //	other includes
44 //_________________________________________________________________________________________________________________
45 #include <rtl/logfile.hxx>
46 #include <cppuhelper/implbase1.hxx>
47 #include <vcl/svapp.hxx>
48 
49 using namespace com::sun::star::uno;
50 using namespace com::sun::star::io;
51 using namespace com::sun::star::lang;
52 using namespace com::sun::star::container;
53 using namespace com::sun::star::beans;
54 using namespace com::sun::star::embed;
55 using namespace ::com::sun::star::ui;
56 using namespace ::com::sun::star::frame;
57 
58 namespace framework
59 {
60 
61 class RootStorageWrapper :  public ::cppu::WeakImplHelper1< com::sun::star::embed::XTransactedObject >
62 {
63     public:
64         //  XInterface, XTypeProvider
RootStorageWrapper(const Reference<XTransactedObject> & xRootCommit)65         RootStorageWrapper( const Reference< XTransactedObject >& xRootCommit ) : m_xRootCommit( xRootCommit ) {}
~RootStorageWrapper()66         virtual ~RootStorageWrapper() {}
67 
68         // XTransactedObject
commit()69         virtual void SAL_CALL commit() throw ( com::sun::star::io::IOException, com::sun::star::lang::WrappedTargetException )
70         {
71             m_xRootCommit->commit();
72         }
73 
revert()74 	    virtual void SAL_CALL revert() throw ( com::sun::star::io::IOException, com::sun::star::lang::WrappedTargetException )
75         {
76             m_xRootCommit->revert();
77         }
78 
79     private:
80         Reference< XTransactedObject > m_xRootCommit;
81 };
82 
83 //*****************************************************************************************************************
84 //	XInterface, XTypeProvider, XServiceInfo
85 //*****************************************************************************************************************
DEFINE_XINTERFACE_4(ModuleUIConfigurationManagerSupplier,OWeakObject,DIRECT_INTERFACE (css::lang::XTypeProvider),DIRECT_INTERFACE (css::lang::XServiceInfo),DIRECT_INTERFACE (css::lang::XComponent),DIRECT_INTERFACE (::com::sun::star::ui::XModuleUIConfigurationManagerSupplier))86 DEFINE_XINTERFACE_4                    (    ModuleUIConfigurationManagerSupplier                    ,
87                                             OWeakObject                                             ,
88                                             DIRECT_INTERFACE( css::lang::XTypeProvider                                          ),
89                                             DIRECT_INTERFACE( css::lang::XServiceInfo                                           ),
90                                             DIRECT_INTERFACE( css::lang::XComponent                                             ),
91 											DIRECT_INTERFACE( ::com::sun::star::ui::XModuleUIConfigurationManagerSupplier )
92 										)
93 
94 DEFINE_XTYPEPROVIDER_4                  (   ModuleUIConfigurationManagerSupplier                                ,
95                                             css::lang::XTypeProvider			                                ,
96                                             css::lang::XServiceInfo				                                ,
97                                             css::lang::XComponent                                               ,
98 											::com::sun::star::ui::XModuleUIConfigurationManagerSupplier
99 										)
100 
101 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   ModuleUIConfigurationManagerSupplier                    ,
102                                             ::cppu::OWeakObject                                     ,
103                                             SERVICENAME_MODULEUICONFIGURATIONMANAGERSUPPLIER        ,
104 											IMPLEMENTATIONNAME_MODULEUICONFIGURATIONMANAGERSUPPLIER
105 										)
106 
107 DEFINE_INIT_SERVICE                     (   ModuleUIConfigurationManagerSupplier, {} )
108 
109 
110 /*TODO_AS
111 void ModuleUIConfigurationManagerSupplier::impl_initStorages()
112 {
113 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::impl_initStorages" );
114     if ( !m_bInit )
115     {
116         RTL_LOGFILE_CONTEXT( aLog, "framework (cd100003) ::ModuleUIConfigurationManagerSupplier::impl_initStorages" );
117 
118         rtl::OUString aFinalSlash( RTL_CONSTASCII_USTRINGPARAM( "/" ));
119         rtl::OUString aConfigRootFolder( RTL_CONSTASCII_USTRINGPARAM( "soffice.cfg/modules" ));
120         rtl::OUString aConfigSubFolder( RTL_CONSTASCII_USTRINGPARAM( "soffice.cfg/modules/soffice.cfg" ));
121         rtl::OUString aConfigRootFolder( RTL_CONSTASCII_USTRINGPARAM( "soffice.cfg" ));
122         rtl::OUString aConfigSubFolder( RTL_CONSTASCII_USTRINGPARAM( "soffice.cfg/soffice.cfg" ));
123         rtl::OUString aConfigFileName( RTL_CONSTASCII_USTRINGPARAM( "soffice.cfg/uiconfig.zip" ));
124 
125         Reference< XPropertySet > xPathSettings( m_xServiceManager->createInstance(
126                                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.PathSettings" ))),
127                                                   UNO_QUERY_THROW );
128 
129         Any a = xPathSettings->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIConfig" )));
130         a >>= m_aDefaultConfigURL;
131         a = xPathSettings->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfig" )));
132         a >>= m_aUserConfigURL;
133 
134         // Use only the first entry from "UIConfig"
135         sal_Int32 nIndex = m_aDefaultConfigURL.indexOf( ';' );
136         if ( nIndex > 0 )
137             m_aDefaultConfigURL = m_aDefaultConfigURL.copy( 0, nIndex );
138 
139         rtl::OUString aDefaultConfigFolderURL( m_aDefaultConfigURL );
140 
141         nIndex = m_aDefaultConfigURL.lastIndexOf( '/' );
142         if (( nIndex > 0 ) &&  ( nIndex != ( m_aDefaultConfigURL.getLength()-1 )))
143         {
144             m_aDefaultConfigURL += aFinalSlash;
145             aDefaultConfigFolderURL += aFinalSlash;
146         }
147 
148         nIndex = m_aUserConfigURL.lastIndexOf( '/' );
149         if (( nIndex > 0 ) &&  ( nIndex != ( m_aUserConfigURL.getLength()-1 )))
150             m_aUserConfigURL += aFinalSlash;
151 
152 //        aDefaultConfigFolderURL += aConfigRootFolder;
153 
154         // Create root storages for user interface configuration data (default and customizable)
155         Reference< XSingleServiceFactory > xStorageFactory( m_xServiceManager->createInstance(
156                                                                 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.StorageFactory" ))),
157                                                             UNO_QUERY_THROW );
158 
159         Sequence< Any > aArgs( 2 );
160 
161         // Default root storage (READ-ACCESS)
162         aArgs[0] <<= m_aDefaultConfigURL + aConfigFileName; //aConfigSubFolder;
163         aArgs[1] <<= ElementModes::READ;
164         m_xDefaultCfgRootStorage = Reference< XStorage >( xStorageFactory->createInstanceWithArguments( aArgs ), UNO_QUERY_THROW );
165 
166 	    Reference < XOutputStream > xTempOut( m_xServiceManager->createInstance (
167                                                 ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
168 						                      UNO_QUERY );
169 
170         Reference< XPackageStructureCreator > xPackageStructCreator( m_xServiceManager->createInstance(
171                                                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.embed.PackageStructureCreator" ))),
172                                                                      UNO_QUERY_THROW );
173 
174         RTL_LOGFILE_CONTEXT_TRACE( aLog, "{ convertToPackage" );
175         xPackageStructCreator->convertToPackage( aDefaultConfigFolderURL, xTempOut );
176         RTL_LOGFILE_CONTEXT_TRACE( aLog, "} convertToPackage" );
177 
178         xTempOut->closeOutput();
179         Reference< XInputStream > xTempIn( xTempOut, UNO_QUERY );
180         Reference< XSeekable > xTempSeek( xTempOut, UNO_QUERY );
181 
182         // Default root storage (READ-ACCESS)
183         xTempSeek->seek( 0 );
184 
185         aArgs[0] <<= xTempIn;
186         aArgs[1] <<= ElementModes::READ;
187         m_xDefaultCfgRootStorage = Reference< XStorage >( xStorageFactory->createInstanceWithArguments( aArgs ), UNO_QUERY_THROW );
188 
189         // Customizable root storage (READWRITE-ACCESS)
190         aArgs[0] <<= m_aUserConfigURL + aConfigSubFolder;
191         aArgs[1] <<= ElementModes::READWRITE;
192         m_xUserCfgRootStorage = Reference< XStorage >( xStorageFactory->createInstanceWithArguments( aArgs ), UNO_QUERY );
193 
194         // Create wrapper object for module user interface configuration managers, so they are able to call commit/revert on
195         // root storage and nothing more (saftey)!
196         RootStorageWrapper* pUserRootStorageWrapper = new RootStorageWrapper( Reference< XTransactedObject >( m_xUserCfgRootStorage, UNO_QUERY ));
197         m_xUserRootCommit = Reference< XTransactedObject>( static_cast< OWeakObject *>( pUserRootStorageWrapper ), UNO_QUERY );
198     }
199 
200     m_bInit = true;
201 }
202 */
203 
204 
205 ModuleUIConfigurationManagerSupplier::ModuleUIConfigurationManagerSupplier( const Reference< XMultiServiceFactory >& xServiceManager ) :
206     ThreadHelpBase( &Application::GetSolarMutex() )
207     , m_bDisposed( false )
208 //TODO_AS    , m_bInit( false )
209     , m_xModuleMgr( Reference< XModuleManager >( xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY ))
210     , m_xServiceManager( xServiceManager )
211     , m_aListenerContainer( m_aLock.getShareableOslMutex() )
212 {
213     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::ModuleUIConfigurationManagerSupplier" );
214     // Retrieve known modules and insert them into our hash_map to speed-up access time.
215     Reference< XNameAccess > xNameAccess( m_xModuleMgr, UNO_QUERY );
216     const Sequence< ::rtl::OUString >     aNameSeq   = xNameAccess->getElementNames();
217     const ::rtl::OUString*                pNameSeq   = aNameSeq.getConstArray();
218     for ( sal_Int32 n = 0; n < aNameSeq.getLength(); n++ )
219         m_aModuleToModuleUICfgMgrMap.insert( ModuleToModuleCfgMgr::value_type(  pNameSeq[n], Reference< XUIConfigurationManager >() ));
220 }
221 
~ModuleUIConfigurationManagerSupplier()222 ModuleUIConfigurationManagerSupplier::~ModuleUIConfigurationManagerSupplier()
223 {
224     m_xUserRootCommit.clear();
225 
226     // dispose all our module user interface configuration managers
227     ModuleToModuleCfgMgr::iterator pIter = m_aModuleToModuleUICfgMgrMap.begin();
228     while ( pIter != m_aModuleToModuleUICfgMgrMap.end() )
229     {
230         Reference< XComponent > xComponent( pIter->second, UNO_QUERY );
231         if ( xComponent.is() )
232             xComponent->dispose();
233         ++pIter;
234     }
235 /*TODO_AS
236     // Dispose our root configuration storages
237     if ( m_xDefaultCfgRootStorage.is() )
238     {
239         Reference< XComponent > xComponent( m_xDefaultCfgRootStorage, UNO_QUERY );
240         xComponent->dispose();
241     }
242 
243     if ( m_xUserCfgRootStorage.is() )
244     {
245         Reference< XComponent > xComponent( m_xUserCfgRootStorage, UNO_QUERY );
246         xComponent->dispose();
247     }
248 */
249 }
250 
251 // XComponent
dispose()252 void SAL_CALL ModuleUIConfigurationManagerSupplier::dispose()
253 throw ( RuntimeException )
254 {
255     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::dispose" );
256     Reference< XComponent > xThis( static_cast< OWeakObject* >(this), UNO_QUERY );
257 
258     css::lang::EventObject aEvent( xThis );
259     m_aListenerContainer.disposeAndClear( aEvent );
260 
261 	{
262 	    ResetableGuard aGuard( m_aLock );
263         m_bDisposed = true;
264     }
265 }
266 
addEventListener(const Reference<XEventListener> & xListener)267 void SAL_CALL ModuleUIConfigurationManagerSupplier::addEventListener( const Reference< XEventListener >& xListener )
268 throw ( RuntimeException )
269 {
270     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::addEventListener" );
271     {
272         ResetableGuard aGuard( m_aLock );
273 
274 	    /* SAFE AREA ----------------------------------------------------------------------------------------------- */
275         if ( m_bDisposed )
276             throw DisposedException();
277     }
278 
279     m_aListenerContainer.addInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
280 }
281 
removeEventListener(const Reference<XEventListener> & xListener)282 void SAL_CALL ModuleUIConfigurationManagerSupplier::removeEventListener( const Reference< XEventListener >& xListener )
283 throw ( RuntimeException )
284 {
285     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::removeEventListener" );
286     /* SAFE AREA ----------------------------------------------------------------------------------------------- */
287     m_aListenerContainer.removeInterface( ::getCppuType( ( const Reference< XEventListener >* ) NULL ), xListener );
288 }
289 
290 // XModuleUIConfigurationManagerSupplier
getUIConfigurationManager(const::rtl::OUString & ModuleIdentifier)291 Reference< XUIConfigurationManager > SAL_CALL ModuleUIConfigurationManagerSupplier::getUIConfigurationManager( const ::rtl::OUString& ModuleIdentifier )
292 throw ( NoSuchElementException, RuntimeException)
293 {
294     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ModuleUIConfigurationManagerSupplier::getUIConfigurationManager" );
295     ResetableGuard aGuard( m_aLock );
296 
297 	/* SAFE AREA ----------------------------------------------------------------------------------------------- */
298     if ( m_bDisposed )
299         throw DisposedException();
300 
301     ModuleToModuleCfgMgr::iterator pIter = m_aModuleToModuleUICfgMgrMap.find( ModuleIdentifier );
302     if ( pIter == m_aModuleToModuleUICfgMgrMap.end() )
303         throw NoSuchElementException();
304 //TODO_AS    impl_initStorages();
305 
306     // Create instance on demand
307     if ( !pIter->second.is() )
308     {
309         /*TODO_AS
310         Reference< XStorage > xDefaultConfigModuleStorage;
311         Reference< XStorage > xUserConfigModuleStorage;
312 
313         try
314         {
315             xDefaultConfigModuleStorage = Reference< XStorage >( m_xDefaultCfgRootStorage->openStorageElement(
316                                                                     sShort, ElementModes::READ ), UNO_QUERY_THROW );
317 
318             if ( m_xUserCfgRootStorage.is() )
319             {
320                 try
321                 {
322                     xUserConfigModuleStorage = Reference< XStorage >( m_xUserCfgRootStorage->openStorageElement(
323                                                                         sShort, ElementModes::READWRITE ), UNO_QUERY );
324                 }
325                 catch( ::com::sun::star::io::IOException& )
326                 {
327                     try
328                     {
329                         xUserConfigModuleStorage = Reference< XStorage >( m_xUserCfgRootStorage->openStorageElement(
330                                                                             sShort, ElementModes::READ ), UNO_QUERY );
331                     }
332                     catch( com::sun::star::uno::Exception& )
333                     {
334                     }
335                 }
336             }
337         }
338         catch ( com::sun::star::uno::Exception& )
339         {
340         }
341         PropertyValue   aArg;
342         Sequence< Any > aArgs( 5 );
343         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
344         aArg.Value <<= ModuleIdentifier;
345         aArgs[0] <<= aArg;
346         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultConfigStorage" ));
347         aArg.Value <<= xDefaultConfigModuleStorage;
348         aArgs[1] <<= aArg;
349         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserConfigStorage" ));
350         aArg.Value <<= xUserConfigModuleStorage;
351         aArgs[2] <<= aArg;
352         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UserRootCommit" ));
353         aArg.Value <<= m_xUserRootCommit;
354         aArgs[3] <<= aArg;
355         */
356         ::rtl::OUString sShort;
357         try
358         {
359             Sequence< PropertyValue > lProps;
360             Reference< XNameAccess > xCont(m_xModuleMgr, UNO_QUERY);
361             xCont->getByName(ModuleIdentifier) >>= lProps;
362             for (sal_Int32 i=0; i<lProps.getLength(); ++i)
363             {
364                 if (lProps[i].Name.equalsAscii("ooSetupFactoryShortName"))
365                 {
366                     lProps[i].Value >>= sShort;
367                     break;
368                 }
369             }
370         }
371         catch( Exception& )
372         {
373             sShort = ::rtl::OUString();
374         }
375 
376         if (!sShort.getLength())
377             throw NoSuchElementException();
378         PropertyValue   aArg;
379         Sequence< Any > aArgs( 2 );
380         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleShortName" ));
381         aArg.Value <<= sShort;
382         aArgs[0] <<= aArg;
383         aArg.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ModuleIdentifier" ));
384         aArg.Value <<= ModuleIdentifier;
385         aArgs[1] <<= aArg;
386 
387         pIter->second.set( m_xServiceManager->createInstanceWithArguments(SERVICENAME_MODULEUICONFIGURATIONMANAGER, aArgs ),UNO_QUERY );
388     }
389 
390     return pIter->second;
391 }
392 
393 } // namespace framework
394 
395