| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| #include <svx/dataaccessdescriptor.hxx> |
| #include <comphelper/stl_types.hxx> |
| #include <comphelper/propertysetinfo.hxx> |
| #include <comphelper/genericpropertyset.hxx> |
| #include <osl/diagnose.h> |
| #include <com/sun/star/sdbc/XConnection.hpp> |
| #include <com/sun/star/ucb/XContent.hpp> |
| #include <com/sun/star/beans/PropertyAttribute.hpp> |
| #include <tools/urlobj.hxx> |
| |
| //........................................................................ |
| namespace svx |
| { |
| //........................................................................ |
| |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::sdbc; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::ucb; |
| using namespace ::comphelper; |
| |
| #define CONST_CHAR( propname ) propname, sizeof(propname) - 1 |
| |
| #ifndef SVX_LIGHT |
| //==================================================================== |
| //= ODADescriptorImpl |
| //==================================================================== |
| class ODADescriptorImpl |
| { |
| protected: |
| sal_Bool m_bSetOutOfDate : 1; |
| sal_Bool m_bSequenceOutOfDate : 1; |
| |
| public: |
| typedef ::std::map< DataAccessDescriptorProperty, Any > DescriptorValues; |
| DescriptorValues m_aValues; |
| Sequence< PropertyValue > m_aAsSequence; |
| Reference< XPropertySet > m_xAsSet; |
| |
| typedef ::std::map< ::rtl::OUString, PropertyMapEntry* > MapString2PropertyEntry; |
| |
| public: |
| ODADescriptorImpl(); |
| ODADescriptorImpl(const ODADescriptorImpl& _rSource); |
| |
| void invalidateExternRepresentations(); |
| |
| void updateSequence(); |
| void updateSet(); |
| |
| /** builds the descriptor from a property value sequence |
| @return <TRUE/> |
| if and only if the sequence contained valid properties only |
| */ |
| sal_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 |
| */ |
| sal_Bool buildFrom( const Reference< XPropertySet >& _rValues ); |
| |
| protected: |
| static PropertyValue buildPropertyValue( const DescriptorValues::const_iterator& _rPos ); |
| static const MapString2PropertyEntry& getPropertyMap( ); |
| static PropertyMapEntry* getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos ); |
| }; |
| |
| //-------------------------------------------------------------------- |
| ODADescriptorImpl::ODADescriptorImpl() |
| :m_bSetOutOfDate(sal_True) |
| ,m_bSequenceOutOfDate(sal_True) |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl& _rSource) |
| :m_bSetOutOfDate( _rSource.m_bSetOutOfDate ) |
| ,m_bSequenceOutOfDate( _rSource.m_bSequenceOutOfDate ) |
| ,m_aValues( _rSource.m_aValues ) |
| { |
| if (!m_bSetOutOfDate) |
| m_xAsSet = _rSource.m_xAsSet; |
| if (!m_bSequenceOutOfDate) |
| m_aAsSequence = _rSource.m_aAsSequence; |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Bool ODADescriptorImpl::buildFrom( const Sequence< PropertyValue >& _rValues ) |
| { |
| const MapString2PropertyEntry& rProperties = getPropertyMap(); |
| |
| sal_Bool bValidPropsOnly = sal_True; |
| |
| // loop through the sequence, and fill our m_aValues |
| const PropertyValue* pValues = _rValues.getConstArray(); |
| const PropertyValue* pValuesEnd = pValues + _rValues.getLength(); |
| for (;pValues != pValuesEnd; ++pValues) |
| { |
| MapString2PropertyEntry::const_iterator aPropPos = rProperties.find( pValues->Name ); |
| if ( aPropPos != rProperties.end() ) |
| { |
| DataAccessDescriptorProperty eProperty = (DataAccessDescriptorProperty)aPropPos->second->mnHandle; |
| m_aValues[eProperty] = pValues->Value; |
| } |
| else |
| // unknown property |
| bValidPropsOnly = sal_False; |
| } |
| |
| if (bValidPropsOnly) |
| { |
| m_aAsSequence = _rValues; |
| m_bSequenceOutOfDate = sal_False; |
| } |
| else |
| m_bSequenceOutOfDate = sal_True; |
| |
| return bValidPropsOnly; |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues ) |
| { |
| Reference< XPropertySetInfo > xPropInfo; |
| if (_rxValues.is()) |
| xPropInfo = _rxValues->getPropertySetInfo(); |
| if (!xPropInfo.is()) |
| { |
| OSL_ENSURE(sal_False, "ODADescriptorImpl::buildFrom: invalid property set!"); |
| return sal_False; |
| } |
| |
| // build a PropertyValue sequence with the current values |
| Sequence< Property > aProperties = xPropInfo->getProperties(); |
| const Property* pProperty = aProperties.getConstArray(); |
| const Property* pPropertyEnd = pProperty + aProperties.getLength(); |
| |
| Sequence< PropertyValue > aValues(aProperties.getLength()); |
| PropertyValue* pValues = aValues.getArray(); |
| |
| for (;pProperty != pPropertyEnd; ++pProperty, ++pValues) |
| { |
| pValues->Name = pProperty->Name; |
| pValues->Value = _rxValues->getPropertyValue(pProperty->Name); |
| } |
| |
| sal_Bool bValidPropsOnly = buildFrom(aValues); |
| if (bValidPropsOnly) |
| { |
| m_xAsSet = _rxValues; |
| m_bSetOutOfDate = sal_False; |
| } |
| else |
| m_bSetOutOfDate = sal_True; |
| |
| return bValidPropsOnly; |
| } |
| |
| //-------------------------------------------------------------------- |
| void ODADescriptorImpl::invalidateExternRepresentations() |
| { |
| m_bSetOutOfDate = sal_True; |
| m_bSequenceOutOfDate = sal_True; |
| } |
| |
| //-------------------------------------------------------------------- |
| const ODADescriptorImpl::MapString2PropertyEntry& ODADescriptorImpl::getPropertyMap( ) |
| { |
| // the properties we know |
| static MapString2PropertyEntry s_aProperties; |
| if ( s_aProperties.empty() ) |
| { |
| static PropertyMapEntry s_aDesriptorProperties[] = |
| { |
| { CONST_CHAR("ActiveConnection"), daConnection, &::getCppuType( static_cast< Reference< XConnection >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("BookmarkSelection"), daBookmarkSelection, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("Column"), daColumnObject, &::getCppuType( static_cast< Reference< XPropertySet >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("ColumnName"), daColumnName, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("Command"), daCommand, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("CommandType"), daCommandType, &::getCppuType( static_cast< sal_Int32* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("Component"), daComponent, &::getCppuType( static_cast< Reference< XContent >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("ConnectionResource"), daConnectionResource, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("Cursor"), daCursor, &::getCppuType( static_cast< Reference< XResultSet>* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("DataSourceName"), daDataSource, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("DatabaseLocation"), daDatabaseLocation, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("EscapeProcessing"), daEscapeProcessing, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("Filter"), daFilter, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { CONST_CHAR("Selection"), daSelection, &::getCppuType( static_cast< Sequence< Any >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 }, |
| { NULL, 0, 0, NULL, 0, 0 } |
| }; |
| |
| PropertyMapEntry* pEntry = s_aDesriptorProperties; |
| while ( pEntry->mpName ) |
| { |
| s_aProperties[ ::rtl::OUString::createFromAscii( pEntry->mpName ) ] = pEntry; |
| ++pEntry; |
| } |
| } |
| |
| return s_aProperties; |
| } |
| |
| //-------------------------------------------------------------------- |
| PropertyMapEntry* ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos ) |
| { |
| const MapString2PropertyEntry& rProperties = getPropertyMap(); |
| |
| sal_Int32 nNeededHandle = (sal_Int32)(_rPos->first); |
| |
| for ( MapString2PropertyEntry::const_iterator loop = rProperties.begin(); |
| loop != rProperties.end(); |
| ++loop |
| ) |
| { |
| if ( nNeededHandle == loop->second->mnHandle ) |
| return loop->second; |
| } |
| throw RuntimeException(); |
| } |
| |
| //-------------------------------------------------------------------- |
| PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos ) |
| { |
| // the map entry |
| PropertyMapEntry* pProperty = getPropertyMapEntry( _rPos ); |
| |
| // build the property value |
| PropertyValue aReturn; |
| aReturn.Name = ::rtl::OUString( pProperty->mpName, pProperty->mnNameLen, RTL_TEXTENCODING_ASCII_US ); |
| aReturn.Handle = pProperty->mnHandle; |
| 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 = sal_False; |
| } |
| |
| //-------------------------------------------------------------------- |
| void ODADescriptorImpl::updateSet() |
| { |
| if (!m_bSetOutOfDate) |
| return; |
| |
| // will be the current values |
| Sequence< PropertyValue > aValuesToSet(m_aValues.size()); |
| PropertyValue* pValuesToSet = aValuesToSet.getArray(); |
| |
| // build a new property set info |
| PropertySetInfo* pPropSetInfo = new PropertySetInfo; |
| |
| // loop through all our values |
| for ( DescriptorValues::const_iterator aLoop = m_aValues.begin(); |
| aLoop != m_aValues.end(); |
| ++aLoop, ++pValuesToSet |
| ) |
| { |
| PropertyMapEntry* pMapEntry = getPropertyMapEntry( aLoop ); |
| pPropSetInfo->add( pMapEntry, 1 ); |
| |
| *pValuesToSet = buildPropertyValue(aLoop); |
| } |
| |
| // create the generic set |
| m_xAsSet = GenericPropertySet_CreateInstance( pPropSetInfo ); |
| |
| // no we have the set, still need to set the current values |
| const PropertyValue* pSetValues = aValuesToSet.getConstArray(); |
| const PropertyValue* pSetValuesEnd = pSetValues + aValuesToSet.getLength(); |
| for (; pSetValues != pSetValuesEnd; ++pSetValues) |
| m_xAsSet->setPropertyValue(pSetValues->Name, pSetValues->Value); |
| |
| // don't need to rebuild next time |
| m_bSetOutOfDate = sal_True; |
| } |
| #endif |
| |
| //==================================================================== |
| //= ODataAccessDescriptor |
| //==================================================================== |
| //-------------------------------------------------------------------- |
| ODataAccessDescriptor::ODataAccessDescriptor() |
| #ifndef SVX_LIGHT |
| :m_pImpl(new ODADescriptorImpl) |
| #else |
| :m_pImpl(NULL) |
| #endif |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor& _rSource ) |
| #ifndef SVX_LIGHT |
| :m_pImpl(new ODADescriptorImpl(*_rSource.m_pImpl)) |
| #else |
| :m_pImpl(NULL) |
| #endif |
| { |
| } |
| |
| //-------------------------------------------------------------------- |
| const ODataAccessDescriptor& ODataAccessDescriptor::operator=(const ODataAccessDescriptor& _rSource) |
| { |
| #ifndef SVX_LIGHT |
| delete m_pImpl; |
| m_pImpl = new ODADescriptorImpl(*_rSource.m_pImpl); |
| #else |
| OSL_ENSURE(sal_False, "ODataAccessDescriptor::operator=: not available in the SVX_LIGHT version!"); |
| #endif |
| return *this; |
| } |
| |
| //-------------------------------------------------------------------- |
| ODataAccessDescriptor::ODataAccessDescriptor( const Reference< XPropertySet >& _rValues ) |
| #ifndef SVX_LIGHT |
| :m_pImpl(new ODADescriptorImpl) |
| #else |
| :m_pImpl(NULL) |
| #endif |
| { |
| #ifndef SVX_LIGHT |
| m_pImpl->buildFrom(_rValues); |
| #else |
| OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!"); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| ODataAccessDescriptor::ODataAccessDescriptor( const Any& _rValues ) |
| #ifndef SVX_LIGHT |
| :m_pImpl(new ODADescriptorImpl) |
| #else |
| :m_pImpl(NULL) |
| #endif |
| { |
| #ifndef SVX_LIGHT |
| // 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 ); |
| #else |
| OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!"); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| ODataAccessDescriptor::ODataAccessDescriptor( const Sequence< PropertyValue >& _rValues ) |
| #ifndef SVX_LIGHT |
| :m_pImpl(new ODADescriptorImpl) |
| #else |
| :m_pImpl(NULL) |
| #endif |
| { |
| #ifndef SVX_LIGHT |
| m_pImpl->buildFrom(_rValues); |
| #else |
| OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!"); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| ODataAccessDescriptor::~ODataAccessDescriptor() |
| { |
| delete m_pImpl; |
| } |
| |
| //-------------------------------------------------------------------- |
| void ODataAccessDescriptor::clear() |
| { |
| #ifndef SVX_LIGHT |
| m_pImpl->m_aValues.clear(); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich) |
| { |
| #ifndef SVX_LIGHT |
| OSL_ENSURE(has(_eWhich), "ODataAccessDescriptor::erase: invalid call!"); |
| if (has(_eWhich)) |
| m_pImpl->m_aValues.erase(_eWhich); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| sal_Bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich) const |
| { |
| #ifndef SVX_LIGHT |
| return m_pImpl->m_aValues.find(_eWhich) != m_pImpl->m_aValues.end(); |
| #else |
| return sal_False; |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| const Any& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich ) const |
| { |
| #ifndef SVX_LIGHT |
| if (!has(_eWhich)) |
| { |
| OSL_ENSURE(sal_False, "ODataAccessDescriptor::operator[]: invalid acessor!"); |
| static const Any aDummy; |
| return aDummy; |
| } |
| |
| return m_pImpl->m_aValues[_eWhich]; |
| #else |
| static const Any aDummy; |
| return aDummy; |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| Any& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich ) |
| { |
| #ifndef SVX_LIGHT |
| m_pImpl->invalidateExternRepresentations(); |
| return m_pImpl->m_aValues[_eWhich]; |
| #else |
| static const Any aDummy; |
| return aDummy; |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| void ODataAccessDescriptor::initializeFrom(const Reference< XPropertySet >& _rxValues, sal_Bool _bClear) |
| { |
| #ifndef SVX_LIGHT |
| if (_bClear) |
| clear(); |
| m_pImpl->buildFrom(_rxValues); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| void ODataAccessDescriptor::initializeFrom(const Sequence< PropertyValue >& _rValues, sal_Bool _bClear) |
| { |
| #ifndef SVX_LIGHT |
| if (_bClear) |
| clear(); |
| m_pImpl->buildFrom(_rValues); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| Sequence< PropertyValue > ODataAccessDescriptor::createPropertyValueSequence() |
| { |
| #ifndef SVX_LIGHT |
| m_pImpl->updateSequence(); |
| return m_pImpl->m_aAsSequence; |
| #else |
| return Sequence< PropertyValue >(); |
| #endif |
| } |
| //-------------------------------------------------------------------- |
| Sequence< Any > ODataAccessDescriptor::createAnySequence() |
| { |
| #ifndef SVX_LIGHT |
| m_pImpl->updateSequence(); |
| Sequence< Any > aRet(m_pImpl->m_aAsSequence.getLength()); |
| const PropertyValue* pBegin = m_pImpl->m_aAsSequence.getConstArray(); |
| const PropertyValue* pEnd = pBegin + m_pImpl->m_aAsSequence.getLength(); |
| for(sal_Int32 i=0;pBegin != pEnd;++pBegin,++i) |
| aRet[i] <<= *pBegin; |
| return aRet; |
| #else |
| return Sequence< createAnySequence >(); |
| #endif |
| } |
| |
| //-------------------------------------------------------------------- |
| Reference< XPropertySet > ODataAccessDescriptor::createPropertySet() |
| { |
| #ifndef SVX_LIGHT |
| m_pImpl->updateSet(); |
| return m_pImpl->m_xAsSet; |
| #else |
| return Reference< XPropertySet >(); |
| #endif |
| } |
| //-------------------------------------------------------------------- |
| ::rtl::OUString ODataAccessDescriptor::getDataSource() const |
| { |
| #ifndef SVX_LIGHT |
| ::rtl::OUString sDataSourceName; |
| if ( has(daDataSource) ) |
| (*this)[daDataSource] >>= sDataSourceName; |
| else if ( has(daDatabaseLocation) ) |
| (*this)[daDatabaseLocation] >>= sDataSourceName; |
| return sDataSourceName; |
| #else |
| return ::rtl::OUString(); |
| #endif |
| } |
| //-------------------------------------------------------------------- |
| void ODataAccessDescriptor::setDataSource(const ::rtl::OUString& _sDataSourceNameOrLocation) |
| { |
| #ifndef SVX_LIGHT |
| if ( _sDataSourceNameOrLocation.getLength() ) |
| { |
| INetURLObject aURL(_sDataSourceNameOrLocation); |
| (*this)[ (( aURL.GetProtocol() == INET_PROT_FILE ) ? daDatabaseLocation : daDataSource)] <<= _sDataSourceNameOrLocation; |
| } |
| else |
| (*this)[ daDataSource ] <<= ::rtl::OUString(); |
| #endif |
| } |
| |
| //........................................................................ |
| } // namespace svx |
| //........................................................................ |
| |
| |