summaryrefslogtreecommitdiffstats
path: root/svx/source/form/dataaccessdescriptor.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/form/dataaccessdescriptor.cxx')
-rw-r--r--svx/source/form/dataaccessdescriptor.cxx356
1 files changed, 356 insertions, 0 deletions
diff --git a/svx/source/form/dataaccessdescriptor.cxx b/svx/source/form/dataaccessdescriptor.cxx
new file mode 100644
index 000000000..78538fbeb
--- /dev/null
+++ b/svx/source/form/dataaccessdescriptor.cxx
@@ -0,0 +1,356 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/dataaccessdescriptor.hxx>
+#include <osl/diagnose.h>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/beans/XPropertySet.hpp>
+#include <tools/urlobj.hxx>
+#include <map>
+
+namespace svx
+{
+ using namespace ::com::sun::star::uno;
+ using namespace ::com::sun::star::beans;
+ using namespace ::com::sun::star::ucb;
+
+ typedef std::pair<OUString const, DataAccessDescriptorProperty> PropertyMapEntry;
+
+ class ODADescriptorImpl
+ {
+ protected:
+ bool m_bSetOutOfDate : 1;
+ bool m_bSequenceOutOfDate : 1;
+
+ public:
+ typedef ::std::map< DataAccessDescriptorProperty, Any > DescriptorValues;
+ DescriptorValues m_aValues;
+ Sequence< PropertyValue > m_aAsSequence;
+
+ typedef ::std::map< OUString, DataAccessDescriptorProperty > MapString2PropertyEntry;
+
+ public:
+ ODADescriptorImpl();
+ ODADescriptorImpl(const ODADescriptorImpl& _rSource);
+
+ void invalidateExternRepresentations();
+
+ void updateSequence();
+
+ /** builds the descriptor from a property value sequence
+ @return <TRUE/>
+ if and only if the sequence contained valid properties only
+ */
+ bool buildFrom( const Sequence< PropertyValue >& _rValues );
+
+ /** builds the descriptor from a property set
+ @return <TRUE/>
+ if and only if the set contained valid properties only
+ */
+ bool buildFrom( const Reference< XPropertySet >& _rValues );
+
+ protected:
+ static PropertyValue buildPropertyValue( const DescriptorValues::const_iterator& _rPos );
+ static const MapString2PropertyEntry& getPropertyMap( );
+ static PropertyMapEntry const * getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos );
+ };
+
+ ODADescriptorImpl::ODADescriptorImpl()
+ :m_bSetOutOfDate(true)
+ ,m_bSequenceOutOfDate(true)
+ {
+ }
+
+ ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl& _rSource)
+ :m_bSetOutOfDate( _rSource.m_bSetOutOfDate )
+ ,m_bSequenceOutOfDate( _rSource.m_bSequenceOutOfDate )
+ ,m_aValues( _rSource.m_aValues )
+ {
+ if (!m_bSequenceOutOfDate)
+ m_aAsSequence = _rSource.m_aAsSequence;
+ }
+
+ bool ODADescriptorImpl::buildFrom( const Sequence< PropertyValue >& _rValues )
+ {
+ const MapString2PropertyEntry& rProperties = getPropertyMap();
+
+ bool bValidPropsOnly = true;
+
+ // loop through the sequence, and fill our m_aValues
+ for (const PropertyValue& rValue : _rValues)
+ {
+ MapString2PropertyEntry::const_iterator aPropPos = rProperties.find( rValue.Name );
+ if ( aPropPos != rProperties.end() )
+ {
+ DataAccessDescriptorProperty eProperty = aPropPos->second;
+ m_aValues[eProperty] = rValue.Value;
+ }
+ else
+ // unknown property
+ bValidPropsOnly = false;
+ }
+
+ if (bValidPropsOnly)
+ {
+ m_aAsSequence = _rValues;
+ m_bSequenceOutOfDate = false;
+ }
+ else
+ m_bSequenceOutOfDate = true;
+
+ return bValidPropsOnly;
+ }
+
+ bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues )
+ {
+ Reference< XPropertySetInfo > xPropInfo;
+ if (_rxValues.is())
+ xPropInfo = _rxValues->getPropertySetInfo();
+ if (!xPropInfo.is())
+ {
+ OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
+ return false;
+ }
+
+ // build a PropertyValue sequence with the current values
+ const Sequence< Property > aProperties = xPropInfo->getProperties();
+
+ Sequence< PropertyValue > aValues(aProperties.getLength());
+ PropertyValue* pValues = aValues.getArray();
+
+ for (const Property& rProperty : aProperties)
+ {
+ pValues->Name = rProperty.Name;
+ pValues->Value = _rxValues->getPropertyValue(rProperty.Name);
+ ++pValues;
+ }
+
+ bool bValidPropsOnly = buildFrom(aValues);
+ m_bSetOutOfDate = !bValidPropsOnly;
+
+ return bValidPropsOnly;
+ }
+
+ void ODADescriptorImpl::invalidateExternRepresentations()
+ {
+ m_bSetOutOfDate = true;
+ m_bSequenceOutOfDate = true;
+ }
+
+ const ODADescriptorImpl::MapString2PropertyEntry& ODADescriptorImpl::getPropertyMap( )
+ {
+ // the properties we know
+ static MapString2PropertyEntry s_aProperties
+ {
+ { OUString("ActiveConnection"), DataAccessDescriptorProperty::Connection, },
+ { OUString("BookmarkSelection"), DataAccessDescriptorProperty::BookmarkSelection, },
+ { OUString("Column"), DataAccessDescriptorProperty::ColumnObject, },
+ { OUString("ColumnName"), DataAccessDescriptorProperty::ColumnName, },
+ { OUString("Command"), DataAccessDescriptorProperty::Command, },
+ { OUString("CommandType"), DataAccessDescriptorProperty::CommandType, },
+ { OUString("Component"), DataAccessDescriptorProperty::Component, },
+ { OUString("ConnectionResource"), DataAccessDescriptorProperty::ConnectionResource, },
+ { OUString("Cursor"), DataAccessDescriptorProperty::Cursor, },
+ { OUString("DataSourceName"), DataAccessDescriptorProperty::DataSource, },
+ { OUString("DatabaseLocation"), DataAccessDescriptorProperty::DatabaseLocation, },
+ { OUString("EscapeProcessing"), DataAccessDescriptorProperty::EscapeProcessing, },
+ { OUString("Filter"), DataAccessDescriptorProperty::Filter, },
+ { OUString("Selection"), DataAccessDescriptorProperty::Selection, }
+ };
+
+ return s_aProperties;
+ }
+
+ PropertyMapEntry const * ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos )
+ {
+ const MapString2PropertyEntry& rProperties = getPropertyMap();
+
+ DataAccessDescriptorProperty nNeededHandle = _rPos->first;
+
+ auto loop = std::find_if(rProperties.begin(), rProperties.end(),
+ [&nNeededHandle](const MapString2PropertyEntry::value_type& rProp) { return nNeededHandle == rProp.second; });
+ if (loop != rProperties.end())
+ return &*loop;
+ throw RuntimeException();
+ }
+
+ PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos )
+ {
+ // the map entry
+ PropertyMapEntry const * pProperty = getPropertyMapEntry( _rPos );
+
+ // build the property value
+ PropertyValue aReturn;
+ aReturn.Name = pProperty->first;
+ aReturn.Handle = static_cast<sal_Int32>(pProperty->second);
+ aReturn.Value = _rPos->second;
+ aReturn.State = PropertyState_DIRECT_VALUE;
+
+ // outta here
+ return aReturn;
+ }
+
+ void ODADescriptorImpl::updateSequence()
+ {
+ if (!m_bSequenceOutOfDate)
+ return;
+
+ m_aAsSequence.realloc(m_aValues.size());
+ PropertyValue* pValue = m_aAsSequence.getArray();
+
+ // loop through all our values
+ for ( DescriptorValues::const_iterator aLoop = m_aValues.begin();
+ aLoop != m_aValues.end();
+ ++aLoop, ++pValue
+ )
+ {
+ *pValue = buildPropertyValue(aLoop);
+ }
+
+ // don't need to rebuild next time
+ m_bSequenceOutOfDate = false;
+ }
+
+ ODataAccessDescriptor::ODataAccessDescriptor()
+ :m_pImpl(new ODADescriptorImpl)
+ {
+ }
+
+ ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor& _rSource )
+ :m_pImpl(new ODADescriptorImpl(*_rSource.m_pImpl))
+ {
+ }
+
+ ODataAccessDescriptor::ODataAccessDescriptor(ODataAccessDescriptor&& _rSource) noexcept
+ :m_pImpl(std::move(_rSource.m_pImpl))
+ {
+ }
+
+ ODataAccessDescriptor& ODataAccessDescriptor::operator=(const ODataAccessDescriptor& _rSource)
+ {
+ if (this != &_rSource)
+ m_pImpl.reset(new ODADescriptorImpl(*_rSource.m_pImpl));
+ return *this;
+ }
+
+ ODataAccessDescriptor& ODataAccessDescriptor::operator=(ODataAccessDescriptor&& _rSource) noexcept
+ {
+ m_pImpl = std::move(_rSource.m_pImpl);
+ return *this;
+ }
+
+ ODataAccessDescriptor::ODataAccessDescriptor( const Reference< XPropertySet >& _rValues )
+ :m_pImpl(new ODADescriptorImpl)
+ {
+ m_pImpl->buildFrom(_rValues);
+ }
+
+ ODataAccessDescriptor::ODataAccessDescriptor( const Any& _rValues )
+ :m_pImpl(new ODADescriptorImpl)
+ {
+ // check if we know the format in the Any
+ Sequence< PropertyValue > aValues;
+ Reference< XPropertySet > xValues;
+ if ( _rValues >>= aValues )
+ m_pImpl->buildFrom( aValues );
+ else if ( _rValues >>= xValues )
+ m_pImpl->buildFrom( xValues );
+ }
+
+ ODataAccessDescriptor::ODataAccessDescriptor( const Sequence< PropertyValue >& _rValues )
+ :m_pImpl(new ODADescriptorImpl)
+ {
+ m_pImpl->buildFrom(_rValues);
+ }
+
+ ODataAccessDescriptor::~ODataAccessDescriptor()
+ {
+ }
+
+ void ODataAccessDescriptor::clear()
+ {
+ m_pImpl->m_aValues.clear();
+ }
+
+ void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich)
+ {
+ OSL_ENSURE(has(_eWhich), "ODataAccessDescriptor::erase: invalid call!");
+ if (has(_eWhich))
+ m_pImpl->m_aValues.erase(_eWhich);
+ }
+
+ bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich) const
+ {
+ return m_pImpl->m_aValues.find(_eWhich) != m_pImpl->m_aValues.end();
+ }
+
+ const Any& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich ) const
+ {
+ if (!has(_eWhich))
+ {
+ OSL_FAIL("ODataAccessDescriptor::operator[]: invalid accessor!");
+ static const Any aDummy;
+ return aDummy;
+ }
+
+ return m_pImpl->m_aValues[_eWhich];
+ }
+
+ Any& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich )
+ {
+ m_pImpl->invalidateExternRepresentations();
+ return m_pImpl->m_aValues[_eWhich];
+ }
+
+ void ODataAccessDescriptor::initializeFrom(const Sequence< PropertyValue >& _rValues)
+ {
+ clear();
+ m_pImpl->buildFrom(_rValues);
+ }
+
+ Sequence< PropertyValue > const & ODataAccessDescriptor::createPropertyValueSequence()
+ {
+ m_pImpl->updateSequence();
+ return m_pImpl->m_aAsSequence;
+ }
+
+ OUString ODataAccessDescriptor::getDataSource() const
+ {
+ OUString sDataSourceName;
+ if ( has(DataAccessDescriptorProperty::DataSource) )
+ (*this)[DataAccessDescriptorProperty::DataSource] >>= sDataSourceName;
+ else if ( has(DataAccessDescriptorProperty::DatabaseLocation) )
+ (*this)[DataAccessDescriptorProperty::DatabaseLocation] >>= sDataSourceName;
+ return sDataSourceName;
+ }
+
+ void ODataAccessDescriptor::setDataSource(const OUString& _sDataSourceNameOrLocation)
+ {
+ if ( !_sDataSourceNameOrLocation.isEmpty() )
+ {
+ INetURLObject aURL(_sDataSourceNameOrLocation);
+ (*this)[ (( aURL.GetProtocol() == INetProtocol::File ) ? DataAccessDescriptorProperty::DatabaseLocation : DataAccessDescriptorProperty::DataSource)] <<= _sDataSourceNameOrLocation;
+ }
+ else
+ (*this)[ DataAccessDescriptorProperty::DataSource ] <<= OUString();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */