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 31 //_________________________________________________________________________________________________________________ 32 // my own includes 33 //_________________________________________________________________________________________________________________ 34 #include "uifactory/factoryconfiguration.hxx" 35 #include <threadhelp/resetableguard.hxx> 36 #include "services.h" 37 38 //_________________________________________________________________________________________________________________ 39 // interface includes 40 //_________________________________________________________________________________________________________________ 41 #include <com/sun/star/beans/PropertyValue.hpp> 42 #include <com/sun/star/beans/XPropertySet.hpp> 43 #include <com/sun/star/container/XNameAccess.hpp> 44 #include <com/sun/star/container/XNameContainer.hpp> 45 #include <com/sun/star/container/XContainer.hpp> 46 47 //_________________________________________________________________________________________________________________ 48 // includes of other projects 49 //_________________________________________________________________________________________________________________ 50 #include <rtl/ustrbuf.hxx> 51 #include <cppuhelper/weak.hxx> 52 #include <rtl/logfile.hxx> 53 54 //_________________________________________________________________________________________________________________ 55 // Defines 56 //_________________________________________________________________________________________________________________ 57 // 58 using namespace com::sun::star; 59 using namespace com::sun::star::uno; 60 using namespace com::sun::star::lang; 61 using namespace com::sun::star::beans; 62 using namespace com::sun::star::container; 63 using namespace ::com::sun::star::frame; 64 65 //_________________________________________________________________________________________________________________ 66 // Namespace 67 //_________________________________________________________________________________________________________________ 68 // 69 70 namespace framework 71 { 72 rtl::OUString getHashKeyFromStrings( const rtl::OUString& aCommandURL, const rtl::OUString& aModuleName ) 73 { 74 rtl::OUStringBuffer aKey( aCommandURL ); 75 aKey.appendAscii( "-" ); 76 aKey.append( aModuleName ); 77 return aKey.makeStringAndClear(); 78 } 79 80 //***************************************************************************************************************** 81 // XInterface, XTypeProvider 82 //***************************************************************************************************************** 83 ConfigurationAccess_ControllerFactory::ConfigurationAccess_ControllerFactory( Reference< XMultiServiceFactory >& rServiceManager,const ::rtl::OUString& _sRoot,bool _bAskValue ) : 84 ThreadHelpBase(), 85 m_aPropCommand( RTL_CONSTASCII_USTRINGPARAM( "Command" )), 86 m_aPropModule( RTL_CONSTASCII_USTRINGPARAM( "Module" )), 87 m_aPropController( RTL_CONSTASCII_USTRINGPARAM( "Controller" )), 88 m_aPropValue( RTL_CONSTASCII_USTRINGPARAM( "Value" )), 89 m_sRoot(_sRoot), 90 m_xServiceManager( rServiceManager ), 91 m_bConfigAccessInitialized( sal_False ), 92 m_bAskValue(_bAskValue) 93 { 94 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::ConfigurationAccess_ControllerFactory" ); 95 m_xConfigProvider = Reference< XMultiServiceFactory >( rServiceManager->createInstance( SERVICENAME_CFGPROVIDER),UNO_QUERY ); 96 } 97 98 ConfigurationAccess_ControllerFactory::~ConfigurationAccess_ControllerFactory() 99 { 100 // SAFE 101 ResetableGuard aLock( m_aLock ); 102 103 Reference< XContainer > xContainer( m_xConfigAccess, UNO_QUERY ); 104 if ( xContainer.is() ) 105 xContainer->removeContainerListener( this ); 106 } 107 108 rtl::OUString ConfigurationAccess_ControllerFactory::getServiceFromCommandModule( const rtl::OUString& rCommandURL, const rtl::OUString& rModule ) const 109 { 110 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::getServiceFromCommandModule" ); 111 // SAFE 112 ResetableGuard aLock( m_aLock ); 113 MenuControllerMap::const_iterator pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rModule )); 114 115 if ( pIter != m_aMenuControllerMap.end() ) 116 return pIter->second.m_aImplementationName; 117 else if ( rModule.getLength() ) 118 { 119 // Try to detect if we have a generic popup menu controller 120 pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rtl::OUString() )); 121 122 if ( pIter != m_aMenuControllerMap.end() ) 123 return pIter->second.m_aImplementationName; 124 } 125 126 return rtl::OUString(); 127 } 128 rtl::OUString ConfigurationAccess_ControllerFactory::getValueFromCommandModule( const rtl::OUString& rCommandURL, const rtl::OUString& rModule ) const 129 { 130 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::getValueFromCommandModule" ); 131 // SAFE 132 ResetableGuard aLock( m_aLock ); 133 134 MenuControllerMap::const_iterator pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rModule )); 135 136 if ( pIter != m_aMenuControllerMap.end() ) 137 return pIter->second.m_aValue; 138 else if ( rModule.getLength() ) 139 { 140 // Try to detect if we have a generic popup menu controller 141 pIter = m_aMenuControllerMap.find( getHashKeyFromStrings( rCommandURL, rtl::OUString() )); 142 143 if ( pIter != m_aMenuControllerMap.end() ) 144 return pIter->second.m_aValue; 145 } 146 147 return rtl::OUString(); 148 } 149 150 151 void ConfigurationAccess_ControllerFactory::addServiceToCommandModule( 152 const rtl::OUString& rCommandURL, 153 const rtl::OUString& rModule, 154 const rtl::OUString& rServiceSpecifier ) 155 { 156 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::addServiceToCommandModule" ); 157 // SAFE 158 ResetableGuard aLock( m_aLock ); 159 160 rtl::OUString aHashKey = getHashKeyFromStrings( rCommandURL, rModule ); 161 m_aMenuControllerMap.insert( MenuControllerMap::value_type( aHashKey,ControllerInfo(rServiceSpecifier,::rtl::OUString()) )); 162 } 163 164 void ConfigurationAccess_ControllerFactory::removeServiceFromCommandModule( 165 const rtl::OUString& rCommandURL, 166 const rtl::OUString& rModule ) 167 { 168 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::removeServiceFromCommandModule" ); 169 // SAFE 170 ResetableGuard aLock( m_aLock ); 171 172 rtl::OUString aHashKey = getHashKeyFromStrings( rCommandURL, rModule ); 173 m_aMenuControllerMap.erase( aHashKey ); 174 } 175 176 // container.XContainerListener 177 void SAL_CALL ConfigurationAccess_ControllerFactory::elementInserted( const ContainerEvent& aEvent ) throw(RuntimeException) 178 { 179 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::elementInserted" ); 180 rtl::OUString aCommand; 181 rtl::OUString aModule; 182 rtl::OUString aService; 183 rtl::OUString aValue; 184 185 // SAFE 186 ResetableGuard aLock( m_aLock ); 187 188 if ( impl_getElementProps( aEvent.Element, aCommand, aModule, aService, aValue )) 189 { 190 // Create hash key from command and module as they are together a primary key to 191 // the UNO service that implements the popup menu controller. 192 rtl::OUString aHashKey( getHashKeyFromStrings( aCommand, aModule )); 193 ControllerInfo& rControllerInfo = m_aMenuControllerMap[ aHashKey ]; 194 rControllerInfo.m_aImplementationName = aService; 195 rControllerInfo.m_aValue = aValue; 196 } 197 } 198 199 void SAL_CALL ConfigurationAccess_ControllerFactory::elementRemoved ( const ContainerEvent& aEvent ) throw(RuntimeException) 200 { 201 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::elementRemoved" ); 202 rtl::OUString aCommand; 203 rtl::OUString aModule; 204 rtl::OUString aService; 205 rtl::OUString aValue; 206 207 // SAFE 208 ResetableGuard aLock( m_aLock ); 209 210 if ( impl_getElementProps( aEvent.Element, aCommand, aModule, aService, aValue )) 211 { 212 // Create hash key from command and module as they are together a primary key to 213 // the UNO service that implements the popup menu controller. 214 rtl::OUString aHashKey( getHashKeyFromStrings( aCommand, aModule )); 215 m_aMenuControllerMap.erase( aHashKey ); 216 } 217 } 218 219 void SAL_CALL ConfigurationAccess_ControllerFactory::elementReplaced( const ContainerEvent& aEvent ) throw(RuntimeException) 220 { 221 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::elementReplaced" ); 222 elementInserted(aEvent); 223 } 224 225 // lang.XEventListener 226 void SAL_CALL ConfigurationAccess_ControllerFactory::disposing( const EventObject& ) throw(RuntimeException) 227 { 228 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::disposing" ); 229 // SAFE 230 // remove our reference to the config access 231 ResetableGuard aLock( m_aLock ); 232 m_xConfigAccess.clear(); 233 } 234 235 void ConfigurationAccess_ControllerFactory::readConfigurationData() 236 { 237 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::readConfigurationData" ); 238 // SAFE 239 ResetableGuard aLock( m_aLock ); 240 241 if ( !m_bConfigAccessInitialized ) 242 { 243 Sequence< Any > aArgs( 1 ); 244 PropertyValue aPropValue; 245 246 aPropValue.Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" )); 247 aPropValue.Value <<= m_sRoot; 248 aArgs[0] <<= aPropValue; 249 250 try 251 { 252 m_xConfigAccess = Reference< XNameAccess >( m_xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS,aArgs ), UNO_QUERY ); 253 } 254 catch ( WrappedTargetException& ) 255 { 256 } 257 258 m_bConfigAccessInitialized = sal_True; 259 } 260 261 if ( m_xConfigAccess.is() ) 262 { 263 // Read and update configuration data 264 updateConfigurationData(); 265 266 uno::Reference< container::XContainer > xContainer( m_xConfigAccess, uno::UNO_QUERY ); 267 // UNSAFE 268 aLock.unlock(); 269 270 if ( xContainer.is() ) 271 xContainer->addContainerListener( this ); 272 } 273 } 274 275 void ConfigurationAccess_ControllerFactory::updateConfigurationData() 276 { 277 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::updateConfigurationData" ); 278 // SAFE 279 ResetableGuard aLock( m_aLock ); 280 if ( m_xConfigAccess.is() ) 281 { 282 Sequence< rtl::OUString > aPopupMenuControllers = m_xConfigAccess->getElementNames(); 283 284 rtl::OUString aCommand; 285 rtl::OUString aModule; 286 rtl::OUString aService; 287 rtl::OUString aHashKey; 288 rtl::OUString aValue; 289 290 m_aMenuControllerMap.clear(); 291 for ( sal_Int32 i = 0; i < aPopupMenuControllers.getLength(); i++ ) 292 { 293 try 294 { 295 if ( impl_getElementProps( m_xConfigAccess->getByName( aPopupMenuControllers[i] ), aCommand, aModule, aService,aValue )) 296 { 297 // Create hash key from command and module as they are together a primary key to 298 // the UNO service that implements the popup menu controller. 299 aHashKey = getHashKeyFromStrings( aCommand, aModule ); 300 m_aMenuControllerMap.insert( MenuControllerMap::value_type( aHashKey, ControllerInfo(aService,aValue) )); 301 } 302 } 303 catch ( NoSuchElementException& ) 304 { 305 } 306 catch ( WrappedTargetException& ) 307 { 308 } 309 } 310 } 311 } 312 313 sal_Bool ConfigurationAccess_ControllerFactory::impl_getElementProps( const Any& aElement, rtl::OUString& aCommand, rtl::OUString& aModule, rtl::OUString& aServiceSpecifier,rtl::OUString& aValue ) const 314 { 315 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "ConfigurationAccess_ControllerFactory::impl_getElementProps" ); 316 Reference< XPropertySet > xPropertySet; 317 aElement >>= xPropertySet; 318 319 if ( xPropertySet.is() ) 320 { 321 try 322 { 323 xPropertySet->getPropertyValue( m_aPropCommand ) >>= aCommand; 324 xPropertySet->getPropertyValue( m_aPropModule ) >>= aModule; 325 xPropertySet->getPropertyValue( m_aPropController ) >>= aServiceSpecifier; 326 if ( m_bAskValue ) 327 xPropertySet->getPropertyValue( m_aPropValue ) >>= aValue; 328 } 329 catch ( com::sun::star::beans::UnknownPropertyException& ) 330 { 331 return sal_False; 332 } 333 catch ( com::sun::star::lang::WrappedTargetException& ) 334 { 335 return sal_False; 336 } 337 } 338 339 return sal_True; 340 } 341 } // namespace framework 342