| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_comphelper.hxx" |
| #include "comphelper/propertybag.hxx" |
| |
| /** === begin UNO includes === **/ |
| #include <com/sun/star/beans/IllegalTypeException.hpp> |
| #include <com/sun/star/beans/PropertyExistException.hpp> |
| #include <com/sun/star/lang/IllegalArgumentException.hpp> |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <com/sun/star/beans/NotRemoveableException.hpp> |
| /** === end UNO includes === **/ |
| |
| #include <map> |
| |
| //........................................................................ |
| 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.isEmpty() ) |
| 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 |
| //........................................................................ |
| |