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/propertysetinfo.hxx>
22 #include <comphelper/genericpropertyset.hxx>
23 #include <osl/diagnose.h>
24 #include <com/sun/star/sdbc/XConnection.hpp>
25 #include <com/sun/star/ucb/XContent.hpp>
26 #include <com/sun/star/beans/PropertyAttribute.hpp>
27 #include <tools/urlobj.hxx>
34 using namespace ::com::sun::star::uno
;
35 using namespace ::com::sun::star::sdbc
;
36 using namespace ::com::sun::star::beans
;
37 using namespace ::com::sun::star::ucb
;
38 using namespace ::comphelper
;
43 class ODADescriptorImpl
46 bool m_bSetOutOfDate
: 1;
47 bool m_bSequenceOutOfDate
: 1;
50 typedef ::std::map
< DataAccessDescriptorProperty
, Any
> DescriptorValues
;
51 DescriptorValues m_aValues
;
52 Sequence
< PropertyValue
> m_aAsSequence
;
53 Reference
< XPropertySet
> m_xAsSet
;
55 typedef ::std::map
< OUString
, PropertyMapEntry
const * > MapString2PropertyEntry
;
59 ODADescriptorImpl(const ODADescriptorImpl
& _rSource
);
61 void invalidateExternRepresentations();
63 void updateSequence();
65 /** builds the descriptor from a property value sequence
67 if and only if the sequence contained valid properties only
69 bool buildFrom( const Sequence
< PropertyValue
>& _rValues
);
71 /** builds the descriptor from a property set
73 if and only if the set contained valid properties only
75 bool buildFrom( const Reference
< XPropertySet
>& _rValues
);
78 static PropertyValue
buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
);
79 static const MapString2PropertyEntry
& getPropertyMap( );
80 static PropertyMapEntry
const * getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
);
84 ODADescriptorImpl::ODADescriptorImpl()
85 :m_bSetOutOfDate(true)
86 ,m_bSequenceOutOfDate(true)
91 ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl
& _rSource
)
92 :m_bSetOutOfDate( _rSource
.m_bSetOutOfDate
)
93 ,m_bSequenceOutOfDate( _rSource
.m_bSequenceOutOfDate
)
94 ,m_aValues( _rSource
.m_aValues
)
97 m_xAsSet
= _rSource
.m_xAsSet
;
98 if (!m_bSequenceOutOfDate
)
99 m_aAsSequence
= _rSource
.m_aAsSequence
;
103 bool ODADescriptorImpl::buildFrom( const Sequence
< PropertyValue
>& _rValues
)
105 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
107 bool bValidPropsOnly
= true;
109 // loop through the sequence, and fill our m_aValues
110 const PropertyValue
* pValues
= _rValues
.getConstArray();
111 const PropertyValue
* pValuesEnd
= pValues
+ _rValues
.getLength();
112 for (;pValues
!= pValuesEnd
; ++pValues
)
114 MapString2PropertyEntry::const_iterator aPropPos
= rProperties
.find( pValues
->Name
);
115 if ( aPropPos
!= rProperties
.end() )
117 DataAccessDescriptorProperty eProperty
= (DataAccessDescriptorProperty
)aPropPos
->second
->mnHandle
;
118 m_aValues
[eProperty
] = pValues
->Value
;
122 bValidPropsOnly
= false;
127 m_aAsSequence
= _rValues
;
128 m_bSequenceOutOfDate
= false;
131 m_bSequenceOutOfDate
= true;
133 return bValidPropsOnly
;
137 bool ODADescriptorImpl::buildFrom( const Reference
< XPropertySet
>& _rxValues
)
139 Reference
< XPropertySetInfo
> xPropInfo
;
141 xPropInfo
= _rxValues
->getPropertySetInfo();
144 OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
148 // build a PropertyValue sequence with the current values
149 Sequence
< Property
> aProperties
= xPropInfo
->getProperties();
150 const Property
* pProperty
= aProperties
.getConstArray();
151 const Property
* pPropertyEnd
= pProperty
+ aProperties
.getLength();
153 Sequence
< PropertyValue
> aValues(aProperties
.getLength());
154 PropertyValue
* pValues
= aValues
.getArray();
156 for (;pProperty
!= pPropertyEnd
; ++pProperty
, ++pValues
)
158 pValues
->Name
= pProperty
->Name
;
159 pValues
->Value
= _rxValues
->getPropertyValue(pProperty
->Name
);
162 bool bValidPropsOnly
= buildFrom(aValues
);
165 m_xAsSet
= _rxValues
;
166 m_bSetOutOfDate
= false;
169 m_bSetOutOfDate
= true;
171 return bValidPropsOnly
;
175 void ODADescriptorImpl::invalidateExternRepresentations()
177 m_bSetOutOfDate
= true;
178 m_bSequenceOutOfDate
= true;
182 const ODADescriptorImpl::MapString2PropertyEntry
& ODADescriptorImpl::getPropertyMap( )
184 // the properties we know
185 static MapString2PropertyEntry s_aProperties
;
186 if ( s_aProperties
.empty() )
188 static PropertyMapEntry
const s_aDesriptorProperties
[] =
190 { OUString("ActiveConnection"), daConnection
, cppu::UnoType
<XConnection
>::get(), PropertyAttribute::TRANSIENT
, 0 },
191 { OUString("BookmarkSelection"), daBookmarkSelection
, ::getBooleanCppuType( ), PropertyAttribute::TRANSIENT
, 0 },
192 { OUString("Column"), daColumnObject
, cppu::UnoType
<XPropertySet
>::get(), PropertyAttribute::TRANSIENT
, 0 },
193 { OUString("ColumnName"), daColumnName
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::TRANSIENT
, 0 },
194 { OUString("Command"), daCommand
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::TRANSIENT
, 0 },
195 { OUString("CommandType"), daCommandType
, ::cppu::UnoType
<sal_Int32
>::get(), PropertyAttribute::TRANSIENT
, 0 },
196 { OUString("Component"), daComponent
, cppu::UnoType
<XContent
>::get(), PropertyAttribute::TRANSIENT
, 0 },
197 { OUString("ConnectionResource"), daConnectionResource
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::TRANSIENT
, 0 },
198 { OUString("Cursor"), daCursor
, cppu::UnoType
<XResultSet
>::get(), PropertyAttribute::TRANSIENT
, 0 },
199 { OUString("DataSourceName"), daDataSource
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::TRANSIENT
, 0 },
200 { OUString("DatabaseLocation"), daDatabaseLocation
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::TRANSIENT
, 0 },
201 { OUString("EscapeProcessing"), daEscapeProcessing
, ::getBooleanCppuType( ), PropertyAttribute::TRANSIENT
, 0 },
202 { OUString("Filter"), daFilter
, ::cppu::UnoType
<OUString
>::get(), PropertyAttribute::TRANSIENT
, 0 },
203 { OUString("Selection"), daSelection
, ::getCppuType( static_cast< Sequence
< Any
>* >(NULL
) ), PropertyAttribute::TRANSIENT
, 0 },
204 { OUString(), 0, css::uno::Type(), 0, 0 }
207 PropertyMapEntry
const * pEntry
= s_aDesriptorProperties
;
208 while ( !pEntry
->maName
.isEmpty() )
210 s_aProperties
[ pEntry
->maName
] = pEntry
;
215 return s_aProperties
;
219 PropertyMapEntry
const * ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
)
221 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
223 sal_Int32 nNeededHandle
= (sal_Int32
)(_rPos
->first
);
225 for ( MapString2PropertyEntry::const_iterator loop
= rProperties
.begin();
226 loop
!= rProperties
.end();
230 if ( nNeededHandle
== loop
->second
->mnHandle
)
233 throw RuntimeException();
237 PropertyValue
ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
)
240 PropertyMapEntry
const * pProperty
= getPropertyMapEntry( _rPos
);
242 // build the property value
243 PropertyValue aReturn
;
244 aReturn
.Name
= pProperty
->maName
;
245 aReturn
.Handle
= pProperty
->mnHandle
;
246 aReturn
.Value
= _rPos
->second
;
247 aReturn
.State
= PropertyState_DIRECT_VALUE
;
254 void ODADescriptorImpl::updateSequence()
256 if (!m_bSequenceOutOfDate
)
259 m_aAsSequence
.realloc(m_aValues
.size());
260 PropertyValue
* pValue
= m_aAsSequence
.getArray();
262 // loop through all our values
263 for ( DescriptorValues::const_iterator aLoop
= m_aValues
.begin();
264 aLoop
!= m_aValues
.end();
268 *pValue
= buildPropertyValue(aLoop
);
271 // don't need to rebuild next time
272 m_bSequenceOutOfDate
= false;
276 //= ODataAccessDescriptor
279 ODataAccessDescriptor::ODataAccessDescriptor()
280 :m_pImpl(new ODADescriptorImpl
)
285 ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor
& _rSource
)
286 :m_pImpl(new ODADescriptorImpl(*_rSource
.m_pImpl
))
291 const ODataAccessDescriptor
& ODataAccessDescriptor::operator=(const ODataAccessDescriptor
& _rSource
)
294 m_pImpl
= new ODADescriptorImpl(*_rSource
.m_pImpl
);
299 ODataAccessDescriptor::ODataAccessDescriptor( const Reference
< XPropertySet
>& _rValues
)
300 :m_pImpl(new ODADescriptorImpl
)
302 m_pImpl
->buildFrom(_rValues
);
306 ODataAccessDescriptor::ODataAccessDescriptor( const Any
& _rValues
)
307 :m_pImpl(new ODADescriptorImpl
)
309 // check if we know the format in the Any
310 Sequence
< PropertyValue
> aValues
;
311 Reference
< XPropertySet
> xValues
;
312 if ( _rValues
>>= aValues
)
313 m_pImpl
->buildFrom( aValues
);
314 else if ( _rValues
>>= xValues
)
315 m_pImpl
->buildFrom( xValues
);
319 ODataAccessDescriptor::ODataAccessDescriptor( const Sequence
< PropertyValue
>& _rValues
)
320 :m_pImpl(new ODADescriptorImpl
)
322 m_pImpl
->buildFrom(_rValues
);
326 ODataAccessDescriptor::~ODataAccessDescriptor()
332 void ODataAccessDescriptor::clear()
334 m_pImpl
->m_aValues
.clear();
338 void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich
)
340 OSL_ENSURE(has(_eWhich
), "ODataAccessDescriptor::erase: invalid call!");
342 m_pImpl
->m_aValues
.erase(_eWhich
);
346 bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich
) const
348 return m_pImpl
->m_aValues
.find(_eWhich
) != m_pImpl
->m_aValues
.end();
352 const Any
& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich
) const
356 OSL_FAIL("ODataAccessDescriptor::operator[]: invalid acessor!");
357 static const Any aDummy
;
361 return m_pImpl
->m_aValues
[_eWhich
];
365 Any
& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich
)
367 m_pImpl
->invalidateExternRepresentations();
368 return m_pImpl
->m_aValues
[_eWhich
];
372 void ODataAccessDescriptor::initializeFrom(const Sequence
< PropertyValue
>& _rValues
, bool _bClear
)
376 m_pImpl
->buildFrom(_rValues
);
380 Sequence
< PropertyValue
> ODataAccessDescriptor::createPropertyValueSequence()
382 m_pImpl
->updateSequence();
383 return m_pImpl
->m_aAsSequence
;
387 OUString
ODataAccessDescriptor::getDataSource() const
389 OUString sDataSourceName
;
390 if ( has(daDataSource
) )
391 (*this)[daDataSource
] >>= sDataSourceName
;
392 else if ( has(daDatabaseLocation
) )
393 (*this)[daDatabaseLocation
] >>= sDataSourceName
;
394 return sDataSourceName
;
397 void ODataAccessDescriptor::setDataSource(const OUString
& _sDataSourceNameOrLocation
)
399 if ( !_sDataSourceNameOrLocation
.isEmpty() )
401 INetURLObject
aURL(_sDataSourceNameOrLocation
);
402 (*this)[ (( aURL
.GetProtocol() == INET_PROT_FILE
) ? daDatabaseLocation
: daDataSource
)] <<= _sDataSourceNameOrLocation
;
405 (*this)[ daDataSource
] <<= OUString();
413 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */