diff options
author | Mikhail Voytenko <mav@openoffice.org> | 2011-01-06 14:57:12 +0100 |
---|---|---|
committer | Mikhail Voytenko <mav@openoffice.org> | 2011-01-06 14:57:12 +0100 |
commit | 8ff51afa0dcd4e5e644e923131ee72435c80b57b (patch) | |
tree | d63f6b6e298485b5f29f60c7af25baca46f59375 /framework/source/fwi | |
parent | fa1f3c352c6126b24ab5af87ea4ebea742c546c2 (diff) | |
parent | 794c821e4d48c34aa376cdc7b6ab2cb029d9574d (diff) |
removetooltypes01: rebase to DEV300_m96
Diffstat (limited to 'framework/source/fwi')
-rw-r--r-- | framework/source/fwi/classes/converter.cxx | 316 | ||||
-rw-r--r-- | framework/source/fwi/classes/propertysethelper.cxx | 450 | ||||
-rw-r--r-- | framework/source/fwi/classes/protocolhandlercache.cxx | 361 | ||||
-rw-r--r-- | framework/source/fwi/helper/mischelper.cxx | 242 | ||||
-rw-r--r-- | framework/source/fwi/helper/networkdomain.cxx | 295 | ||||
-rw-r--r-- | framework/source/fwi/helper/shareablemutex.cxx | 81 | ||||
-rw-r--r-- | framework/source/fwi/jobs/configaccess.cxx | 242 | ||||
-rw-r--r-- | framework/source/fwi/jobs/jobconst.cxx | 74 | ||||
-rw-r--r-- | framework/source/fwi/threadhelp/lockhelper.cxx | 549 | ||||
-rw-r--r-- | framework/source/fwi/threadhelp/transactionmanager.cxx | 374 | ||||
-rw-r--r-- | framework/source/fwi/uielement/constitemcontainer.cxx | 479 | ||||
-rw-r--r-- | framework/source/fwi/uielement/itemcontainer.cxx | 266 | ||||
-rw-r--r-- | framework/source/fwi/uielement/rootitemcontainer.cxx | 466 |
13 files changed, 4195 insertions, 0 deletions
diff --git a/framework/source/fwi/classes/converter.cxx b/framework/source/fwi/classes/converter.cxx new file mode 100644 index 000000000000..d70b099c9e03 --- /dev/null +++ b/framework/source/fwi/classes/converter.cxx @@ -0,0 +1,316 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <classes/converter.hxx> +#include <rtl/ustrbuf.hxx> + +namespace framework{ + +//----------------------------------------------------------------------------- +/** + * pack every property item of source list into an any entry of destination list + * Resulting list will have follow format then: "sequence< Any(PropertyValue) >". + * If one item couldn't be converted it will be ignored - means target list can + * be smaller then source list. Source list isn't changed anytime. + * + * algorithm: + * (a) reserve enough space on destination list for all possible entries of + * source list + * (b) try to pack every property of source into an any of destination list + * (b1) count successfully packed entries only + * (c) use this count of packed entries to resize destination list + * Because we getted enough space before - that will remove unused items + * of destination list at the end of it only. + */ +css::uno::Sequence< css::uno::Any > Converter::convert_seqProp2seqAny( const css::uno::Sequence< css::beans::PropertyValue >& lSource ) +{ + sal_Int32 nCount = lSource.getLength(); + css::uno::Sequence< css::uno::Any > lDestination(nCount); + + for (sal_Int32 nItem=0; nItem<nCount; ++nItem) + lDestination[nItem]<<=lSource[nItem]; + + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + * do the same like convert_seqProp2seqAny() before - but reverse. + * It try to unpack PropertyValue items from given Any's. + */ +css::uno::Sequence< css::beans::PropertyValue > Converter::convert_seqAny2seqProp( const css::uno::Sequence< css::uno::Any >& lSource ) +{ + sal_Int32 nCount = lSource.getLength(); + sal_Int32 nRealCount = 0; + css::uno::Sequence< css::beans::PropertyValue > lDestination(nCount); + + for (sal_Int32 nItem=0; nItem<nCount; ++nItem) + { + if (lSource[nItem]>>=lDestination[nItem]) + ++nRealCount; + } + + if (nRealCount!=nCount) + lDestination.realloc(nRealCount); + + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + * converts a sequence of NamedValue to a sequence of PropertyValue. + */ +css::uno::Sequence< css::beans::PropertyValue > Converter::convert_seqNamedVal2seqPropVal( const css::uno::Sequence< css::beans::NamedValue >& lSource ) +{ + sal_Int32 nCount = lSource.getLength(); + css::uno::Sequence< css::beans::PropertyValue > lDestination(nCount); + for (sal_Int32 nItem=0; nItem<nCount; ++nItem) + { + lDestination[nItem].Name = lSource[nItem].Name ; + lDestination[nItem].Value = lSource[nItem].Value; + } + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + * converts a sequence of PropertyValue to a sequence of NamedValue. + */ +css::uno::Sequence< css::beans::NamedValue > Converter::convert_seqPropVal2seqNamedVal( const css::uno::Sequence< css::beans::PropertyValue >& lSource ) +{ + sal_Int32 nCount = lSource.getLength(); + css::uno::Sequence< css::beans::NamedValue > lDestination(nCount); + for (sal_Int32 nItem=0; nItem<nCount; ++nItem) + { + lDestination[nItem].Name = lSource[nItem].Name ; + lDestination[nItem].Value = lSource[nItem].Value; + } + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + * converts a sequence of unicode strings into a vector of such items + */ +OUStringList Converter::convert_seqOUString2OUStringList( const css::uno::Sequence< ::rtl::OUString >& lSource ) +{ + OUStringList lDestination; + sal_Int32 nCount = lSource.getLength(); + + for (sal_Int32 nItem=0; nItem<nCount; ++nItem ) + { + lDestination.push_back(lSource[nItem]); + } + + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + * converts a vector of unicode strings into a sequence of such items + */ +css::uno::Sequence< ::rtl::OUString > Converter::convert_OUStringList2seqOUString( const OUStringList& lSource ) +{ + css::uno::Sequence< ::rtl::OUString > lDestination(lSource.size()); + sal_uInt32 nItem = 0; + for (OUStringList::const_iterator pIterator=lSource.begin(); pIterator!=lSource.end(); ++pIterator) + { + lDestination[nItem] = *pIterator; + ++nItem; + } + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + * converts an unicode string hash to a sequence<PropertyValue>, where names and values match to key and values. + */ +css::uno::Sequence< css::beans::PropertyValue > Converter::convert_OUStringHash2seqProp( const OUStringHash& lSource ) +{ + css::uno::Sequence< css::beans::PropertyValue > lDestination (lSource.size()); + css::beans::PropertyValue* pDestination = lDestination.getArray(); + sal_Int32 nItem = 0; + for (OUStringHash::const_iterator pItem=lSource.begin(); pItem!=lSource.end(); ++pItem) + { + pDestination[nItem].Name = pItem->first ; + pDestination[nItem].Value <<= pItem->second; + ++nItem; + } + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + * converts a sequence<PropertyValue> to an unicode string hash, where keys and values match to names and values. + */ +OUStringHash Converter::convert_seqProp2OUStringHash( const css::uno::Sequence< css::beans::PropertyValue >& lSource ) +{ + OUStringHash lDestination; + sal_Int32 nCount = lSource.getLength(); + const css::beans::PropertyValue* pSource = lSource.getConstArray(); + for (sal_Int32 nItem=0; nItem<nCount; ++nItem) + { + pSource[nItem].Value >>= lDestination[pSource[nItem].Name]; + } + return lDestination; +} + +//----------------------------------------------------------------------------- +/** + @short convert timestamp from String to tools::DateTime notation + @descr Format: "<day>.<month>.<year>/<hour>:<min>:<sec>" + e.g. : "1.11.2001/13:45:16" + + @param sString + timestamp in string notation + + @return timestamp in DateTime notation + */ +DateTime Converter::convert_String2DateTime( /*IN*/ const ::rtl::OUString& sSource ) +{ + DateTime aStamp ; + sal_Int32 nIndex = 0; + + sal_uInt16 nDay = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'.', nIndex ).toInt32()); + if( nIndex>0 ) + { + sal_uInt16 nMonth = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'.', nIndex ).toInt32()); + if( nIndex>0 ) + { + sal_uInt16 nYear = (sal_uInt16)(sSource.getToken( 0, (sal_Unicode)'/', nIndex ).toInt32()); + if( nIndex>0 ) + { + sal_uInt32 nHour = sSource.getToken( 0, (sal_Unicode)':', nIndex ).toInt32(); + if( nIndex>0 ) + { + sal_uInt32 nMin = sSource.getToken( 0, (sal_Unicode)':', nIndex ).toInt32(); + if( nIndex>0 && nIndex<sSource.getLength() ) + { + sal_uInt32 nSec = sSource.copy( nIndex, sSource.getLength()-nIndex ).toInt32(); + + Date aDate( nDay , nMonth, nYear ); + Time aTime( nHour, nMin , nSec ); + aStamp = DateTime( aDate, aTime ); + } + } + } + } + } + return aStamp; +} + +//----------------------------------------------------------------------------- +/** + @short convert timestamp from DateTime to String notation + @descr Format: "<day>.<month>.<year>/<hour>:<min>:<sec>" + e.g. : "1.11.2001/13:45:16" + + @param aStamp + timestamp in DateTime notation + + @return timestamp in String notation + */ +::rtl::OUString Converter::convert_DateTime2String( /*IN*/ const DateTime& aSource ) +{ + ::rtl::OUStringBuffer sBuffer(25); + + sBuffer.append( (sal_Int32)aSource.GetDay() ); + sBuffer.append( (sal_Unicode)'.' ); + sBuffer.append( (sal_Int32)aSource.GetMonth() ); + sBuffer.append( (sal_Unicode)'.' ); + sBuffer.append( (sal_Int32)aSource.GetYear() ); + sBuffer.append( (sal_Unicode)'/' ); + sBuffer.append( (sal_Int32)aSource.GetHour() ); + sBuffer.append( (sal_Unicode)':' ); + sBuffer.append( (sal_Int32)aSource.GetMin() ); + sBuffer.append( (sal_Unicode)':' ); + sBuffer.append( (sal_Int32)aSource.GetSec() ); + + return sBuffer.makeStringAndClear(); +} + +::rtl::OUString Converter::convert_DateTime2ISO8601( const DateTime& aSource ) +{ + ::rtl::OUStringBuffer sBuffer(25); + + sal_Int32 nYear = aSource.GetYear(); + sal_Int32 nMonth = aSource.GetMonth(); + sal_Int32 nDay = aSource.GetDay(); + + sal_Int32 nHour = aSource.GetHour(); + sal_Int32 nMin = aSource.GetMin(); + sal_Int32 nSec = aSource.GetSec(); + + // write year formated as "YYYY" + if (nYear<10) + sBuffer.appendAscii("000"); + else + if (nYear<100) + sBuffer.appendAscii("00"); + else + if (nYear<1000) + sBuffer.appendAscii("0"); + sBuffer.append( (sal_Int32)nYear ); + + sBuffer.appendAscii("-"); + // write month formated as "MM" + if (nMonth<10) + sBuffer.appendAscii("0"); + sBuffer.append( (sal_Int32)nMonth ); + + sBuffer.appendAscii("-"); + // write day formated as "DD" + if (nDay<10) + sBuffer.appendAscii("0"); + sBuffer.append( (sal_Int32)nDay ); + + sBuffer.appendAscii("T"); + // write hours formated as "hh" + if (nHour<10) + sBuffer.appendAscii("0"); + sBuffer.append( (sal_Int32)nHour ); + + sBuffer.appendAscii(":"); + // write min formated as "mm" + if (nMin<10) + sBuffer.appendAscii("0"); + sBuffer.append( (sal_Int32)nMin ); + + sBuffer.appendAscii(":"); + // write sec formated as "ss" + if (nSec<10) + sBuffer.appendAscii("0"); + sBuffer.append( (sal_Int32)nSec ); + + sBuffer.appendAscii("Z"); + + return sBuffer.makeStringAndClear(); +} + +} // namespace framework diff --git a/framework/source/fwi/classes/propertysethelper.cxx b/framework/source/fwi/classes/propertysethelper.cxx new file mode 100644 index 000000000000..2e41106a9ceb --- /dev/null +++ b/framework/source/fwi/classes/propertysethelper.cxx @@ -0,0 +1,450 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes + +#include <classes/propertysethelper.hxx> +#include <threadhelp/transactionguard.hxx> +#include <threadhelp/readguard.hxx> +#include <threadhelp/writeguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes + +//_________________________________________________________________________________________________________________ +// other includes + +//_________________________________________________________________________________________________________________ +// namespace + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// non exported definitions + +//----------------------------------------------------------------------------- +PropertySetHelper::PropertySetHelper(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , + LockHelper* pExternalLock , + TransactionManager* pExternalTransactionManager , + sal_Bool bReleaseLockOnCall ) + : m_xSMGR (xSMGR ) + , m_lSimpleChangeListener(pExternalLock->getShareableOslMutex()) + , m_lVetoChangeListener (pExternalLock->getShareableOslMutex()) + , m_bReleaseLockOnCall (bReleaseLockOnCall ) + , m_rLock (*pExternalLock ) + , m_rTransactionManager (*pExternalTransactionManager ) +{ +} + +//----------------------------------------------------------------------------- +PropertySetHelper::~PropertySetHelper() +{ +} + +//----------------------------------------------------------------------------- +void PropertySetHelper::impl_setPropertyChangeBroadcaster(const css::uno::Reference< css::uno::XInterface >& xBroadcaster) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS); + + // SAFE -> + WriteGuard aWriteLock(m_rLock); + m_xBroadcaster = xBroadcaster; + aWriteLock.unlock(); + // <- SAFE +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::impl_addPropertyInfo(const css::beans::Property& aProperty) + throw(css::beans::PropertyExistException, + css::uno::Exception ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS); + + // SAFE -> + WriteGuard aWriteLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(aProperty.Name); + if (pIt != m_lProps.end()) + throw css::beans::PropertyExistException(); + + m_lProps[aProperty.Name] = aProperty; + // <- SAFE +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::impl_removePropertyInfo(const ::rtl::OUString& sProperty) + throw(css::beans::UnknownPropertyException, + css::uno::Exception ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS); + + // SAFE -> + WriteGuard aWriteLock(m_rLock); + + PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sProperty); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + m_lProps.erase(pIt); + // <- SAFE +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::impl_enablePropertySet() +{ +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::impl_disablePropertySet() +{ + TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS); + + // SAFE -> + WriteGuard aWriteLock(m_rLock); + + css::uno::Reference< css::uno::XInterface > xThis(static_cast< css::beans::XPropertySet* >(this), css::uno::UNO_QUERY); + css::lang::EventObject aEvent(xThis); + + m_lSimpleChangeListener.disposeAndClear(aEvent); + m_lVetoChangeListener.disposeAndClear(aEvent); + m_lProps.free(); + + aWriteLock.unlock(); + // <- SAFE +} + +//----------------------------------------------------------------------------- +sal_Bool PropertySetHelper::impl_existsVeto(const css::beans::PropertyChangeEvent& aEvent) +{ + /* Dont use the lock here! + The used helper is threadsafe and it lives for the whole lifetime of + our own object. + */ + ::cppu::OInterfaceContainerHelper* pVetoListener = m_lVetoChangeListener.getContainer(aEvent.PropertyName); + if (! pVetoListener) + return sal_False; + + ::cppu::OInterfaceIteratorHelper pListener(*pVetoListener); + while (pListener.hasMoreElements()) + { + try + { + css::uno::Reference< css::beans::XVetoableChangeListener > xListener( + ((css::beans::XVetoableChangeListener*)pListener.next()), + css::uno::UNO_QUERY_THROW); + xListener->vetoableChange(aEvent); + } + catch(const css::uno::RuntimeException&) + { pListener.remove(); } + catch(const css::beans::PropertyVetoException&) + { return sal_True; } + } + + return sal_False; +} + +//----------------------------------------------------------------------------- +void PropertySetHelper::impl_notifyChangeListener(const css::beans::PropertyChangeEvent& aEvent) +{ + /* Dont use the lock here! + The used helper is threadsafe and it lives for the whole lifetime of + our own object. + */ + ::cppu::OInterfaceContainerHelper* pSimpleListener = m_lSimpleChangeListener.getContainer(aEvent.PropertyName); + if (! pSimpleListener) + return; + + ::cppu::OInterfaceIteratorHelper pListener(*pSimpleListener); + while (pListener.hasMoreElements()) + { + try + { + css::uno::Reference< css::beans::XPropertyChangeListener > xListener( + ((css::beans::XVetoableChangeListener*)pListener.next()), + css::uno::UNO_QUERY_THROW); + xListener->propertyChange(aEvent); + } + catch(const css::uno::RuntimeException&) + { pListener.remove(); } + } +} + +//----------------------------------------------------------------------------- +css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PropertySetHelper::getPropertySetInfo() + throw(css::uno::RuntimeException) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + css::uno::Reference< css::beans::XPropertySetInfo > xInfo(static_cast< css::beans::XPropertySetInfo* >(this), css::uno::UNO_QUERY_THROW); + return xInfo; +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::setPropertyValue(const ::rtl::OUString& sProperty, + const css::uno::Any& aValue ) + throw(css::beans::UnknownPropertyException, + css::beans::PropertyVetoException , + css::lang::IllegalArgumentException , + css::lang::WrappedTargetException , + css::uno::RuntimeException ) +{ + // TODO look for e.g. readonly props and reject setProp() call! + + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + // SAFE -> + WriteGuard aWriteLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + css::beans::Property aPropInfo = pIt->second; + + sal_Bool bLocked = sal_True; + if (m_bReleaseLockOnCall) + { + aWriteLock.unlock(); + bLocked = sal_False; + // <- SAFE + } + + css::uno::Any aCurrentValue = impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle); + + if (! bLocked) + { + // SAFE -> + aWriteLock.lock(); + bLocked = sal_True; + } + + sal_Bool bWillBeChanged = (aCurrentValue != aValue); + if (! bWillBeChanged) + return; + + css::beans::PropertyChangeEvent aEvent; + aEvent.PropertyName = aPropInfo.Name; + aEvent.Further = sal_False; + aEvent.PropertyHandle = aPropInfo.Handle; + aEvent.OldValue = aCurrentValue; + aEvent.NewValue = aValue; + aEvent.Source = css::uno::Reference< css::uno::XInterface >(m_xBroadcaster.get(), css::uno::UNO_QUERY); + + if (m_bReleaseLockOnCall) + { + aWriteLock.unlock(); + bLocked = sal_False; + // <- SAFE + } + + if (impl_existsVeto(aEvent)) + throw css::beans::PropertyVetoException(); + + impl_setPropertyValue(aPropInfo.Name, aPropInfo.Handle, aValue); + + impl_notifyChangeListener(aEvent); +} + +//----------------------------------------------------------------------------- +css::uno::Any SAL_CALL PropertySetHelper::getPropertyValue(const ::rtl::OUString& sProperty) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException , + css::uno::RuntimeException ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + css::beans::Property aPropInfo = pIt->second; + + sal_Bool bLocked = sal_True; + if (m_bReleaseLockOnCall) + { + aReadLock.unlock(); + bLocked = sal_False; + // <- SAFE + } + + return impl_getPropertyValue(aPropInfo.Name, aPropInfo.Handle); +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::addPropertyChangeListener(const ::rtl::OUString& sProperty, + const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException , + css::uno::RuntimeException ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + aReadLock.unlock(); + // <- SAFE + + m_lSimpleChangeListener.addInterface(sProperty, xListener); +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::removePropertyChangeListener(const ::rtl::OUString& sProperty, + const css::uno::Reference< css::beans::XPropertyChangeListener >& xListener) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException , + css::uno::RuntimeException ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + aReadLock.unlock(); + // <- SAFE + + m_lSimpleChangeListener.removeInterface(sProperty, xListener); +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::addVetoableChangeListener(const ::rtl::OUString& sProperty, + const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException , + css::uno::RuntimeException ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + aReadLock.unlock(); + // <- SAFE + + m_lVetoChangeListener.addInterface(sProperty, xListener); +} + +//----------------------------------------------------------------------------- +void SAL_CALL PropertySetHelper::removeVetoableChangeListener(const ::rtl::OUString& sProperty, + const css::uno::Reference< css::beans::XVetoableChangeListener >& xListener) + throw(css::beans::UnknownPropertyException, + css::lang::WrappedTargetException , + css::uno::RuntimeException ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_SOFTEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sProperty); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + aReadLock.unlock(); + // <- SAFE + + m_lVetoChangeListener.removeInterface(sProperty, xListener); +} + +//----------------------------------------------------------------------------- +css::uno::Sequence< css::beans::Property > SAL_CALL PropertySetHelper::getProperties() + throw(css::uno::RuntimeException) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + sal_Int32 c = (sal_Int32)m_lProps.size(); + css::uno::Sequence< css::beans::Property > lProps(c); + PropertySetHelper::TPropInfoHash::const_iterator pIt ; + + for ( pIt = m_lProps.begin(); + pIt != m_lProps.end() ; + ++pIt ) + { + lProps[--c] = pIt->second; + } + + return lProps; + // <- SAFE +} + +//----------------------------------------------------------------------------- +css::beans::Property SAL_CALL PropertySetHelper::getPropertyByName(const ::rtl::OUString& sName) + throw(css::beans::UnknownPropertyException, + css::uno::RuntimeException ) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + PropertySetHelper::TPropInfoHash::const_iterator pIt = m_lProps.find(sName); + if (pIt == m_lProps.end()) + throw css::beans::UnknownPropertyException(); + + return pIt->second; + // <- SAFE +} + +//----------------------------------------------------------------------------- +sal_Bool SAL_CALL PropertySetHelper::hasPropertyByName(const ::rtl::OUString& sName) + throw(css::uno::RuntimeException) +{ + TransactionGuard aTransaction(m_rTransactionManager, E_HARDEXCEPTIONS); + + // SAFE -> + ReadGuard aReadLock(m_rLock); + + PropertySetHelper::TPropInfoHash::iterator pIt = m_lProps.find(sName); + sal_Bool bExist = (pIt != m_lProps.end()); + + return bExist; + // <- SAFE +} + +} // namespace framework diff --git a/framework/source/fwi/classes/protocolhandlercache.cxx b/framework/source/fwi/classes/protocolhandlercache.cxx new file mode 100644 index 000000000000..89412e9c6c65 --- /dev/null +++ b/framework/source/fwi/classes/protocolhandlercache.cxx @@ -0,0 +1,361 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +/*TODO + - change "singleton" behaviour by using new helper ::comhelper::SingletonRef + - rename method exist() to existHandlerForURL() or similar one + - may its a good idea to replace struct ProtocolHandler by css::beans::NamedValue type?! +*/ + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ + +#include <classes/protocolhandlercache.hxx> +#include <classes/converter.hxx> +#include <threadhelp/readguard.hxx> +#include <threadhelp/writeguard.hxx> +#include <threadhelp/lockhelper.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <tools/wldcrd.hxx> +#include <unotools/configpathes.hxx> +#include <rtl/ustrbuf.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// non exported const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// non exported definitions +//_________________________________________________________________________________________________________________ + +/** + @short overloaded index operator of hash map to support pattern key search + @descr All keys inside this hash map are URL pattern which points to an uno + implementation name of a protocol handler service which is registered + for this pattern. This operator makes it easy to find such registered + handler by using a full qualified URL and compare it with all pattern + keys. + + @param sURL + the full qualified URL which should match to a registered pattern + + @return An iterator which points to the found item inside the hash or PatternHash::end() + if no pattern match this given <var>sURL</var>. + + @modified 30.04.2002 09:52, as96863 + */ +PatternHash::iterator PatternHash::findPatternKey( const ::rtl::OUString& sURL ) +{ + PatternHash::iterator pItem = this->begin(); + while( pItem!=this->end() ) + { + WildCard aPattern(pItem->first); + if (aPattern.Matches(sURL)) + break; + ++pItem; + } + return pItem; +} + +//_________________________________________________________________________________________________________________ + +/** + @short initialize static member of class HandlerCache + @descr We use a singleton pattern to implement this handler cache. + That means it use two static member list to hold all neccessary informations + and a ref count mechanism to create/destroy it on demand. + + @modified 30.04.2002 11:13, as96863 + */ +HandlerHash* HandlerCache::m_pHandler = NULL; +PatternHash* HandlerCache::m_pPattern = NULL; +sal_Int32 HandlerCache::m_nRefCount = 0 ; +HandlerCFGAccess* HandlerCache::m_pConfig = NULL; + +//_________________________________________________________________________________________________________________ + +/** + @short ctor of the cache of all registered protoco handler + @descr It tries to open the right configuration package automaticly + and fill the internal structures. After that the cache can be + used for read access on this data and perform some search + operations on it. + + @modified 30.04.2002 10:02, as96863 + */ +HandlerCache::HandlerCache() +{ + /* SAFE */{ + WriteGuard aGlobalLock( LockHelper::getGlobalLock() ); + + if (m_nRefCount==0) + { + m_pHandler = new HandlerHash(); + m_pPattern = new PatternHash(); + m_pConfig = new HandlerCFGAccess(PACKAGENAME_PROTOCOLHANDLER); + m_pConfig->read(&m_pHandler,&m_pPattern); + m_pConfig->setCache(this); + } + + ++m_nRefCount; + /* SAFE */} +} + +//_________________________________________________________________________________________________________________ + +/** + @short dtor of the cache + @descr It frees all used memory. In further implementations (may if we support write access too) + it's a good place to flush changes back to the configuration - but not needed yet. + + @modified 30.04.2002 09:54, as96863 + */ +HandlerCache::~HandlerCache() +{ + /* SAFE */{ + WriteGuard aGlobalLock( LockHelper::getGlobalLock() ); + + if( m_nRefCount==1) + { + m_pConfig->setCache(NULL); + m_pHandler->free(); + m_pPattern->free(); + + delete m_pConfig; + delete m_pHandler; + delete m_pPattern; + m_pConfig = NULL; + m_pHandler= NULL; + m_pPattern= NULL; + } + + --m_nRefCount; + /* SAFE */} +} + +//_________________________________________________________________________________________________________________ + +/** + @short dtor of the cache + @descr It frees all used memory. In further implementations (may if we support write access too) + it's a good place to flush changes back to the configuration - but not needed yet. + + @modified 30.04.2002 09:54, as96863 + */ +sal_Bool HandlerCache::search( const ::rtl::OUString& sURL, ProtocolHandler* pReturn ) const +{ + sal_Bool bFound = sal_False; + /* SAFE */{ + ReadGuard aReadLock( LockHelper::getGlobalLock() ); + PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL); + if (pItem!=m_pPattern->end()) + { + *pReturn = (*m_pHandler)[pItem->second]; + bFound = sal_True; + } + /* SAFE */} + return bFound; +} + +//_________________________________________________________________________________________________________________ + +/** + @short search for a registered handler by using an URL struct + @descr We combine neccessary parts of this struct to a valid URL string + and call our other search method ... + It's a helper for outside code. + + @modified 30.04.2002 09:54, as96863 + */ +sal_Bool HandlerCache::search( const css::util::URL& aURL, ProtocolHandler* pReturn ) const +{ + return search( aURL.Complete, pReturn ); +} + +//_________________________________________________________________________________________________________________ + +sal_Bool HandlerCache::exists( const ::rtl::OUString& sURL ) const +{ + sal_Bool bFound = sal_False; + /* SAFE */{ + ReadGuard aReadLock( LockHelper::getGlobalLock() ); + PatternHash::const_iterator pItem = m_pPattern->findPatternKey(sURL); + bFound = pItem!=m_pPattern->end(); + /* SAFE */} + return bFound; +} + +//_________________________________________________________________________________________________________________ +void HandlerCache::takeOver(HandlerHash* pHandler, PatternHash* pPattern) +{ + // SAFE -> + WriteGuard aWriteLock( LockHelper::getGlobalLock() ); + + HandlerHash* pOldHandler = m_pHandler; + PatternHash* pOldPattern = m_pPattern; + + m_pHandler = pHandler; + m_pPattern = pPattern; + + pOldHandler->free(); + pOldPattern->free(); + delete pOldHandler; + delete pOldPattern; + + aWriteLock.unlock(); + // <- SAFE +} + +//_________________________________________________________________________________________________________________ + +/** + @short dtor of the config access class + @descr It opens the configuration package automaticly by using base class mechanism. + After that "read()" method of this class should be called to use it. + + @param sPackage + specifies the package name of the configuration data which should be used + + @modified 30.04.2002 10:06, as96863 + */ +HandlerCFGAccess::HandlerCFGAccess( const ::rtl::OUString& sPackage ) + : ConfigItem( sPackage ) +{ + css::uno::Sequence< ::rtl::OUString > lListenPathes(1); + lListenPathes[0] = SETNAME_HANDLER; + EnableNotification(lListenPathes); +} + +//_________________________________________________________________________________________________________________ + +/** + @short use base class mechanism to fill given structures + @descr User use us as a wrapper between configuration api and his internal structures. + He give us some pointer to his member and we fill it. + + @param pHandler + pointer to a list of protocol handler infos + + @param pPattern + reverse map of handler pattern to her uno names + + @modified 30.04.2002 09:54, as96863 + */ +void HandlerCFGAccess::read( HandlerHash** ppHandler , + PatternHash** ppPattern ) +{ + // list of all uno implementation names without encoding + css::uno::Sequence< ::rtl::OUString > lNames = GetNodeNames( SETNAME_HANDLER, ::utl::CONFIG_NAME_LOCAL_PATH ); + sal_Int32 nSourceCount = lNames.getLength(); + sal_Int32 nTargetCount = nSourceCount; + // list of all full qualified path names of configuration entries + css::uno::Sequence< ::rtl::OUString > lFullNames ( nTargetCount ); + + // expand names to full path names + sal_Int32 nSource=0; + sal_Int32 nTarget=0; + for( nSource=0; nSource<nSourceCount; ++nSource ) + { + ::rtl::OUStringBuffer sPath( SETNAME_HANDLER ); + sPath.append(CFG_PATH_SEPERATOR); + sPath.append(lNames[nSource]); + sPath.append(CFG_PATH_SEPERATOR); + sPath.append(PROPERTY_PROTOCOLS); + + lFullNames[nTarget] = sPath.makeStringAndClear(); + ++nTarget; + } + + // get values at all + css::uno::Sequence< css::uno::Any > lValues = GetProperties( lFullNames ); + LOG_ASSERT2( lFullNames.getLength()!=lValues.getLength(), "HandlerCFGAccess::read()", "Miss some configuration values of handler set!" ) + + // fill structures + nSource = 0; + for( nTarget=0; nTarget<nTargetCount; ++nTarget ) + { + // create it new for every loop to guarantee a real empty object! + ProtocolHandler aHandler; + aHandler.m_sUNOName = ::utl::extractFirstFromConfigurationPath(lNames[nSource]); + + // unpack all values of this handler + css::uno::Sequence< ::rtl::OUString > lTemp; + lValues[nTarget] >>= lTemp; + aHandler.m_lProtocols = Converter::convert_seqOUString2OUStringList(lTemp); + + // register his pattern into the performance search hash + for (OUStringList::iterator pItem =aHandler.m_lProtocols.begin(); + pItem!=aHandler.m_lProtocols.end() ; + ++pItem ) + { + (**ppPattern)[*pItem] = lNames[nSource]; + } + + // ï¿œnsert the handler info into the normal handler cache + (**ppHandler)[lNames[nSource]] = aHandler; + ++nSource; + } +} + +//_________________________________________________________________________________________________________________ +void HandlerCFGAccess::Notify(const css::uno::Sequence< rtl::OUString >& /*lPropertyNames*/) +{ + HandlerHash* pHandler = new HandlerHash; + PatternHash* pPattern = new PatternHash; + + read(&pHandler, &pPattern); + if (m_pCache) + m_pCache->takeOver(pHandler, pPattern); + else + { + delete pHandler; + delete pPattern; + } +} + +void HandlerCFGAccess::Commit() +{ +} + +} // namespace framework diff --git a/framework/source/fwi/helper/mischelper.cxx b/framework/source/fwi/helper/mischelper.cxx new file mode 100644 index 000000000000..641200069dfc --- /dev/null +++ b/framework/source/fwi/helper/mischelper.cxx @@ -0,0 +1,242 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/document/XDocumentLanguages.hpp> +#include <com/sun/star/frame/XModuleManager.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> + +#include <tools/debug.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <i18npool/mslangid.hxx> +#include <svtools/langtab.hxx> +#include <comphelper/processfactory.hxx> +#include <helper/mischelper.hxx> +#include <services.h> + + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::frame; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; + +using ::rtl::OUString; + + +namespace framework +{ + +uno::Reference< linguistic2::XLanguageGuessing > LanguageGuessingHelper::GetGuesser() const +{ + if (!m_xLanguageGuesser.is()) + { + try + { + m_xLanguageGuesser = uno::Reference< linguistic2::XLanguageGuessing >( + m_xServiceManager->createInstance( + rtl::OUString::createFromAscii( "com.sun.star.linguistic2.LanguageGuessing" ) ), + uno::UNO_QUERY ); + } + catch (uno::Exception &r) + { + (void) r; + DBG_ASSERT( 0, "failed to get language guessing component" ); + } + } + return m_xLanguageGuesser; +} + +//////////////////////////////////////////////////////////// + +::rtl::OUString RetrieveLabelFromCommand( + const ::rtl::OUString& aCmdURL, + const uno::Reference< lang::XMultiServiceFactory >& _xServiceFactory, + uno::Reference< container::XNameAccess >& _xUICommandLabels, + const uno::Reference< frame::XFrame >& _xFrame, + ::rtl::OUString& _rModuleIdentifier, + sal_Bool& _rIni, + const sal_Char* _pName) +{ + ::rtl::OUString aLabel; + + // Retrieve popup menu labels + if ( !_xUICommandLabels.is() ) + { + try + { + if ( !_rIni ) + { + _rIni = sal_True; + Reference< XModuleManager > xModuleManager( _xServiceFactory->createInstance( SERVICENAME_MODULEMANAGER ), UNO_QUERY_THROW ); + + try + { + _rModuleIdentifier = xModuleManager->identify( _xFrame ); + } + catch( Exception& ) + { + } + } + + Reference< XNameAccess > xNameAccess( _xServiceFactory->createInstance( SERVICENAME_UICOMMANDDESCRIPTION ), UNO_QUERY ); + if ( xNameAccess.is() ) + { + xNameAccess->getByName( _rModuleIdentifier ) >>= _xUICommandLabels; + } + } + catch ( Exception& ) + { + } + } + + if ( _xUICommandLabels.is() ) + { + try + { + if ( aCmdURL.getLength() > 0 ) + { + rtl::OUString aStr; + Sequence< PropertyValue > aPropSeq; + if( _xUICommandLabels->hasByName( aCmdURL ) ) + { + if ( _xUICommandLabels->getByName( aCmdURL ) >>= aPropSeq ) + { + for ( sal_Int32 i = 0; i < aPropSeq.getLength(); i++ ) + { + if ( aPropSeq[i].Name.equalsAscii( _pName/*"Label"*/ )) + { + aPropSeq[i].Value >>= aStr; + break; + } + } + } + } + aLabel = aStr; + } + } + catch ( com::sun::star::uno::Exception& ) + { + } + } + + return aLabel; +} + +//////////////////////////////////////////////////////////// + +void FillLangItems( std::set< OUString > &rLangItems, + const SvtLanguageTable & rLanguageTable, + const uno::Reference< frame::XFrame > & rxFrame, + const LanguageGuessingHelper & rLangGuessHelper, + sal_Int16 nScriptType, + const OUString & rCurLang, + const OUString & rKeyboardLang, + const OUString & rGuessedTextLang ) +{ + rLangItems.clear(); + + //1--add current language + if( rCurLang != OUString() && + LANGUAGE_DONTKNOW != rLanguageTable.GetType( rCurLang )) + rLangItems.insert( rCurLang ); + + //2--System + const AllSettings& rAllSettings = Application::GetSettings(); + LanguageType rSystemLanguage = rAllSettings.GetLanguage(); + if( rSystemLanguage != LANGUAGE_DONTKNOW ) + { + if ( IsScriptTypeMatchingToLanguage( nScriptType, rSystemLanguage )) + rLangItems.insert( OUString( rLanguageTable.GetString( rSystemLanguage )) ); + } + + //3--UI + LanguageType rUILanguage = rAllSettings.GetUILanguage(); + if( rUILanguage != LANGUAGE_DONTKNOW ) + { + if ( IsScriptTypeMatchingToLanguage( nScriptType, rUILanguage )) + rLangItems.insert( OUString( rLanguageTable.GetString( rUILanguage )) ); + } + + //4--guessed language + uno::Reference< linguistic2::XLanguageGuessing > xLangGuesser( rLangGuessHelper.GetGuesser() ); + if ( xLangGuesser.is() && rGuessedTextLang.getLength() > 0) + { + ::com::sun::star::lang::Locale aLocale(xLangGuesser->guessPrimaryLanguage( rGuessedTextLang, 0, rGuessedTextLang.getLength()) ); + LanguageType nLang = MsLangId::convertLocaleToLanguageWithFallback( aLocale ); + if (nLang != LANGUAGE_DONTKNOW && nLang != LANGUAGE_NONE && nLang != LANGUAGE_SYSTEM + && IsScriptTypeMatchingToLanguage( nScriptType, nLang )) + rLangItems.insert( rLanguageTable.GetString( nLang )); + } + + //5--keyboard language + if( rKeyboardLang != OUString()) + { + if ( IsScriptTypeMatchingToLanguage( nScriptType, rLanguageTable.GetType( rKeyboardLang ))) + rLangItems.insert( rKeyboardLang ); + } + + //6--all languages used in current document + Reference< com::sun::star::frame::XModel > xModel; + if ( rxFrame.is() ) + { + Reference< com::sun::star::frame::XController > xController( rxFrame->getController(), UNO_QUERY ); + if ( xController.is() ) + xModel = xController->getModel(); + } + Reference< document::XDocumentLanguages > xDocumentLanguages( xModel, UNO_QUERY ); + /*the description of nScriptType + LATIN : 0x001 + ASIAN : 0x002 + COMPLEX: 0x004 + */ + const sal_Int16 nMaxCount = 7; + if ( xDocumentLanguages.is() ) + { + Sequence< Locale > rLocales( xDocumentLanguages->getDocumentLanguages( nScriptType, nMaxCount )); + if ( rLocales.getLength() > 0 ) + { + for ( sal_uInt16 i = 0; i < rLocales.getLength(); ++i ) + { + if ( rLangItems.size() == static_cast< size_t >(nMaxCount) ) + break; + const Locale& rLocale=rLocales[i]; + if( IsScriptTypeMatchingToLanguage( nScriptType, rLanguageTable.GetType( rLocale.Language ))) + rLangItems.insert( OUString( rLocale.Language ) ); + } + } + } +} + +} // namespace framework + + diff --git a/framework/source/fwi/helper/networkdomain.cxx b/framework/source/fwi/helper/networkdomain.cxx new file mode 100644 index 000000000000..fcc966402944 --- /dev/null +++ b/framework/source/fwi/helper/networkdomain.cxx @@ -0,0 +1,295 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <helper/networkdomain.hxx> + +namespace framework +{ + +#ifdef WNT +//_________________________________________________________________________________________________________________ +// Windows +//_________________________________________________________________________________________________________________ + +#define UNICODE +#if defined _MSC_VER +#pragma warning(push, 1) +#endif +#include <windows.h> +#if defined _MSC_VER +#pragma warning(pop) +#endif + +//_________________________________________________________________________________________________________________ +// Win NT, Win 2000, Win XP +//_________________________________________________________________________________________________________________ + +static DWORD WINAPI GetUserDomainW_NT( LPWSTR lpBuffer, DWORD nSize ) +{ + return GetEnvironmentVariable( TEXT("USERDOMAIN"), lpBuffer, nSize ); +} + +//_________________________________________________________________________________________________________________ +// Win 9x,Win ME +//_________________________________________________________________________________________________________________ + +static DWORD WINAPI GetUserDomainW_WINDOWS( LPWSTR lpBuffer, DWORD nSize ) +{ + HKEY hkeyLogon; + HKEY hkeyWorkgroup; + DWORD dwResult = 0; + + + if ( ERROR_SUCCESS == RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + TEXT("Network\\Logon"), + 0, KEY_READ, &hkeyLogon ) ) + { + DWORD dwLogon = 0; + DWORD dwLogonSize = sizeof(dwLogon); + RegQueryValueEx( hkeyLogon, TEXT("LMLogon"), 0, NULL, (LPBYTE)&dwLogon, &dwLogonSize ); + RegCloseKey( hkeyLogon ); + + if ( dwLogon ) + { + HKEY hkeyNetworkProvider; + + if ( ERROR_SUCCESS == RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + TEXT("SYSTEM\\CurrentControlSet\\Services\\MSNP32\\NetworkProvider"), + 0, KEY_READ, &hkeyNetworkProvider ) ) + { + DWORD dwBufferSize = nSize; + LONG lResult = RegQueryValueEx( hkeyNetworkProvider, TEXT("AuthenticatingAgent"), 0, NULL, (LPBYTE)lpBuffer, &dwBufferSize ); + + if ( ERROR_SUCCESS == lResult || ERROR_MORE_DATA == lResult ) + dwResult = dwBufferSize / sizeof(TCHAR); + + RegCloseKey( hkeyNetworkProvider ); + } + } + } + else if ( ERROR_SUCCESS == RegOpenKeyEx( + HKEY_LOCAL_MACHINE, + TEXT("SYSTEM\\CurrentControlSet\\Services\\VxD\\VNETSUP"), + 0, KEY_READ, &hkeyWorkgroup ) ) + { + DWORD dwBufferSize = nSize; + LONG lResult = RegQueryValueEx( hkeyWorkgroup, TEXT("Workgroup"), 0, NULL, (LPBYTE)lpBuffer, &dwBufferSize ); + + if ( ERROR_SUCCESS == lResult || ERROR_MORE_DATA == lResult ) + dwResult = dwBufferSize / sizeof(TCHAR); + + RegCloseKey( hkeyWorkgroup ); + } + + + return dwResult; +} + +static rtl::OUString GetUserDomain() +{ + sal_Unicode aBuffer[256]; + + long nVersion = GetVersion(); + DWORD nResult; + + if ( nVersion < 0 ) + nResult = GetUserDomainW_WINDOWS( reinterpret_cast<LPWSTR>(aBuffer), sizeof( aBuffer ) ); + else + nResult = GetUserDomainW_NT( reinterpret_cast<LPWSTR>(aBuffer), sizeof( aBuffer ) ); + + if ( nResult > 0 ) + return rtl::OUString( aBuffer ); + else + return rtl::OUString(); +} + +//_________________________________________________________________________________________________________________ +// Windows +//_________________________________________________________________________________________________________________ + +rtl::OUString NetworkDomain::GetYPDomainName() +{ + return ::rtl::OUString(); +} + +rtl::OUString NetworkDomain::GetNTDomainName() +{ + return GetUserDomain(); +} + +#elif defined( UNIX ) + +#include <rtl/ustring.h> +#include <stdlib.h> +#include <errno.h> +#include <osl/thread.h> + +//_________________________________________________________________________________________________________________ +// Unix +//_________________________________________________________________________________________________________________ + +#if defined( SOLARIS ) + +//_________________________________________________________________________________________________________________ +// Solaris +//_________________________________________________________________________________________________________________ + +#include <sys/systeminfo.h> +#include <sal/alloca.h> + +static rtl_uString *getDomainName() +{ + /* Initialize and assume failure */ + rtl_uString *ustrDomainName = NULL; + + char szBuffer[256]; + + long nCopied = sizeof(szBuffer); + char *pBuffer = szBuffer; + long nBufSize; + + do + { + nBufSize = nCopied; + nCopied = sysinfo( SI_SRPC_DOMAIN, pBuffer, nBufSize ); + + /* If nCopied is greater than buffersize we need to allocate + a buffer with suitable size */ + + if ( nCopied > nBufSize ) + pBuffer = (char *)alloca( nCopied ); + + } while ( nCopied > nBufSize ); + + if ( -1 != nCopied ) + { + rtl_string2UString( + &ustrDomainName, + pBuffer, + nCopied - 1, + osl_getThreadTextEncoding(), + OSTRING_TO_OUSTRING_CVTFLAGS ); + } + + return ustrDomainName; +} + +#elif defined( LINUX ) /* endif SOLARIS */ + +//_________________________________________________________________________________________________________________ +// Linux +//_________________________________________________________________________________________________________________ + +#include <unistd.h> +#include <string.h> + +static rtl_uString *getDomainName() +{ + /* Initialize and assume failure */ + rtl_uString *ustrDomainName = NULL; + + char *pBuffer; + int result; + size_t nBufSize = 0; + + do + { + nBufSize += 256; /* Increase buffer size by steps of 256 bytes */ + pBuffer = (char *)alloca( nBufSize ); + result = getdomainname( pBuffer, nBufSize ); + /* If buffersize in not large enough -1 is returned and errno + is set to EINVAL. This only applies to libc. With glibc the name + is truncated. */ + } while ( -1 == result && EINVAL == errno ); + + if ( 0 == result ) + { + rtl_string2UString( + &ustrDomainName, + pBuffer, + strlen( pBuffer ), + osl_getThreadTextEncoding(), + OSTRING_TO_OUSTRING_CVTFLAGS ); + } + + return ustrDomainName; +} + +#else /* LINUX */ + +//_________________________________________________________________________________________________________________ +// Other Unix +//_________________________________________________________________________________________________________________ + +static rtl_uString *getDomainName() +{ + return NULL; +} + +#endif + +//_________________________________________________________________________________________________________________ +// Unix +//_________________________________________________________________________________________________________________ + +rtl::OUString NetworkDomain::GetYPDomainName() +{ + rtl_uString* pResult = getDomainName(); + if ( pResult ) + return rtl::OUString( pResult ); + else + return rtl::OUString(); +} + +rtl::OUString NetworkDomain::GetNTDomainName() +{ + return ::rtl::OUString(); +} + +#else /* UNIX */ + +//_________________________________________________________________________________________________________________ +// Other operating systems (non-Windows and non-Unix) +//_________________________________________________________________________________________________________________ + +rtl::OUString NetworkDomain::GetYPDomainName() +{ + return rtl::OUString(); +} + +rtl::OUString NetworkDomain::GetNTDomainName() +{ + return rtl::OUString(); +} + +#endif + +} // namespace framework diff --git a/framework/source/fwi/helper/shareablemutex.cxx b/framework/source/fwi/helper/shareablemutex.cxx new file mode 100644 index 000000000000..b173c6c34a4f --- /dev/null +++ b/framework/source/fwi/helper/shareablemutex.cxx @@ -0,0 +1,81 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +#include <helper/shareablemutex.hxx> + +namespace framework +{ + +ShareableMutex::ShareableMutex() +{ + pMutexRef = new MutexRef; + pMutexRef->acquire(); +} + +ShareableMutex::ShareableMutex( const ShareableMutex& rShareableMutex ) +{ + pMutexRef = rShareableMutex.pMutexRef; + if ( pMutexRef ) + pMutexRef->acquire(); +} + +const ShareableMutex& ShareableMutex::operator=( const ShareableMutex& rShareableMutex ) +{ + if ( rShareableMutex.pMutexRef ) + rShareableMutex.pMutexRef->acquire(); + if ( pMutexRef ) + pMutexRef->release(); + pMutexRef = rShareableMutex.pMutexRef; + return *this; +} + +ShareableMutex::~ShareableMutex() +{ + if ( pMutexRef ) + pMutexRef->release(); +} + +void ShareableMutex::acquire() +{ + if ( pMutexRef ) + pMutexRef->m_oslMutex.acquire(); +} + +void ShareableMutex::release() +{ + if ( pMutexRef ) + pMutexRef->m_oslMutex.release(); +} + +::osl::Mutex& ShareableMutex::getShareableOslMutex() +{ + return pMutexRef->m_oslMutex; +} + +} diff --git a/framework/source/fwi/jobs/configaccess.cxx b/framework/source/fwi/jobs/configaccess.cxx new file mode 100644 index 000000000000..95226268ce2b --- /dev/null +++ b/framework/source/fwi/jobs/configaccess.cxx @@ -0,0 +1,242 @@ + /************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//________________________________ +// my own includes +#include <jobs/configaccess.hxx> +#include <threadhelp/readguard.hxx> +#include <threadhelp/writeguard.hxx> +#include <threadhelp/resetableguard.hxx> +#include <general.h> +#include <services.h> + +//________________________________ +// interface includes +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/beans/XMultiHierarchicalPropertySet.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <com/sun/star/util/XChangesBatch.hpp> + +//________________________________ +// includes of other projects +#include <unotools/configpathes.hxx> +#include <rtl/ustrbuf.hxx> + +//________________________________ +// namespace + +namespace framework{ + +//________________________________ +// non exported const + +//________________________________ +// non exported definitions + +//________________________________ +// declarations + +//________________________________ +/** + @short open the configuration of this job + @descr We open the configuration of this job only. Not the whole package or the whole + job set. We are interested on our own properties only. + We set the opened configuration access as our member. So any following method, + which needs cfg access, can use it. That prevent us against multiple open/close requests. + But you can use this method to upgrade an already opened configuration too. + + @param eMode + force opening of the configuration access in readonly or in read/write mode + */ +ConfigAccess::ConfigAccess( /*IN*/ const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR , + /*IN*/ const ::rtl::OUString& sRoot ) + : ThreadHelpBase( ) + , m_xSMGR ( xSMGR ) + , m_sRoot ( sRoot ) + , m_eMode ( E_CLOSED ) +{ +} + +//________________________________ +/** + @short last chance to close an open configuration access point + @descr In case our user forgot to close this configuration point + in the right way, normaly he will run into some trouble - + e.g. losing data. + */ +ConfigAccess::~ConfigAccess() +{ + close(); +} + +//________________________________ +/** + @short return the internal mode of this instance + @descr May be the outside user need any information about successfully opened + or closed config access point objects. He can control the internal mode to do so. + + @return The internal open state of this object. + */ +ConfigAccess::EOpenMode ConfigAccess::getMode() const +{ + /* SAFE { */ + ReadGuard aReadLock(m_aLock); + return m_eMode; + /* } SAFE */ +} + +//________________________________ +/** + @short open the configuration access in the specified mode + @descr We set the opened configuration access as our member. So any following method, + which needs cfg access, can use it. That prevent us against multiple open/close requests. + But you can use this method to upgrade an already opened configuration too. + It's possible to open a config access in READONLY mode first and "open" it at a second + time within the mode READWRITE. Then we will upgrade it. Dowgrade will be possible too. + + But note: closing will be done explicitly by calling method close() ... not by + downgrading with mode CLOSED! + + @param eMode + force (re)opening of the configuration access in readonly or in read/write mode + */ +void ConfigAccess::open( /*IN*/ EOpenMode eMode ) +{ + /* SAFE { */ + // We must lock the whole method to be shure, that nobody + // outside uses our internal member m_xAccess! + WriteGuard aWriteLock(m_aLock); + + // check if configuration is already open in the right mode. + // By the way: Don't allow closing by using this method! + if ( + (eMode !=E_CLOSED) && + (m_eMode!=eMode ) + ) + { + // We have to close the old access point without any question here. + // It will be open again using the new mode. + // can be called without checks! It does the checks by itself ... + // e.g. for already closed or not opened configuration. + // Flushing of all made changes will be done here too. + close(); + + // create the configuration provider, which provides sub access points + css::uno::Reference< css::lang::XMultiServiceFactory > xConfigProvider(m_xSMGR->createInstance(SERVICENAME_CFGPROVIDER), css::uno::UNO_QUERY); + if (xConfigProvider.is()) + { + css::beans::PropertyValue aParam; + aParam.Name = DECLARE_ASCII("nodepath"); + aParam.Value <<= m_sRoot; + + css::uno::Sequence< css::uno::Any > lParams(1); + lParams[0] <<= aParam; + + // open it + try + { + if (eMode==E_READONLY) + m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGREADACCESS , lParams); + else + if (eMode==E_READWRITE) + m_xConfig = xConfigProvider->createInstanceWithArguments(SERVICENAME_CFGUPDATEACCESS, lParams); + } + catch(css::uno::Exception& ex) + { + (void) ex; // avoid warning + LOG_WARNING("open config ...", U2B(ex.Message)) + } + + m_eMode = E_CLOSED; + if (m_xConfig.is()) + m_eMode = eMode; + } + } + + aWriteLock.unlock(); + /* } SAFE */ +} + +//________________________________ +/** + @short close the internal opened configuration access and flush all changes + @descr It checks, if the given access is valid and react in the right way. + It flushes all changes ... so nobody else must know this state. + */ +void ConfigAccess::close() +{ + /* SAFE { */ + // Lock the whole method, to be shure that nobody else uses our internal members + // during this time. + WriteGuard aWriteLock(m_aLock); + + // check already closed configuration + if (m_xConfig.is()) + { + css::uno::Reference< css::util::XChangesBatch > xFlush(m_xConfig, css::uno::UNO_QUERY); + if (xFlush.is()) + xFlush->commitChanges(); + m_xConfig = css::uno::Reference< css::uno::XInterface >(); + m_eMode = E_CLOSED; + } + + aWriteLock.unlock(); + /* } SAFE */ +} + +//________________________________ +/** + @short provides an access to the internal wrapped configuration access + @descr It's not allowed to safe this c++ (!) reference outside. You have + to use it directly. Further you must use our public lock member m_aLock + to synchronize your code with our internal structures and our interface + methods. Acquire it before you call cfg() and release it afterwards immediatly. + + E.g.: ConfigAccess aAccess(...); + ReadGuard aReadLock(aAccess.m_aLock); + Reference< XPropertySet > xSet(aAccess.cfg(), UNO_QUERY); + Any aProp = xSet->getPropertyValue("..."); + aReadLock.unlock(); + + @attention During this time it's not allowed to call the methods open() or close()! + Otherwhise you will change your own referenced config access. Anything will + be possible then. + + @return A c++(!) reference to the uno instance of the configuration access point. + */ +const css::uno::Reference< css::uno::XInterface >& ConfigAccess::cfg() +{ + // must be synchronized from outside! + // => no lock here ... + return m_xConfig; +} + +} // namespace framework diff --git a/framework/source/fwi/jobs/jobconst.cxx b/framework/source/fwi/jobs/jobconst.cxx new file mode 100644 index 000000000000..b71a68342a69 --- /dev/null +++ b/framework/source/fwi/jobs/jobconst.cxx @@ -0,0 +1,74 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//________________________________ +// my own includes + +#include <jobs/jobconst.hxx> + +//________________________________ +// interface includes + +//________________________________ +// includes of other projects + +//________________________________ +// namespace + +namespace framework{ + +//________________________________ +// non exported const + +//________________________________ +// non exported definitions + +//________________________________ +// declarations + +const ::rtl::OUString JobConst::ANSWER_DEACTIVATE_JOB() +{ + static const ::rtl::OUString PROP = ::rtl::OUString::createFromAscii("Deactivate"); + return PROP; +} + +const ::rtl::OUString JobConst::ANSWER_SAVE_ARGUMENTS() +{ + static const ::rtl::OUString PROP = ::rtl::OUString::createFromAscii("SaveArguments"); + return PROP; +} + +const ::rtl::OUString JobConst::ANSWER_SEND_DISPATCHRESULT() +{ + static const ::rtl::OUString PROP = ::rtl::OUString::createFromAscii("SendDispatchResult"); + return PROP; +} + +} // namespace framework diff --git a/framework/source/fwi/threadhelp/lockhelper.cxx b/framework/source/fwi/threadhelp/lockhelper.cxx new file mode 100644 index 000000000000..4c5ebb7a5d91 --- /dev/null +++ b/framework/source/fwi/threadhelp/lockhelper.cxx @@ -0,0 +1,549 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <threadhelp/lockhelper.hxx> +#include <general.h> +#include <macros/debug.hxx> + +#include <macros/generic.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <vos/process.hxx> + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// declarations +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short use ctor to initialize instance + @descr We must initialize our member "m_eLockType". This value specify handling of locking. + User use this helper as parameter for a guard creation. + These guard use "m_eLockType" to set lock in the right way by using right mutex or rw-lock. + + @seealso enum ELockType + @seealso class ReadGuard + @seealso class WriteGuard + + @param "rSolarMutex", for some components we must be "vcl-free"! So we can't work with our solar mutex + directly. User must set his reference at this instance - so we can work with it! + @return - + + @onerror - +*//*-*************************************************************************************************************/ +LockHelper::LockHelper( ::vos::IMutex* pSolarMutex ) + : m_pFairRWLock ( NULL ) + , m_pOwnMutex ( NULL ) + , m_pSolarMutex ( NULL ) + , m_pShareableOslMutex( NULL ) + , m_bDummySolarMutex ( sal_False ) +{ + m_eLockType = implts_getLockType(); + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : { + m_pOwnMutex = new ::osl::Mutex; + } + break; + case E_SOLARMUTEX : { + if( pSolarMutex == NULL ) + { + m_pSolarMutex = new ::vos::OMutex; + m_bDummySolarMutex = sal_True; + } + else + { + m_pSolarMutex = pSolarMutex; + } + } + break; + case E_FAIRRWLOCK : { + m_pFairRWLock = new FairRWLock; + } + break; + #ifdef ENABLE_ASSERTIONS + default : LOG_ASSERT2( m_eLockType!=E_NOTHING, "LockHelper::ctor()", "Invalid lock type found .. so code will not be threadsafe!" ) + #endif + } +} + +/*-************************************************************************************************************//** + @short default dtor to release safed pointer + @descr We have created dynamical mutex- or lock-member ... or we hold a pointer to external objects. + We must release it! + + @seealso ctor() + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +LockHelper::~LockHelper() +{ + if( m_pShareableOslMutex != NULL ) + { + // Sometimes we hold two pointer to same object! + // (e.g. if m_eLockType==E_OWNMUTEX!) + // So we should forget it ... but don't delete it twice! + if( m_pShareableOslMutex != m_pOwnMutex ) + { + delete m_pShareableOslMutex; + } + m_pShareableOslMutex = NULL; + } + if( m_pOwnMutex != NULL ) + { + delete m_pOwnMutex; + m_pOwnMutex = NULL; + } + if( m_pSolarMutex != NULL ) + { + if (m_bDummySolarMutex) + { + delete static_cast<vos::OMutex*>(m_pSolarMutex); + m_bDummySolarMutex = sal_False; + } + m_pSolarMutex = NULL; + } + if( m_pFairRWLock != NULL ) + { + delete m_pFairRWLock; + m_pFairRWLock = NULL; + } +} + +/*-************************************************************************************************************//** + @interface IMutex + @short set an exclusiv lock + @descr We must match this lock call with current set lock type and used lock member. + If a mutex should be used - it will be easy ... but if a rw-lock should be used + we must simulate it as a write access! + + @attention If a shareable osl mutex exist, he must be used as twice! + It's neccessary for some cppu-helper classes ... + + @seealso method acquireWriteAccess() + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +void LockHelper::acquire() +{ + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : { + m_pOwnMutex->acquire(); + } + break; + case E_SOLARMUTEX : { + m_pSolarMutex->acquire(); + } + break; + case E_FAIRRWLOCK : { + m_pFairRWLock->acquireWriteAccess(); + } + break; + } +} + +/*-************************************************************************************************************//** + @interface IMutex + @short release exclusiv lock + @descr We must match this unlock call with current set lock type and used lock member. + If a mutex should be used - it will be easy ... but if a rw-lock should be used + we must simulate it as a write access! + + @attention If a shareable osl mutex exist, he must be used as twice! + It's neccessary for some cppu-helper classes ... + + @seealso method releaseWriteAccess() + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +void LockHelper::release() +{ + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : { + m_pOwnMutex->release(); + } + break; + case E_SOLARMUTEX : { + m_pSolarMutex->release(); + } + break; + case E_FAIRRWLOCK : { + m_pFairRWLock->releaseWriteAccess(); + } + break; + } +} + +/*-************************************************************************************************************//** + @interface IRWLock + @short set lock for reading + @descr A guard should call this method to acquire read access on your member. + Writing isn't allowed then - but nobody could check it for you! + We use m_eLockType to differ between all possible "lock-member"!!! + + @attention If a shareable osl mutex exist, he must be used as twice! + It's neccessary for some cppu-helper classes ... + + @seealso method releaseReadAccess() + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +void LockHelper::acquireReadAccess() +{ + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : { + m_pOwnMutex->acquire(); + } + break; + case E_SOLARMUTEX : { + m_pSolarMutex->acquire(); + } + break; + case E_FAIRRWLOCK : { + m_pFairRWLock->acquireReadAccess(); + } + break; + } +} + +/*-************************************************************************************************************//** + @interface IRWLock + @short reset lock for reading + @descr A guard should call this method to release read access on your member. + We use m_eLockType to differ between all possible "lock-member"!!! + + @attention If a shareable osl mutex exist, he must be used as twice! + It's neccessary for some cppu-helper classes ... + + @seealso method acquireReadAccess() + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +void LockHelper::releaseReadAccess() +{ + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : { + m_pOwnMutex->release(); + } + break; + case E_SOLARMUTEX : { + m_pSolarMutex->release(); + } + break; + case E_FAIRRWLOCK : { + m_pFairRWLock->releaseReadAccess(); + } + break; + } +} + +/*-************************************************************************************************************//** + @interface IRWLock + @short set lock for writing + @descr A guard should call this method to acquire write access on your member. + Reading is allowed too - of course. + After successfully calling of this method you are the only writer. + We use m_eLockType to differ between all possible "lock-member"!!! + + @attention If a shareable osl mutex exist, he must be used as twice! + It's neccessary for some cppu-helper classes ... + + @seealso method releaseWriteAccess() + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +void LockHelper::acquireWriteAccess() +{ + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : { + m_pOwnMutex->acquire(); + } + break; + case E_SOLARMUTEX : { + m_pSolarMutex->acquire(); + } + break; + case E_FAIRRWLOCK : { + m_pFairRWLock->acquireWriteAccess(); + } + break; + } +} + +/*-************************************************************************************************************//** + @interface IRWLock + @short reset lock for writing + @descr A guard should call this method to release write access on your member. + We use m_eLockType to differ between all possible "lock-member"!!! + + @attention If a shareable osl mutex exist, he must be used as twice! + It's neccessary for some cppu-helper classes ... + + @seealso method acquireWriteAccess() + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +void LockHelper::releaseWriteAccess() +{ + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : { + m_pOwnMutex->release(); + } + break; + case E_SOLARMUTEX : { + m_pSolarMutex->release(); + } + break; + case E_FAIRRWLOCK : { + m_pFairRWLock->releaseWriteAccess(); + } + break; + } +} + +/*-************************************************************************************************************//** + @interface IRWLock + @short downgrade a write access to a read access + @descr A guard should call this method to change a write to a read access. + New readers can work too - new writer are blocked! + We use m_eLockType to differ between all possible "lock-member"!!! + + @attention Ignore shareable mutex(!) - because this call never should release a lock completly! + We change a write access to a read access only. + + @attention a) Don't call this method if you are not a writer! + Results are not defined then ... + An upgrade can't be implemented realy ... because acquiring new access + will be the same - there no differences! + b) Without function if m_eLockTyp is different from E_FAIRRWLOCK(!) ... + because, a mutex don't support it realy. + + @seealso - + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +void LockHelper::downgradeWriteAccess() +{ + switch( m_eLockType ) + { + case E_NOTHING : break; // There is nothing to do ... + case E_OWNMUTEX : break; // Not supported for mutex! + case E_SOLARMUTEX : break; // Not supported for mutex! + case E_FAIRRWLOCK : m_pFairRWLock->downgradeWriteAccess(); + break; + } +} + +/*-************************************************************************************************************//** + @short return a reference to a static lock helper + @descr Sometimes we need the global mutex or rw-lock! (e.g. in our own static methods) + But it's not a good idea to use these global one very often ... + Thats why we use this little helper method. + We create our own "class global static" lock. + It will be created at first call only! + All other requests use these created one then directly. + + @seealso - + + @param - + @return A reference to a static mutex/lock member. + + @onerror No error should occure. +*//*-*************************************************************************************************************/ +LockHelper& LockHelper::getGlobalLock( ::vos::IMutex* pSolarMutex ) +{ + // Initialize static "member" only for one time! + // Algorithm: + // a) Start with an invalid lock (NULL pointer) + // b) If these method first called (lock not already exist!) ... + // c) ... we must create a new one. Protect follow code with the global mutex - + // (It must be - we create a static variable!) + // d) Check pointer again - because ... another instance of our class could be faster then these one! + // e) Create the new lock and set it for return on static variable. + // f) Return new created or already existing lock object. + static LockHelper* pLock = NULL; + if( pLock == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if( pLock == NULL ) + { + static LockHelper aLock( pSolarMutex ); + pLock = &aLock; + } + } + return *pLock; +} + +/*-************************************************************************************************************//** + @short return a reference to shared mutex member + @descr Sometimes we need a osl-mutex for sharing with our uno helper ... + What can we do? + a) If we have an initialized "own mutex" ... we can use it! + b) Otherwhise we must use a different mutex member :-( + I HOPE IT WORKS! + + @seealso - + + @param - + @return A reference to a shared mutex. + + @onerror No error should occure. +*//*-*************************************************************************************************************/ +::osl::Mutex& LockHelper::getShareableOslMutex() +{ + if( m_pShareableOslMutex == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if( m_pShareableOslMutex == NULL ) + { + switch( m_eLockType ) + { + case E_OWNMUTEX : { + m_pShareableOslMutex = m_pOwnMutex; + } + break; + default : { + m_pShareableOslMutex = new ::osl::Mutex; + } + break; + } + } + } + return *m_pShareableOslMutex; +} + +/*-************************************************************************************************************//** + @short search for right lock type, which should be used by an instance of this struct + @descr We must initialize our member "m_eLockType". This value specify handling of locking. + How we can do that? We search for an environment variable. We do it only for one time .... + because the environment is fix. So we safe this value and use it for all further requests. + If no variable could be found - we use a fallback! + + @attention We have numbered all our enum values for ELockType. So we can use it as value of searched + environment variable too! + + @seealso enum ELockType + @seealso environment LOCKTYPE + + @param - + @return A reference to a created and right initialized lock type! + + @onerror We use a fallback! +*//*-*************************************************************************************************************/ +ELockType& LockHelper::implts_getLockType() +{ + // Initialize static "member" only for one time! + // Algorithm: + // a) Start with an invalid variable (NULL pointer) + // b) If these method first called (value not already exist!) ... + // c) ... we must create a new one. Protect follow code with the global mutex - + // (It must be - we create a static variable!) + // d) Check pointer again - because ... another instance of our class could be faster then these one! + // e) Create the new static variable, get value from the environment and set it + // f) Return new created or already existing static variable. + static ELockType* pType = NULL; + if( pType == NULL ) + { + ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() ); + if( pType == NULL ) + { + static ELockType eType = FALLBACK_LOCKTYPE; + + ::vos::OStartupInfo aEnvironment; + ::rtl::OUString sValue ; + if( aEnvironment.getEnvironment( ENVVAR_LOCKTYPE, sValue ) == ::vos::OStartupInfo::E_None ) + { + eType = (ELockType)(sValue.toInt32()); + } + + LOG_LOCKTYPE( FALLBACK_LOCKTYPE, eType ) + + pType = &eType; + } + } + return *pType; +} + +} // namespace framework diff --git a/framework/source/fwi/threadhelp/transactionmanager.cxx b/framework/source/fwi/threadhelp/transactionmanager.cxx new file mode 100644 index 000000000000..3523ddbbd128 --- /dev/null +++ b/framework/source/fwi/threadhelp/transactionmanager.cxx @@ -0,0 +1,374 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" + +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <threadhelp/transactionmanager.hxx> +#include <threadhelp/resetableguard.hxx> +#include <macros/debug.hxx> + +#include <macros/generic.hxx> +#include <fwidllapi.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/lang/DisposedException.hpp> +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// namespace +//_________________________________________________________________________________________________________________ + +namespace framework{ + +//_________________________________________________________________________________________________________________ +// non exported const +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// non exported declarations +//_________________________________________________________________________________________________________________ + +//_________________________________________________________________________________________________________________ +// definitions +//_________________________________________________________________________________________________________________ + +/*-************************************************************************************************************//** + @short standard ctor + @descr Initialize instance with right start values for correct working. + + @seealso - + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +TransactionManager::TransactionManager() + : m_eWorkingMode ( E_INIT ) + , m_nTransactionCount ( 0 ) +{ + m_aBarrier.open(); +} + +/*-************************************************************************************************************//** + @short standard dtor + @descr - + + @seealso - + + @param - + @return - + + @onerror - +*//*-*************************************************************************************************************/ +TransactionManager::~TransactionManager() +{ +} + +/*-****************************************************************************************************//** + @interface ITransactionManager + @short set new working mode + @descr These implementation knows for states of working: E_INIT, E_WORK, E_CLOSING, E_CLOSE + You can step during this ones only from the left to the right side and start at left side again! + (This is neccessary e.g. for refcounted objects!) + This call will block till all current existing transactions was finished. + Follow results occure: + E_INIT : All requests on this implementation are refused. + It's your decision to react in a right way. + + E_WORK : The object can work now. The full functionality is available. + + E_BEFORECLOSE : The object start the closing mechanism ... but sometimes + e.g. the dispose() method need to call some private methods. + These some special methods should use E_SOFTEXCEPTIONS or ignore + E_INCLOSE as returned reason for E_NOEXCEPTIONS to detect this special case! + + E_CLOSE : Object is already dead! All further requests will be refused. + It's your decision to react in a right way. + + @seealso - + + @param "eMode", is the new mode - but we don't accept setting mode in wrong order! + @return - + + @onerror We do nothing. +*//*-*****************************************************************************************************/ +void TransactionManager::setWorkingMode( EWorkingMode eMode ) +{ + // Safe member access. + ::osl::ClearableMutexGuard aAccessGuard( m_aAccessLock ); + sal_Bool bWaitFor = sal_False ; + // Change working mode first! + if ( + ( m_eWorkingMode == E_INIT && eMode == E_WORK ) || + ( m_eWorkingMode == E_WORK && eMode == E_BEFORECLOSE ) || + ( m_eWorkingMode == E_BEFORECLOSE && eMode == E_CLOSE ) || + ( m_eWorkingMode == E_CLOSE && eMode == E_INIT ) + ) + { + m_eWorkingMode = eMode; + if( m_eWorkingMode == E_BEFORECLOSE || m_eWorkingMode == E_CLOSE ) + { + bWaitFor = sal_True; + } + } + + // Wait for current existing transactions then! + // (Only neccessary for changing to E_BEFORECLOSE or E_CLOSE! ... + // otherwise; if you wait at setting E_WORK another thrad could finish a acquire-call during our unlock() and wait() call + // ... and we will wait forever here!!!) + // Don't forget to release access mutex before. + aAccessGuard.clear(); + if( bWaitFor == sal_True ) + { + m_aBarrier.wait(); + } +} + +/*-****************************************************************************************************//** + @interface ITransactionManager + @short get current working mode + @descr If you stand in your close() or init() method ... but don't know + if you called more then ones(!) ... you can use this function to get + right information. + e.g: You have a method init() which is used to change working mode from + E_INIT to E_WORK and should be used to initialize some member too ... + What should you do: + + void init( sal_Int32 nValue ) + { + // Reject this call if our transaction manager say: "Object already initialized!" + // Otherwise initialize your member. + if( m_aTransactionManager.getWorkingMode() == E_INIT ) + { + // Object is uninitialized ... + // Make member access threadsafe! + ResetableGuard aGuard( m_aMutex ); + + // Check working mode again .. because anozï¿œther instance could be faster. + // (It's possible to set this guard at first of this method too!) + if( m_aTransactionManager.getWorkingMode() == E_INIT ) + { + m_aMember = nValue; + + // Object is initialized now ... set working mode to E_WORK! + m_aTransactionManager.setWorkingMode( E_WORK ); + } + } + } + + @seealso method setWorkingMode() + + @param - + @return Current set mode. + + @onerror No error should occure. +*//*-*****************************************************************************************************/ +EWorkingMode TransactionManager::getWorkingMode() const +{ + // Synchronize access to internal member! + ::osl::MutexGuard aAccessLock( m_aAccessLock ); + return m_eWorkingMode; +} + +/*-****************************************************************************************************//** + @interface ITransactionManager + @short start new transaction + @descr A guard should use this method to start a new transaction. He should looks for rejected + calls to by using parameter eMode and eReason. + If call was not rejected your transaction will be non breakable during releasing your transaction + guard! BUT ... your code isn't threadsafe then! It's a transaction manager only .... + + @seealso method unregisterTransaction() + + @param "eMode" ,used to enable/disable throwing exceptions automaticly for rejected calls + @param "eReason" ,reason for rejected calls if eMode=E_NOEXCEPTIONS + @return - + + @onerror - +*//*-*****************************************************************************************************/ +void TransactionManager::registerTransaction( EExceptionMode eMode, ERejectReason& eReason ) throw( css::uno::RuntimeException, css::lang::DisposedException ) +{ + // Look for rejected calls first. + // If call was refused we throw some exceptions or do nothing! + // It depends from given parameter eMode. + if( isCallRejected( eReason ) == sal_True ) + { + impl_throwExceptions( eMode, eReason ); + } + + // BUT if no exception was thrown ... (may be eMode = E_SOFTEXCEPTIONS!) + // we must register this transaction too! + // Don't use "else" or a new scope here!!! + + // Safe access to internal member. + ::osl::MutexGuard aAccessGuard( m_aAccessLock ); + + #ifdef ENABLE_MUTEXDEBUG + LOG_ASSERT2( m_nTransactionCount<0, "TransactionManager::acquire()", "Wrong ref count detected!" ) + #endif + + // Register this new transaction. + // If it is the first one .. close gate to disable changing of working mode. + ++m_nTransactionCount; + if( m_nTransactionCount == 1 ) + { + m_aBarrier.close(); + } +} + +/*-****************************************************************************************************//** + @interface ITransactionManager + @short finish transaction + @descr A guard should call this method to release current transaction. + + @seealso method registerTransaction() + + @param - + @return - + + @onerror - +*//*-*****************************************************************************************************/ +void TransactionManager::unregisterTransaction() throw( css::uno::RuntimeException, css::lang::DisposedException ) +{ + // This call could not rejected! + // Safe access to internal member. + ::osl::MutexGuard aAccessGuard( m_aAccessLock ); + + #ifdef ENABLE_MUTEXDEBUG + LOG_ASSERT2( m_nTransactionCount<=0, "TransactionManager::release()", "Wrong ref count detected!" ) + #endif + + // Deregister this transaction. + // If it was the last one ... open gate to enable changing of working mode! + // (see setWorkingMode()) + + --m_nTransactionCount; + if( m_nTransactionCount == 0 ) + { + m_aBarrier.open(); + } +} + +/*-****************************************************************************************************//** + @interface ITransactionManager + @short look for rejected calls + @descr Sometimes user need a possibility to get information about rejected calls + without starting a transaction! + + @seealso - + + @param "eReason" returns reason of a rejected call + @return true if call was rejected, false otherwise + + @onerror We return false. +*//*-*****************************************************************************************************/ +sal_Bool TransactionManager::isCallRejected( ERejectReason& eReason ) const +{ + // This call must safe access to internal member only. + // Set "possible reason" for return and check reject-state then! + // User should look for return value first - reason then ... + ::osl::MutexGuard aAccessGuard( m_aAccessLock ); + switch( m_eWorkingMode ) + { + case E_INIT : eReason = E_UNINITIALIZED ; + break; + case E_WORK : eReason = E_NOREASON ; + break; + case E_BEFORECLOSE : eReason = E_INCLOSE ; + break; + case E_CLOSE : eReason = E_CLOSED ; + break; + } + return( eReason!=E_NOREASON ); +} + +/*-****************************************************************************************************//** + @short throw any exceptions for rejected calls + @descr If user whish to use our automaticly exception mode we use this impl-method. + We check all combinations of eReason and eExceptionMode and throw right exception with some + descriptions for recipient of it. + + @seealso method registerTransaction() + @seealso enum ERejectReason + @seealso enum EExceptionMode + + @param "eReason" , reason for rejected call + @param "eMode" , exception mode - set by user + @return - + + @onerror - +*//*-*****************************************************************************************************/ +void TransactionManager::impl_throwExceptions( EExceptionMode eMode, ERejectReason eReason ) const throw( css::uno::RuntimeException, css::lang::DisposedException ) +{ + if( eMode != E_NOEXCEPTIONS ) + { + switch( eReason ) + { + case E_UNINITIALIZED : if( eMode == E_HARDEXCEPTIONS ) + { + // Help programmer to find out, why this exception is thrown! + LOG_ERROR( "TransactionManager...", "Owner instance not right initialized yet. Call was rejected! Normaly it's an algorithm error ... wrong usin of class!" ) + //ATTENTION: temp. disabled - till all bad code positions are detected and changed! */ + // throw css::uno::RuntimeException( DECLARE_ASCII("TransactionManager...\nOwner instance not right initialized yet. Call was rejected! Normaly it's an algorithm error ... wrong usin of class!\n" ), css::uno::Reference< css::uno::XInterface >() ); + } + break; + case E_INCLOSE : if( eMode == E_HARDEXCEPTIONS ) + { + // Help programmer to find out, why this exception is thrown! + LOG_ERROR( "TransactionManager...", "Owner instance stand in close method. Call was rejected!" ) + throw css::lang::DisposedException( DECLARE_ASCII("TransactionManager...\nOwner instance stand in close method. Call was rejected!\n" ), css::uno::Reference< css::uno::XInterface >() ); + } + break; + case E_CLOSED : { + // Help programmer to find out, why this exception is thrown! + LOG_ERROR( "TransactionManager...", "Owner instance already closed. Call was rejected!" ) + throw css::lang::DisposedException( DECLARE_ASCII("TransactionManager...\nOwner instance already closed. Call was rejected!\n" ), css::uno::Reference< css::uno::XInterface >() ); + } + case E_NOREASON : { + // Help programmer to find out + LOG_ERROR( "TransactionManager...", "Impossible case E_NOREASON!" ) + } + break; + default: break; // nothing to do + } + } +} + +} // namespace framework diff --git a/framework/source/fwi/uielement/constitemcontainer.cxx b/framework/source/fwi/uielement/constitemcontainer.cxx new file mode 100644 index 000000000000..9ef9a72e5093 --- /dev/null +++ b/framework/source/fwi/uielement/constitemcontainer.cxx @@ -0,0 +1,479 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <uielement/constitemcontainer.hxx> +#include <uielement/rootitemcontainer.hxx> +#include <uielement/itemcontainer.hxx> +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/beans/PropertyAttribute.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ +#include <cppuhelper/implbase1.hxx> + +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; + +const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >"; + +const int PROPHANDLE_UINAME = 1; +const int PROPCOUNT = 1; +const rtl::OUString PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" )); + +namespace framework +{ + +/** + * The class which implements the PropertySetInfo interface. + */ +extern "C" +{ +static int SAL_CALL compare_OUString_Property_Impl( const void *arg1, const void *arg2 ) SAL_THROW( () ) +{ + return ((::rtl::OUString *)arg1)->compareTo( ((Property *)arg2)->Name ); +} +} + +class OPropertySetHelperInfo_Impl + : public WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo > +{ + Sequence < Property > aInfos; + +public: + OPropertySetHelperInfo_Impl( IPropertyArrayHelper & rHelper_ ) SAL_THROW( () ); + + // XPropertySetInfo-Methoden + virtual Sequence< Property > SAL_CALL getProperties(void) throw(::com::sun::star::uno::RuntimeException); + virtual Property SAL_CALL getPropertyByName(const ::rtl::OUString& PropertyName) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasPropertyByName(const ::rtl::OUString& PropertyName) throw(::com::sun::star::uno::RuntimeException); +}; + + +/** + * Create an object that implements XPropertySetInfo IPropertyArrayHelper. + */ +OPropertySetHelperInfo_Impl::OPropertySetHelperInfo_Impl( + IPropertyArrayHelper & rHelper_ ) + SAL_THROW( () ) + :aInfos( rHelper_.getProperties() ) +{ +} + +/** + * Return the sequence of properties, which are provided throug the constructor. + */ +Sequence< Property > OPropertySetHelperInfo_Impl::getProperties(void) throw(::com::sun::star::uno::RuntimeException) +{ + return aInfos; +} + +/** + * Return the sequence of properties, which are provided throug the constructor. + */ +Property OPropertySetHelperInfo_Impl::getPropertyByName( const ::rtl::OUString & PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException) +{ + Property * pR; + pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof( Property ), + compare_OUString_Property_Impl ); + if( !pR ) { + throw UnknownPropertyException(); + } + + return *pR; +} + +/** + * Return the sequence of properties, which are provided throug the constructor. + */ +sal_Bool OPropertySetHelperInfo_Impl::hasPropertyByName( const ::rtl::OUString & PropertyName ) throw(::com::sun::star::uno::RuntimeException) +{ + Property * pR; + pR = (Property *)bsearch( &PropertyName, aInfos.getConstArray(), aInfos.getLength(), + sizeof( Property ), + compare_OUString_Property_Impl ); + return pR != NULL; +} + +//***************************************************************************************************************** +// XInterface, XTypeProvider +//***************************************************************************************************************** +DEFINE_XINTERFACE_6 ( ConstItemContainer , + OWeakObject , + DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ), + DIRECT_INTERFACE( ::com::sun::star::container::XElementAccess ), + DIRECT_INTERFACE( ::com::sun::star::container::XIndexAccess ), + DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel ) + ) + +DEFINE_XTYPEPROVIDER_6 ( ConstItemContainer , + ::com::sun::star::lang::XTypeProvider , + ::com::sun::star::container::XIndexAccess , + ::com::sun::star::container::XElementAccess , + ::com::sun::star::beans::XFastPropertySet , + ::com::sun::star::beans::XPropertySet , + ::com::sun::star::lang::XUnoTunnel + ) + +ConstItemContainer::ConstItemContainer() : ::cppu::OWeakObject() +{ +} + +ConstItemContainer::ConstItemContainer( const RootItemContainer& rRootItemContainer, sal_Bool bFastCopy ) +{ + ShareGuard( rRootItemContainer.m_aShareMutex ); + + // If bFastCopy is set the onwer of the root item container will transfer ownership to us. So + // it is possible to copy only the root part. + m_aUIName = rRootItemContainer.m_aUIName; + if ( bFastCopy ) + m_aItemVector = rRootItemContainer.m_aItemVector; + else + copyItemContainer( rRootItemContainer.m_aItemVector ); +} + +ConstItemContainer::ConstItemContainer( const ItemContainer& rItemContainer ) +{ + ShareGuard( rItemContainer.m_aShareMutex ); + copyItemContainer( rItemContainer.m_aItemVector ); +} + +ConstItemContainer::ConstItemContainer( const Reference< XIndexAccess >& rSourceContainer, sal_Bool bFastCopy ) +{ + // We also have to copy the UIName property + try + { + Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY ); + if ( xPropSet.is() ) + { + rtl::OUString aUIName; + xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName; + } + } + catch ( Exception& ) + { + } + + if ( rSourceContainer.is() ) + { + try + { + sal_Int32 nCount = rSourceContainer->getCount(); + m_aItemVector.reserve(nCount); + if ( bFastCopy ) + { + for ( sal_Int32 i = 0; i < nCount; i++ ) + { + Sequence< PropertyValue > aPropSeq; + if ( rSourceContainer->getByIndex( i ) >>= aPropSeq ) + m_aItemVector.push_back( aPropSeq ); + } + } + else + { + for ( sal_Int32 i = 0; i < nCount; i++ ) + { + Sequence< PropertyValue > aPropSeq; + if ( rSourceContainer->getByIndex( i ) >>= aPropSeq ) + { + sal_Int32 nContainerIndex = -1; + Reference< XIndexAccess > xIndexAccess; + for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) + { + if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) + { + aPropSeq[j].Value >>= xIndexAccess; + nContainerIndex = j; + break; + } + } + + if ( xIndexAccess.is() && nContainerIndex >= 0 ) + aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess ); + + m_aItemVector.push_back( aPropSeq ); + } + } + } + } + catch ( IndexOutOfBoundsException& ) + { + } + } +} + +ConstItemContainer::~ConstItemContainer() +{ +} + +// private +void ConstItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector ) +{ + const sal_uInt32 nCount = rSourceVector.size(); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + sal_Int32 nContainerIndex = -1; + Sequence< PropertyValue > aPropSeq( rSourceVector[i] ); + Reference< XIndexAccess > xIndexAccess; + for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) + { + if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) + { + aPropSeq[j].Value >>= xIndexAccess; + nContainerIndex = j; + break; + } + } + + if ( xIndexAccess.is() && nContainerIndex >= 0 ) + aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess ); + + m_aItemVector.push_back( aPropSeq ); + } +} + +Reference< XIndexAccess > ConstItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer ) +{ + Reference< XIndexAccess > xReturn; + if ( rSubContainer.is() ) + { + ItemContainer* pSource = ItemContainer::GetImplementation( rSubContainer ); + ConstItemContainer* pSubContainer( 0 ); + if ( pSource ) + pSubContainer = new ConstItemContainer( *pSource ); + else + pSubContainer = new ConstItemContainer( rSubContainer ); + xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY ); + } + + return xReturn; +} + +// XUnoTunnel +sal_Int64 ConstItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException) +{ + if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( ConstItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) ) + { + return reinterpret_cast< sal_Int64 >( this ); + } + return 0; +} + +const Sequence< sal_Int8 >& ConstItemContainer::GetUnoTunnelId() throw() +{ + static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL; + if( !pSeq ) + { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +ConstItemContainer* ConstItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw() +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY ); + return xUT.is() ? reinterpret_cast< ConstItemContainer* >(sal::static_int_cast< sal_IntPtr >( + xUT->getSomething( ConstItemContainer::GetUnoTunnelId() ))) : NULL; +} + +// XElementAccess +sal_Bool SAL_CALL ConstItemContainer::hasElements() +throw ( RuntimeException ) +{ + return ( !m_aItemVector.empty() ); +} + +// XIndexAccess +sal_Int32 SAL_CALL ConstItemContainer::getCount() +throw ( RuntimeException ) +{ + return m_aItemVector.size(); +} + +Any SAL_CALL ConstItemContainer::getByIndex( sal_Int32 Index ) +throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + if ( sal_Int32( m_aItemVector.size()) > Index ) + return makeAny( m_aItemVector[Index] ); + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); +} + +// XPropertySet +Reference< XPropertySetInfo > SAL_CALL ConstItemContainer::getPropertySetInfo() +throw (::com::sun::star::uno::RuntimeException) +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! + static Reference< XPropertySetInfo >* pInfo = NULL; + + if( pInfo == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + // Control this pointer again, another instance can be faster then these! + if( pInfo == NULL ) + { + // Create structure of propertysetinfo for baseclass "OPropertySetHelper". + // (Use method "getInfoHelper()".) + static Reference< XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + pInfo = &xInfo; + } + } + + return (*pInfo); +} + +void SAL_CALL ConstItemContainer::setPropertyValue( const ::rtl::OUString&, const Any& ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ +} + +Any SAL_CALL ConstItemContainer::getPropertyValue( const ::rtl::OUString& PropertyName ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + if ( PropertyName.equals( PROPNAME_UINAME )) + return makeAny( m_aUIName ); + + throw UnknownPropertyException(); +} + +void SAL_CALL ConstItemContainer::addPropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ +} + +void SAL_CALL ConstItemContainer::removePropertyChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + // Only read-only properties - do nothing +} + +void SAL_CALL ConstItemContainer::addVetoableChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + // Only read-only properties - do nothing +} + +void SAL_CALL ConstItemContainer::removeVetoableChangeListener( const ::rtl::OUString&, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + // Only read-only properties - do nothing +} + +// XFastPropertySet +void SAL_CALL ConstItemContainer::setFastPropertyValue( sal_Int32, const ::com::sun::star::uno::Any& ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ +} + +Any SAL_CALL ConstItemContainer::getFastPropertyValue( sal_Int32 nHandle ) +throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) +{ + if ( nHandle == PROPHANDLE_UINAME ) + return makeAny( m_aUIName ); + + throw UnknownPropertyException(); +} + +::cppu::IPropertyArrayHelper& SAL_CALL ConstItemContainer::getInfoHelper() +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! + static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; + + if( pInfoHelper == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + // Control this pointer again, another instance can be faster then these! + if( pInfoHelper == NULL ) + { + // Define static member to give structure of properties to baseclass "OPropertySetHelper". + // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable. + // "sal_True" say: Table is sorted by name. + static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True ); + pInfoHelper = &aInfoHelper; + } + } + + return(*pInfoHelper); +} + +const com::sun::star::uno::Sequence< com::sun::star::beans::Property > ConstItemContainer::impl_getStaticPropertyDescriptor() +{ + // Create a new static property array to initialize sequence! + // Table of all predefined properties of this class. Its used from OPropertySetHelper-class! + // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!! + // It's necessary for methods of OPropertySetHelper. + // ATTENTION: + // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!! + + static const com::sun::star::beans::Property pProperties[] = + { + com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME , + ::getCppuType((const rtl::OUString*)NULL), + com::sun::star::beans::PropertyAttribute::TRANSIENT | com::sun::star::beans::PropertyAttribute::READONLY ) + }; + // Use it to initialize sequence! + static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT ); + // Return static "PropertyDescriptor" + return lPropertyDescriptor; +} + +Reference < XPropertySetInfo > ConstItemContainer::createPropertySetInfo( + IPropertyArrayHelper & rProperties ) SAL_THROW( () ) +{ + return static_cast< XPropertySetInfo * >( new OPropertySetHelperInfo_Impl( rProperties ) ); +} + +} // namespace framework + diff --git a/framework/source/fwi/uielement/itemcontainer.cxx b/framework/source/fwi/uielement/itemcontainer.cxx new file mode 100644 index 000000000000..943a5abe2f03 --- /dev/null +++ b/framework/source/fwi/uielement/itemcontainer.cxx @@ -0,0 +1,266 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <uielement/itemcontainer.hxx> +#include <uielement/constitemcontainer.hxx> +#include <threadhelp/resetableguard.hxx> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; + +const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >"; + +namespace framework +{ + +//***************************************************************************************************************** +// XInterface, XTypeProvider +//***************************************************************************************************************** + +ItemContainer::ItemContainer( const ShareableMutex& rMutex ) : + m_aShareMutex( rMutex ) +{ +} + + +ItemContainer::ItemContainer( const ConstItemContainer& rConstItemContainer, const ShareableMutex& rMutex ) : m_aShareMutex( rMutex ) +{ + copyItemContainer( rConstItemContainer.m_aItemVector, rMutex ); +} + +ItemContainer::ItemContainer( const Reference< XIndexAccess >& rSourceContainer, const ShareableMutex& rMutex ) : + m_aShareMutex( rMutex ) +{ + if ( rSourceContainer.is() ) + { + sal_Int32 nCount = rSourceContainer->getCount(); + try + { + for ( sal_Int32 i = 0; i < nCount; i++ ) + { + Sequence< PropertyValue > aPropSeq; + if ( rSourceContainer->getByIndex( i ) >>= aPropSeq ) + { + sal_Int32 nContainerIndex = -1; + Reference< XIndexAccess > xIndexAccess; + for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) + { + if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) + { + aPropSeq[j].Value >>= xIndexAccess; + nContainerIndex = j; + break; + } + } + + if ( xIndexAccess.is() && nContainerIndex >= 0 ) + aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex ); + + m_aItemVector.push_back( aPropSeq ); + } + } + } + catch ( IndexOutOfBoundsException& ) + { + } + } +} + +ItemContainer::~ItemContainer() +{ +} + +// private +void ItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector, const ShareableMutex& rMutex ) +{ + const sal_uInt32 nCount = rSourceVector.size(); + for ( sal_uInt32 i = 0; i < nCount; ++i ) + { + sal_Int32 nContainerIndex = -1; + Sequence< PropertyValue > aPropSeq( rSourceVector[i] ); + Reference< XIndexAccess > xIndexAccess; + for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) + { + if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) + { + aPropSeq[j].Value >>= xIndexAccess; + nContainerIndex = j; + break; + } + } + + if ( xIndexAccess.is() && nContainerIndex >= 0 ) + aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess, rMutex ); + + m_aItemVector.push_back( aPropSeq ); + } +} + +Reference< XIndexAccess > ItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer, const ShareableMutex& rMutex ) +{ + Reference< XIndexAccess > xReturn; + if ( rSubContainer.is() ) + { + ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer ); + ItemContainer* pSubContainer( 0 ); + if ( pSource ) + pSubContainer = new ItemContainer( *pSource, rMutex ); + else + pSubContainer = new ItemContainer( rSubContainer, rMutex ); + xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY ); + } + + return xReturn; +} + +// XUnoTunnel +sal_Int64 ItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException) +{ + if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( ItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) ) + return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this )); + + return 0; +} + +const Sequence< sal_Int8 >& ItemContainer::GetUnoTunnelId() throw() +{ + static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL; + if( !pSeq ) + { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +ItemContainer* ItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw() +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY ); + return xUT.is() ? reinterpret_cast< ItemContainer* >(sal::static_int_cast< sal_IntPtr >( + xUT->getSomething( ItemContainer::GetUnoTunnelId() ))) : NULL; +} + +// XElementAccess +sal_Bool SAL_CALL ItemContainer::hasElements() +throw ( RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + return ( !m_aItemVector.empty() ); +} + +// XIndexAccess +sal_Int32 SAL_CALL ItemContainer::getCount() +throw ( RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + return m_aItemVector.size(); +} + +Any SAL_CALL ItemContainer::getByIndex( sal_Int32 Index ) +throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + if ( sal_Int32( m_aItemVector.size()) > Index ) + return makeAny( m_aItemVector[Index] ); + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); +} + +// XIndexContainer +void SAL_CALL ItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem ) +throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + Sequence< PropertyValue > aSeq; + if ( aItem >>= aSeq ) + { + ShareGuard aLock( m_aShareMutex ); + if ( sal_Int32( m_aItemVector.size()) == Index ) + m_aItemVector.push_back( aSeq ); + else if ( sal_Int32( m_aItemVector.size()) >Index ) + { + std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); + aIter += Index; + m_aItemVector.insert( aIter, aSeq ); + } + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); + } + else + throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), + (OWeakObject *)this, 2 ); +} + +void SAL_CALL ItemContainer::removeByIndex( sal_Int32 Index ) +throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + if ( (sal_Int32)m_aItemVector.size() > Index ) + { + std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); + aIter += Index; + m_aItemVector.erase( aIter ); + } + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); +} + +void SAL_CALL ItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem ) +throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + Sequence< PropertyValue > aSeq; + if ( aItem >>= aSeq ) + { + ShareGuard aLock( m_aShareMutex ); + if ( sal_Int32( m_aItemVector.size()) > Index ) + m_aItemVector[Index] = aSeq; + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); + } + else + throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), + (OWeakObject *)this, 2 ); +} + +} // namespace framework + diff --git a/framework/source/fwi/uielement/rootitemcontainer.cxx b/framework/source/fwi/uielement/rootitemcontainer.cxx new file mode 100644 index 000000000000..02a040a05bc1 --- /dev/null +++ b/framework/source/fwi/uielement/rootitemcontainer.cxx @@ -0,0 +1,466 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_framework.hxx" +//_________________________________________________________________________________________________________________ +// my own includes +//_________________________________________________________________________________________________________________ +#include <uielement/rootitemcontainer.hxx> + +#ifndef __FRAMEWORK_UIELEMENT_ITEMCONTAINER_HHX_ +#include <uielement/itemcontainer.hxx> +#endif + +#ifndef __FRAMEWORK_UIELEMENT_CONSTITEMCONTAINER_HHX_ +#include <uielement/constitemcontainer.hxx> +#endif +#include <threadhelp/resetableguard.hxx> +#include <general.h> +#include <properties.h> + +//_________________________________________________________________________________________________________________ +// interface includes +//_________________________________________________________________________________________________________________ +#include <com/sun/star/beans/PropertyAttribute.hpp> + +//_________________________________________________________________________________________________________________ +// other includes +//_________________________________________________________________________________________________________________ + +using namespace cppu; +using namespace com::sun::star::uno; +using namespace com::sun::star::lang; +using namespace com::sun::star::beans; +using namespace com::sun::star::container; + +const char WRONG_TYPE_EXCEPTION[] = "Type must be com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >"; + +const int PROPHANDLE_UINAME = 1; +const int PROPCOUNT = 1; +const rtl::OUString PROPNAME_UINAME( RTL_CONSTASCII_USTRINGPARAM( "UIName" )); + +namespace framework +{ + +//***************************************************************************************************************** +// XInterface, XTypeProvider +//***************************************************************************************************************** +DEFINE_XINTERFACE_10 ( RootItemContainer , + OWeakObject , + DIRECT_INTERFACE( ::com::sun::star::lang::XTypeProvider ), + DIRECT_INTERFACE( ::com::sun::star::container::XIndexContainer ), + DIRECT_INTERFACE( ::com::sun::star::lang::XUnoTunnel ), + DIRECT_INTERFACE( ::com::sun::star::lang::XSingleComponentFactory ), + DIRECT_INTERFACE( ::com::sun::star::beans::XMultiPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::beans::XFastPropertySet ), + DIRECT_INTERFACE( ::com::sun::star::beans::XPropertySet ), + DERIVED_INTERFACE( ::com::sun::star::container::XIndexReplace, com::sun::star::container::XIndexContainer ), + DERIVED_INTERFACE( ::com::sun::star::container::XIndexAccess, com::sun::star::container::XIndexReplace ), + DERIVED_INTERFACE( ::com::sun::star::container::XElementAccess, ::com::sun::star::container::XIndexAccess ) + ) + +DEFINE_XTYPEPROVIDER_10 ( RootItemContainer , + ::com::sun::star::lang::XTypeProvider , + ::com::sun::star::container::XIndexContainer , + ::com::sun::star::container::XIndexReplace , + ::com::sun::star::container::XIndexAccess , + ::com::sun::star::container::XElementAccess , + ::com::sun::star::beans::XMultiPropertySet , + ::com::sun::star::beans::XFastPropertySet , + ::com::sun::star::beans::XPropertySet , + ::com::sun::star::lang::XUnoTunnel , + ::com::sun::star::lang::XSingleComponentFactory + ) + +RootItemContainer::RootItemContainer() + : ThreadHelpBase ( ) + , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) + , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) + , ::cppu::OWeakObject() +{ +} + +RootItemContainer::RootItemContainer( const ConstItemContainer& rConstItemContainer ) + : ThreadHelpBase ( ) + , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) + , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) + , ::cppu::OWeakObject() +{ + m_aUIName = rConstItemContainer.m_aUIName; + copyItemContainer( rConstItemContainer.m_aItemVector ); +} + +RootItemContainer::RootItemContainer( const Reference< XIndexAccess >& rSourceContainer ) + : ThreadHelpBase ( ) + , ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >( m_aLock.getShareableOslMutex() ) + , ::cppu::OPropertySetHelper ( *(static_cast< ::cppu::OBroadcastHelper* >(this)) ) + , ::cppu::OWeakObject() +{ + // We also have to copy the UIName property + try + { + Reference< XPropertySet > xPropSet( rSourceContainer, UNO_QUERY ); + if ( xPropSet.is() ) + { + xPropSet->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UIName" ))) >>= m_aUIName; + } + } + catch ( Exception& ) + { + } + + if ( rSourceContainer.is() ) + { + sal_Int32 nCount = rSourceContainer->getCount(); + try + { + for ( sal_Int32 i = 0; i < nCount; i++ ) + { + Sequence< PropertyValue > aPropSeq; + if ( rSourceContainer->getByIndex( i ) >>= aPropSeq ) + { + sal_Int32 nContainerIndex = -1; + Reference< XIndexAccess > xIndexAccess; + for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) + { + if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) + { + aPropSeq[j].Value >>= xIndexAccess; + nContainerIndex = j; + break; + } + } + + if ( xIndexAccess.is() && nContainerIndex >= 0 ) + aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess ); + + m_aItemVector.push_back( aPropSeq ); + } + } + } + catch ( IndexOutOfBoundsException& ) + { + } + } +} + +RootItemContainer::~RootItemContainer() +{ +} + +// private +void RootItemContainer::copyItemContainer( const std::vector< Sequence< PropertyValue > >& rSourceVector ) +{ + const sal_uInt32 nCount = rSourceVector.size(); + m_aItemVector.reserve(nCount); + for ( sal_uInt32 i = 0; i < nCount; i++ ) + { + sal_Int32 nContainerIndex = -1; + Sequence< PropertyValue > aPropSeq( rSourceVector[i] ); + Reference< XIndexAccess > xIndexAccess; + for ( sal_Int32 j = 0; j < aPropSeq.getLength(); j++ ) + { + if ( aPropSeq[j].Name.equalsAscii( "ItemDescriptorContainer" )) + { + aPropSeq[j].Value >>= xIndexAccess; + nContainerIndex = j; + break; + } + } + + if ( xIndexAccess.is() && nContainerIndex >= 0 ) + aPropSeq[nContainerIndex].Value <<= deepCopyContainer( xIndexAccess ); + + m_aItemVector.push_back( aPropSeq ); + } +} + +Reference< XIndexAccess > RootItemContainer::deepCopyContainer( const Reference< XIndexAccess >& rSubContainer ) +{ + Reference< XIndexAccess > xReturn; + if ( rSubContainer.is() ) + { + ConstItemContainer* pSource = ConstItemContainer::GetImplementation( rSubContainer ); + ItemContainer* pSubContainer( 0 ); + if ( pSource ) + pSubContainer = new ItemContainer( *pSource, m_aShareMutex ); + else + pSubContainer = new ItemContainer( rSubContainer, m_aShareMutex ); + xReturn = Reference< XIndexAccess >( static_cast< OWeakObject* >( pSubContainer ), UNO_QUERY ); + } + + return xReturn; +} + +// XUnoTunnel +sal_Int64 RootItemContainer::getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& rIdentifier ) throw(::com::sun::star::uno::RuntimeException) +{ + if( ( rIdentifier.getLength() == 16 ) && ( 0 == rtl_compareMemory( RootItemContainer::GetUnoTunnelId().getConstArray(), rIdentifier.getConstArray(), 16 ) ) ) + return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this )); + return 0; +} + +const Sequence< sal_Int8 >& RootItemContainer::GetUnoTunnelId() throw() +{ + static ::com::sun::star::uno::Sequence< sal_Int8 > * pSeq = NULL; + if( !pSeq ) + { + ::osl::Guard< ::osl::Mutex > aGuard( ::osl::Mutex::getGlobalMutex() ); + if( !pSeq ) + { + static ::com::sun::star::uno::Sequence< sal_Int8 > aSeq( 16 ); + rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True ); + pSeq = &aSeq; + } + } + return *pSeq; +} + +RootItemContainer* RootItemContainer::GetImplementation( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxIFace ) throw() +{ + ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( rxIFace, ::com::sun::star::uno::UNO_QUERY ); + return xUT.is() ? reinterpret_cast< RootItemContainer* >(sal::static_int_cast< sal_IntPtr >( + xUT->getSomething( RootItemContainer::GetUnoTunnelId() ))) : NULL; +} + +// XElementAccess +sal_Bool SAL_CALL RootItemContainer::hasElements() +throw ( RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + return ( !m_aItemVector.empty() ); +} + +// XIndexAccess +sal_Int32 SAL_CALL RootItemContainer::getCount() +throw ( RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + return m_aItemVector.size(); +} + +Any SAL_CALL RootItemContainer::getByIndex( sal_Int32 Index ) +throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + if ( sal_Int32( m_aItemVector.size()) > Index ) + return makeAny( m_aItemVector[Index] ); + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); +} + +// XIndexContainer +void SAL_CALL RootItemContainer::insertByIndex( sal_Int32 Index, const Any& aItem ) +throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + Sequence< PropertyValue > aSeq; + if ( aItem >>= aSeq ) + { + ShareGuard aLock( m_aShareMutex ); + if ( sal_Int32( m_aItemVector.size()) == Index ) + m_aItemVector.push_back( aSeq ); + else if ( sal_Int32( m_aItemVector.size()) >Index ) + { + std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); + aIter += Index; + m_aItemVector.insert( aIter, aSeq ); + } + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); + } + else + throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), + (OWeakObject *)this, 2 ); +} + +void SAL_CALL RootItemContainer::removeByIndex( sal_Int32 Index ) +throw ( IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + ShareGuard aLock( m_aShareMutex ); + if ( (sal_Int32)m_aItemVector.size() > Index ) + { + std::vector< Sequence< PropertyValue > >::iterator aIter = m_aItemVector.begin(); + aIter += Index; + m_aItemVector.erase( aIter ); + } + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); +} + +void SAL_CALL RootItemContainer::replaceByIndex( sal_Int32 Index, const Any& aItem ) +throw ( IllegalArgumentException, IndexOutOfBoundsException, WrappedTargetException, RuntimeException ) +{ + Sequence< PropertyValue > aSeq; + if ( aItem >>= aSeq ) + { + ShareGuard aLock( m_aShareMutex ); + if ( sal_Int32( m_aItemVector.size()) > Index ) + m_aItemVector[Index] = aSeq; + else + throw IndexOutOfBoundsException( ::rtl::OUString(), (OWeakObject *)this ); + } + else + throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( WRONG_TYPE_EXCEPTION )), + (OWeakObject *)this, 2 ); +} + +Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithContext( const Reference< XComponentContext >& ) +throw ( Exception, RuntimeException) +{ + return (OWeakObject *)(new ItemContainer( m_aShareMutex )); +} + +Reference< XInterface > SAL_CALL RootItemContainer::createInstanceWithArgumentsAndContext( const Sequence< Any >&, const Reference< XComponentContext >& ) +throw (Exception, RuntimeException) +{ + return (OWeakObject *)(new ItemContainer( m_aShareMutex )); +} + +// XPropertySet helper +sal_Bool SAL_CALL RootItemContainer::convertFastPropertyValue( Any& aConvertedValue , + Any& aOldValue , + sal_Int32 nHandle , + const Any& aValue ) +throw( com::sun::star::lang::IllegalArgumentException ) +{ + // Initialize state with sal_False !!! + // (Handle can be invalid) + sal_Bool bReturn = sal_False; + + switch( nHandle ) + { + case PROPHANDLE_UINAME: + bReturn = PropHelper::willPropertyBeChanged( + com::sun::star::uno::makeAny(m_aUIName), + aValue, + aOldValue, + aConvertedValue); + break; + } + + // Return state of operation. + return bReturn ; +} + +void SAL_CALL RootItemContainer::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle , + const com::sun::star::uno::Any& aValue ) +throw( com::sun::star::uno::Exception ) +{ + switch( nHandle ) + { + case PROPHANDLE_UINAME: + aValue >>= m_aUIName; + break; + } +} + +void SAL_CALL RootItemContainer::getFastPropertyValue( com::sun::star::uno::Any& aValue , + sal_Int32 nHandle ) const +{ + switch( nHandle ) + { + case PROPHANDLE_UINAME: + aValue <<= m_aUIName; + break; + } +} + +::cppu::IPropertyArrayHelper& SAL_CALL RootItemContainer::getInfoHelper() +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfoHelper is NULL - for the second call pInfoHelper is different from NULL! + static ::cppu::OPropertyArrayHelper* pInfoHelper = NULL; + + if( pInfoHelper == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + + // Control this pointer again, another instance can be faster then these! + if( pInfoHelper == NULL ) + { + // Define static member to give structure of properties to baseclass "OPropertySetHelper". + // "impl_getStaticPropertyDescriptor" is a non exported and static funtion, who will define a static propertytable. + // "sal_True" say: Table is sorted by name. + static ::cppu::OPropertyArrayHelper aInfoHelper( impl_getStaticPropertyDescriptor(), sal_True ); + pInfoHelper = &aInfoHelper; + } + } + + return(*pInfoHelper); +} + +com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > SAL_CALL RootItemContainer::getPropertySetInfo() +throw (::com::sun::star::uno::RuntimeException) +{ + // Optimize this method ! + // We initialize a static variable only one time. And we don't must use a mutex at every call! + // For the first call; pInfo is NULL - for the second call pInfo is different from NULL! + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo >* pInfo = NULL; + + if( pInfo == NULL ) + { + // Ready for multithreading + osl::MutexGuard aGuard( osl::Mutex::getGlobalMutex() ) ; + // Control this pointer again, another instance can be faster then these! + if( pInfo == NULL ) + { + // Create structure of propertysetinfo for baseclass "OPropertySetHelper". + // (Use method "getInfoHelper()".) + static com::sun::star::uno::Reference< com::sun::star::beans::XPropertySetInfo > xInfo( createPropertySetInfo( getInfoHelper() ) ); + pInfo = &xInfo; + } + } + + return (*pInfo); +} + +const com::sun::star::uno::Sequence< com::sun::star::beans::Property > RootItemContainer::impl_getStaticPropertyDescriptor() +{ + // Create a new static property array to initialize sequence! + // Table of all predefined properties of this class. Its used from OPropertySetHelper-class! + // Don't forget to change the defines (see begin of this file), if you add, change or delete a property in this list!!! + // It's necessary for methods of OPropertySetHelper. + // ATTENTION: + // YOU MUST SORT FOLLOW TABLE BY NAME ALPHABETICAL !!! + + static const com::sun::star::beans::Property pProperties[] = + { + com::sun::star::beans::Property( PROPNAME_UINAME, PROPHANDLE_UINAME , + ::getCppuType((const rtl::OUString*)NULL), + com::sun::star::beans::PropertyAttribute::TRANSIENT ) + }; + // Use it to initialize sequence! + static const com::sun::star::uno::Sequence< com::sun::star::beans::Property > lPropertyDescriptor( pProperties, PROPCOUNT ); + // Return static "PropertyDescriptor" + return lPropertyDescriptor; +} + +} // namespace framework + |