xref: /AOO41X/main/svx/source/form/dataaccessdescriptor.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 #include <svx/dataaccessdescriptor.hxx>
27 #include <comphelper/stl_types.hxx>
28 #include <comphelper/propertysetinfo.hxx>
29 #include <comphelper/genericpropertyset.hxx>
30 #include <osl/diagnose.h>
31 #include <com/sun/star/sdbc/XConnection.hpp>
32 #include <com/sun/star/ucb/XContent.hpp>
33 #include <com/sun/star/beans/PropertyAttribute.hpp>
34 #include <tools/urlobj.hxx>
35 
36 //........................................................................
37 namespace svx
38 {
39 //........................................................................
40 
41     using namespace ::com::sun::star::uno;
42     using namespace ::com::sun::star::sdbc;
43     using namespace ::com::sun::star::beans;
44     using namespace ::com::sun::star::ucb;
45     using namespace ::comphelper;
46 
47 #define CONST_CHAR( propname ) propname, sizeof(propname) - 1
48 
49 #ifndef SVX_LIGHT
50     //====================================================================
51     //= ODADescriptorImpl
52     //====================================================================
53     class ODADescriptorImpl
54     {
55     protected:
56         sal_Bool                    m_bSetOutOfDate         : 1;
57         sal_Bool                    m_bSequenceOutOfDate    : 1;
58 
59     public:
60         typedef ::std::map< DataAccessDescriptorProperty, Any >     DescriptorValues;
61         DescriptorValues            m_aValues;
62         Sequence< PropertyValue >   m_aAsSequence;
63         Reference< XPropertySet >   m_xAsSet;
64 
65         typedef ::std::map< ::rtl::OUString, PropertyMapEntry* >    MapString2PropertyEntry;
66 
67     public:
68         ODADescriptorImpl();
69         ODADescriptorImpl(const ODADescriptorImpl& _rSource);
70 
71         void invalidateExternRepresentations();
72 
73         void updateSequence();
74         void updateSet();
75 
76         /** builds the descriptor from a property value sequence
77             @return <TRUE/>
78                 if and only if the sequence contained valid properties only
79         */
80         sal_Bool buildFrom( const Sequence< PropertyValue >& _rValues );
81 
82         /** builds the descriptor from a property set
83             @return <TRUE/>
84                 if and only if the set contained valid properties only
85         */
86         sal_Bool buildFrom( const Reference< XPropertySet >& _rValues );
87 
88     protected:
89         static PropertyValue                    buildPropertyValue( const DescriptorValues::const_iterator& _rPos );
90         static const MapString2PropertyEntry&   getPropertyMap( );
91         static PropertyMapEntry*                getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos );
92     };
93 
94     //--------------------------------------------------------------------
ODADescriptorImpl()95     ODADescriptorImpl::ODADescriptorImpl()
96         :m_bSetOutOfDate(sal_True)
97         ,m_bSequenceOutOfDate(sal_True)
98     {
99     }
100 
101     //--------------------------------------------------------------------
ODADescriptorImpl(const ODADescriptorImpl & _rSource)102     ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl& _rSource)
103         :m_bSetOutOfDate( _rSource.m_bSetOutOfDate )
104         ,m_bSequenceOutOfDate( _rSource.m_bSequenceOutOfDate )
105         ,m_aValues( _rSource.m_aValues )
106     {
107         if (!m_bSetOutOfDate)
108             m_xAsSet = _rSource.m_xAsSet;
109         if (!m_bSequenceOutOfDate)
110             m_aAsSequence = _rSource.m_aAsSequence;
111     }
112 
113     //--------------------------------------------------------------------
buildFrom(const Sequence<PropertyValue> & _rValues)114     sal_Bool ODADescriptorImpl::buildFrom( const Sequence< PropertyValue >& _rValues )
115     {
116         const MapString2PropertyEntry& rProperties = getPropertyMap();
117 
118         sal_Bool bValidPropsOnly = sal_True;
119 
120         // loop through the sequence, and fill our m_aValues
121         const PropertyValue* pValues = _rValues.getConstArray();
122         const PropertyValue* pValuesEnd = pValues + _rValues.getLength();
123         for (;pValues != pValuesEnd; ++pValues)
124         {
125             MapString2PropertyEntry::const_iterator aPropPos = rProperties.find( pValues->Name );
126             if ( aPropPos != rProperties.end() )
127             {
128                 DataAccessDescriptorProperty eProperty = (DataAccessDescriptorProperty)aPropPos->second->mnHandle;
129                 m_aValues[eProperty] = pValues->Value;
130             }
131             else
132                 // unknown property
133                 bValidPropsOnly = sal_False;
134         }
135 
136         if (bValidPropsOnly)
137         {
138             m_aAsSequence = _rValues;
139             m_bSequenceOutOfDate = sal_False;
140         }
141         else
142             m_bSequenceOutOfDate = sal_True;
143 
144         return bValidPropsOnly;
145     }
146 
147     //--------------------------------------------------------------------
buildFrom(const Reference<XPropertySet> & _rxValues)148     sal_Bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues )
149     {
150         Reference< XPropertySetInfo > xPropInfo;
151         if (_rxValues.is())
152             xPropInfo = _rxValues->getPropertySetInfo();
153         if (!xPropInfo.is())
154         {
155             OSL_ENSURE(sal_False, "ODADescriptorImpl::buildFrom: invalid property set!");
156             return sal_False;
157         }
158 
159         // build a PropertyValue sequence with the current values
160         Sequence< Property > aProperties = xPropInfo->getProperties();
161         const Property* pProperty = aProperties.getConstArray();
162         const Property* pPropertyEnd = pProperty + aProperties.getLength();
163 
164         Sequence< PropertyValue > aValues(aProperties.getLength());
165         PropertyValue* pValues = aValues.getArray();
166 
167         for (;pProperty != pPropertyEnd; ++pProperty, ++pValues)
168         {
169             pValues->Name = pProperty->Name;
170             pValues->Value = _rxValues->getPropertyValue(pProperty->Name);
171         }
172 
173         sal_Bool bValidPropsOnly = buildFrom(aValues);
174         if (bValidPropsOnly)
175         {
176             m_xAsSet = _rxValues;
177             m_bSetOutOfDate = sal_False;
178         }
179         else
180             m_bSetOutOfDate = sal_True;
181 
182         return bValidPropsOnly;
183     }
184 
185     //--------------------------------------------------------------------
invalidateExternRepresentations()186     void ODADescriptorImpl::invalidateExternRepresentations()
187     {
188         m_bSetOutOfDate = sal_True;
189         m_bSequenceOutOfDate = sal_True;
190     }
191 
192     //--------------------------------------------------------------------
getPropertyMap()193     const ODADescriptorImpl::MapString2PropertyEntry& ODADescriptorImpl::getPropertyMap( )
194     {
195         // the properties we know
196         static MapString2PropertyEntry s_aProperties;
197         if ( s_aProperties.empty() )
198         {
199             static PropertyMapEntry s_aDesriptorProperties[] =
200             {
201                 { CONST_CHAR("ActiveConnection"),   daConnection,           &::getCppuType( static_cast< Reference< XConnection >* >(NULL) ),   PropertyAttribute::TRANSIENT, 0 },
202                 { CONST_CHAR("BookmarkSelection"),  daBookmarkSelection,    &::getBooleanCppuType( ),                                           PropertyAttribute::TRANSIENT, 0 },
203                 { CONST_CHAR("Column"),             daColumnObject,         &::getCppuType( static_cast< Reference< XPropertySet >* >(NULL) ),  PropertyAttribute::TRANSIENT, 0 },
204                 { CONST_CHAR("ColumnName"),         daColumnName,           &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ),            PropertyAttribute::TRANSIENT, 0 },
205                 { CONST_CHAR("Command"),            daCommand,              &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ),            PropertyAttribute::TRANSIENT, 0 },
206                 { CONST_CHAR("CommandType"),        daCommandType,          &::getCppuType( static_cast< sal_Int32* >(NULL) ),                  PropertyAttribute::TRANSIENT, 0 },
207                 { CONST_CHAR("Component"),          daComponent,            &::getCppuType( static_cast< Reference< XContent >* >(NULL) ),      PropertyAttribute::TRANSIENT, 0 },
208                 { CONST_CHAR("ConnectionResource"), daConnectionResource,   &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ),            PropertyAttribute::TRANSIENT, 0 },
209                 { CONST_CHAR("Cursor"),             daCursor,               &::getCppuType( static_cast< Reference< XResultSet>* >(NULL) ),     PropertyAttribute::TRANSIENT, 0 },
210                 { CONST_CHAR("DataSourceName"),     daDataSource,           &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ),            PropertyAttribute::TRANSIENT, 0 },
211                 { CONST_CHAR("DatabaseLocation"),   daDatabaseLocation,     &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ),            PropertyAttribute::TRANSIENT, 0 },
212                 { CONST_CHAR("EscapeProcessing"),   daEscapeProcessing,     &::getBooleanCppuType( ),                                           PropertyAttribute::TRANSIENT, 0 },
213                 { CONST_CHAR("Filter"),             daFilter,               &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ),            PropertyAttribute::TRANSIENT, 0 },
214                 { CONST_CHAR("Selection"),          daSelection,            &::getCppuType( static_cast< Sequence< Any >* >(NULL) ),            PropertyAttribute::TRANSIENT, 0 },
215                 { NULL, 0, 0, NULL, 0, 0 }
216             };
217 
218             PropertyMapEntry* pEntry = s_aDesriptorProperties;
219             while ( pEntry->mpName )
220             {
221                 s_aProperties[ ::rtl::OUString::createFromAscii( pEntry->mpName ) ] = pEntry;
222                 ++pEntry;
223             }
224         }
225 
226         return s_aProperties;
227     }
228 
229     //--------------------------------------------------------------------
getPropertyMapEntry(const DescriptorValues::const_iterator & _rPos)230     PropertyMapEntry* ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos )
231     {
232         const MapString2PropertyEntry& rProperties = getPropertyMap();
233 
234         sal_Int32 nNeededHandle = (sal_Int32)(_rPos->first);
235 
236         for ( MapString2PropertyEntry::const_iterator loop = rProperties.begin();
237               loop != rProperties.end();
238               ++loop
239             )
240         {
241             if ( nNeededHandle == loop->second->mnHandle )
242                 return loop->second;
243         }
244         throw RuntimeException();
245     }
246 
247     //--------------------------------------------------------------------
buildPropertyValue(const DescriptorValues::const_iterator & _rPos)248     PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos )
249     {
250         // the map entry
251         PropertyMapEntry* pProperty = getPropertyMapEntry( _rPos );
252 
253         // build the property value
254         PropertyValue aReturn;
255         aReturn.Name    = ::rtl::OUString( pProperty->mpName, pProperty->mnNameLen, RTL_TEXTENCODING_ASCII_US );
256         aReturn.Handle  = pProperty->mnHandle;
257         aReturn.Value   = _rPos->second;
258         aReturn.State   = PropertyState_DIRECT_VALUE;
259 
260         // outta here
261         return aReturn;
262     }
263 
264     //--------------------------------------------------------------------
updateSequence()265     void ODADescriptorImpl::updateSequence()
266     {
267         if (!m_bSequenceOutOfDate)
268             return;
269 
270         m_aAsSequence.realloc(m_aValues.size());
271         PropertyValue* pValue = m_aAsSequence.getArray();
272 
273         // loop through all our values
274         for (   DescriptorValues::const_iterator aLoop = m_aValues.begin();
275                 aLoop != m_aValues.end();
276                 ++aLoop, ++pValue
277             )
278         {
279             *pValue = buildPropertyValue(aLoop);
280         }
281 
282         // don't need to rebuild next time
283         m_bSequenceOutOfDate = sal_False;
284     }
285 
286     //--------------------------------------------------------------------
updateSet()287     void ODADescriptorImpl::updateSet()
288     {
289         if (!m_bSetOutOfDate)
290             return;
291 
292         // will be the current values
293         Sequence< PropertyValue > aValuesToSet(m_aValues.size());
294         PropertyValue* pValuesToSet = aValuesToSet.getArray();
295 
296         // build a new property set info
297         PropertySetInfo* pPropSetInfo = new PropertySetInfo;
298 
299         // loop through all our values
300         for (   DescriptorValues::const_iterator aLoop = m_aValues.begin();
301                 aLoop != m_aValues.end();
302                 ++aLoop, ++pValuesToSet
303             )
304         {
305             PropertyMapEntry* pMapEntry = getPropertyMapEntry( aLoop );
306             pPropSetInfo->add( pMapEntry, 1 );
307 
308             *pValuesToSet = buildPropertyValue(aLoop);
309         }
310 
311         // create the generic set
312         m_xAsSet = GenericPropertySet_CreateInstance( pPropSetInfo );
313 
314         // no we have the set, still need to set the current values
315         const PropertyValue* pSetValues = aValuesToSet.getConstArray();
316         const PropertyValue* pSetValuesEnd = pSetValues + aValuesToSet.getLength();
317         for (; pSetValues != pSetValuesEnd; ++pSetValues)
318             m_xAsSet->setPropertyValue(pSetValues->Name, pSetValues->Value);
319 
320         // don't need to rebuild next time
321         m_bSetOutOfDate = sal_True;
322     }
323 #endif
324 
325     //====================================================================
326     //= ODataAccessDescriptor
327     //====================================================================
328     //--------------------------------------------------------------------
ODataAccessDescriptor()329     ODataAccessDescriptor::ODataAccessDescriptor()
330 #ifndef SVX_LIGHT
331         :m_pImpl(new ODADescriptorImpl)
332 #else
333         :m_pImpl(NULL)
334 #endif
335     {
336     }
337 
338     //--------------------------------------------------------------------
ODataAccessDescriptor(const ODataAccessDescriptor & _rSource)339     ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor& _rSource )
340 #ifndef SVX_LIGHT
341         :m_pImpl(new ODADescriptorImpl(*_rSource.m_pImpl))
342 #else
343         :m_pImpl(NULL)
344 #endif
345     {
346     }
347 
348     //--------------------------------------------------------------------
operator =(const ODataAccessDescriptor & _rSource)349     const ODataAccessDescriptor& ODataAccessDescriptor::operator=(const ODataAccessDescriptor& _rSource)
350     {
351 #ifndef SVX_LIGHT
352         delete m_pImpl;
353         m_pImpl = new ODADescriptorImpl(*_rSource.m_pImpl);
354 #else
355         OSL_ENSURE(sal_False, "ODataAccessDescriptor::operator=: not available in the SVX_LIGHT version!");
356 #endif
357         return *this;
358     }
359 
360     //--------------------------------------------------------------------
ODataAccessDescriptor(const Reference<XPropertySet> & _rValues)361     ODataAccessDescriptor::ODataAccessDescriptor( const Reference< XPropertySet >& _rValues )
362 #ifndef SVX_LIGHT
363         :m_pImpl(new ODADescriptorImpl)
364 #else
365         :m_pImpl(NULL)
366 #endif
367     {
368 #ifndef SVX_LIGHT
369         m_pImpl->buildFrom(_rValues);
370 #else
371         OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!");
372 #endif
373     }
374 
375     //--------------------------------------------------------------------
ODataAccessDescriptor(const Any & _rValues)376     ODataAccessDescriptor::ODataAccessDescriptor( const Any& _rValues )
377 #ifndef SVX_LIGHT
378         :m_pImpl(new ODADescriptorImpl)
379 #else
380         :m_pImpl(NULL)
381 #endif
382     {
383 #ifndef SVX_LIGHT
384         // check if we know the format in the Any
385         Sequence< PropertyValue > aValues;
386         Reference< XPropertySet > xValues;
387         if ( _rValues >>= aValues )
388             m_pImpl->buildFrom( aValues );
389         else if ( _rValues >>= xValues )
390             m_pImpl->buildFrom( xValues );
391 #else
392         OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!");
393 #endif
394     }
395 
396     //--------------------------------------------------------------------
ODataAccessDescriptor(const Sequence<PropertyValue> & _rValues)397     ODataAccessDescriptor::ODataAccessDescriptor( const Sequence< PropertyValue >& _rValues )
398 #ifndef SVX_LIGHT
399         :m_pImpl(new ODADescriptorImpl)
400 #else
401         :m_pImpl(NULL)
402 #endif
403     {
404 #ifndef SVX_LIGHT
405         m_pImpl->buildFrom(_rValues);
406 #else
407         OSL_ENSURE(sal_False, "ODataAccessDescriptor::ODataAccessDescriptor: not available in the SVX_LIGHT version!");
408 #endif
409     }
410 
411     //--------------------------------------------------------------------
~ODataAccessDescriptor()412     ODataAccessDescriptor::~ODataAccessDescriptor()
413     {
414         delete m_pImpl;
415     }
416 
417     //--------------------------------------------------------------------
clear()418     void ODataAccessDescriptor::clear()
419     {
420 #ifndef SVX_LIGHT
421         m_pImpl->m_aValues.clear();
422 #endif
423     }
424 
425     //--------------------------------------------------------------------
erase(DataAccessDescriptorProperty _eWhich)426     void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich)
427     {
428 #ifndef SVX_LIGHT
429         OSL_ENSURE(has(_eWhich), "ODataAccessDescriptor::erase: invalid call!");
430         if (has(_eWhich))
431             m_pImpl->m_aValues.erase(_eWhich);
432 #endif
433     }
434 
435     //--------------------------------------------------------------------
has(DataAccessDescriptorProperty _eWhich) const436     sal_Bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich) const
437     {
438 #ifndef SVX_LIGHT
439         return m_pImpl->m_aValues.find(_eWhich) != m_pImpl->m_aValues.end();
440 #else
441         return sal_False;
442 #endif
443     }
444 
445     //--------------------------------------------------------------------
operator [](DataAccessDescriptorProperty _eWhich) const446     const Any& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich ) const
447     {
448 #ifndef SVX_LIGHT
449         if (!has(_eWhich))
450         {
451             OSL_ENSURE(sal_False, "ODataAccessDescriptor::operator[]: invalid acessor!");
452             static const Any aDummy;
453             return aDummy;
454         }
455 
456         return m_pImpl->m_aValues[_eWhich];
457 #else
458         static const Any aDummy;
459         return aDummy;
460 #endif
461     }
462 
463     //--------------------------------------------------------------------
operator [](DataAccessDescriptorProperty _eWhich)464     Any& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich )
465     {
466 #ifndef SVX_LIGHT
467         m_pImpl->invalidateExternRepresentations();
468         return m_pImpl->m_aValues[_eWhich];
469 #else
470         static const Any aDummy;
471         return aDummy;
472 #endif
473     }
474 
475     //--------------------------------------------------------------------
initializeFrom(const Reference<XPropertySet> & _rxValues,sal_Bool _bClear)476     void ODataAccessDescriptor::initializeFrom(const Reference< XPropertySet >& _rxValues, sal_Bool _bClear)
477     {
478 #ifndef SVX_LIGHT
479         if (_bClear)
480             clear();
481         m_pImpl->buildFrom(_rxValues);
482 #endif
483     }
484 
485     //--------------------------------------------------------------------
initializeFrom(const Sequence<PropertyValue> & _rValues,sal_Bool _bClear)486     void ODataAccessDescriptor::initializeFrom(const Sequence< PropertyValue >& _rValues, sal_Bool _bClear)
487     {
488 #ifndef SVX_LIGHT
489         if (_bClear)
490             clear();
491         m_pImpl->buildFrom(_rValues);
492 #endif
493     }
494 
495     //--------------------------------------------------------------------
createPropertyValueSequence()496     Sequence< PropertyValue > ODataAccessDescriptor::createPropertyValueSequence()
497     {
498 #ifndef SVX_LIGHT
499         m_pImpl->updateSequence();
500         return m_pImpl->m_aAsSequence;
501 #else
502         return Sequence< PropertyValue >();
503 #endif
504     }
505     //--------------------------------------------------------------------
createAnySequence()506     Sequence< Any > ODataAccessDescriptor::createAnySequence()
507     {
508 #ifndef SVX_LIGHT
509         m_pImpl->updateSequence();
510         Sequence< Any > aRet(m_pImpl->m_aAsSequence.getLength());
511         const PropertyValue* pBegin = m_pImpl->m_aAsSequence.getConstArray();
512         const PropertyValue* pEnd     = pBegin + m_pImpl->m_aAsSequence.getLength();
513         for(sal_Int32 i=0;pBegin != pEnd;++pBegin,++i)
514             aRet[i] <<= *pBegin;
515         return aRet;
516 #else
517         return Sequence< createAnySequence >();
518 #endif
519     }
520 
521     //--------------------------------------------------------------------
createPropertySet()522     Reference< XPropertySet > ODataAccessDescriptor::createPropertySet()
523     {
524 #ifndef SVX_LIGHT
525         m_pImpl->updateSet();
526         return m_pImpl->m_xAsSet;
527 #else
528         return Reference< XPropertySet >();
529 #endif
530     }
531     //--------------------------------------------------------------------
getDataSource() const532     ::rtl::OUString ODataAccessDescriptor::getDataSource() const
533     {
534 #ifndef SVX_LIGHT
535         ::rtl::OUString sDataSourceName;
536         if ( has(daDataSource) )
537             (*this)[daDataSource] >>= sDataSourceName;
538         else if ( has(daDatabaseLocation) )
539             (*this)[daDatabaseLocation] >>= sDataSourceName;
540         return sDataSourceName;
541 #else
542         return ::rtl::OUString();
543 #endif
544     }
545     //--------------------------------------------------------------------
setDataSource(const::rtl::OUString & _sDataSourceNameOrLocation)546     void ODataAccessDescriptor::setDataSource(const ::rtl::OUString& _sDataSourceNameOrLocation)
547     {
548 #ifndef SVX_LIGHT
549         if ( _sDataSourceNameOrLocation.getLength() )
550         {
551             INetURLObject aURL(_sDataSourceNameOrLocation);
552             (*this)[ (( aURL.GetProtocol() == INET_PROT_FILE ) ? daDatabaseLocation : daDataSource)] <<= _sDataSourceNameOrLocation;
553         }
554         else
555             (*this)[ daDataSource ] <<= ::rtl::OUString();
556 #endif
557     }
558 
559 //........................................................................
560 }   // namespace svx
561 //........................................................................
562 
563 
564