merge the formfield patch from ooo-build
[ooovba.git] / framework / source / uifactory / uielementfactorymanager.cxx
blob67e6a936b08f6a72f45125622f6be3171221d4f3
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: uielementfactorymanager.cxx,v $
10 * $Revision: 1.10.12.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
34 //_________________________________________________________________________________________________________________
35 // my own includes
36 //_________________________________________________________________________________________________________________
37 #include <uifactory/uielementfactorymanager.hxx>
38 #include <uifactory/windowcontentfactorymanager.hxx>
39 #include <threadhelp/resetableguard.hxx>
40 #include "services.h"
42 //_________________________________________________________________________________________________________________
43 // interface includes
44 //_________________________________________________________________________________________________________________
45 #include <com/sun/star/beans/PropertyValue.hpp>
46 #include <com/sun/star/beans/XPropertySet.hpp>
47 #include <com/sun/star/container/XNameAccess.hpp>
48 #include <com/sun/star/container/XNameContainer.hpp>
49 #include <com/sun/star/container/XContainer.hpp>
50 #include <com/sun/star/frame/XFrame.hpp>
52 //_________________________________________________________________________________________________________________
53 // includes of other projects
54 //_________________________________________________________________________________________________________________
55 #include <rtl/ustrbuf.hxx>
56 #include <cppuhelper/weak.hxx>
57 #include <tools/urlobj.hxx>
58 #include <vcl/svapp.hxx>
59 #include <rtl/logfile.hxx>
60 //_________________________________________________________________________________________________________________
61 // Defines
62 //_________________________________________________________________________________________________________________
63 //
65 using namespace com::sun::star::uno;
66 using namespace com::sun::star::lang;
67 using namespace com::sun::star::beans;
68 using namespace com::sun::star::frame;
69 using namespace com::sun::star::container;
70 using namespace ::com::sun::star::ui;
71 using namespace ::com::sun::star::frame;
73 //_________________________________________________________________________________________________________________
74 // Namespace
75 //_________________________________________________________________________________________________________________
76 //
78 namespace framework
81 // global function needed by both implementations
82 rtl::OUString getHashKeyFromStrings( const rtl::OUString& aType, const rtl::OUString& aName, const rtl::OUString& aModuleName )
84 rtl::OUStringBuffer aKey( aType );
85 aKey.appendAscii( "^" );
86 aKey.append( aName );
87 aKey.appendAscii( "^" );
88 aKey.append( aModuleName );
89 return aKey.makeStringAndClear();
93 //*****************************************************************************************************************
94 // Configuration access class for UIElementFactoryManager implementation
95 //*****************************************************************************************************************
98 ConfigurationAccess_FactoryManager::ConfigurationAccess_FactoryManager( Reference< XMultiServiceFactory >& rServiceManager,const ::rtl::OUString& _sRoot ) :
99 ThreadHelpBase(),
100 m_aPropType( RTL_CONSTASCII_USTRINGPARAM( "Type" )),
101 m_aPropName( RTL_CONSTASCII_USTRINGPARAM( "Name" )),
102 m_aPropModule( RTL_CONSTASCII_USTRINGPARAM( "Module" )),
103 m_aPropFactory( RTL_CONSTASCII_USTRINGPARAM( "FactoryImplementation" )),
104 m_sRoot(_sRoot),
105 m_xServiceManager( rServiceManager ),
106 m_bConfigAccessInitialized( sal_False ),
107 m_bConfigDirty(true)
109 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::ConfigurationAccess_FactoryManager" );
110 m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance( SERVICENAME_CFGPROVIDER),UNO_QUERY );
113 ConfigurationAccess_FactoryManager::~ConfigurationAccess_FactoryManager()
115 // SAFE
116 ResetableGuard aLock( m_aLock );
118 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
119 if ( xContainer.is() )
120 xContainer->removeContainerListener( this );
123 rtl::OUString ConfigurationAccess_FactoryManager::getFactorySpecifierFromTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule ) const
125 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getFactorySpecifierFromTypeNameModule" );
126 // SAFE
127 ResetableGuard aLock( m_aLock );
129 FactoryManagerMap::const_iterator pIter =
130 m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rName, rModule ));
131 if ( pIter != m_aFactoryManagerMap.end() )
132 return pIter->second;
133 else
135 pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rName, rtl::OUString() ));
136 if ( pIter != m_aFactoryManagerMap.end() )
137 return pIter->second;
138 else
140 // Support factories which uses a defined prefix before the ui name.
141 sal_Int32 nIndex = rName.indexOf( '_' );
142 if ( nIndex > 0 )
144 rtl::OUString aName = rName.copy( 0, nIndex+1 );
145 pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, aName, rtl::OUString() ));
146 if ( pIter != m_aFactoryManagerMap.end() )
147 return pIter->second;
150 pIter = m_aFactoryManagerMap.find( getHashKeyFromStrings( rType, rtl::OUString(), rtl::OUString() ));
151 if ( pIter != m_aFactoryManagerMap.end() )
152 return pIter->second;
156 return rtl::OUString();
159 void ConfigurationAccess_FactoryManager::addFactorySpecifierToTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule, const rtl::OUString& rServiceSpecifier )
161 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::addFactorySpecifierToTypeNameModule" );
162 // SAFE
163 ResetableGuard aLock( m_aLock );
165 rtl::OUString aHashKey = getHashKeyFromStrings( rType, rName, rModule );
167 FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.find( aHashKey );
169 if ( pIter != m_aFactoryManagerMap.end() )
170 throw ElementExistException();
171 else
172 m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, rServiceSpecifier ));
176 void ConfigurationAccess_FactoryManager::removeFactorySpecifierFromTypeNameModule( const rtl::OUString& rType, const rtl::OUString& rName, const rtl::OUString& rModule )
178 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::removeFactorySpecifierFromTypeNameModule" );
179 // SAFE
180 ResetableGuard aLock( m_aLock );
182 rtl::OUString aHashKey = getHashKeyFromStrings( rType, rName, rModule );
184 FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.find( aHashKey );
186 if ( pIter == m_aFactoryManagerMap.end() )
187 throw NoSuchElementException();
188 else
189 m_aFactoryManagerMap.erase( aHashKey );
192 Sequence< Sequence< PropertyValue > > ConfigurationAccess_FactoryManager::getFactoriesDescription() const
194 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getFactoriesDescription" );
195 // SAFE
196 ResetableGuard aLock( m_aLock );
198 Sequence< Sequence< PropertyValue > > aSeqSeq;
200 sal_Int32 nIndex( 0 );
201 FactoryManagerMap::const_iterator pIter = m_aFactoryManagerMap.begin();
202 while ( pIter != m_aFactoryManagerMap.end() )
204 rtl::OUString aFactory = pIter->first;
205 if ( aFactory.getLength() > 0 )
207 sal_Int32 nToken = 0;
208 Sequence< PropertyValue > aSeq( 1 );
210 aSeqSeq.realloc( aSeqSeq.getLength() + 1 );
211 aSeq[0].Name = m_aPropType;
212 aSeq[0].Value = makeAny( aFactory.getToken( 0, '^', nToken ));
213 if ( nToken > 0 )
215 aSeq.realloc( 2 );
216 aSeq[1].Name = m_aPropName;
217 aSeq[1].Value = makeAny( aFactory.getToken( 0, '^', nToken ));
218 if ( nToken > 0 )
220 aSeq.realloc( 3 );
221 aSeq[2].Name = m_aPropModule;
222 aSeq[2].Value = makeAny( aFactory.getToken( 0, '^', nToken ));
226 aSeqSeq[nIndex++] = aSeq;
229 ++pIter;
232 return aSeqSeq;
235 // container.XContainerListener
236 void SAL_CALL ConfigurationAccess_FactoryManager::elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException)
238 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::elementInserted" );
239 rtl::OUString aType;
240 rtl::OUString aName;
241 rtl::OUString aModule;
242 rtl::OUString aService;
244 // SAFE
245 ResetableGuard aLock( m_aLock );
247 if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
249 // Create hash key from type, name and module as they are together a primary key to
250 // the UNO service that implements a user interface factory.
251 rtl::OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
252 m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, aService ));
256 void SAL_CALL ConfigurationAccess_FactoryManager::elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException)
258 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::elementRemoved " );
259 rtl::OUString aType;
260 rtl::OUString aName;
261 rtl::OUString aModule;
262 rtl::OUString aService;
264 // SAFE
265 ResetableGuard aLock( m_aLock );
267 if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
269 // Create hash key from command and model as they are together a primary key to
270 // the UNO service that implements the popup menu controller.
271 rtl::OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
272 m_aFactoryManagerMap.erase( aHashKey );
276 void SAL_CALL ConfigurationAccess_FactoryManager::elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException)
278 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::elementReplaced" );
279 rtl::OUString aType;
280 rtl::OUString aName;
281 rtl::OUString aModule;
282 rtl::OUString aService;
284 // SAFE
285 ResetableGuard aLock( m_aLock );
287 if ( impl_getElementProps( aEvent.Element, aType, aName, aModule, aService ))
289 // Create hash key from command and model as they are together a primary key to
290 // the UNO service that implements the popup menu controller.
291 rtl::OUString aHashKey( getHashKeyFromStrings( aType, aName, aModule ));
292 m_aFactoryManagerMap.erase( aHashKey );
293 m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, aService ));
297 // lang.XEventListener
298 void SAL_CALL ConfigurationAccess_FactoryManager::disposing( const EventObject& ) throw(RuntimeException)
300 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::disposing" );
301 // SAFE
302 // remove our reference to the config access
303 ResetableGuard aLock( m_aLock );
304 m_xConfigAccess.clear();
307 void ConfigurationAccess_FactoryManager::readConfigurationData()
309 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::readConfigurationData" );
310 // SAFE
311 ResetableGuard aLock( m_aLock );
313 if ( !m_bConfigAccessInitialized )
315 Sequence< Any > aArgs( 1 );
316 PropertyValue aPropValue;
318 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ));
319 aPropValue.Value <<= m_sRoot;
320 aArgs[0] <<= aPropValue;
324 m_xConfigAccess.set( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ), UNO_QUERY );
326 catch ( WrappedTargetException& )
330 m_bConfigAccessInitialized = sal_True;
333 if ( m_xConfigAccess.is() )
335 Sequence< rtl::OUString > aUIElementFactories = m_xConfigAccess->getElementNames();
337 rtl::OUString aType;
338 rtl::OUString aName;
339 rtl::OUString aModule;
340 rtl::OUString aService;
341 rtl::OUString aHashKey;
342 Reference< XPropertySet > xPropertySet;
343 for ( sal_Int32 i = 0; i < aUIElementFactories.getLength(); i++ )
345 if ( impl_getElementProps( m_xConfigAccess->getByName( aUIElementFactories[i] ), aType, aName, aModule, aService ))
347 // Create hash key from type, name and module as they are together a primary key to
348 // the UNO service that implements the user interface element factory.
349 aHashKey = getHashKeyFromStrings( aType, aName, aModule );
350 m_aFactoryManagerMap.insert( FactoryManagerMap::value_type( aHashKey, aService ));
354 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY );
355 aLock.unlock();
356 // UNSAFE
357 if ( xContainer.is() )
358 xContainer->addContainerListener( this );
362 sal_Bool ConfigurationAccess_FactoryManager::impl_getElementProps( const Any& aElement, rtl::OUString& rType, rtl::OUString& rName, rtl::OUString& rModule, rtl::OUString& rServiceSpecifier ) const
364 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::impl_getElementProps" );
365 Reference< XPropertySet > xPropertySet;
366 aElement >>= xPropertySet;
368 if ( xPropertySet.is() )
372 xPropertySet->getPropertyValue( m_aPropType ) >>= rType;
373 xPropertySet->getPropertyValue( m_aPropName ) >>= rName;
374 xPropertySet->getPropertyValue( m_aPropModule ) >>= rModule;
375 xPropertySet->getPropertyValue( m_aPropFactory ) >>= rServiceSpecifier;
377 catch ( com::sun::star::beans::UnknownPropertyException& )
379 return sal_False;
381 catch ( com::sun::star::lang::WrappedTargetException& )
383 return sal_False;
387 return sal_True;
390 //*****************************************************************************************************************
391 // XInterface, XTypeProvider, XServiceInfo
392 //*****************************************************************************************************************
393 DEFINE_XSERVICEINFO_ONEINSTANCESERVICE ( UIElementFactoryManager ,
394 ::cppu::OWeakObject ,
395 SERVICENAME_UIELEMENTFACTORYMANAGER ,
396 IMPLEMENTATIONNAME_UIELEMENTFACTORYMANAGER
399 DEFINE_INIT_SERVICE ( UIElementFactoryManager, {} )
401 UIElementFactoryManager::UIElementFactoryManager( const Reference< XMultiServiceFactory >& xServiceManager ) :
402 ThreadHelpBase( &Application::GetSolarMutex() ),
403 m_bConfigRead( sal_False ),
404 m_xServiceManager( xServiceManager )
406 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::UIElementFactoryManager" );
407 m_pConfigAccess = new ConfigurationAccess_FactoryManager( m_xServiceManager,rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.UI.Factories/Registered/UIElementFactories" )) );
408 m_pConfigAccess->acquire();
409 m_xModuleManager = Reference< XModuleManager >( m_xServiceManager->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY );
412 UIElementFactoryManager::~UIElementFactoryManager()
414 ResetableGuard aLock( m_aLock );
416 // reduce reference count
417 m_pConfigAccess->release();
420 // XUIElementFactory
421 Reference< XUIElement > SAL_CALL UIElementFactoryManager::createUIElement(
422 const ::rtl::OUString& ResourceURL,
423 const Sequence< PropertyValue >& Args )
424 throw ( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException )
426 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::createUIElement" );
427 // SAFE
428 ResetableGuard aLock( m_aLock );
430 if ( !m_bConfigRead )
432 m_bConfigRead = sal_True;
433 m_pConfigAccess->readConfigurationData();
436 const rtl::OUString aPropFrame( RTL_CONSTASCII_USTRINGPARAM( "Frame" ));
438 rtl::OUString aModuleId;
439 PropertyValue aPropValue;
440 Reference< XFrame > xFrame;
442 // Retrieve the frame instance from the arguments to determine the module identifier. This must be provided
443 // to the search function. An empty module identifier is provided if the frame is missing or the module id cannot
444 // retrieve from it.
445 for ( int i = 0; i < Args.getLength(); i++ )
447 if ( Args[i].Name.equals( aPropFrame ))
448 Args[i].Value >>= xFrame;
451 Reference< XModuleManager > xManager( m_xModuleManager );
452 aLock.unlock();
454 // Determine the module identifier
457 if ( xFrame.is() && xManager.is() )
458 aModuleId = xManager->identify( Reference< XInterface >( xFrame, UNO_QUERY ) );
460 Reference< XUIElementFactory > xUIElementFactory = getFactory( ResourceURL, aModuleId );
461 if ( xUIElementFactory.is() )
462 return xUIElementFactory->createUIElement( ResourceURL, Args );
464 catch ( UnknownModuleException& )
468 throw NoSuchElementException();
471 // XUIElementFactoryRegistration
472 Sequence< Sequence< PropertyValue > > SAL_CALL UIElementFactoryManager::getRegisteredFactories()
473 throw ( RuntimeException )
475 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getRegisteredFactories" );
476 // SAFE
477 ResetableGuard aLock( m_aLock );
479 if ( !m_bConfigRead )
481 m_bConfigRead = sal_True;
482 m_pConfigAccess->readConfigurationData();
485 return m_pConfigAccess->getFactoriesDescription();
488 Reference< XUIElementFactory > SAL_CALL UIElementFactoryManager::getFactory( const ::rtl::OUString& aResourceURL, const ::rtl::OUString& aModuleId )
489 throw ( RuntimeException )
491 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::getFactory" );
492 ResetableGuard aLock( m_aLock );
494 if ( !m_bConfigRead )
496 m_bConfigRead = sal_True;
497 m_pConfigAccess->readConfigurationData();
500 rtl::OUString aType;
501 rtl::OUString aName;
503 WindowContentFactoryManager::RetrieveTypeNameFromResourceURL( aResourceURL, aType, aName );
505 Reference< XMultiServiceFactory > xSManager( m_xServiceManager );
507 rtl::OUString aServiceSpecifier = m_pConfigAccess->getFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
509 aLock.unlock();
510 if ( aServiceSpecifier.getLength() )
511 return Reference< XUIElementFactory >( xSManager->createInstance( aServiceSpecifier ), UNO_QUERY );
512 else
513 return Reference< XUIElementFactory >();
516 void SAL_CALL UIElementFactoryManager::registerFactory( const ::rtl::OUString& aType, const ::rtl::OUString& aName, const ::rtl::OUString& aModuleId, const ::rtl::OUString& aFactoryImplementationName )
517 throw ( ElementExistException, RuntimeException )
519 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::registerFactory" );
520 // SAFE
521 ResetableGuard aLock( m_aLock );
523 if ( !m_bConfigRead )
525 m_bConfigRead = sal_True;
526 m_pConfigAccess->readConfigurationData();
529 m_pConfigAccess->addFactorySpecifierToTypeNameModule( aType, aName, aModuleId, aFactoryImplementationName );
530 // SAFE
533 void SAL_CALL UIElementFactoryManager::deregisterFactory( const ::rtl::OUString& aType, const ::rtl::OUString& aName, const ::rtl::OUString& aModuleId )
534 throw ( NoSuchElementException, RuntimeException )
536 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "UIElementFactoryManager::deregisterFactory" );
537 // SAFE
538 ResetableGuard aLock( m_aLock );
540 if ( !m_bConfigRead )
542 m_bConfigRead = sal_True;
543 m_pConfigAccess->readConfigurationData();
546 m_pConfigAccess->removeFactorySpecifierFromTypeNameModule( aType, aName, aModuleId );
547 // SAFE
550 } // namespace framework