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 <osl/diagnose.h>
22 #include <com/sun/star/sdbc/XConnection.hpp>
23 #include <com/sun/star/ucb/XContent.hpp>
24 #include <com/sun/star/beans/PropertyAttribute.hpp>
25 #include <com/sun/star/beans/PropertyValue.hpp>
26 #include <com/sun/star/beans/XPropertySet.hpp>
27 #include <tools/urlobj.hxx>
32 using namespace ::com::sun::star::uno
;
33 using namespace ::com::sun::star::sdbc
;
34 using namespace ::com::sun::star::beans
;
35 using namespace ::com::sun::star::ucb
;
37 typedef std::pair
<OUString
const, DataAccessDescriptorProperty
> PropertyMapEntry
;
39 class ODADescriptorImpl
42 bool m_bSetOutOfDate
: 1;
43 bool m_bSequenceOutOfDate
: 1;
46 typedef ::std::map
< DataAccessDescriptorProperty
, Any
> DescriptorValues
;
47 DescriptorValues m_aValues
;
48 Sequence
< PropertyValue
> m_aAsSequence
;
50 typedef ::std::map
< OUString
, DataAccessDescriptorProperty
> MapString2PropertyEntry
;
54 ODADescriptorImpl(const ODADescriptorImpl
& _rSource
);
56 void invalidateExternRepresentations();
58 void updateSequence();
60 /** builds the descriptor from a property value sequence
62 if and only if the sequence contained valid properties only
64 bool buildFrom( const Sequence
< PropertyValue
>& _rValues
);
66 /** builds the descriptor from a property set
68 if and only if the set contained valid properties only
70 bool buildFrom( const Reference
< XPropertySet
>& _rValues
);
73 static PropertyValue
buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
);
74 static const MapString2PropertyEntry
& getPropertyMap( );
75 static PropertyMapEntry
const * getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
);
78 ODADescriptorImpl::ODADescriptorImpl()
79 :m_bSetOutOfDate(true)
80 ,m_bSequenceOutOfDate(true)
84 ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl
& _rSource
)
85 :m_bSetOutOfDate( _rSource
.m_bSetOutOfDate
)
86 ,m_bSequenceOutOfDate( _rSource
.m_bSequenceOutOfDate
)
87 ,m_aValues( _rSource
.m_aValues
)
89 if (!m_bSequenceOutOfDate
)
90 m_aAsSequence
= _rSource
.m_aAsSequence
;
93 bool ODADescriptorImpl::buildFrom( const Sequence
< PropertyValue
>& _rValues
)
95 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
97 bool bValidPropsOnly
= true;
99 // loop through the sequence, and fill our m_aValues
100 for (const PropertyValue
& rValue
: _rValues
)
102 MapString2PropertyEntry::const_iterator aPropPos
= rProperties
.find( rValue
.Name
);
103 if ( aPropPos
!= rProperties
.end() )
105 DataAccessDescriptorProperty eProperty
= aPropPos
->second
;
106 m_aValues
[eProperty
] = rValue
.Value
;
110 bValidPropsOnly
= false;
115 m_aAsSequence
= _rValues
;
116 m_bSequenceOutOfDate
= false;
119 m_bSequenceOutOfDate
= true;
121 return bValidPropsOnly
;
124 bool ODADescriptorImpl::buildFrom( const Reference
< XPropertySet
>& _rxValues
)
126 Reference
< XPropertySetInfo
> xPropInfo
;
128 xPropInfo
= _rxValues
->getPropertySetInfo();
131 OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
135 // build a PropertyValue sequence with the current values
136 const Sequence
< Property
> aProperties
= xPropInfo
->getProperties();
138 Sequence
< PropertyValue
> aValues(aProperties
.getLength());
139 PropertyValue
* pValues
= aValues
.getArray();
141 for (const Property
& rProperty
: aProperties
)
143 pValues
->Name
= rProperty
.Name
;
144 pValues
->Value
= _rxValues
->getPropertyValue(rProperty
.Name
);
148 bool bValidPropsOnly
= buildFrom(aValues
);
149 m_bSetOutOfDate
= !bValidPropsOnly
;
151 return bValidPropsOnly
;
154 void ODADescriptorImpl::invalidateExternRepresentations()
156 m_bSetOutOfDate
= true;
157 m_bSequenceOutOfDate
= true;
160 const ODADescriptorImpl::MapString2PropertyEntry
& ODADescriptorImpl::getPropertyMap( )
162 // the properties we know
163 static MapString2PropertyEntry s_aProperties
165 { OUString("ActiveConnection"), DataAccessDescriptorProperty::Connection
, },
166 { OUString("BookmarkSelection"), DataAccessDescriptorProperty::BookmarkSelection
, },
167 { OUString("Column"), DataAccessDescriptorProperty::ColumnObject
, },
168 { OUString("ColumnName"), DataAccessDescriptorProperty::ColumnName
, },
169 { OUString("Command"), DataAccessDescriptorProperty::Command
, },
170 { OUString("CommandType"), DataAccessDescriptorProperty::CommandType
, },
171 { OUString("Component"), DataAccessDescriptorProperty::Component
, },
172 { OUString("ConnectionResource"), DataAccessDescriptorProperty::ConnectionResource
, },
173 { OUString("Cursor"), DataAccessDescriptorProperty::Cursor
, },
174 { OUString("DataSourceName"), DataAccessDescriptorProperty::DataSource
, },
175 { OUString("DatabaseLocation"), DataAccessDescriptorProperty::DatabaseLocation
, },
176 { OUString("EscapeProcessing"), DataAccessDescriptorProperty::EscapeProcessing
, },
177 { OUString("Filter"), DataAccessDescriptorProperty::Filter
, },
178 { OUString("Selection"), DataAccessDescriptorProperty::Selection
, }
181 return s_aProperties
;
184 PropertyMapEntry
const * ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator
& _rPos
)
186 const MapString2PropertyEntry
& rProperties
= getPropertyMap();
188 DataAccessDescriptorProperty nNeededHandle
= _rPos
->first
;
190 auto loop
= std::find_if(rProperties
.begin(), rProperties
.end(),
191 [&nNeededHandle
](const MapString2PropertyEntry::value_type
& rProp
) { return nNeededHandle
== rProp
.second
; });
192 if (loop
!= rProperties
.end())
194 throw RuntimeException();
197 PropertyValue
ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator
& _rPos
)
200 PropertyMapEntry
const * pProperty
= getPropertyMapEntry( _rPos
);
202 // build the property value
203 PropertyValue aReturn
;
204 aReturn
.Name
= pProperty
->first
;
205 aReturn
.Handle
= static_cast<sal_Int32
>(pProperty
->second
);
206 aReturn
.Value
= _rPos
->second
;
207 aReturn
.State
= PropertyState_DIRECT_VALUE
;
213 void ODADescriptorImpl::updateSequence()
215 if (!m_bSequenceOutOfDate
)
218 m_aAsSequence
.realloc(m_aValues
.size());
219 PropertyValue
* pValue
= m_aAsSequence
.getArray();
221 // loop through all our values
222 for ( DescriptorValues::const_iterator aLoop
= m_aValues
.begin();
223 aLoop
!= m_aValues
.end();
227 *pValue
= buildPropertyValue(aLoop
);
230 // don't need to rebuild next time
231 m_bSequenceOutOfDate
= false;
234 ODataAccessDescriptor::ODataAccessDescriptor()
235 :m_pImpl(new ODADescriptorImpl
)
239 ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor
& _rSource
)
240 :m_pImpl(new ODADescriptorImpl(*_rSource
.m_pImpl
))
244 ODataAccessDescriptor::ODataAccessDescriptor(ODataAccessDescriptor
&& _rSource
) noexcept
245 :m_pImpl(std::move(_rSource
.m_pImpl
))
249 ODataAccessDescriptor
& ODataAccessDescriptor::operator=(const ODataAccessDescriptor
& _rSource
)
251 if (this != &_rSource
)
252 m_pImpl
.reset(new ODADescriptorImpl(*_rSource
.m_pImpl
));
256 ODataAccessDescriptor
& ODataAccessDescriptor::operator=(ODataAccessDescriptor
&& _rSource
) noexcept
258 m_pImpl
= std::move(_rSource
.m_pImpl
);
262 ODataAccessDescriptor::ODataAccessDescriptor( const Reference
< XPropertySet
>& _rValues
)
263 :m_pImpl(new ODADescriptorImpl
)
265 m_pImpl
->buildFrom(_rValues
);
268 ODataAccessDescriptor::ODataAccessDescriptor( const Any
& _rValues
)
269 :m_pImpl(new ODADescriptorImpl
)
271 // check if we know the format in the Any
272 Sequence
< PropertyValue
> aValues
;
273 Reference
< XPropertySet
> xValues
;
274 if ( _rValues
>>= aValues
)
275 m_pImpl
->buildFrom( aValues
);
276 else if ( _rValues
>>= xValues
)
277 m_pImpl
->buildFrom( xValues
);
280 ODataAccessDescriptor::ODataAccessDescriptor( const Sequence
< PropertyValue
>& _rValues
)
281 :m_pImpl(new ODADescriptorImpl
)
283 m_pImpl
->buildFrom(_rValues
);
286 ODataAccessDescriptor::~ODataAccessDescriptor()
290 void ODataAccessDescriptor::clear()
292 m_pImpl
->m_aValues
.clear();
295 void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich
)
297 OSL_ENSURE(has(_eWhich
), "ODataAccessDescriptor::erase: invalid call!");
299 m_pImpl
->m_aValues
.erase(_eWhich
);
302 bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich
) const
304 return m_pImpl
->m_aValues
.find(_eWhich
) != m_pImpl
->m_aValues
.end();
307 const Any
& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich
) const
311 OSL_FAIL("ODataAccessDescriptor::operator[]: invalid accessor!");
312 static const Any aDummy
;
316 return m_pImpl
->m_aValues
[_eWhich
];
319 Any
& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich
)
321 m_pImpl
->invalidateExternRepresentations();
322 return m_pImpl
->m_aValues
[_eWhich
];
325 void ODataAccessDescriptor::initializeFrom(const Sequence
< PropertyValue
>& _rValues
)
328 m_pImpl
->buildFrom(_rValues
);
331 Sequence
< PropertyValue
> const & ODataAccessDescriptor::createPropertyValueSequence()
333 m_pImpl
->updateSequence();
334 return m_pImpl
->m_aAsSequence
;
337 OUString
ODataAccessDescriptor::getDataSource() const
339 OUString sDataSourceName
;
340 if ( has(DataAccessDescriptorProperty::DataSource
) )
341 (*this)[DataAccessDescriptorProperty::DataSource
] >>= sDataSourceName
;
342 else if ( has(DataAccessDescriptorProperty::DatabaseLocation
) )
343 (*this)[DataAccessDescriptorProperty::DatabaseLocation
] >>= sDataSourceName
;
344 return sDataSourceName
;
347 void ODataAccessDescriptor::setDataSource(const OUString
& _sDataSourceNameOrLocation
)
349 if ( !_sDataSourceNameOrLocation
.isEmpty() )
351 INetURLObject
aURL(_sDataSourceNameOrLocation
);
352 (*this)[ (( aURL
.GetProtocol() == INetProtocol::File
) ? DataAccessDescriptorProperty::DatabaseLocation
: DataAccessDescriptorProperty::DataSource
)] <<= _sDataSourceNameOrLocation
;
355 (*this)[ DataAccessDescriptorProperty::DataSource
] <<= OUString();
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */