1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: dataaccessdescriptor.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/dataaccessdescriptor.hxx>
34 #include <comphelper/stl_types.hxx>
35 #include <comphelper/propertysetinfo.hxx>
36 #include <comphelper/genericpropertyset.hxx>
37 #include <osl/diagnose.h>
38 #include <com/sun/star/sdbc/XConnection.hpp>
39 #include <com/sun/star/ucb/XContent.hpp>
40 #include <com/sun/star/beans/PropertyAttribute.hpp>
41 #include <tools/urlobj.hxx>
43 //........................................................................
46 //........................................................................
48 using namespace ::com::sun::star::uno
;
49 using namespace ::com::sun::star::sdbc
;
50 using namespace ::com::sun::star::beans
;
51 using namespace ::com::sun::star::ucb
;
52 using namespace ::comphelper
;
54 #define CONST_CHAR( propname ) propname, sizeof(propname) - 1
57 //====================================================================
59 //====================================================================
60 class ODADescriptorImpl
63 sal_Bool m_bSetOutOfDate
: 1;
64 sal_Bool m_bSequenceOutOfDate
: 1;
67 typedef ::std::map
< DataAccessDescriptorProperty
, Any
> DescriptorValues
;
68 DescriptorValues m_aValues
;
69 Sequence
< PropertyValue
> m_aAsSequence
;
70 Reference
< XPropertySet
> m_xAsSet
;
72 typedef ::std::map
< ::rtl::OUString
, PropertyMapEntry
* > MapString2PropertyEntry
;
76 ODADescriptorImpl(const ODADescriptorImpl
& _rSource
);
78 void invalidateExternRepresentations();
80 void updateSequence();
83 /** builds the descriptor from a property value sequence
85 if and only if the sequence contained valid properties only
87 sal_Bool
buildFrom( const Sequence
< PropertyValue
>& _rValues
);
89 /** builds the descriptor from a property set
91 if and only if the set contained valid properties only
93 sal_Bool
buildFrom( const Reference
< XPropertySet
>& _rValues
);
96 static PropertyValue
buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
);
97 static const MapString2PropertyEntry
& getPropertyMap( );
98 static PropertyMapEntry
* getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
);
101 //--------------------------------------------------------------------
102 ODADescriptorImpl::ODADescriptorImpl()
103 :m_bSetOutOfDate(sal_True
)
104 ,m_bSequenceOutOfDate(sal_True
)
108 //--------------------------------------------------------------------
109 ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl
& _rSource
)
110 :m_bSetOutOfDate( _rSource
.m_bSetOutOfDate
)
111 ,m_bSequenceOutOfDate( _rSource
.m_bSequenceOutOfDate
)
112 ,m_aValues( _rSource
.m_aValues
)
114 if (!m_bSetOutOfDate
)
115 m_xAsSet
= _rSource
.m_xAsSet
;
116 if (!m_bSequenceOutOfDate
)
117 m_aAsSequence
= _rSource
.m_aAsSequence
;
120 //--------------------------------------------------------------------
121 sal_Bool
ODADescriptorImpl::buildFrom( const Sequence
< PropertyValue
>& _rValues
)
123 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
125 sal_Bool bValidPropsOnly
= sal_True
;
127 // loop through the sequence, and fill our m_aValues
128 const PropertyValue
* pValues
= _rValues
.getConstArray();
129 const PropertyValue
* pValuesEnd
= pValues
+ _rValues
.getLength();
130 for (;pValues
!= pValuesEnd
; ++pValues
)
132 MapString2PropertyEntry::const_iterator aPropPos
= rProperties
.find( pValues
->Name
);
133 if ( aPropPos
!= rProperties
.end() )
135 DataAccessDescriptorProperty eProperty
= (DataAccessDescriptorProperty
)aPropPos
->second
->mnHandle
;
136 m_aValues
[eProperty
] = pValues
->Value
;
140 bValidPropsOnly
= sal_False
;
145 m_aAsSequence
= _rValues
;
146 m_bSequenceOutOfDate
= sal_False
;
149 m_bSequenceOutOfDate
= sal_True
;
151 return bValidPropsOnly
;
154 //--------------------------------------------------------------------
155 sal_Bool
ODADescriptorImpl::buildFrom( const Reference
< XPropertySet
>& _rxValues
)
157 Reference
< XPropertySetInfo
> xPropInfo
;
159 xPropInfo
= _rxValues
->getPropertySetInfo();
162 OSL_ENSURE(sal_False
, "ODADescriptorImpl::buildFrom: invalid property set!");
166 // build a PropertyValue sequence with the current values
167 Sequence
< Property
> aProperties
= xPropInfo
->getProperties();
168 const Property
* pProperty
= aProperties
.getConstArray();
169 const Property
* pPropertyEnd
= pProperty
+ aProperties
.getLength();
171 Sequence
< PropertyValue
> aValues(aProperties
.getLength());
172 PropertyValue
* pValues
= aValues
.getArray();
174 for (;pProperty
!= pPropertyEnd
; ++pProperty
, ++pValues
)
176 pValues
->Name
= pProperty
->Name
;
177 pValues
->Value
= _rxValues
->getPropertyValue(pProperty
->Name
);
180 sal_Bool bValidPropsOnly
= buildFrom(aValues
);
183 m_xAsSet
= _rxValues
;
184 m_bSetOutOfDate
= sal_False
;
187 m_bSetOutOfDate
= sal_True
;
189 return bValidPropsOnly
;
192 //--------------------------------------------------------------------
193 void ODADescriptorImpl::invalidateExternRepresentations()
195 m_bSetOutOfDate
= sal_True
;
196 m_bSequenceOutOfDate
= sal_True
;
199 //--------------------------------------------------------------------
200 const ODADescriptorImpl::MapString2PropertyEntry
& ODADescriptorImpl::getPropertyMap( )
202 // the properties we know
203 static MapString2PropertyEntry s_aProperties
;
204 if ( s_aProperties
.empty() )
206 static PropertyMapEntry s_aDesriptorProperties
[] =
208 { CONST_CHAR("ActiveConnection"), daConnection
, &::getCppuType( static_cast< Reference
< XConnection
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
209 { CONST_CHAR("BookmarkSelection"), daBookmarkSelection
, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT
, 0 },
210 { CONST_CHAR("Column"), daColumnObject
, &::getCppuType( static_cast< Reference
< XPropertySet
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
211 { CONST_CHAR("ColumnName"), daColumnName
, &::getCppuType( static_cast< ::rtl::OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
212 { CONST_CHAR("Command"), daCommand
, &::getCppuType( static_cast< ::rtl::OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
213 { CONST_CHAR("CommandType"), daCommandType
, &::getCppuType( static_cast< sal_Int32
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
214 { CONST_CHAR("Component"), daComponent
, &::getCppuType( static_cast< Reference
< XContent
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
215 { CONST_CHAR("ConnectionResource"), daConnectionResource
, &::getCppuType( static_cast< ::rtl::OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
216 { CONST_CHAR("Cursor"), daCursor
, &::getCppuType( static_cast< Reference
< XResultSet
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
217 { CONST_CHAR("DataSourceName"), daDataSource
, &::getCppuType( static_cast< ::rtl::OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
218 { CONST_CHAR("DatabaseLocation"), daDatabaseLocation
, &::getCppuType( static_cast< ::rtl::OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
219 { CONST_CHAR("EscapeProcessing"), daEscapeProcessing
, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT
, 0 },
220 { CONST_CHAR("Filter"), daFilter
, &::getCppuType( static_cast< ::rtl::OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
221 { CONST_CHAR("Selection"), daSelection
, &::getCppuType( static_cast< Sequence
< Any
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
222 { NULL
, 0, 0, NULL
, 0, 0 }
225 PropertyMapEntry
* pEntry
= s_aDesriptorProperties
;
226 while ( pEntry
->mpName
)
228 s_aProperties
[ ::rtl::OUString::createFromAscii( pEntry
->mpName
) ] = pEntry
;
233 return s_aProperties
;
236 //--------------------------------------------------------------------
237 PropertyMapEntry
* ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
)
239 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
241 sal_Int32 nNeededHandle
= (sal_Int32
)(_rPos
->first
);
243 for ( MapString2PropertyEntry::const_iterator loop
= rProperties
.begin();
244 loop
!= rProperties
.end();
248 if ( nNeededHandle
== loop
->second
->mnHandle
)
251 throw RuntimeException();
254 //--------------------------------------------------------------------
255 PropertyValue
ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
)
258 PropertyMapEntry
* pProperty
= getPropertyMapEntry( _rPos
);
260 // build the property value
261 PropertyValue aReturn
;
262 aReturn
.Name
= ::rtl::OUString( pProperty
->mpName
, pProperty
->mnNameLen
, RTL_TEXTENCODING_ASCII_US
);
263 aReturn
.Handle
= pProperty
->mnHandle
;
264 aReturn
.Value
= _rPos
->second
;
265 aReturn
.State
= PropertyState_DIRECT_VALUE
;
271 //--------------------------------------------------------------------
272 void ODADescriptorImpl::updateSequence()
274 if (!m_bSequenceOutOfDate
)
277 m_aAsSequence
.realloc(m_aValues
.size());
278 PropertyValue
* pValue
= m_aAsSequence
.getArray();
280 // loop through all our values
281 for ( DescriptorValues::const_iterator aLoop
= m_aValues
.begin();
282 aLoop
!= m_aValues
.end();
286 *pValue
= buildPropertyValue(aLoop
);
289 // don't need to rebuild next time
290 m_bSequenceOutOfDate
= sal_False
;
293 //--------------------------------------------------------------------
294 void ODADescriptorImpl::updateSet()
296 if (!m_bSetOutOfDate
)
299 // will be the current values
300 Sequence
< PropertyValue
> aValuesToSet(m_aValues
.size());
301 PropertyValue
* pValuesToSet
= aValuesToSet
.getArray();
303 // build a new property set info
304 PropertySetInfo
* pPropSetInfo
= new PropertySetInfo
;
306 // loop through all our values
307 for ( DescriptorValues::const_iterator aLoop
= m_aValues
.begin();
308 aLoop
!= m_aValues
.end();
309 ++aLoop
, ++pValuesToSet
312 PropertyMapEntry
* pMapEntry
= getPropertyMapEntry( aLoop
);
313 pPropSetInfo
->add( pMapEntry
, 1 );
315 *pValuesToSet
= buildPropertyValue(aLoop
);
318 // create the generic set
319 m_xAsSet
= GenericPropertySet_CreateInstance( pPropSetInfo
);
321 // no we have the set, still need to set the current values
322 const PropertyValue
* pSetValues
= aValuesToSet
.getConstArray();
323 const PropertyValue
* pSetValuesEnd
= pSetValues
+ aValuesToSet
.getLength();
324 for (; pSetValues
!= pSetValuesEnd
; ++pSetValues
)
325 m_xAsSet
->setPropertyValue(pSetValues
->Name
, pSetValues
->Value
);
327 // don't need to rebuild next time
328 m_bSetOutOfDate
= sal_True
;
332 //====================================================================
333 //= ODataAccessDescriptor
334 //====================================================================
335 //--------------------------------------------------------------------
336 ODataAccessDescriptor::ODataAccessDescriptor()
338 :m_pImpl(new ODADescriptorImpl
)
345 //--------------------------------------------------------------------
346 ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor
& _rSource
)
348 :m_pImpl(new ODADescriptorImpl(*_rSource
.m_pImpl
))
355 //--------------------------------------------------------------------
356 const ODataAccessDescriptor
& ODataAccessDescriptor::operator=(const ODataAccessDescriptor
& _rSource
)
360 m_pImpl
= new ODADescriptorImpl(*_rSource
.m_pImpl
);
362 OSL_ENSURE(sal_False
, "ODataAccessDescriptor::operator=: not available in the SVX_LIGHT version!");
367 //--------------------------------------------------------------------
368 ODataAccessDescriptor::ODataAccessDescriptor( const Reference
< XPropertySet
>& _rValues
)
370 :m_pImpl(new ODADescriptorImpl
)
376 m_pImpl
->buildFrom(_rValues
);
378 OSL_ENSURE(sal_False
, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!");
382 //--------------------------------------------------------------------
383 ODataAccessDescriptor::ODataAccessDescriptor( const Any
& _rValues
)
385 :m_pImpl(new ODADescriptorImpl
)
391 // check if we know the format in the Any
392 Sequence
< PropertyValue
> aValues
;
393 Reference
< XPropertySet
> xValues
;
394 if ( _rValues
>>= aValues
)
395 m_pImpl
->buildFrom( aValues
);
396 else if ( _rValues
>>= xValues
)
397 m_pImpl
->buildFrom( xValues
);
399 OSL_ENSURE(sal_False
, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!");
403 //--------------------------------------------------------------------
404 ODataAccessDescriptor::ODataAccessDescriptor( const Sequence
< PropertyValue
>& _rValues
)
406 :m_pImpl(new ODADescriptorImpl
)
412 m_pImpl
->buildFrom(_rValues
);
414 OSL_ENSURE(sal_False
, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!");
418 //--------------------------------------------------------------------
419 ODataAccessDescriptor::~ODataAccessDescriptor()
424 //--------------------------------------------------------------------
425 void ODataAccessDescriptor::clear()
428 m_pImpl
->m_aValues
.clear();
432 //--------------------------------------------------------------------
433 void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich
)
436 OSL_ENSURE(has(_eWhich
), "ODataAccessDescriptor::erase: invalid call!");
438 m_pImpl
->m_aValues
.erase(_eWhich
);
442 //--------------------------------------------------------------------
443 sal_Bool
ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich
) const
446 return m_pImpl
->m_aValues
.find(_eWhich
) != m_pImpl
->m_aValues
.end();
452 //--------------------------------------------------------------------
453 const Any
& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich
) const
458 OSL_ENSURE(sal_False
, "ODataAccessDescriptor::operator[]: invalid acessor!");
459 static const Any aDummy
;
463 return m_pImpl
->m_aValues
[_eWhich
];
465 static const Any aDummy
;
470 //--------------------------------------------------------------------
471 Any
& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich
)
474 m_pImpl
->invalidateExternRepresentations();
475 return m_pImpl
->m_aValues
[_eWhich
];
477 static const Any aDummy
;
482 //--------------------------------------------------------------------
483 void ODataAccessDescriptor::initializeFrom(const Reference
< XPropertySet
>& _rxValues
, sal_Bool _bClear
)
488 m_pImpl
->buildFrom(_rxValues
);
492 //--------------------------------------------------------------------
493 void ODataAccessDescriptor::initializeFrom(const Sequence
< PropertyValue
>& _rValues
, sal_Bool _bClear
)
498 m_pImpl
->buildFrom(_rValues
);
502 //--------------------------------------------------------------------
503 Sequence
< PropertyValue
> ODataAccessDescriptor::createPropertyValueSequence()
506 m_pImpl
->updateSequence();
507 return m_pImpl
->m_aAsSequence
;
509 return Sequence
< PropertyValue
>();
512 //--------------------------------------------------------------------
513 Sequence
< Any
> ODataAccessDescriptor::createAnySequence()
516 m_pImpl
->updateSequence();
517 Sequence
< Any
> aRet(m_pImpl
->m_aAsSequence
.getLength());
518 const PropertyValue
* pBegin
= m_pImpl
->m_aAsSequence
.getConstArray();
519 const PropertyValue
* pEnd
= pBegin
+ m_pImpl
->m_aAsSequence
.getLength();
520 for(sal_Int32 i
=0;pBegin
!= pEnd
;++pBegin
,++i
)
524 return Sequence
< createAnySequence
>();
528 //--------------------------------------------------------------------
529 Reference
< XPropertySet
> ODataAccessDescriptor::createPropertySet()
532 m_pImpl
->updateSet();
533 return m_pImpl
->m_xAsSet
;
535 return Reference
< XPropertySet
>();
538 //--------------------------------------------------------------------
539 ::rtl::OUString
ODataAccessDescriptor::getDataSource() const
542 ::rtl::OUString sDataSourceName
;
543 if ( has(daDataSource
) )
544 (*this)[daDataSource
] >>= sDataSourceName
;
545 else if ( has(daDatabaseLocation
) )
546 (*this)[daDatabaseLocation
] >>= sDataSourceName
;
547 return sDataSourceName
;
549 return ::rtl::OUString();
552 //--------------------------------------------------------------------
553 void ODataAccessDescriptor::setDataSource(const ::rtl::OUString
& _sDataSourceNameOrLocation
)
556 if ( _sDataSourceNameOrLocation
.getLength() )
558 INetURLObject
aURL(_sDataSourceNameOrLocation
);
559 (*this)[ (( aURL
.GetProtocol() == INET_PROT_FILE
) ? daDatabaseLocation
: daDataSource
)] <<= _sDataSourceNameOrLocation
;
562 (*this)[ daDataSource
] <<= ::rtl::OUString();
566 //........................................................................
568 //........................................................................