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