LibreOffice Module svx (master)  1
dataaccessdescriptor.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
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>
29 
30 namespace svx
31 {
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;
36 
37  typedef std::pair<OUString const, DataAccessDescriptorProperty> PropertyMapEntry;
38 
40  {
41  protected:
42  bool m_bSetOutOfDate : 1;
44 
45  public:
46  typedef ::std::map< DataAccessDescriptorProperty, Any > DescriptorValues;
47  DescriptorValues m_aValues;
48  Sequence< PropertyValue > m_aAsSequence;
49 
50  typedef ::std::map< OUString, DataAccessDescriptorProperty > MapString2PropertyEntry;
51 
52  public:
54  ODADescriptorImpl(const ODADescriptorImpl& _rSource);
55 
57 
58  void updateSequence();
59 
64  bool buildFrom( const Sequence< PropertyValue >& _rValues );
65 
70  bool buildFrom( const Reference< XPropertySet >& _rValues );
71 
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 );
76  };
77 
79  :m_bSetOutOfDate(true)
80  ,m_bSequenceOutOfDate(true)
81  {
82  }
83 
85  :m_bSetOutOfDate( _rSource.m_bSetOutOfDate )
86  ,m_bSequenceOutOfDate( _rSource.m_bSequenceOutOfDate )
87  ,m_aValues( _rSource.m_aValues )
88  {
90  m_aAsSequence = _rSource.m_aAsSequence;
91  }
92 
93  bool ODADescriptorImpl::buildFrom( const Sequence< PropertyValue >& _rValues )
94  {
95  const MapString2PropertyEntry& rProperties = getPropertyMap();
96 
97  bool bValidPropsOnly = true;
98 
99  // loop through the sequence, and fill our m_aValues
100  for (const PropertyValue& rValue : _rValues)
101  {
102  MapString2PropertyEntry::const_iterator aPropPos = rProperties.find( rValue.Name );
103  if ( aPropPos != rProperties.end() )
104  {
105  DataAccessDescriptorProperty eProperty = aPropPos->second;
106  m_aValues[eProperty] = rValue.Value;
107  }
108  else
109  // unknown property
110  bValidPropsOnly = false;
111  }
112 
113  if (bValidPropsOnly)
114  {
115  m_aAsSequence = _rValues;
116  m_bSequenceOutOfDate = false;
117  }
118  else
119  m_bSequenceOutOfDate = true;
120 
121  return bValidPropsOnly;
122  }
123 
124  bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues )
125  {
126  Reference< XPropertySetInfo > xPropInfo;
127  if (_rxValues.is())
128  xPropInfo = _rxValues->getPropertySetInfo();
129  if (!xPropInfo.is())
130  {
131  OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
132  return false;
133  }
134 
135  // build a PropertyValue sequence with the current values
136  const Sequence< Property > aProperties = xPropInfo->getProperties();
137 
138  Sequence< PropertyValue > aValues(aProperties.getLength());
139  PropertyValue* pValues = aValues.getArray();
140 
141  for (const Property& rProperty : aProperties)
142  {
143  pValues->Name = rProperty.Name;
144  pValues->Value = _rxValues->getPropertyValue(rProperty.Name);
145  ++pValues;
146  }
147 
148  bool bValidPropsOnly = buildFrom(aValues);
149  m_bSetOutOfDate = !bValidPropsOnly;
150 
151  return bValidPropsOnly;
152  }
153 
155  {
156  m_bSetOutOfDate = true;
157  m_bSequenceOutOfDate = true;
158  }
159 
161  {
162  // the properties we know
163  static MapString2PropertyEntry s_aProperties
164  {
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, }
179  };
180 
181  return s_aProperties;
182  }
183 
184  PropertyMapEntry const * ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos )
185  {
186  const MapString2PropertyEntry& rProperties = getPropertyMap();
187 
188  DataAccessDescriptorProperty nNeededHandle = _rPos->first;
189 
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();
195  }
196 
197  PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos )
198  {
199  // the map entry
200  PropertyMapEntry const * pProperty = getPropertyMapEntry( _rPos );
201 
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;
208 
209  // outta here
210  return aReturn;
211  }
212 
214  {
216  return;
217 
218  m_aAsSequence.realloc(m_aValues.size());
219  PropertyValue* pValue = m_aAsSequence.getArray();
220 
221  // loop through all our values
222  for ( DescriptorValues::const_iterator aLoop = m_aValues.begin();
223  aLoop != m_aValues.end();
224  ++aLoop, ++pValue
225  )
226  {
227  *pValue = buildPropertyValue(aLoop);
228  }
229 
230  // don't need to rebuild next time
231  m_bSequenceOutOfDate = false;
232  }
233 
236  {
237  }
238 
240  :m_pImpl(new ODADescriptorImpl(*_rSource.m_pImpl))
241  {
242  }
243 
245  :m_pImpl(std::move(_rSource.m_pImpl))
246  {
247  }
248 
250  {
251  if (this != &_rSource)
252  m_pImpl.reset(new ODADescriptorImpl(*_rSource.m_pImpl));
253  return *this;
254  }
255 
257  {
258  m_pImpl = std::move(_rSource.m_pImpl);
259  return *this;
260  }
261 
262  ODataAccessDescriptor::ODataAccessDescriptor( const Reference< XPropertySet >& _rValues )
264  {
265  m_pImpl->buildFrom(_rValues);
266  }
267 
268  ODataAccessDescriptor::ODataAccessDescriptor( const Any& _rValues )
269  :m_pImpl(new ODADescriptorImpl)
270  {
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 );
278  }
279 
280  ODataAccessDescriptor::ODataAccessDescriptor( const Sequence< PropertyValue >& _rValues )
281  :m_pImpl(new ODADescriptorImpl)
282  {
283  m_pImpl->buildFrom(_rValues);
284  }
285 
287  {
288  }
289 
291  {
292  m_pImpl->m_aValues.clear();
293  }
294 
296  {
297  OSL_ENSURE(has(_eWhich), "ODataAccessDescriptor::erase: invalid call!");
298  if (has(_eWhich))
299  m_pImpl->m_aValues.erase(_eWhich);
300  }
301 
303  {
304  return m_pImpl->m_aValues.find(_eWhich) != m_pImpl->m_aValues.end();
305  }
306 
308  {
309  if (!has(_eWhich))
310  {
311  OSL_FAIL("ODataAccessDescriptor::operator[]: invalid accessor!");
312  static const Any aDummy;
313  return aDummy;
314  }
315 
316  return m_pImpl->m_aValues[_eWhich];
317  }
318 
320  {
321  m_pImpl->invalidateExternRepresentations();
322  return m_pImpl->m_aValues[_eWhich];
323  }
324 
325  void ODataAccessDescriptor::initializeFrom(const Sequence< PropertyValue >& _rValues)
326  {
327  clear();
328  m_pImpl->buildFrom(_rValues);
329  }
330 
331  Sequence< PropertyValue > const & ODataAccessDescriptor::createPropertyValueSequence()
332  {
333  m_pImpl->updateSequence();
334  return m_pImpl->m_aAsSequence;
335  }
336 
338  {
339  OUString sDataSourceName;
341  (*this)[DataAccessDescriptorProperty::DataSource] >>= sDataSourceName;
343  (*this)[DataAccessDescriptorProperty::DatabaseLocation] >>= sDataSourceName;
344  return sDataSourceName;
345  }
346 
347  void ODataAccessDescriptor::setDataSource(const OUString& _sDataSourceNameOrLocation)
348  {
349  if ( !_sDataSourceNameOrLocation.isEmpty() )
350  {
351  INetURLObject aURL(_sDataSourceNameOrLocation);
352  (*this)[ (( aURL.GetProtocol() == INetProtocol::File ) ? DataAccessDescriptorProperty::DatabaseLocation : DataAccessDescriptorProperty::DataSource)] <<= _sDataSourceNameOrLocation;
353  }
354  else
355  (*this)[ DataAccessDescriptorProperty::DataSource ] <<= OUString();
356  }
357 }
358 
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
URL aURL
ODataAccessDescriptor & operator=(const ODataAccessDescriptor &_rSource)
void setDataSource(const OUString &_sDataSourceNameOrLocation)
set the data source name, if it is not file URL
::std::map< OUString, DataAccessDescriptorProperty > MapString2PropertyEntry
void initializeFrom(const css::uno::Sequence< css::beans::PropertyValue > &_rValues)
initialized the descriptor from the property values given The descriptor will clear all its current s...
css::uno::Sequence< css::beans::PropertyValue > const & createPropertyValueSequence()
returns the descriptor as property value sequence
escape processing (boolean)
::std::map< DataAccessDescriptorProperty, Any > DescriptorValues
std::unique_ptr< ODADescriptorImpl > m_pImpl
PropertiesInfo aProperties
selection are bookmarks? (boolean)
static PropertyValue buildPropertyValue(const DescriptorValues::const_iterator &_rPos)
void clear()
empties the descriptor
DataAccessDescriptorProperty
void erase(DataAccessDescriptorProperty _eWhich)
erases the given property from the descriptor
std::pair< OUString const, DataAccessDescriptorProperty > PropertyMapEntry
OUString getDataSource() const
returns either the data source name if given or the database location
Sequence< PropertyValue > m_aValues
const PropertyValue * pValues
class encapsulating the css::sdb::DataAccessDescriptor service.
bool has(DataAccessDescriptorProperty _eWhich) const
checks whether or not a given property is present in the descriptor
Sequence< PropertyValue > m_aAsSequence
INetProtocol GetProtocol() const
const css::uno::Any & operator[](DataAccessDescriptorProperty _eWhich) const
return the value of a given property
static const MapString2PropertyEntry & getPropertyMap()
static PropertyMapEntry const * getPropertyMapEntry(const DescriptorValues::const_iterator &_rPos)
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
bool buildFrom(const Sequence< PropertyValue > &_rValues)
builds the descriptor from a property value sequence