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