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