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 // MARKER(update_precomp.py): autogen include statement, do not remove
28 #include "precompiled_extensions.hxx"
29 
30 #include "sal/config.h"
31 #include "cppuhelper/factory.hxx"
32 #include "cppuhelper/implementationentry.hxx"
33 #include "cppuhelper/implbase3.hxx"
34 #include "com/sun/star/lang/XServiceInfo.hpp"
35 #include "com/sun/star/inspection/XStringRepresentation.hpp"
36 #include "com/sun/star/lang/XInitialization.hpp"
37 #include "com/sun/star/script/XTypeConverter.hpp"
38 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
39 #include <com/sun/star/reflection/XConstantsTypeDescription.hpp>
40 #include <com/sun/star/beans/XIntrospection.hpp>
41 #include <com/sun/star/util/DateTime.hpp>
42 #include <com/sun/star/util/Date.hpp>
43 #include <com/sun/star/util/Time.hpp>
44 #include <comphelper/sequence.hxx>
45 #include <connectivity/dbconversion.hxx>
46 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPRC_HXX_
47 #include "modulepcr.hxx"
48 #endif
49 #ifndef _EXTENSIONS_FORMCTRLR_PROPRESID_HRC_
50 #include "formresid.hrc"
51 #endif
52 #include <tools/debug.hxx>
53 #include <tools/string.hxx>
54 #include <tools/StringListResource.hxx>
55 #include <comphelper/types.hxx>
56 #ifndef _EXTENSIONS_PROPCTRLR_MODULEPCR_HXX_
57 #include "modulepcr.hxx"
58 #endif
59 
60 #include <functional>
61 #include <algorithm>
62 
63 // component helper namespace
64 namespace comp_StringRepresentation {
65 
66 using namespace ::com::sun::star;
67 
68 // component and service helper functions:
69 ::rtl::OUString SAL_CALL _getImplementationName();
70 uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames();
71 uno::Reference< uno::XInterface > SAL_CALL _create( uno::Reference< uno::XComponentContext > const & context );
72 
73 } // closing component helper namespace
74 
75 
76 namespace pcr{
77 
78 using namespace ::com::sun::star;
79 using namespace ::com::sun::star::uno;
80 
81 class StringRepresentation:
82     public ::cppu::WeakImplHelper3<
83         lang::XServiceInfo,
84         inspection::XStringRepresentation,
85         lang::XInitialization>
86 {
87 public:
88     explicit StringRepresentation(uno::Reference< uno::XComponentContext > const & context);
89 
90     // lang::XServiceInfo:
91     virtual ::rtl::OUString SAL_CALL getImplementationName() throw (uno::RuntimeException);
92     virtual ::sal_Bool SAL_CALL supportsService(const ::rtl::OUString & ServiceName) throw (uno::RuntimeException);
93     virtual uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw (uno::RuntimeException);
94 
95     // inspection::XStringRepresentation:
96     virtual ::rtl::OUString SAL_CALL convertToControlValue(const uno::Any & PropertyValue) throw (uno::RuntimeException, uno::Exception);
97     virtual uno::Any SAL_CALL convertToPropertyValue(const ::rtl::OUString & ControlValue, const uno::Type & ControlValueType) throw (uno::RuntimeException, uno::Exception);
98 
99     // lang::XInitialization:
100     virtual void SAL_CALL initialize(const uno::Sequence< uno::Any > & aArguments) throw (uno::RuntimeException, uno::Exception);
101 
102 private:
103     StringRepresentation(StringRepresentation &); // not defined
104     void operator =(StringRepresentation &); // not defined
105 
106     virtual ~StringRepresentation() {}
107 
108     /** converts a generic value into a string representation
109 
110         If you want to convert values whose string representation does not depend
111         on a concrete property, use this version
112 
113         @return <TRUE/>
114             if and only if the value could be converted
115     */
116     bool            convertGenericValueToString(
117                         const uno::Any&   _rValue,
118                                 ::rtl::OUString&              _rStringRep
119                     );
120 
121     /** converts string representation into generic value
122 
123         If you want to convert values whose string representation does not depend
124         on a concrete property, use this version
125 
126         @return <TRUE/>
127             if and only if the value could be converted
128     */
129     bool            convertStringToGenericValue(
130                         const ::rtl::OUString&              _rStringRep,
131                                 uno::Any&   _rValue,
132                         const uno::Type& _rTargetType
133                     );
134 
135     /** uses the simple convert method from the type converter
136     *
137     * \param _rValue the value to be converted
138     * \return the converted string.
139     */
140     ::rtl::OUString convertSimpleToString( const uno::Any& _rValue );
141 
142     /** converts a string into his constant value if it exists, otherwise the type converter is used.
143     * \param _rValue the value to be converted
144     * \param _ePropertyType teh type of the propery to be converted into
145     * \return the converted value
146     */
147     uno::Any convertStringToSimple( const ::rtl::OUString& _rValue,const uno::TypeClass& _ePropertyType );
148 
149     uno::Reference< uno::XComponentContext >                                m_xContext;
150     uno::Reference< script::XTypeConverter >                                m_xTypeConverter;
151     uno::Reference< reflection::XConstantsTypeDescription >                 m_xTypeDescription;
152     uno::Sequence< ::rtl::OUString >                                        m_aValues;
153     uno::Sequence< uno::Reference< reflection::XConstantTypeDescription> >  m_aConstants;
154 
155 };
156 
157 StringRepresentation::StringRepresentation(uno::Reference< uno::XComponentContext > const & context) :
158     m_xContext(context)
159 {}
160 
161 // com.sun.star.uno.XServiceInfo:
162 ::rtl::OUString  SAL_CALL StringRepresentation::getImplementationName() throw (uno::RuntimeException)
163 {
164     return comp_StringRepresentation::_getImplementationName();
165 }
166 
167 ::sal_Bool SAL_CALL StringRepresentation::supportsService(::rtl::OUString const & serviceName) throw (uno::RuntimeException)
168 {
169     return ::comphelper::existsValue(serviceName,comp_StringRepresentation::_getSupportedServiceNames());
170 }
171 
172 uno::Sequence< ::rtl::OUString >  SAL_CALL StringRepresentation::getSupportedServiceNames() throw (uno::RuntimeException)
173 {
174     return comp_StringRepresentation::_getSupportedServiceNames();
175 }
176 
177 // inspection::XStringRepresentation:
178 ::rtl::OUString SAL_CALL StringRepresentation::convertToControlValue(const uno::Any & PropertyValue) throw (uno::RuntimeException, uno::Exception)
179 {
180     ::rtl::OUString sReturn;
181     if ( !convertGenericValueToString( PropertyValue, sReturn ) )
182     {
183         sReturn = convertSimpleToString( PropertyValue );
184 #ifdef DBG_UTIL
185         if ( !sReturn.getLength() && PropertyValue.hasValue() )
186         {
187             ::rtl::OString sMessage( "StringRepresentation::convertPropertyValueToStringRepresentation: cannot convert values of type '" );
188             sMessage += ::rtl::OString( PropertyValue.getValueType().getTypeName().getStr(), PropertyValue.getValueType().getTypeName().getLength(), RTL_TEXTENCODING_ASCII_US );
189             sMessage += ::rtl::OString( "'!" );
190             DBG_ERROR( sMessage.getStr() );
191         }
192 #endif
193     }
194 
195     return sReturn;
196 }
197 
198 uno::Any SAL_CALL StringRepresentation::convertToPropertyValue(const ::rtl::OUString & ControlValue, const uno::Type & ControlValueType) throw (uno::RuntimeException, uno::Exception)
199 {
200     uno::Any aReturn;
201 
202     uno::TypeClass ePropertyType = ControlValueType.getTypeClass();
203 	switch ( ePropertyType )
204 	{
205 	case uno::TypeClass_FLOAT:
206 	case uno::TypeClass_DOUBLE:
207 	case uno::TypeClass_BYTE:
208 	case uno::TypeClass_SHORT:
209 	case uno::TypeClass_LONG:
210 	case uno::TypeClass_HYPER:
211 	case uno::TypeClass_UNSIGNED_SHORT:
212 	case uno::TypeClass_UNSIGNED_LONG:
213 	case uno::TypeClass_UNSIGNED_HYPER:
214 		try
215 		{
216             aReturn = convertStringToSimple(ControlValue, ePropertyType);
217 		}
218 		catch( const script::CannotConvertException& ) { }
219         catch( const lang::IllegalArgumentException& ) { }
220 		break;
221 
222     default:
223     #if OSL_DEBUG_LEVEL > 0
224         bool bCanConvert =
225     #endif
226         convertStringToGenericValue( ControlValue, aReturn, ControlValueType );
227 
228     #if OSL_DEBUG_LEVEL > 0
229         // could not convert ...
230         if ( !bCanConvert && ControlValue.getLength() )
231         {
232             ::rtl::OString sMessage( "StringRepresentation::convertStringRepresentationToPropertyValue: cannot convert into values of type '" );
233             sMessage += ::rtl::OString( ControlValueType.getTypeName().getStr(), ControlValueType.getTypeName().getLength(), RTL_TEXTENCODING_ASCII_US );
234             sMessage += ::rtl::OString( "'!" );
235             DBG_ERROR( sMessage.getStr() );
236         }
237     #endif
238     }
239 
240     return aReturn;
241 }
242 
243 // lang::XInitialization:
244 void SAL_CALL StringRepresentation::initialize(const uno::Sequence< uno::Any > & aArguments) throw (uno::RuntimeException, uno::Exception)
245 {
246     sal_Int32 nLength = aArguments.getLength();
247     if ( nLength )
248     {
249         const uno::Any* pIter = aArguments.getConstArray();
250         m_xTypeConverter.set(*pIter++,uno::UNO_QUERY);
251         if ( nLength == 3 )
252         {
253             ::rtl::OUString sConstantName;
254             *pIter++ >>= sConstantName;
255             *pIter >>= m_aValues;
256 
257             if ( m_xContext.is() )
258             {
259                 uno::Reference< container::XHierarchicalNameAccess > xTypeDescProv(
260                     m_xContext->getValueByName( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "/singletons/com.sun.star.reflection.theTypeDescriptionManager" ) ) ),
261                     uno::UNO_QUERY_THROW );
262 
263                 m_xTypeDescription.set( xTypeDescProv->getByHierarchicalName( sConstantName ), uno::UNO_QUERY_THROW );
264                 m_aConstants = m_xTypeDescription->getConstants();
265             }
266         }
267     }
268 }
269 //------------------------------------------------------------------------
270 ::rtl::OUString StringRepresentation::convertSimpleToString( const uno::Any& _rValue )
271 {
272 	::rtl::OUString sReturn;
273 	if ( m_xTypeConverter.is() && _rValue.hasValue() )
274 	{
275 		try
276 		{
277             if ( m_aConstants.getLength() )
278             {
279                 sal_Int16 nConstantValue = 0;
280                 if ( _rValue >>= nConstantValue )
281                 {
282                     const uno::Reference< reflection::XConstantTypeDescription>* pIter = m_aConstants.getConstArray();
283                     const uno::Reference< reflection::XConstantTypeDescription>* pEnd  = pIter + m_aConstants.getLength();
284                     for(sal_Int32 i = 0;pIter != pEnd;++pIter,++i)
285                     {
286                         if ( (*pIter)->getConstantValue() == _rValue )
287                         {
288                             OSL_ENSURE(i < m_aValues.getLength() ,"StringRepresentation::convertSimpleToString: Index is not in range of m_aValues");
289                             sReturn = m_aValues[i];
290                             break;
291                         }
292                     }
293                 }
294             }
295 
296             if ( !sReturn.getLength() )
297 			    m_xTypeConverter->convertToSimpleType( _rValue, uno::TypeClass_STRING ) >>= sReturn;
298 		}
299 		catch( script::CannotConvertException& ) { }
300 		catch( lang::IllegalArgumentException& ) { }
301 	}
302 	return sReturn;
303 }
304 
305 //--------------------------------------------------------------------
306 namespace
307 {
308     struct ConvertIntegerFromAndToString
309     {
310         ::rtl::OUString operator()( sal_Int32 _rIntValue ) const
311         {
312             return ::rtl::OUString::valueOf( (sal_Int32)_rIntValue );
313         }
314         sal_Int32 operator()( const ::rtl::OUString& _rStringValue ) const
315         {
316             return _rStringValue.toInt32();
317         }
318     };
319 
320     struct StringIdentity
321     {
322         ::rtl::OUString operator()( const ::rtl::OUString& _rValue ) const
323         {
324             return _rValue;
325         }
326     };
327 
328     template < class ElementType, class Transformer >
329     ::rtl::OUString composeSequenceElements( const Sequence< ElementType >& _rElements, const Transformer& _rTransformer )
330     {
331 		String sCompose;
332 
333 		// loop through the elements and concatenate the string representations of the integers
334 		// (separated by a line break)
335         const ElementType* pElements = _rElements.getConstArray();
336         const ElementType* pElementsEnd = pElements + _rElements.getLength();
337         for ( ; pElements != pElementsEnd; ++pElements )
338         {
339 			sCompose += String( _rTransformer( *pElements ) );
340 			if ( pElements != pElementsEnd )
341 				sCompose += '\n';
342         }
343 
344         return sCompose;
345     }
346 
347     template < class ElementType, class Transformer >
348     void splitComposedStringToSequence( const ::rtl::OUString& _rComposed, Sequence< ElementType >& _out_SplitUp, const Transformer& _rTransformer )
349     {
350         _out_SplitUp.realloc( 0 );
351         if ( !_rComposed.getLength() )
352             return;
353         sal_Int32 tokenPos = 0;
354         do
355         {
356             _out_SplitUp.realloc( _out_SplitUp.getLength() + 1 );
357             _out_SplitUp[ _out_SplitUp.getLength() - 1 ] = (ElementType)_rTransformer( _rComposed.getToken( 0, '\n', tokenPos ) );
358         }
359         while ( tokenPos != -1 );
360     }
361 }
362 
363 //--------------------------------------------------------------------
364 bool StringRepresentation::convertGenericValueToString( const uno::Any& _rValue, ::rtl::OUString& _rStringRep )
365 {
366     bool bCanConvert = true;
367 
368 	switch ( _rValue.getValueTypeClass() )
369 	{
370     case uno::TypeClass_STRING:
371         _rValue >>= _rStringRep;
372         break;
373 
374 	case uno::TypeClass_BOOLEAN:
375 	{
376         ::std::vector< ::rtl::OUString > aListEntries;
377         tools::StringListResource aRes(PcrRes(RID_RSC_ENUM_YESNO),aListEntries);
378         sal_Bool bValue = sal_False;
379         _rValue >>= bValue;
380         _rStringRep = bValue ? aListEntries[1] : aListEntries[0];
381 	}
382 	break;
383 
384 	// some sequence types
385 	case uno::TypeClass_SEQUENCE:
386 	{
387 		Sequence< ::rtl::OUString > aStringValues;
388         Sequence< sal_Int8 > aInt8Values;
389 		Sequence< sal_uInt16 > aUInt16Values;
390         Sequence< sal_Int16 > aInt16Values;
391 		Sequence< sal_uInt32 > aUInt32Values;
392         Sequence< sal_Int32 > aInt32Values;
393 
394         // string sequences
395         if ( _rValue >>= aStringValues )
396 		{
397             _rStringRep = composeSequenceElements( aStringValues, StringIdentity() );
398 		}
399 		// byte sequences
400 		else if ( _rValue >>= aInt8Values )
401 		{
402             _rStringRep = composeSequenceElements( aInt8Values, ConvertIntegerFromAndToString() );
403 		}
404 		// uInt16 sequences
405 		else if ( _rValue >>= aUInt16Values )
406 		{
407             _rStringRep = composeSequenceElements( aUInt16Values, ConvertIntegerFromAndToString() );
408 		}
409 		// Int16 sequences
410 		else if ( _rValue >>= aInt16Values )
411 		{
412             _rStringRep = composeSequenceElements( aInt16Values, ConvertIntegerFromAndToString() );
413 		}
414 		// uInt32 sequences
415 		else if ( _rValue >>= aUInt32Values )
416 		{
417             _rStringRep = composeSequenceElements( aUInt32Values, ConvertIntegerFromAndToString() );
418 		}
419 		// Int32 sequences
420 		else if ( _rValue >>= aInt32Values )
421 		{
422             _rStringRep = composeSequenceElements( aInt32Values, ConvertIntegerFromAndToString() );
423 		}
424         else
425             bCanConvert = false;
426 	}
427 	break;
428     case uno::TypeClass_CONSTANT:
429         {
430             int i = 0;
431             ++i;
432         }
433         break;
434 
435 	// some structs
436     case uno::TypeClass_STRUCT:
437         OSL_ENSURE( false, "StringRepresentation::convertGenericValueToString(STRUCT): this is dead code - isn't it?" );
438         if ( _rValue.getValueType().equals( ::getCppuType( static_cast< util::Date* >( NULL ) ) ) )
439         {
440             // weird enough, the string representation of dates, as used
441             // by the control displaying dates, and thus as passed through the layers,
442             // is YYYYMMDD.
443             util::Date aUnoDate;
444             _rValue >>= aUnoDate;
445             _rStringRep = ::dbtools::DBTypeConversion::toDateString(aUnoDate);
446         }
447         else if ( _rValue.getValueType().equals( ::getCppuType( static_cast< util::Time* >( NULL ) ) ) )
448         {
449             // similar for time (HHMMSSHH)
450             util::Time aUnoTime;
451             _rValue >>= aUnoTime;
452             _rStringRep = ::dbtools::DBTypeConversion::toTimeString(aUnoTime);
453         }
454         else if ( _rValue.getValueType().equals( ::getCppuType( static_cast< util::DateTime* >( NULL ) ) ) )
455         {
456             util::DateTime aUnoDateTime;
457             _rValue >>= aUnoDateTime;
458             _rStringRep = ::dbtools::DBTypeConversion::toDateTimeString(aUnoDateTime);
459         }
460         else
461             bCanConvert = false;
462         break;
463 
464     default:
465         bCanConvert = false;
466         break;
467 	}
468 
469     return bCanConvert;
470 }
471 //------------------------------------------------------------------------
472 uno::Any StringRepresentation::convertStringToSimple( const ::rtl::OUString& _rValue,const uno::TypeClass& _ePropertyType )
473 {
474 	uno::Any aReturn;
475 	if ( m_xTypeConverter.is() && _rValue.getLength() )
476 	{
477 		try
478 		{
479             if ( m_aConstants.getLength() && m_aValues.getLength() )
480             {
481                 const ::rtl::OUString* pIter = m_aValues.getConstArray();
482                 const ::rtl::OUString* pEnd	  = pIter + m_aValues.getLength();
483                 for(sal_Int32 i = 0;pIter != pEnd;++pIter,++i)
484                 {
485                     if ( *pIter == _rValue )
486                     {
487                         OSL_ENSURE(i < m_aConstants.getLength() ,"StringRepresentation::convertSimpleToString: Index is not in range of m_aValues");
488                         aReturn <<= m_aConstants[i]->getConstantValue();
489                         break;
490                     }
491                 }
492             }
493 
494             if ( !aReturn.hasValue() )
495                 aReturn = m_xTypeConverter->convertToSimpleType( makeAny( _rValue ), _ePropertyType );
496 		}
497 		catch( script::CannotConvertException& ) { }
498 		catch( lang::IllegalArgumentException& ) { }
499 	}
500 	return aReturn;
501 }
502 //--------------------------------------------------------------------
503 bool StringRepresentation::convertStringToGenericValue( const ::rtl::OUString& _rStringRep, uno::Any& _rValue, const uno::Type& _rTargetType )
504 {
505     bool bCanConvert = true;
506 
507     switch ( _rTargetType.getTypeClass() )
508     {
509 	case uno::TypeClass_STRING:
510         _rValue <<= _rStringRep;
511         break;
512 
513     case uno::TypeClass_BOOLEAN:
514 	{
515         ::std::vector< ::rtl::OUString > aListEntries;
516         tools::StringListResource aRes(PcrRes(RID_RSC_ENUM_YESNO),aListEntries);
517         if ( aListEntries[0] == _rStringRep )
518 			_rValue <<= (sal_Bool)sal_False;
519 		else
520 			_rValue <<= (sal_Bool)sal_True;
521 	}
522 	break;
523 
524 	case uno::TypeClass_SEQUENCE:
525 	{
526 		uno::Type aElementType = ::comphelper::getSequenceElementType( _rTargetType );
527 
528 		String aStr( _rStringRep );
529 		switch ( aElementType.getTypeClass() )
530 		{
531 			case uno::TypeClass_STRING:
532 			{
533                 Sequence< ::rtl::OUString > aElements;
534                 splitComposedStringToSequence( aStr, aElements, StringIdentity() );
535 				_rValue <<= aElements;
536 			}
537 			break;
538 			case uno::TypeClass_SHORT:
539 			{
540                 Sequence< sal_Int16 > aElements;
541                 splitComposedStringToSequence( aStr, aElements, ConvertIntegerFromAndToString() );
542 				_rValue <<= aElements;
543 			}
544 			break;
545 			case uno::TypeClass_UNSIGNED_SHORT:
546 			{
547                 Sequence< sal_uInt16 > aElements;
548                 splitComposedStringToSequence( aStr, aElements, ConvertIntegerFromAndToString() );
549 				_rValue <<= aElements;
550 			}
551 			break;
552 			case uno::TypeClass_LONG:
553 			{
554                 Sequence< sal_Int32 > aElements;
555                 splitComposedStringToSequence( aStr, aElements, ConvertIntegerFromAndToString() );
556 				_rValue <<= aElements;
557 			}
558 			break;
559 			case uno::TypeClass_UNSIGNED_LONG:
560 			{
561                 Sequence< sal_uInt32 > aElements;
562                 splitComposedStringToSequence( aStr, aElements, ConvertIntegerFromAndToString() );
563 				_rValue <<= aElements;
564 			}
565 			break;
566 			case uno::TypeClass_BYTE:
567 			{
568                 Sequence< sal_Int8 > aElements;
569                 splitComposedStringToSequence( aStr, aElements, ConvertIntegerFromAndToString() );
570 				_rValue <<= aElements;
571 			}
572 			break;
573             default:
574                 bCanConvert = false;
575                 break;
576 		}
577 	}
578 	break;
579 
580     case uno::TypeClass_STRUCT:
581         OSL_ENSURE( false, "StringRepresentation::convertStringToGenericValue(STRUCT): this is dead code - isn't it?" );
582         if ( _rTargetType.equals( ::getCppuType( static_cast< util::Date* >( NULL ) ) ) )
583         {
584             // weird enough, the string representation of dates, as used
585             // by the control displaying dates, and thus as passed through the layers,
586             // is YYYYMMDD.
587 
588             _rValue <<= ::dbtools::DBTypeConversion::toDate(_rStringRep);
589         }
590         else if ( _rTargetType.equals( ::getCppuType( static_cast< util::Time* >( NULL ) ) ) )
591         {
592             // similar for time (HHMMSSHH)
593             _rValue <<= ::dbtools::DBTypeConversion::toTime(_rStringRep);
594         }
595         else if ( _rTargetType.equals( ::getCppuType( static_cast< util::DateTime* >( NULL ) ) ) )
596         {
597             _rValue <<= ::dbtools::DBTypeConversion::toDateTime(_rStringRep);
598         }
599         else
600             bCanConvert = false;
601         break;
602 
603     default:
604         bCanConvert = false;
605         break;
606     }
607 
608     return bCanConvert;
609 }
610 //------------------------------------------------------------------------
611 //------------------------------------------------------------------------
612 } // pcr
613 //------------------------------------------------------------------------
614 
615 
616 // component helper namespace
617 namespace comp_StringRepresentation {
618 
619 ::rtl::OUString SAL_CALL _getImplementationName() {
620     return ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
621         "StringRepresentation"));
622 }
623 
624 uno::Sequence< ::rtl::OUString > SAL_CALL _getSupportedServiceNames()
625 {
626     uno::Sequence< ::rtl::OUString > s(1);
627     s[0] = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
628         "com.sun.star.inspection.StringRepresentation"));
629     return s;
630 }
631 
632 uno::Reference< uno::XInterface > SAL_CALL _create(
633     const uno::Reference< uno::XComponentContext > & context)
634         SAL_THROW((uno::Exception))
635 {
636     return static_cast< ::cppu::OWeakObject * >(new pcr::StringRepresentation(context));
637 }
638 
639 } // closing component helper namespace
640 
641 //------------------------------------------------------------------------
642 extern "C" void SAL_CALL createRegistryInfo_StringRepresentation()
643 {
644     ::pcr::PcrModule::getInstance().registerImplementation(
645             comp_StringRepresentation::_getImplementationName(),
646             comp_StringRepresentation::_getSupportedServiceNames(),
647             comp_StringRepresentation::_create
648         );
649 }
650 
651