Bump version to 6.4-15
[LibreOffice.git] / svx / source / form / dataaccessdescriptor.cxx
blobcbfea8c0e593a0b33d261872224612418eea73a5
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
28 #include <map>
30 namespace svx
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
41 protected:
42 bool m_bSetOutOfDate : 1;
43 bool m_bSequenceOutOfDate : 1;
45 public:
46 typedef ::std::map< DataAccessDescriptorProperty, Any > DescriptorValues;
47 DescriptorValues m_aValues;
48 Sequence< PropertyValue > m_aAsSequence;
50 typedef ::std::map< OUString, DataAccessDescriptorProperty > MapString2PropertyEntry;
52 public:
53 ODADescriptorImpl();
54 ODADescriptorImpl(const ODADescriptorImpl& _rSource);
56 void invalidateExternRepresentations();
58 void updateSequence();
60 /** builds the descriptor from a property value sequence
61 @return <TRUE/>
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
67 @return <TRUE/>
68 if and only if the set contained valid properties only
70 bool buildFrom( const Reference< XPropertySet >& _rValues );
72 protected:
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;
108 else
109 // unknown property
110 bValidPropsOnly = false;
113 if (bValidPropsOnly)
115 m_aAsSequence = _rValues;
116 m_bSequenceOutOfDate = false;
118 else
119 m_bSequenceOutOfDate = true;
121 return bValidPropsOnly;
124 bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues )
126 Reference< XPropertySetInfo > xPropInfo;
127 if (_rxValues.is())
128 xPropInfo = _rxValues->getPropertySetInfo();
129 if (!xPropInfo.is())
131 OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
132 return false;
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);
145 ++pValues;
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())
193 return &*loop;
194 throw RuntimeException();
197 PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos )
199 // the map entry
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;
209 // outta here
210 return aReturn;
213 void ODADescriptorImpl::updateSequence()
215 if (!m_bSequenceOutOfDate)
216 return;
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();
224 ++aLoop, ++pValue
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));
253 return *this;
256 ODataAccessDescriptor& ODataAccessDescriptor::operator=(ODataAccessDescriptor&& _rSource) noexcept
258 m_pImpl = std::move(_rSource.m_pImpl);
259 return *this;
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!");
298 if (has(_eWhich))
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
309 if (!has(_eWhich))
311 OSL_FAIL("ODataAccessDescriptor::operator[]: invalid accessor!");
312 static const Any aDummy;
313 return 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)
327 clear();
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;
354 else
355 (*this)[ DataAccessDescriptorProperty::DataSource ] <<= OUString();
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */