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