1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26
27 #include "cacheitem.hxx"
28 #include "macros.hxx"
29 #include "constant.hxx"
30
31 //_______________________________________________
32 // includes
33 #include <com/sun/star/uno/Sequence.h>
34
35 #ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_Hpp_
36 #include <com/sun/star/beans/PropertyValue.hpp>
37 #endif
38
39 //_______________________________________________
40 // namespace
41
42 namespace filter{
43 namespace config{
44
45 namespace css = ::com::sun::star;
46
47 //_______________________________________________
48 // definitions
49
50 /*-----------------------------------------------
51 04.11.2003 09:27
52 -----------------------------------------------*/
CacheItem()53 CacheItem::CacheItem()
54 : SequenceAsHashMap()
55 {
56 }
57
58 /*-----------------------------------------------
59 26.06.2003 11:37
60 -----------------------------------------------*/
update(const CacheItem & rUpdateItem)61 void CacheItem::update(const CacheItem& rUpdateItem)
62 {
63 for(const_iterator pItUpdate = rUpdateItem.begin();
64 pItUpdate != rUpdateItem.end() ;
65 ++pItUpdate )
66 {
67 iterator pItThis = this->find(pItUpdate->first);
68 if (pItThis == this->end())
69 (*this)[pItUpdate->first] = pItUpdate->second; // add new prop
70 else
71 pItThis->second = pItUpdate->second; // change value of existing prop
72 }
73 }
74
75 /*-----------------------------------------------
76 26.11.2003 13:27
77 -----------------------------------------------*/
validateUINames(const::rtl::OUString & sActLocale)78 void CacheItem::validateUINames(const ::rtl::OUString& sActLocale)
79 {
80 if (!sActLocale.getLength())
81 return;
82
83 // 1) check UINames first
84 const_iterator pUINames = find(PROPNAME_UINAMES);
85 const_iterator pUIName = find(PROPNAME_UINAME );
86
87 ::comphelper::SequenceAsHashMap lUINames;
88 if (pUINames != end())
89 lUINames << pUINames->second;
90
91 ::rtl::OUString sUIName;
92 if (pUIName != end())
93 pUIName->second >>= sUIName;
94
95 if (sUIName.getLength())
96 {
97 // 1a) set UIName inside list of UINames for current locale
98 lUINames[sActLocale] <<= sUIName;
99 }
100 else if (lUINames.size()>0)
101 {
102 // 1b) or get it from this list, if it not exist!
103 lUINames[sActLocale] >>= sUIName;
104 }
105
106 (*this)[PROPNAME_UINAMES] <<= lUINames.getAsConstPropertyValueList();
107 (*this)[PROPNAME_UINAME ] <<= sUIName;
108 }
109
110 /*-----------------------------------------------
111 12.01.2004 13:32
112 -----------------------------------------------*/
getAsPackedPropertyValueList()113 css::uno::Sequence< css::beans::PropertyValue > CacheItem::getAsPackedPropertyValueList()
114 {
115 sal_Int32 c = (sal_Int32)size();
116 sal_Int32 i = 0;
117
118 css::uno::Sequence< css::beans::PropertyValue > lList(c);
119 css::beans::PropertyValue* pList = lList.getArray();
120
121 for (const_iterator pProp = begin();
122 pProp != end() ;
123 ++pProp )
124 {
125 const ::rtl::OUString& rName = pProp->first;
126 const css::uno::Any& rValue = pProp->second;
127
128 if (!rValue.hasValue())
129 continue;
130
131 pList[i].Name = rName ;
132 pList[i].Value = rValue;
133 ++i;
134 }
135 lList.realloc(i);
136
137 return lList;
138 }
139
140 /*-----------------------------------------------
141 17.07.2003 08:27
142 -----------------------------------------------*/
isSubSet(const css::uno::Any & aSubSet,const css::uno::Any & aSet)143 sal_Bool isSubSet(const css::uno::Any& aSubSet,
144 const css::uno::Any& aSet )
145 {
146 css::uno::Type aT1 = aSubSet.getValueType();
147 css::uno::Type aT2 = aSet.getValueType();
148
149 if (!aT1.equals(aT2))
150 {
151 _FILTER_CONFIG_LOG_("isSubSet() ... types of any values are different => return FALSE\n")
152 return sal_False;
153 }
154
155 css::uno::TypeClass aTypeClass = aT1.getTypeClass();
156 switch(aTypeClass)
157 {
158 //---------------------------------------
159 case css::uno::TypeClass_BOOLEAN :
160 case css::uno::TypeClass_BYTE :
161 case css::uno::TypeClass_SHORT :
162 case css::uno::TypeClass_UNSIGNED_SHORT :
163 case css::uno::TypeClass_LONG :
164 case css::uno::TypeClass_UNSIGNED_LONG :
165 case css::uno::TypeClass_HYPER :
166 case css::uno::TypeClass_UNSIGNED_HYPER :
167 case css::uno::TypeClass_FLOAT :
168 case css::uno::TypeClass_DOUBLE :
169 {
170 sal_Bool bIs = (aSubSet == aSet);
171 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for atomic types => return %s\n", bIs ? "TRUE" : "FALSE")
172 return bIs;
173 }
174
175 //---------------------------------------
176 case css::uno::TypeClass_STRING :
177 {
178 ::rtl::OUString v1;
179 ::rtl::OUString v2;
180
181 if (
182 (aSubSet >>= v1) &&
183 (aSet >>= v2)
184 )
185 {
186 sal_Bool bIs = (v1.equals(v2));
187 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for string types => return %s\n", bIs ? "TRUE" : "FALSE")
188 return bIs;
189 }
190 }
191 break;
192
193 //---------------------------------------
194 case css::uno::TypeClass_ANY :
195 {
196 css::uno::Any v1;
197 css::uno::Any v2;
198
199 if (
200 (aSubSet >>= v1) &&
201 (aSet >>= v2)
202 )
203 {
204 sal_Bool bIs = (isSubSet(v1, v2));
205 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for packed any types => return %s\n", bIs ? "TRUE" : "FALSE")
206 return bIs;
207 }
208 }
209 break;
210
211 //---------------------------------------
212 case css::uno::TypeClass_STRUCT :
213 {
214 css::beans::PropertyValue p1;
215 css::beans::PropertyValue p2;
216
217 if (
218 (aSubSet >>= p1) &&
219 (aSet >>= p2)
220 )
221 {
222 sal_Bool bIs = (
223 (p1.Name.equals(p2.Name) ) &&
224 (isSubSet(p1.Value, p2.Value))
225 );
226 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for structured types [PropertyValue] => return %s\n", bIs ? "TRUE" : "FALSE")
227 return bIs;
228 }
229
230 css::beans::NamedValue n1;
231 css::beans::NamedValue n2;
232
233 if (
234 (aSubSet >>= n1) &&
235 (aSet >>= n2)
236 )
237 {
238 sal_Bool bIs = (
239 (n1.Name.equals(n2.Name) ) &&
240 (isSubSet(n1.Value, n2.Value))
241 );
242 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for structured types [NamedValue] => return %s\n", bIs ? "TRUE" : "FALSE")
243 return bIs;
244 }
245 }
246 break;
247
248 //---------------------------------------
249 case css::uno::TypeClass_SEQUENCE :
250 {
251 css::uno::Sequence< ::rtl::OUString > uno_s1;
252 css::uno::Sequence< ::rtl::OUString > uno_s2;
253
254 if (
255 (aSubSet >>= uno_s1) &&
256 (aSet >>= uno_s2)
257 )
258 {
259 OUStringList stl_s1(uno_s1);
260 OUStringList stl_s2(uno_s2);
261
262 for (OUStringList::const_iterator it1 = stl_s1.begin();
263 it1 != stl_s1.end() ;
264 ++it1 )
265 {
266 if (::std::find(stl_s2.begin(), stl_s2.end(), *it1) == stl_s2.end())
267 {
268 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [OUString] ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(*it1))
269 return sal_False;
270 }
271 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [OUString] ... found \"%s\" => continue loop\n", _FILTER_CONFIG_TO_ASCII_(*it1))
272 }
273 _FILTER_CONFIG_LOG_("isSubSet() ... check for list types [OUString] => return TRUE\n")
274 return sal_True;
275 }
276
277 css::uno::Sequence< css::beans::PropertyValue > uno_p1;
278 css::uno::Sequence< css::beans::PropertyValue > uno_p2;
279
280 if (
281 (aSubSet >>= uno_p1) &&
282 (aSet >>= uno_p2)
283 )
284 {
285 ::comphelper::SequenceAsHashMap stl_p1(uno_p1);
286 ::comphelper::SequenceAsHashMap stl_p2(uno_p2);
287
288 for (::comphelper::SequenceAsHashMap::const_iterator it1 = stl_p1.begin();
289 it1 != stl_p1.end() ;
290 ++it1 )
291 {
292 ::comphelper::SequenceAsHashMap::const_iterator it2 = stl_p2.find(it1->first);
293 if (it2 == stl_p2.end())
294 {
295 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [PropertyValue] ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
296 return sal_False;
297 }
298 if (!isSubSet(it1->second, it2->second))
299 {
300 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [PropertyValue] ... found \"%s\" but has different value => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
301 return sal_False;
302 }
303 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [PropertyValue] ... found \"%s\" with right value => continue loop\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
304 }
305 _FILTER_CONFIG_LOG_("isSubSet() ... check for list types [PropertyValue] => return TRUE\n")
306 return sal_True;
307 }
308
309 css::uno::Sequence< css::beans::NamedValue > uno_n1;
310 css::uno::Sequence< css::beans::NamedValue > uno_n2;
311
312 if (
313 (aSubSet >>= uno_n1) &&
314 (aSet >>= uno_n2)
315 )
316 {
317 ::comphelper::SequenceAsHashMap stl_n1(uno_n1);
318 ::comphelper::SequenceAsHashMap stl_n2(uno_n2);
319
320 for (::comphelper::SequenceAsHashMap::const_iterator it1 = stl_n1.begin();
321 it1 != stl_n1.end() ;
322 ++it1 )
323 {
324 ::comphelper::SequenceAsHashMap::const_iterator it2 = stl_n2.find(it1->first);
325 if (it2 == stl_n2.end())
326 {
327 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [NamedValue] ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
328 return sal_False;
329 }
330 if (!isSubSet(it1->second, it2->second))
331 {
332 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [NamedValue] ... found \"%s\" but has different value => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
333 return sal_False;
334 }
335 _FILTER_CONFIG_LOG_1_("isSubSet() ... check for list types [NamedValue] ... found \"%s\" with right value => continue loop\n", _FILTER_CONFIG_TO_ASCII_(it1->first))
336 }
337 _FILTER_CONFIG_LOG_("isSubSet() ... check for list types [NamedValue] => return TRUE\n")
338 return sal_True;
339 }
340 }
341 break;
342 /*
343 case css::uno::TypeClass_CHAR :
344 case css::uno::TypeClass_VOID :
345 case css::uno::TypeClass_TYPE :
346 case css::uno::TypeClass_ENUM :
347 case css::uno::TypeClass_TYPEDEF :
348 case css::uno::TypeClass_UNION :
349 case css::uno::TypeClass_EXCEPTION :
350 case css::uno::TypeClass_ARRAY :
351 case css::uno::TypeClass_INTERFACE :
352 case css::uno::TypeClass_SERVICE :
353 case css::uno::TypeClass_MODULE :
354 case css::uno::TypeClass_INTERFACE_METHOD :
355 case css::uno::TypeClass_INTERFACE_ATTRIBUTE :
356 case css::uno::TypeClass_UNKNOWN :
357 case css::uno::TypeClass_PROPERTY :
358 case css::uno::TypeClass_CONSTANT :
359 case css::uno::TypeClass_CONSTANTS :
360 case css::uno::TypeClass_SINGLETON :
361 */
362 default: break;
363 }
364
365 OSL_ENSURE(sal_False, "isSubSet() ... this point should not be reached!");
366 return sal_False;
367 }
368
369 /*-----------------------------------------------
370 14.07.2003 10:24
371 -----------------------------------------------*/
haveProps(const CacheItem & lProps) const372 sal_Bool CacheItem::haveProps(const CacheItem& lProps) const
373 {
374 for (const_iterator pIt = lProps.begin();
375 pIt != lProps.end() ;
376 ++pIt )
377 {
378 // i) one required property does not exist at this item => return false
379 const_iterator pItThis = this->find(pIt->first);
380 if (pItThis == this->end())
381 {
382 _FILTER_CONFIG_LOG_1_("CacheItem::haveProps() ... dont found \"%s\" => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
383 return sal_False;
384 }
385
386 // ii) one item does not have the right value => return false
387 if (!isSubSet(pIt->second, pItThis->second))
388 {
389 _FILTER_CONFIG_LOG_1_("CacheItem::haveProps() ... item \"%s\" has different value => return FALSE\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
390 return sal_False;
391 }
392 }
393
394 // this method was not breaked before =>
395 // the given property set seems to match with our
396 // own properties in its minimum => return TRUE
397 _FILTER_CONFIG_LOG_("CacheItem::haveProps() ... => return TRUE\n")
398 return sal_True;
399 }
400
401 /*-----------------------------------------------
402 14.07.2003 10:43
403 -----------------------------------------------*/
dontHaveProps(const CacheItem & lProps) const404 sal_Bool CacheItem::dontHaveProps(const CacheItem& lProps) const
405 {
406 for (const_iterator pIt = lProps.begin();
407 pIt != lProps.end() ;
408 ++pIt )
409 {
410 // i) one item does not exists in general
411 // => continue with next one, because
412 // "excluding" means ... "dont have it".
413 // And "not exists" match to "dont have it".
414 const_iterator pItThis = this->find(pIt->first);
415 if (pItThis == this->end())
416 {
417 _FILTER_CONFIG_LOG_1_("CacheItem::dontHaveProps() ... not found \"%s\" => continue loop!\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
418 continue;
419 }
420
421 // ii) one item have the right value => return false
422 // because this item has the requested property ...
423 // But we checked for "dont have it" here.
424 if (isSubSet(pIt->second, pItThis->second))
425 {
426 _FILTER_CONFIG_LOG_1_("CacheItem::dontHaveProps() ... item \"%s\" has same value => return FALSE!\n", _FILTER_CONFIG_TO_ASCII_(pIt->first))
427 return sal_False;
428 }
429 }
430
431 // this method was not breaked before =>
432 // That means: this item has no matching property
433 // of the given set. It "dont have" it ... => return true.
434 _FILTER_CONFIG_LOG_("CacheItem::dontHaveProps() ... => return TRUE\n")
435 return sal_True;
436 }
437
438 } // namespace config
439 } // namespace filter
440