1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <svx/dataaccessdescriptor.hxx>
21 #include <comphelper/stl_types.hxx>
22 #include <comphelper/propertysetinfo.hxx>
23 #include <comphelper/genericpropertyset.hxx>
24 #include <osl/diagnose.h>
25 #include <com/sun/star/sdbc/XConnection.hpp>
26 #include <com/sun/star/ucb/XContent.hpp>
27 #include <com/sun/star/beans/PropertyAttribute.hpp>
28 #include <tools/urlobj.hxx>
30 //........................................................................
33 //........................................................................
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::sdbc
;
37 using namespace ::com::sun::star::beans
;
38 using namespace ::com::sun::star::ucb
;
39 using namespace ::comphelper
;
41 #define CONST_CHAR( propname ) propname, sizeof(propname) - 1
43 //====================================================================
45 //====================================================================
46 class ODADescriptorImpl
49 sal_Bool m_bSetOutOfDate
: 1;
50 sal_Bool m_bSequenceOutOfDate
: 1;
53 typedef ::std::map
< DataAccessDescriptorProperty
, Any
> DescriptorValues
;
54 DescriptorValues m_aValues
;
55 Sequence
< PropertyValue
> m_aAsSequence
;
56 Reference
< XPropertySet
> m_xAsSet
;
58 typedef ::std::map
< OUString
, PropertyMapEntry
* > MapString2PropertyEntry
;
62 ODADescriptorImpl(const ODADescriptorImpl
& _rSource
);
64 void invalidateExternRepresentations();
66 void updateSequence();
68 /** builds the descriptor from a property value sequence
70 if and only if the sequence contained valid properties only
72 sal_Bool
buildFrom( const Sequence
< PropertyValue
>& _rValues
);
74 /** builds the descriptor from a property set
76 if and only if the set contained valid properties only
78 sal_Bool
buildFrom( const Reference
< XPropertySet
>& _rValues
);
81 static PropertyValue
buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
);
82 static const MapString2PropertyEntry
& getPropertyMap( );
83 static PropertyMapEntry
* getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
);
86 //--------------------------------------------------------------------
87 ODADescriptorImpl::ODADescriptorImpl()
88 :m_bSetOutOfDate(sal_True
)
89 ,m_bSequenceOutOfDate(sal_True
)
93 //--------------------------------------------------------------------
94 ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl
& _rSource
)
95 :m_bSetOutOfDate( _rSource
.m_bSetOutOfDate
)
96 ,m_bSequenceOutOfDate( _rSource
.m_bSequenceOutOfDate
)
97 ,m_aValues( _rSource
.m_aValues
)
100 m_xAsSet
= _rSource
.m_xAsSet
;
101 if (!m_bSequenceOutOfDate
)
102 m_aAsSequence
= _rSource
.m_aAsSequence
;
105 //--------------------------------------------------------------------
106 sal_Bool
ODADescriptorImpl::buildFrom( const Sequence
< PropertyValue
>& _rValues
)
108 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
110 sal_Bool bValidPropsOnly
= sal_True
;
112 // loop through the sequence, and fill our m_aValues
113 const PropertyValue
* pValues
= _rValues
.getConstArray();
114 const PropertyValue
* pValuesEnd
= pValues
+ _rValues
.getLength();
115 for (;pValues
!= pValuesEnd
; ++pValues
)
117 MapString2PropertyEntry::const_iterator aPropPos
= rProperties
.find( pValues
->Name
);
118 if ( aPropPos
!= rProperties
.end() )
120 DataAccessDescriptorProperty eProperty
= (DataAccessDescriptorProperty
)aPropPos
->second
->mnHandle
;
121 m_aValues
[eProperty
] = pValues
->Value
;
125 bValidPropsOnly
= sal_False
;
130 m_aAsSequence
= _rValues
;
131 m_bSequenceOutOfDate
= sal_False
;
134 m_bSequenceOutOfDate
= sal_True
;
136 return bValidPropsOnly
;
139 //--------------------------------------------------------------------
140 sal_Bool
ODADescriptorImpl::buildFrom( const Reference
< XPropertySet
>& _rxValues
)
142 Reference
< XPropertySetInfo
> xPropInfo
;
144 xPropInfo
= _rxValues
->getPropertySetInfo();
147 OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
151 // build a PropertyValue sequence with the current values
152 Sequence
< Property
> aProperties
= xPropInfo
->getProperties();
153 const Property
* pProperty
= aProperties
.getConstArray();
154 const Property
* pPropertyEnd
= pProperty
+ aProperties
.getLength();
156 Sequence
< PropertyValue
> aValues(aProperties
.getLength());
157 PropertyValue
* pValues
= aValues
.getArray();
159 for (;pProperty
!= pPropertyEnd
; ++pProperty
, ++pValues
)
161 pValues
->Name
= pProperty
->Name
;
162 pValues
->Value
= _rxValues
->getPropertyValue(pProperty
->Name
);
165 sal_Bool bValidPropsOnly
= buildFrom(aValues
);
168 m_xAsSet
= _rxValues
;
169 m_bSetOutOfDate
= sal_False
;
172 m_bSetOutOfDate
= sal_True
;
174 return bValidPropsOnly
;
177 //--------------------------------------------------------------------
178 void ODADescriptorImpl::invalidateExternRepresentations()
180 m_bSetOutOfDate
= sal_True
;
181 m_bSequenceOutOfDate
= sal_True
;
184 //--------------------------------------------------------------------
185 const ODADescriptorImpl::MapString2PropertyEntry
& ODADescriptorImpl::getPropertyMap( )
187 // the properties we know
188 static MapString2PropertyEntry s_aProperties
;
189 if ( s_aProperties
.empty() )
191 static PropertyMapEntry s_aDesriptorProperties
[] =
193 { CONST_CHAR("ActiveConnection"), daConnection
, &::getCppuType( static_cast< Reference
< XConnection
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
194 { CONST_CHAR("BookmarkSelection"), daBookmarkSelection
, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT
, 0 },
195 { CONST_CHAR("Column"), daColumnObject
, &::getCppuType( static_cast< Reference
< XPropertySet
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
196 { CONST_CHAR("ColumnName"), daColumnName
, &::getCppuType( static_cast< OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
197 { CONST_CHAR("Command"), daCommand
, &::getCppuType( static_cast< OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
198 { CONST_CHAR("CommandType"), daCommandType
, &::getCppuType( static_cast< sal_Int32
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
199 { CONST_CHAR("Component"), daComponent
, &::getCppuType( static_cast< Reference
< XContent
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
200 { CONST_CHAR("ConnectionResource"), daConnectionResource
, &::getCppuType( static_cast< OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
201 { CONST_CHAR("Cursor"), daCursor
, &::getCppuType( static_cast< Reference
< XResultSet
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
202 { CONST_CHAR("DataSourceName"), daDataSource
, &::getCppuType( static_cast< OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
203 { CONST_CHAR("DatabaseLocation"), daDatabaseLocation
, &::getCppuType( static_cast< OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
204 { CONST_CHAR("EscapeProcessing"), daEscapeProcessing
, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT
, 0 },
205 { CONST_CHAR("Filter"), daFilter
, &::getCppuType( static_cast< OUString
* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
206 { CONST_CHAR("Selection"), daSelection
, &::getCppuType( static_cast< Sequence
< Any
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
207 { NULL
, 0, 0, NULL
, 0, 0 }
210 PropertyMapEntry
* pEntry
= s_aDesriptorProperties
;
211 while ( pEntry
->mpName
)
213 s_aProperties
[ OUString::createFromAscii( pEntry
->mpName
) ] = pEntry
;
218 return s_aProperties
;
221 //--------------------------------------------------------------------
222 PropertyMapEntry
* ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
)
224 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
226 sal_Int32 nNeededHandle
= (sal_Int32
)(_rPos
->first
);
228 for ( MapString2PropertyEntry::const_iterator loop
= rProperties
.begin();
229 loop
!= rProperties
.end();
233 if ( nNeededHandle
== loop
->second
->mnHandle
)
236 throw RuntimeException();
239 //--------------------------------------------------------------------
240 PropertyValue
ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
)
243 PropertyMapEntry
* pProperty
= getPropertyMapEntry( _rPos
);
245 // build the property value
246 PropertyValue aReturn
;
247 aReturn
.Name
= OUString( pProperty
->mpName
, pProperty
->mnNameLen
, RTL_TEXTENCODING_ASCII_US
);
248 aReturn
.Handle
= pProperty
->mnHandle
;
249 aReturn
.Value
= _rPos
->second
;
250 aReturn
.State
= PropertyState_DIRECT_VALUE
;
256 //--------------------------------------------------------------------
257 void ODADescriptorImpl::updateSequence()
259 if (!m_bSequenceOutOfDate
)
262 m_aAsSequence
.realloc(m_aValues
.size());
263 PropertyValue
* pValue
= m_aAsSequence
.getArray();
265 // loop through all our values
266 for ( DescriptorValues::const_iterator aLoop
= m_aValues
.begin();
267 aLoop
!= m_aValues
.end();
271 *pValue
= buildPropertyValue(aLoop
);
274 // don't need to rebuild next time
275 m_bSequenceOutOfDate
= sal_False
;
278 //====================================================================
279 //= ODataAccessDescriptor
280 //====================================================================
281 //--------------------------------------------------------------------
282 ODataAccessDescriptor::ODataAccessDescriptor()
283 :m_pImpl(new ODADescriptorImpl
)
287 //--------------------------------------------------------------------
288 ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor
& _rSource
)
289 :m_pImpl(new ODADescriptorImpl(*_rSource
.m_pImpl
))
293 //--------------------------------------------------------------------
294 const ODataAccessDescriptor
& ODataAccessDescriptor::operator=(const ODataAccessDescriptor
& _rSource
)
297 m_pImpl
= new ODADescriptorImpl(*_rSource
.m_pImpl
);
301 //--------------------------------------------------------------------
302 ODataAccessDescriptor::ODataAccessDescriptor( const Reference
< XPropertySet
>& _rValues
)
303 :m_pImpl(new ODADescriptorImpl
)
305 m_pImpl
->buildFrom(_rValues
);
308 //--------------------------------------------------------------------
309 ODataAccessDescriptor::ODataAccessDescriptor( const Any
& _rValues
)
310 :m_pImpl(new ODADescriptorImpl
)
312 // check if we know the format in the Any
313 Sequence
< PropertyValue
> aValues
;
314 Reference
< XPropertySet
> xValues
;
315 if ( _rValues
>>= aValues
)
316 m_pImpl
->buildFrom( aValues
);
317 else if ( _rValues
>>= xValues
)
318 m_pImpl
->buildFrom( xValues
);
321 //--------------------------------------------------------------------
322 ODataAccessDescriptor::ODataAccessDescriptor( const Sequence
< PropertyValue
>& _rValues
)
323 :m_pImpl(new ODADescriptorImpl
)
325 m_pImpl
->buildFrom(_rValues
);
328 //--------------------------------------------------------------------
329 ODataAccessDescriptor::~ODataAccessDescriptor()
334 //--------------------------------------------------------------------
335 void ODataAccessDescriptor::clear()
337 m_pImpl
->m_aValues
.clear();
340 //--------------------------------------------------------------------
341 void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich
)
343 OSL_ENSURE(has(_eWhich
), "ODataAccessDescriptor::erase: invalid call!");
345 m_pImpl
->m_aValues
.erase(_eWhich
);
348 //--------------------------------------------------------------------
349 sal_Bool
ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich
) const
351 return m_pImpl
->m_aValues
.find(_eWhich
) != m_pImpl
->m_aValues
.end();
354 //--------------------------------------------------------------------
355 const Any
& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich
) const
359 OSL_FAIL("ODataAccessDescriptor::operator[]: invalid acessor!");
360 static const Any aDummy
;
364 return m_pImpl
->m_aValues
[_eWhich
];
367 //--------------------------------------------------------------------
368 Any
& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich
)
370 m_pImpl
->invalidateExternRepresentations();
371 return m_pImpl
->m_aValues
[_eWhich
];
374 //--------------------------------------------------------------------
375 void ODataAccessDescriptor::initializeFrom(const Sequence
< PropertyValue
>& _rValues
, sal_Bool _bClear
)
379 m_pImpl
->buildFrom(_rValues
);
382 //--------------------------------------------------------------------
383 Sequence
< PropertyValue
> ODataAccessDescriptor::createPropertyValueSequence()
385 m_pImpl
->updateSequence();
386 return m_pImpl
->m_aAsSequence
;
389 //--------------------------------------------------------------------
390 OUString
ODataAccessDescriptor::getDataSource() const
392 OUString sDataSourceName
;
393 if ( has(daDataSource
) )
394 (*this)[daDataSource
] >>= sDataSourceName
;
395 else if ( has(daDatabaseLocation
) )
396 (*this)[daDatabaseLocation
] >>= sDataSourceName
;
397 return sDataSourceName
;
399 //--------------------------------------------------------------------
400 void ODataAccessDescriptor::setDataSource(const OUString
& _sDataSourceNameOrLocation
)
402 if ( !_sDataSourceNameOrLocation
.isEmpty() )
404 INetURLObject
aURL(_sDataSourceNameOrLocation
);
405 (*this)[ (( aURL
.GetProtocol() == INET_PROT_FILE
) ? daDatabaseLocation
: daDataSource
)] <<= _sDataSourceNameOrLocation
;
408 (*this)[ daDataSource
] <<= OUString();
411 //........................................................................
413 //........................................................................
416 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */