xref: /AOO41X/main/ucbhelper/source/provider/propertyvalueset.cxx (revision ac9096f48ddc8269a54878c5b102c19157b971bd)
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_ucbhelper.hxx"
26 
27 /**************************************************************************
28                                 TODO
29  **************************************************************************
30 
31  *************************************************************************/
32 
33 #ifndef __VECTOR__
34 #include <vector>
35 #endif
36 #include <com/sun/star/beans/Property.hpp>
37 #include <com/sun/star/beans/XPropertyAccess.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/beans/XPropertySetInfo.hpp>
40 #include <com/sun/star/script/XTypeConverter.hpp>
41 
42 #include "osl/diagnose.h"
43 #include "osl/mutex.hxx"
44 #include <ucbhelper/propertyvalueset.hxx>
45 
46 using namespace com::sun::star::beans;
47 using namespace com::sun::star::container;
48 using namespace com::sun::star::io;
49 using namespace com::sun::star::lang;
50 using namespace com::sun::star::script;
51 using namespace com::sun::star::sdbc;
52 using namespace com::sun::star::uno;
53 using namespace com::sun::star::util;
54 using namespace rtl;
55 
56 namespace ucbhelper_impl
57 {
58 
59 //=========================================================================
60 //
61 // PropertyValue.
62 //
63 //=========================================================================
64 
65 const sal_uInt32 NO_VALUE_SET               = 0x00000000;
66 const sal_uInt32 STRING_VALUE_SET           = 0x00000001;
67 const sal_uInt32 BOOLEAN_VALUE_SET          = 0x00000002;
68 const sal_uInt32 BYTE_VALUE_SET             = 0x00000004;
69 const sal_uInt32 SHORT_VALUE_SET            = 0x00000008;
70 const sal_uInt32 INT_VALUE_SET              = 0x00000010;
71 const sal_uInt32 LONG_VALUE_SET             = 0x00000020;
72 const sal_uInt32 FLOAT_VALUE_SET            = 0x00000040;
73 const sal_uInt32 DOUBLE_VALUE_SET           = 0x00000080;
74 const sal_uInt32 BYTES_VALUE_SET            = 0x00000100;
75 const sal_uInt32 DATE_VALUE_SET             = 0x00000200;
76 const sal_uInt32 TIME_VALUE_SET             = 0x00000400;
77 const sal_uInt32 TIMESTAMP_VALUE_SET        = 0x00000800;
78 const sal_uInt32 BINARYSTREAM_VALUE_SET     = 0x00001000;
79 const sal_uInt32 CHARACTERSTREAM_VALUE_SET  = 0x00002000;
80 const sal_uInt32 REF_VALUE_SET              = 0x00004000;
81 const sal_uInt32 BLOB_VALUE_SET             = 0x00008000;
82 const sal_uInt32 CLOB_VALUE_SET             = 0x00010000;
83 const sal_uInt32 ARRAY_VALUE_SET            = 0x00020000;
84 const sal_uInt32 OBJECT_VALUE_SET           = 0x00040000;
85 
86 struct PropertyValue
87 {
88     ::rtl::OUString
89                 sPropertyName;
90 
91     sal_uInt32  nPropsSet;
92     sal_uInt32  nOrigValue;
93 
94     OUString    aString;    // getString
95     sal_Bool    bBoolean;   // getBoolean
96     sal_Int8    nByte;      // getByte
97     sal_Int16   nShort;     // getShort
98     sal_Int32   nInt;       // getInt
99     sal_Int64   nLong;      // getLong
100     float       nFloat;     // getFloat
101     double      nDouble;    // getDouble
102 
103     Sequence< sal_Int8 >        aBytes;             // getBytes
104     Date                        aDate;              // getDate
105     Time                        aTime;              // getTime
106     DateTime                    aTimestamp;         // getTimestamp
107     Reference< XInputStream >   xBinaryStream;      // getBinaryStream
108     Reference< XInputStream >   xCharacterStream;   // getCharacterStream
109     Reference< XRef >           xRef;               // getRef
110     Reference< XBlob >          xBlob;              // getBlob
111     Reference< XClob >          xClob;              // getClob
112     Reference< XArray >         xArray;             // getArray
113     Any                         aObject;            // getObject
114 
PropertyValueucbhelper_impl::PropertyValue115     inline PropertyValue()
116         : nPropsSet( NO_VALUE_SET ), nOrigValue( NO_VALUE_SET ),
117           bBoolean(false),
118           nByte(0),
119           nShort(0),
120           nInt(0),
121           nLong(0),
122           nFloat(0.0),
123           nDouble(0.0)
124         {}
125 };
126 } // namespace ucbhelper_impl
127 
128 using namespace ucbhelper_impl;
129 
130 namespace ucbhelper
131 {
132 
133 //=========================================================================
134 //
135 // class PropertyValues.
136 //
137 //=========================================================================
138 
139 typedef std::vector< ucbhelper_impl::PropertyValue > PropertyValuesVector;
140 
141 class PropertyValues : public PropertyValuesVector {};
142 
143 } // namespace ucbhelper
144 
145 //=========================================================================
146 //
147 // Welcome to the macro hell...
148 //
149 //=========================================================================
150 
151 #define GETVALUE_IMPL_TYPE( _type_, _type_name_, _member_name_, _cppu_type_ ) \
152                                                                               \
153     osl::MutexGuard aGuard( m_aMutex );                                       \
154                                                                               \
155     _type_ aValue = _type_();   /* default ctor */                            \
156                                                                               \
157     m_bWasNull = sal_True;                                                    \
158                                                                               \
159     if ( ( columnIndex < 1 )                                                  \
160          || ( columnIndex > sal_Int32( m_pValues->size() ) ) )                \
161     {                                                                         \
162         OSL_ENSURE( sal_False, "PropertyValueSet - index out of range!" );    \
163     }                                                                         \
164     else                                                                      \
165     {                                                                         \
166         ucbhelper_impl::PropertyValue& rValue                                 \
167             = (*m_pValues)[ columnIndex - 1 ];                                \
168                                                                               \
169         if ( rValue.nOrigValue != NO_VALUE_SET )                              \
170         {                                                                     \
171             if ( rValue.nPropsSet & _type_name_ )                             \
172             {                                                                 \
173                 /* Values is present natively... */                           \
174                 aValue = rValue._member_name_;                                \
175                 m_bWasNull = sal_False;                                       \
176             }                                                                 \
177             else                                                              \
178             {                                                                 \
179                 if ( !(rValue.nPropsSet & OBJECT_VALUE_SET) )                 \
180                 {                                                             \
181                     /* Value is not (yet) available as Any. Create it. */     \
182                     getObject( columnIndex, Reference< XNameAccess >() );     \
183                 }                                                             \
184                                                                               \
185                 if ( rValue.nPropsSet & OBJECT_VALUE_SET )                    \
186                 {                                                             \
187                     /* Value is available as Any. */                          \
188                                                                               \
189                     if ( rValue.aObject.hasValue() )                          \
190                     {                                                         \
191                         /* Try to convert into native value. */               \
192                         if ( rValue.aObject >>= aValue )                      \
193                         {                                                     \
194                             rValue._member_name_ = aValue;                    \
195                             rValue.nPropsSet |= _type_name_;                  \
196                             m_bWasNull = sal_False;                           \
197                         }                                                     \
198                         else                                                  \
199                         {                                                     \
200                             /* Last chance. Try type converter service... */  \
201                                                                               \
202                             Reference< XTypeConverter > xConverter            \
203                                                     = getTypeConverter();     \
204                             if ( xConverter.is() )                            \
205                             {                                                 \
206                                 try                                           \
207                                 {                                             \
208                                     Any aConvAny = xConverter->convertTo(     \
209                                                             rValue.aObject,   \
210                                                             _cppu_type_ );    \
211                                                                               \
212                                     if ( aConvAny >>= aValue )                \
213                                     {                                         \
214                                         rValue._member_name_ = aValue;        \
215                                         rValue.nPropsSet |= _type_name_;      \
216                                         m_bWasNull = sal_False;               \
217                                     }                                         \
218                                 }                                             \
219                                 catch ( IllegalArgumentException )            \
220                                 {                                             \
221                                 }                                             \
222                                 catch ( CannotConvertException )              \
223                                 {                                             \
224                                 }                                             \
225                             }                                                 \
226                         }                                                     \
227                     }                                                         \
228                 }                                                             \
229             }                                                                 \
230         }                                                                     \
231     }                                                                         \
232     return aValue;
233 
234 #define GETVALUE_IMPL( _type_, _type_name_, _member_name_ )                   \
235     GETVALUE_IMPL_TYPE( _type_,                                               \
236                         _type_name_,                                          \
237                         _member_name_,                                        \
238                         getCppuType( static_cast< const _type_ * >( 0 ) ) )
239 
240 #define SETVALUE_IMPL( _prop_name_, _type_name_, _member_name_, _value_ )     \
241                                                                               \
242     osl::MutexGuard aGuard( m_aMutex );                                       \
243                                                                               \
244     ucbhelper_impl::PropertyValue aNewValue;                                  \
245     aNewValue.sPropertyName = _prop_name_;                                    \
246     aNewValue.nPropsSet     = _type_name_;                                    \
247     aNewValue.nOrigValue    = _type_name_;                                    \
248     aNewValue._member_name_ = _value_;                                        \
249                                                                               \
250     m_pValues->push_back( aNewValue );
251 
252 namespace ucbhelper {
253 
254 //=========================================================================
255 //=========================================================================
256 //
257 // PropertyValueSet Implementation.
258 //
259 //=========================================================================
260 //=========================================================================
261 
262 #define PROPERTYVALUESET_INIT()             \
263   m_xSMgr( rxSMgr ),                        \
264   m_pValues( new PropertyValues ),          \
265   m_bWasNull( sal_False ),                  \
266   m_bTriedToGetTypeConverter( sal_False )
267 
268 //=========================================================================
PropertyValueSet(const Reference<XMultiServiceFactory> & rxSMgr)269 PropertyValueSet::PropertyValueSet(
270                     const Reference< XMultiServiceFactory >& rxSMgr )
271 : PROPERTYVALUESET_INIT()
272 {
273 }
274 
275 //=========================================================================
PropertyValueSet(const Reference<XMultiServiceFactory> & rxSMgr,const Sequence<com::sun::star::beans::PropertyValue> & rValues)276 PropertyValueSet::PropertyValueSet(
277             const Reference< XMultiServiceFactory >& rxSMgr,
278             const Sequence< com::sun::star::beans::PropertyValue >& rValues )
279 : PROPERTYVALUESET_INIT()
280 {
281     sal_Int32 nCount = rValues.getLength();
282     if ( nCount )
283     {
284         const com::sun::star::beans::PropertyValue* pValues
285             = rValues.getConstArray();
286 
287         for ( sal_Int32 n = 0; n < nCount; ++n )
288         {
289             const com::sun::star::beans::PropertyValue& rValue = pValues[ n ];
290             appendObject( Property( rValue.Name,
291                                     rValue.Handle,
292                                     rValue.Value.getValueType(),
293                                     0 ),
294                           rValue.Value );
295         }
296     }
297 }
298 
299 //=========================================================================
300 // virtual
~PropertyValueSet()301 PropertyValueSet::~PropertyValueSet()
302 {
303     delete m_pValues;
304 }
305 
306 //=========================================================================
307 //
308 // XInterface methods.
309 //
310 //=========================================================================
311 
312 XINTERFACE_IMPL_3( PropertyValueSet,
313                    XTypeProvider,
314                    XRow,
315                    XColumnLocate );
316 
317 //=========================================================================
318 //
319 // XTypeProvider methods.
320 //
321 //=========================================================================
322 
323 XTYPEPROVIDER_IMPL_3( PropertyValueSet,
324                       XTypeProvider,
325                       XRow,
326                       XColumnLocate );
327 
328 //=========================================================================
329 //
330 // XRow methods.
331 //
332 //=========================================================================
333 
334 // virtual
wasNull()335 sal_Bool SAL_CALL PropertyValueSet::wasNull()
336     throw( SQLException, RuntimeException )
337 {
338     // This method can not be implemented correctly!!! Imagine different
339     // threads doing a getXYZ - wasNull calling sequence on the same
340     // implementation object...
341     return m_bWasNull;
342 }
343 
344 //=========================================================================
345 // virtual
getString(sal_Int32 columnIndex)346 OUString SAL_CALL PropertyValueSet::getString( sal_Int32 columnIndex )
347     throw( SQLException, RuntimeException )
348 {
349     GETVALUE_IMPL( OUString, STRING_VALUE_SET, aString );
350 }
351 
352 //=========================================================================
353 // virtual
getBoolean(sal_Int32 columnIndex)354 sal_Bool SAL_CALL PropertyValueSet::getBoolean( sal_Int32 columnIndex )
355     throw( SQLException, RuntimeException )
356 {
357     GETVALUE_IMPL_TYPE(
358             sal_Bool, BOOLEAN_VALUE_SET, bBoolean, getCppuBooleanType() );
359 }
360 
361 //=========================================================================
362 // virtual
getByte(sal_Int32 columnIndex)363 sal_Int8 SAL_CALL PropertyValueSet::getByte( sal_Int32 columnIndex )
364     throw( SQLException, RuntimeException )
365 {
366     GETVALUE_IMPL( sal_Int8, BYTE_VALUE_SET, nByte );
367 }
368 
369 //=========================================================================
370 // virtual
getShort(sal_Int32 columnIndex)371 sal_Int16 SAL_CALL PropertyValueSet::getShort( sal_Int32 columnIndex )
372     throw( SQLException, RuntimeException )
373 {
374     GETVALUE_IMPL( sal_Int16, SHORT_VALUE_SET, nShort );
375 }
376 
377 //=========================================================================
378 // virtual
getInt(sal_Int32 columnIndex)379 sal_Int32 SAL_CALL PropertyValueSet::getInt( sal_Int32 columnIndex )
380     throw( SQLException, RuntimeException )
381 {
382     GETVALUE_IMPL( sal_Int32, INT_VALUE_SET, nInt );
383 }
384 
385 //=========================================================================
386 // virtual
getLong(sal_Int32 columnIndex)387 sal_Int64 SAL_CALL PropertyValueSet::getLong( sal_Int32 columnIndex )
388     throw( SQLException, RuntimeException )
389 {
390     GETVALUE_IMPL( sal_Int64, LONG_VALUE_SET, nLong );
391 }
392 
393 //=========================================================================
394 // virtual
getFloat(sal_Int32 columnIndex)395 float SAL_CALL PropertyValueSet::getFloat( sal_Int32 columnIndex )
396     throw( SQLException, RuntimeException )
397 {
398     GETVALUE_IMPL( float, FLOAT_VALUE_SET, nFloat );
399 }
400 
401 //=========================================================================
402 // virtual
getDouble(sal_Int32 columnIndex)403 double SAL_CALL PropertyValueSet::getDouble( sal_Int32 columnIndex )
404     throw( SQLException, RuntimeException )
405 {
406     GETVALUE_IMPL( double, DOUBLE_VALUE_SET, nDouble );
407 }
408 
409 //=========================================================================
410 // virtual
411 Sequence< sal_Int8 > SAL_CALL
getBytes(sal_Int32 columnIndex)412 PropertyValueSet::getBytes( sal_Int32 columnIndex )
413     throw( SQLException, RuntimeException )
414 {
415     GETVALUE_IMPL( Sequence< sal_Int8 >, BYTES_VALUE_SET, aBytes );
416 }
417 
418 //=========================================================================
419 // virtual
getDate(sal_Int32 columnIndex)420 Date SAL_CALL PropertyValueSet::getDate( sal_Int32 columnIndex )
421     throw( SQLException, RuntimeException )
422 {
423     GETVALUE_IMPL( Date, DATE_VALUE_SET, aDate );
424 }
425 
426 //=========================================================================
427 // virtual
getTime(sal_Int32 columnIndex)428 Time SAL_CALL PropertyValueSet::getTime( sal_Int32 columnIndex )
429     throw( SQLException, RuntimeException )
430 {
431     GETVALUE_IMPL( Time, TIME_VALUE_SET, aTime );
432 }
433 
434 //=========================================================================
435 // virtual
getTimestamp(sal_Int32 columnIndex)436 DateTime SAL_CALL PropertyValueSet::getTimestamp( sal_Int32 columnIndex )
437     throw( SQLException, RuntimeException )
438 {
439     GETVALUE_IMPL( DateTime, TIMESTAMP_VALUE_SET, aTimestamp );
440 }
441 
442 //=========================================================================
443 // virtual
444 Reference< XInputStream > SAL_CALL
getBinaryStream(sal_Int32 columnIndex)445 PropertyValueSet::getBinaryStream( sal_Int32 columnIndex )
446     throw( SQLException, RuntimeException )
447 {
448     GETVALUE_IMPL(
449         Reference< XInputStream >, BINARYSTREAM_VALUE_SET, xBinaryStream );
450 }
451 
452 //=========================================================================
453 // virtual
454 Reference< XInputStream > SAL_CALL
getCharacterStream(sal_Int32 columnIndex)455 PropertyValueSet::getCharacterStream( sal_Int32 columnIndex )
456     throw( SQLException, RuntimeException )
457 {
458     GETVALUE_IMPL(
459         Reference< XInputStream >, CHARACTERSTREAM_VALUE_SET, xCharacterStream );
460 }
461 
462 //=========================================================================
463 // virtual
getObject(sal_Int32 columnIndex,const Reference<XNameAccess> &)464 Any SAL_CALL PropertyValueSet::getObject(
465                                     sal_Int32 columnIndex,
466                                     const Reference< XNameAccess >& )
467     throw( SQLException, RuntimeException )
468 {
469     osl::MutexGuard aGuard( m_aMutex );
470 
471     Any aValue;
472 
473     m_bWasNull = sal_True;
474 
475     if ( ( columnIndex < 1 )
476          || ( columnIndex > sal_Int32( m_pValues->size() ) ) )
477     {
478         OSL_ENSURE( sal_False, "PropertyValueSet - index out of range!" );
479     }
480     else
481     {
482         ucbhelper_impl::PropertyValue& rValue
483             = (*m_pValues)[ columnIndex - 1 ];
484 
485         if ( rValue.nPropsSet & OBJECT_VALUE_SET )
486         {
487             // Values is present natively...
488             aValue = rValue.aObject;
489             m_bWasNull = sal_False;
490         }
491         else
492         {
493             // Make Any from original value.
494 
495             switch ( rValue.nOrigValue )
496             {
497                 case NO_VALUE_SET:
498                     break;
499 
500                 case STRING_VALUE_SET:
501                     aValue <<= rValue.aString;
502                     break;
503 
504                 case BOOLEAN_VALUE_SET:
505                     aValue <<= rValue.bBoolean;
506                     break;
507 
508                 case BYTE_VALUE_SET:
509                     aValue <<= rValue.nByte;
510                     break;
511 
512                 case SHORT_VALUE_SET:
513                     aValue <<= rValue.nShort;
514                     break;
515 
516                 case INT_VALUE_SET:
517                     aValue <<= rValue.nInt;
518                     break;
519 
520                 case LONG_VALUE_SET:
521                     aValue <<= rValue.nLong;
522                     break;
523 
524                 case FLOAT_VALUE_SET:
525                     aValue <<= rValue.nFloat;
526                     break;
527 
528                 case DOUBLE_VALUE_SET:
529                     aValue <<= rValue.nDouble;
530                     break;
531 
532                 case BYTES_VALUE_SET:
533                     aValue <<= rValue.aBytes;
534                     break;
535 
536                 case DATE_VALUE_SET:
537                     aValue <<= rValue.aDate;
538                     break;
539 
540                 case TIME_VALUE_SET:
541                     aValue <<= rValue.aTime;
542                     break;
543 
544                 case TIMESTAMP_VALUE_SET:
545                     aValue <<= rValue.aTimestamp;
546                     break;
547 
548                 case BINARYSTREAM_VALUE_SET:
549                     aValue <<= rValue.xBinaryStream;
550                     break;
551 
552                 case CHARACTERSTREAM_VALUE_SET:
553                     aValue <<= rValue.xCharacterStream;
554                     break;
555 
556                 case REF_VALUE_SET:
557                     aValue <<= rValue.xRef;
558                     break;
559 
560                 case BLOB_VALUE_SET:
561                     aValue <<= rValue.xBlob;
562                     break;
563 
564                 case CLOB_VALUE_SET:
565                     aValue <<= rValue.xClob;
566                     break;
567 
568                 case ARRAY_VALUE_SET:
569                     aValue <<= rValue.xArray;
570                     break;
571 
572                 case OBJECT_VALUE_SET:
573                     // Fall-through is intended!
574                 default:
575                     OSL_ENSURE( sal_False,
576                                 "PropertyValueSet::getObject - "
577                                 "Wrong original type" );
578                     break;
579             }
580 
581             if ( aValue.hasValue() )
582             {
583                 rValue.aObject = aValue;
584                 rValue.nPropsSet |= OBJECT_VALUE_SET;
585                 m_bWasNull = sal_False;
586             }
587         }
588     }
589 
590     return aValue;
591 }
592 
593 //=========================================================================
594 // virtual
getRef(sal_Int32 columnIndex)595 Reference< XRef > SAL_CALL PropertyValueSet::getRef( sal_Int32 columnIndex )
596     throw( SQLException, RuntimeException )
597 {
598     GETVALUE_IMPL( Reference< XRef >, REF_VALUE_SET, xRef );
599 }
600 
601 //=========================================================================
602 // virtual
getBlob(sal_Int32 columnIndex)603 Reference< XBlob > SAL_CALL PropertyValueSet::getBlob( sal_Int32 columnIndex )
604     throw( SQLException, RuntimeException )
605 {
606     GETVALUE_IMPL( Reference< XBlob >, BLOB_VALUE_SET, xBlob );
607 }
608 
609 //=========================================================================
610 // virtual
getClob(sal_Int32 columnIndex)611 Reference< XClob > SAL_CALL PropertyValueSet::getClob( sal_Int32 columnIndex )
612     throw( SQLException, RuntimeException )
613 {
614     GETVALUE_IMPL( Reference< XClob >, CLOB_VALUE_SET, xClob );
615 }
616 
617 //=========================================================================
618 // virtual
getArray(sal_Int32 columnIndex)619 Reference< XArray > SAL_CALL PropertyValueSet::getArray( sal_Int32 columnIndex )
620     throw( SQLException, RuntimeException )
621 {
622     GETVALUE_IMPL( Reference< XArray >, ARRAY_VALUE_SET, xArray );
623 }
624 
625 //=========================================================================
626 //
627 // XColumnLocate methods.
628 //
629 //=========================================================================
630 
631 // virtual
findColumn(const OUString & columnName)632 sal_Int32 SAL_CALL PropertyValueSet::findColumn( const OUString& columnName )
633     throw( SQLException, RuntimeException )
634 {
635     osl::MutexGuard aGuard( m_aMutex );
636 
637     if ( columnName.getLength() )
638     {
639         sal_Int32 nCount = m_pValues->size();
640         for ( sal_Int32 n = 0; n < nCount; ++n )
641         {
642             if ( (*m_pValues)[ n ].sPropertyName.equals( columnName ) )
643                 return sal_Int32( n + 1 ); // Index is 1-based.
644         }
645     }
646     return 0;
647 }
648 
649 //=========================================================================
650 //
651 // Non-interface methods.
652 //
653 //=========================================================================
654 
getTypeConverter()655 const Reference< XTypeConverter >& PropertyValueSet::getTypeConverter()
656 {
657     osl::MutexGuard aGuard( m_aMutex );
658 
659     if ( !m_bTriedToGetTypeConverter && !m_xTypeConverter.is() )
660     {
661         m_bTriedToGetTypeConverter = sal_True;
662         m_xTypeConverter = Reference< XTypeConverter >(
663                                 m_xSMgr->createInstance(
664                                     OUString::createFromAscii(
665                                         "com.sun.star.script.Converter" ) ),
666                                 UNO_QUERY );
667 
668         OSL_ENSURE( m_xTypeConverter.is(),
669                     "PropertyValueSet::getTypeConverter() - "
670                     "Service 'com.sun.star.script.Converter' n/a!" );
671     }
672     return m_xTypeConverter;
673 }
674 
675 //=========================================================================
getLength() const676 sal_Int32 PropertyValueSet::getLength() const
677 {
678     return m_pValues->size();
679 }
680 
681 //=========================================================================
appendString(const::rtl::OUString & rPropName,const OUString & rValue)682 void PropertyValueSet::appendString( const ::rtl::OUString& rPropName,
683                                      const OUString& rValue )
684 {
685     SETVALUE_IMPL( rPropName, STRING_VALUE_SET, aString, rValue );
686 }
687 
688 //=========================================================================
appendBoolean(const::rtl::OUString & rPropName,sal_Bool bValue)689 void PropertyValueSet::appendBoolean( const ::rtl::OUString& rPropName,
690                                       sal_Bool bValue )
691 {
692     SETVALUE_IMPL( rPropName, BOOLEAN_VALUE_SET, bBoolean, bValue );
693 }
694 
695 //=========================================================================
appendByte(const::rtl::OUString & rPropName,sal_Int8 nValue)696 void PropertyValueSet::appendByte( const ::rtl::OUString& rPropName,
697                                    sal_Int8 nValue )
698 {
699     SETVALUE_IMPL( rPropName, BYTE_VALUE_SET, nByte, nValue );
700 }
701 
702 //=========================================================================
appendShort(const::rtl::OUString & rPropName,sal_Int16 nValue)703 void PropertyValueSet::appendShort( const ::rtl::OUString& rPropName,
704                                     sal_Int16 nValue )
705 {
706     SETVALUE_IMPL( rPropName, SHORT_VALUE_SET, nShort, nValue );
707 }
708 
709 //=========================================================================
appendInt(const::rtl::OUString & rPropName,sal_Int32 nValue)710 void PropertyValueSet::appendInt( const ::rtl::OUString& rPropName,
711                                   sal_Int32 nValue )
712 {
713     SETVALUE_IMPL( rPropName, INT_VALUE_SET, nInt, nValue );
714 }
715 
716 //=========================================================================
appendLong(const::rtl::OUString & rPropName,sal_Int64 nValue)717 void PropertyValueSet::appendLong( const ::rtl::OUString& rPropName,
718                                    sal_Int64 nValue )
719 {
720     SETVALUE_IMPL( rPropName, LONG_VALUE_SET, nLong, nValue );
721 }
722 
723 //=========================================================================
appendFloat(const::rtl::OUString & rPropName,float nValue)724 void PropertyValueSet::appendFloat( const ::rtl::OUString& rPropName,
725                                     float nValue )
726 {
727     SETVALUE_IMPL( rPropName, FLOAT_VALUE_SET, nFloat, nValue );
728 }
729 
730 //=========================================================================
appendDouble(const::rtl::OUString & rPropName,double nValue)731 void PropertyValueSet::appendDouble( const ::rtl::OUString& rPropName,
732                                      double nValue )
733 {
734     SETVALUE_IMPL( rPropName, DOUBLE_VALUE_SET, nDouble, nValue );
735 }
736 
737 //=========================================================================
appendBytes(const::rtl::OUString & rPropName,const Sequence<sal_Int8> & rValue)738 void PropertyValueSet::appendBytes( const ::rtl::OUString& rPropName,
739                                     const Sequence< sal_Int8 >& rValue )
740 {
741     SETVALUE_IMPL( rPropName, BYTES_VALUE_SET, aBytes, rValue );
742 }
743 
744 //=========================================================================
appendDate(const::rtl::OUString & rPropName,const Date & rValue)745 void PropertyValueSet::appendDate( const ::rtl::OUString& rPropName,
746                                    const Date& rValue )
747 {
748     SETVALUE_IMPL( rPropName, DATE_VALUE_SET, aDate, rValue );
749 }
750 
751 //=========================================================================
appendTime(const::rtl::OUString & rPropName,const Time & rValue)752 void PropertyValueSet::appendTime( const ::rtl::OUString& rPropName,
753                                    const Time& rValue )
754 {
755     SETVALUE_IMPL( rPropName, TIME_VALUE_SET, aTime, rValue );
756 }
757 
758 //=========================================================================
appendTimestamp(const::rtl::OUString & rPropName,const DateTime & rValue)759 void PropertyValueSet::appendTimestamp( const ::rtl::OUString& rPropName,
760                                         const DateTime& rValue )
761 {
762     SETVALUE_IMPL( rPropName, TIMESTAMP_VALUE_SET, aTimestamp, rValue );
763 }
764 
765 //=========================================================================
appendBinaryStream(const::rtl::OUString & rPropName,const Reference<XInputStream> & rValue)766 void PropertyValueSet::appendBinaryStream(
767                                 const ::rtl::OUString& rPropName,
768                                 const Reference< XInputStream >& rValue )
769 {
770     SETVALUE_IMPL( rPropName, BINARYSTREAM_VALUE_SET, xBinaryStream, rValue );
771 }
772 
773 //=========================================================================
appendCharacterStream(const::rtl::OUString & rPropName,const Reference<XInputStream> & rValue)774 void PropertyValueSet::appendCharacterStream(
775                                 const ::rtl::OUString& rPropName,
776                                 const Reference< XInputStream >& rValue )
777 {
778     SETVALUE_IMPL( rPropName, CHARACTERSTREAM_VALUE_SET, xCharacterStream, rValue );
779 }
780 
781 //=========================================================================
appendObject(const::rtl::OUString & rPropName,const Any & rValue)782 void PropertyValueSet::appendObject( const ::rtl::OUString& rPropName,
783                                      const Any& rValue )
784 {
785     SETVALUE_IMPL( rPropName, OBJECT_VALUE_SET, aObject, rValue );
786 }
787 
788 //=========================================================================
appendRef(const::rtl::OUString & rPropName,const Reference<XRef> & rValue)789 void PropertyValueSet::appendRef( const ::rtl::OUString& rPropName,
790                                   const Reference< XRef >& rValue )
791 {
792     SETVALUE_IMPL( rPropName, REF_VALUE_SET, xRef, rValue );
793 }
794 
795 //=========================================================================
appendBlob(const::rtl::OUString & rPropName,const Reference<XBlob> & rValue)796 void PropertyValueSet::appendBlob( const ::rtl::OUString& rPropName,
797                                    const Reference< XBlob >& rValue )
798 {
799     SETVALUE_IMPL( rPropName, BLOB_VALUE_SET, xBlob, rValue );
800 }
801 
802 //=========================================================================
appendClob(const::rtl::OUString & rPropName,const Reference<XClob> & rValue)803 void PropertyValueSet::appendClob( const ::rtl::OUString& rPropName,
804                                    const Reference< XClob >& rValue )
805 {
806     SETVALUE_IMPL( rPropName, CLOB_VALUE_SET, xClob, rValue );
807 }
808 
809 //=========================================================================
appendArray(const::rtl::OUString & rPropName,const Reference<XArray> & rValue)810 void PropertyValueSet::appendArray( const ::rtl::OUString& rPropName,
811                                     const Reference< XArray >& rValue )
812 {
813     SETVALUE_IMPL( rPropName, ARRAY_VALUE_SET, xArray, rValue );
814 }
815 
816 //=========================================================================
appendVoid(const::rtl::OUString & rPropName)817 void PropertyValueSet::appendVoid( const ::rtl::OUString& rPropName )
818 {
819     SETVALUE_IMPL( rPropName, NO_VALUE_SET, aObject, Any() );
820 }
821 
822 //=========================================================================
appendPropertySet(const Reference<XPropertySet> & rxSet)823 void PropertyValueSet::appendPropertySet(
824                                 const Reference< XPropertySet >& rxSet )
825 {
826     if ( rxSet.is() )
827     {
828         Reference< XPropertySetInfo > xInfo = rxSet->getPropertySetInfo();
829         if ( xInfo.is() )
830         {
831             Sequence< Property > aProps      = xInfo->getProperties();
832             const Property*      pProps      = aProps.getConstArray();
833             sal_Int32            nPropsCount = aProps.getLength();
834 
835             Reference< XPropertyAccess > xPropertyAccess( rxSet, UNO_QUERY );
836             if ( xPropertyAccess.is() )
837             {
838                 // Efficient: Get all prop values with one ( remote) call.
839 
840                 Sequence< ::com::sun::star::beans::PropertyValue > aPropValues
841                     = xPropertyAccess->getPropertyValues();
842 
843                 const ::com::sun::star::beans::PropertyValue* pPropValues
844                     = aPropValues.getConstArray();
845 
846                 sal_Int32 nValuesCount = aPropValues.getLength();
847                 for ( sal_Int32 n = 0; n < nValuesCount; ++n )
848                 {
849                     const ::com::sun::star::beans::PropertyValue& rPropValue
850                         = pPropValues[ n ];
851 
852                     // Find info for current property value.
853                     for ( sal_Int32 m = 0; m < nPropsCount; ++m )
854                     {
855                         const Property& rProp = pProps[ m ];
856                         if ( rProp.Name == rPropValue.Name )
857                         {
858                             // Found!
859                             appendObject( rProp, rPropValue.Value );
860                             break;
861                         }
862                     }
863                 }
864             }
865             else
866             {
867                 // Get every single prop value with one ( remote) call.
868 
869                 for ( sal_Int32 n = 0; n < nPropsCount; ++n )
870                 {
871                     const Property& rProp = pProps[ n ];
872 
873                     try
874                     {
875                         Any aValue = rxSet->getPropertyValue( rProp.Name );
876 
877                         if ( aValue.hasValue() )
878                             appendObject( rProp, aValue );
879                     }
880                     catch ( UnknownPropertyException )
881                     {
882                     }
883                     catch ( WrappedTargetException )
884                     {
885                     }
886                 }
887             }
888         }
889     }
890 }
891 
892 //=========================================================================
appendPropertySetValue(const Reference<XPropertySet> & rxSet,const Property & rProperty)893 sal_Bool PropertyValueSet::appendPropertySetValue(
894                                 const Reference< XPropertySet >& rxSet,
895                                 const Property& rProperty )
896 {
897     if ( rxSet.is() )
898     {
899         try
900         {
901             Any aValue = rxSet->getPropertyValue( rProperty.Name );
902             if ( aValue.hasValue() )
903             {
904                 appendObject( rProperty, aValue );
905                 return sal_True;
906             }
907         }
908         catch ( UnknownPropertyException )
909         {
910         }
911         catch ( WrappedTargetException )
912         {
913         }
914     }
915 
916     // Error.
917     return sal_False;
918 }
919 
920 } // namespace ucbhelper
921