Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <comphelper/propertybag.hxx>
21 :
22 : #include <com/sun/star/beans/IllegalTypeException.hpp>
23 : #include <com/sun/star/beans/PropertyExistException.hpp>
24 : #include <com/sun/star/container/ElementExistException.hpp>
25 : #include <com/sun/star/lang/IllegalArgumentException.hpp>
26 : #include <com/sun/star/beans/PropertyAttribute.hpp>
27 : #include <com/sun/star/beans/NotRemoveableException.hpp>
28 :
29 : #include <map>
30 :
31 :
32 : namespace comphelper
33 : {
34 :
35 :
36 : using ::com::sun::star::uno::Any;
37 : using ::com::sun::star::uno::Type;
38 : using ::com::sun::star::uno::TypeClass_VOID;
39 : using ::com::sun::star::beans::IllegalTypeException;
40 : using ::com::sun::star::beans::PropertyExistException;
41 : using ::com::sun::star::container::ElementExistException;
42 : using ::com::sun::star::lang::IllegalArgumentException;
43 : using ::com::sun::star::beans::Property;
44 : using ::com::sun::star::beans::NotRemoveableException;
45 : using ::com::sun::star::beans::UnknownPropertyException;
46 :
47 : namespace PropertyAttribute = ::com::sun::star::beans::PropertyAttribute;
48 :
49 :
50 : //= PropertyBag_Impl
51 :
52 : typedef ::std::map< sal_Int32, Any > MapInt2Any;
53 6437 : struct PropertyBag_Impl
54 : {
55 6516 : PropertyBag_Impl() : m_bAllowEmptyPropertyName(false) { }
56 : MapInt2Any aDefaults;
57 : bool m_bAllowEmptyPropertyName;
58 : };
59 :
60 :
61 : //= PropertyBag
62 :
63 :
64 6516 : PropertyBag::PropertyBag()
65 6516 : :m_pImpl( new PropertyBag_Impl )
66 : {
67 6516 : }
68 :
69 6437 : PropertyBag::~PropertyBag()
70 : {
71 6437 : }
72 :
73 :
74 4618 : void PropertyBag::setAllowEmptyPropertyName( bool i_isAllowed )
75 : {
76 4618 : m_pImpl->m_bAllowEmptyPropertyName = i_isAllowed;
77 4618 : }
78 :
79 :
80 : namespace
81 : {
82 35174 : void lcl_checkForEmptyName( const bool _allowEmpty, const OUString& _name )
83 : {
84 35174 : if ( !_allowEmpty && _name.isEmpty() )
85 : throw IllegalArgumentException(
86 : "The property name must not be empty.",
87 : // TODO: resource
88 : NULL,
89 : 1
90 40 : );
91 35134 : }
92 :
93 34492 : void lcl_checkNameAndHandle_PropertyExistException( const OUString& _name, const sal_Int32 _handle, const PropertyBag& _container )
94 : {
95 34492 : if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) )
96 : throw PropertyExistException(
97 : "Property name or handle already used.",
98 336 : NULL );
99 :
100 34156 : }
101 :
102 642 : void lcl_checkNameAndHandle_ElementExistException( const OUString& _name, const sal_Int32 _handle, const PropertyBag& _container )
103 : {
104 642 : if ( _container.hasPropertyByName( _name ) || _container.hasPropertyByHandle( _handle ) )
105 : throw ElementExistException(
106 : "Property name or handle already used.",
107 0 : NULL );
108 :
109 642 : }
110 :
111 : }
112 :
113 :
114 642 : void PropertyBag::addVoidProperty( const OUString& _rName, const Type& _rType, sal_Int32 _nHandle, sal_Int32 _nAttributes )
115 : {
116 642 : if ( _rType.getTypeClass() == TypeClass_VOID )
117 : throw IllegalArgumentException(
118 : "Illegal property type: VOID",
119 : // TODO: resource
120 : NULL,
121 : 1
122 0 : );
123 :
124 : // check name/handle sanity
125 642 : lcl_checkForEmptyName( m_pImpl->m_bAllowEmptyPropertyName, _rName );
126 642 : lcl_checkNameAndHandle_ElementExistException( _rName, _nHandle, *this );
127 :
128 : // register the property
129 : OSL_ENSURE( _nAttributes & PropertyAttribute::MAYBEVOID, "PropertyBag::addVoidProperty: this is for default-void properties only!" );
130 642 : registerPropertyNoMember( _rName, _nHandle, _nAttributes | PropertyAttribute::MAYBEVOID, _rType, NULL );
131 :
132 : // remember the default
133 642 : m_pImpl->aDefaults.insert( MapInt2Any::value_type( _nHandle, Any() ) );
134 642 : }
135 :
136 :
137 34570 : void PropertyBag::addProperty( const OUString& _rName, sal_Int32 _nHandle, sal_Int32 _nAttributes, const Any& _rInitialValue )
138 : {
139 : // check type sanity
140 34570 : Type aPropertyType = _rInitialValue.getValueType();
141 34570 : if ( aPropertyType.getTypeClass() == TypeClass_VOID )
142 : throw IllegalTypeException(
143 : "The initial value must be non-NULL to determine the property type.",
144 : // TODO: resource
145 38 : NULL );
146 :
147 : // check name/handle sanity
148 34532 : lcl_checkForEmptyName( m_pImpl->m_bAllowEmptyPropertyName, _rName );
149 34492 : lcl_checkNameAndHandle_PropertyExistException( _rName, _nHandle, *this );
150 :
151 : // register the property
152 : registerPropertyNoMember( _rName, _nHandle, _nAttributes, aPropertyType,
153 34156 : _rInitialValue.hasValue() ? _rInitialValue.getValue() : NULL );
154 :
155 : // remember the default
156 34156 : m_pImpl->aDefaults.insert( MapInt2Any::value_type( _nHandle, _rInitialValue ) );
157 34156 : }
158 :
159 :
160 48 : void PropertyBag::removeProperty( const OUString& _rName )
161 : {
162 48 : const Property& rProp = getProperty( _rName );
163 : // will throw an UnknownPropertyException if necessary
164 46 : if ( ( rProp.Attributes & PropertyAttribute::REMOVABLE ) == 0 )
165 2 : throw NotRemoveableException( OUString(), NULL );
166 44 : const sal_Int32 nHandle = rProp.Handle;
167 :
168 44 : revokeProperty( nHandle );
169 :
170 44 : m_pImpl->aDefaults.erase( nHandle );
171 44 : }
172 :
173 :
174 70694 : void PropertyBag::getFastPropertyValue( sal_Int32 _nHandle, Any& _out_rValue ) const
175 : {
176 70694 : if ( !hasPropertyByHandle( _nHandle ) )
177 0 : throw UnknownPropertyException();
178 :
179 70694 : OPropertyContainerHelper::getFastPropertyValue( _out_rValue, _nHandle );
180 70694 : }
181 :
182 :
183 1820 : bool PropertyBag::convertFastPropertyValue( sal_Int32 _nHandle, const Any& _rNewValue, Any& _out_rConvertedValue, Any& _out_rCurrentValue ) const
184 : {
185 1820 : if ( !hasPropertyByHandle( _nHandle ) )
186 0 : throw UnknownPropertyException();
187 :
188 : return const_cast< PropertyBag* >( this )->OPropertyContainerHelper::convertFastPropertyValue(
189 1820 : _out_rConvertedValue, _out_rCurrentValue, _nHandle, _rNewValue );
190 : }
191 :
192 :
193 54 : void PropertyBag::setFastPropertyValue( sal_Int32 _nHandle, const Any& _rValue )
194 : {
195 54 : if ( !hasPropertyByHandle( _nHandle ) )
196 0 : throw UnknownPropertyException();
197 :
198 54 : OPropertyContainerHelper::setFastPropertyValue( _nHandle, _rValue );
199 54 : }
200 :
201 :
202 27680 : void PropertyBag::getPropertyDefaultByHandle( sal_Int32 _nHandle, Any& _out_rValue ) const
203 : {
204 27680 : if ( !hasPropertyByHandle( _nHandle ) )
205 0 : throw UnknownPropertyException();
206 :
207 27680 : MapInt2Any::const_iterator pos = m_pImpl->aDefaults.find( _nHandle );
208 : OSL_ENSURE( pos != m_pImpl->aDefaults.end(), "PropertyBag::getPropertyDefaultByHandle: inconsistency!" );
209 27680 : if ( pos != m_pImpl->aDefaults.end() )
210 27680 : _out_rValue = pos->second;
211 : else
212 0 : _out_rValue.clear();
213 27680 : }
214 :
215 :
216 :
217 : } // namespace comphelper
218 :
219 :
220 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|