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