/************************************************************************* * * 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_comphelper.hxx" #include "comphelper/propertybag.hxx" /** === begin UNO includes === **/ #include #include #include #include #include /** === end UNO includes === **/ #include //........................................................................ namespace comphelper { //........................................................................ /** === begin UNO using === **/ using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Type; using ::com::sun::star::uno::TypeClass_VOID; using ::com::sun::star::beans::IllegalTypeException; using ::com::sun::star::beans::PropertyExistException; using ::com::sun::star::lang::IllegalArgumentException; using ::com::sun::star::beans::Property; using ::com::sun::star::beans::NotRemoveableException; using ::com::sun::star::beans::UnknownPropertyException; /** === end UNO using === **/ namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute; //==================================================================== //= PropertyBag_Impl //==================================================================== typedef ::std::map< sal_Int32, Any > MapInt2Any; struct PropertyBag_Impl { PropertyBag_Impl() : m_bAllowEmptyPropertyName(false) { } MapInt2Any aDefaults; bool m_bAllowEmptyPropertyName; }; //==================================================================== //= PropertyBag //==================================================================== //-------------------------------------------------------------------- PropertyBag::PropertyBag() :m_pImpl( new PropertyBag_Impl ) { } PropertyBag::~PropertyBag() { } //-------------------------------------------------------------------- void PropertyBag::setAllowEmptyPropertyName( bool i_isAllowed ) { m_pImpl->m_bAllowEmptyPropertyName = i_isAllowed; } //-------------------------------------------------------------------- namespace { void lcl_checkForEmptyName( const bool _allowEmpty, const ::rtl::OUString& _name ) { if ( !_allowEmpty && !_name.getLength() ) throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The property name must not be empty." ) ), // TODO: resource NULL, 1 ); } void lcl_checkNameAndHandle( const ::rtl::OUString& _name, const sal_Int32 _handle, const PropertyBag& _container ) { if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) ) throw PropertyExistException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Property name or handle already used." ) ), // TODO: resource NULL ); } } //-------------------------------------------------------------------- void PropertyBag::addVoidProperty( const ::rtl::OUString& _rName, const Type& _rType, sal_Int32 _nHandle, sal_Int32 _nAttributes ) { if ( _rType.getTypeClass() == TypeClass_VOID ) throw IllegalArgumentException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Illegal property type: VOID" ) ), // TODO: resource NULL, 1 ); // check name/handle sanity lcl_checkForEmptyName( m_pImpl->m_bAllowEmptyPropertyName, _rName ); lcl_checkNameAndHandle( _rName, _nHandle, *this ); // register the property OSL_ENSURE( _nAttributes & PropertyAttribute::MAYBEVOID, "PropertyBag::addVoidProperty: this is for default-void properties only!" ); registerPropertyNoMember( _rName, _nHandle, _nAttributes | PropertyAttribute::MAYBEVOID, _rType, NULL ); // remember the default m_pImpl->aDefaults.insert( MapInt2Any::value_type( _nHandle, Any() ) ); } //-------------------------------------------------------------------- void PropertyBag::addProperty( const ::rtl::OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Any& _rInitialValue ) { // check type sanity Type aPropertyType = _rInitialValue.getValueType(); if ( aPropertyType.getTypeClass() == TypeClass_VOID ) throw IllegalTypeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The initial value must be non-NULL to determine the property type." ) ), // TODO: resource NULL ); // check name/handle sanity lcl_checkForEmptyName( m_pImpl->m_bAllowEmptyPropertyName, _rName ); lcl_checkNameAndHandle( _rName, _nHandle, *this ); // register the property registerPropertyNoMember( _rName, _nHandle, _nAttributes, aPropertyType, _rInitialValue.hasValue() ? _rInitialValue.getValue() : NULL ); // remember the default m_pImpl->aDefaults.insert( MapInt2Any::value_type( _nHandle, _rInitialValue ) ); } //-------------------------------------------------------------------- void PropertyBag::removeProperty( const ::rtl::OUString& _rName ) { const Property& rProp = getProperty( _rName ); // will throw an UnknownPropertyException if necessary if ( ( rProp.Attributes & PropertyAttribute::REMOVEABLE ) == 0 ) throw NotRemoveableException( ::rtl::OUString(), NULL ); const sal_Int32 nHandle = rProp.Handle; revokeProperty( nHandle ); m_pImpl->aDefaults.erase( nHandle ); } //-------------------------------------------------------------------- void PropertyBag::getFastPropertyValue( sal_Int32 _nHandle, Any& _out_rValue ) const { if ( !hasPropertyByHandle( _nHandle ) ) throw UnknownPropertyException(); OPropertyContainerHelper::getFastPropertyValue( _out_rValue, _nHandle ); } //-------------------------------------------------------------------- bool PropertyBag::convertFastPropertyValue( sal_Int32 _nHandle, const Any& _rNewValue, Any& _out_rConvertedValue, Any& _out_rCurrentValue ) const { if ( !hasPropertyByHandle( _nHandle ) ) throw UnknownPropertyException(); return const_cast< PropertyBag* >( this )->OPropertyContainerHelper::convertFastPropertyValue( _out_rConvertedValue, _out_rCurrentValue, _nHandle, _rNewValue ); } //-------------------------------------------------------------------- void PropertyBag::setFastPropertyValue( sal_Int32 _nHandle, const Any& _rValue ) { if ( !hasPropertyByHandle( _nHandle ) ) throw UnknownPropertyException(); OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue ); } //-------------------------------------------------------------------- void PropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _out_rValue ) const { if ( !hasPropertyByHandle( _nHandle ) ) throw UnknownPropertyException(); MapInt2Any::const_iterator pos = m_pImpl->aDefaults.find( _nHandle ); OSL_ENSURE( pos != m_pImpl->aDefaults.end(), "PropertyBag::getPropertyDefaultByHandle: inconsistency!" ); if ( pos != m_pImpl->aDefaults.end() ) _out_rValue = pos->second; else _out_rValue.clear(); } //........................................................................ } // namespace comphelper //........................................................................