Line data Source code
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 :
20 : #include <svx/dataaccessdescriptor.hxx>
21 : #include <comphelper/stl_types.hxx>
22 : #include <comphelper/propertysetinfo.hxx>
23 : #include <comphelper/genericpropertyset.hxx>
24 : #include <osl/diagnose.h>
25 : #include <com/sun/star/sdbc/XConnection.hpp>
26 : #include <com/sun/star/ucb/XContent.hpp>
27 : #include <com/sun/star/beans/PropertyAttribute.hpp>
28 : #include <tools/urlobj.hxx>
29 :
30 : //........................................................................
31 : namespace svx
32 : {
33 : //........................................................................
34 :
35 : using namespace ::com::sun::star::uno;
36 : using namespace ::com::sun::star::sdbc;
37 : using namespace ::com::sun::star::beans;
38 : using namespace ::com::sun::star::ucb;
39 : using namespace ::comphelper;
40 :
41 : #define CONST_CHAR( propname ) propname, sizeof(propname) - 1
42 :
43 : //====================================================================
44 : //= ODADescriptorImpl
45 : //====================================================================
46 0 : class ODADescriptorImpl
47 : {
48 : protected:
49 : sal_Bool m_bSetOutOfDate : 1;
50 : sal_Bool m_bSequenceOutOfDate : 1;
51 :
52 : public:
53 : typedef ::std::map< DataAccessDescriptorProperty, Any > DescriptorValues;
54 : DescriptorValues m_aValues;
55 : Sequence< PropertyValue > m_aAsSequence;
56 : Reference< XPropertySet > m_xAsSet;
57 :
58 : typedef ::std::map< ::rtl::OUString, PropertyMapEntry* > MapString2PropertyEntry;
59 :
60 : public:
61 : ODADescriptorImpl();
62 : ODADescriptorImpl(const ODADescriptorImpl& _rSource);
63 :
64 : void invalidateExternRepresentations();
65 :
66 : void updateSequence();
67 :
68 : /** builds the descriptor from a property value sequence
69 : @return <TRUE/>
70 : if and only if the sequence contained valid properties only
71 : */
72 : sal_Bool buildFrom( const Sequence< PropertyValue >& _rValues );
73 :
74 : /** builds the descriptor from a property set
75 : @return <TRUE/>
76 : if and only if the set contained valid properties only
77 : */
78 : sal_Bool buildFrom( const Reference< XPropertySet >& _rValues );
79 :
80 : protected:
81 : static PropertyValue buildPropertyValue( const DescriptorValues::const_iterator& _rPos );
82 : static const MapString2PropertyEntry& getPropertyMap( );
83 : static PropertyMapEntry* getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos );
84 : };
85 :
86 : //--------------------------------------------------------------------
87 0 : ODADescriptorImpl::ODADescriptorImpl()
88 : :m_bSetOutOfDate(sal_True)
89 0 : ,m_bSequenceOutOfDate(sal_True)
90 : {
91 0 : }
92 :
93 : //--------------------------------------------------------------------
94 0 : ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl& _rSource)
95 : :m_bSetOutOfDate( _rSource.m_bSetOutOfDate )
96 : ,m_bSequenceOutOfDate( _rSource.m_bSequenceOutOfDate )
97 0 : ,m_aValues( _rSource.m_aValues )
98 : {
99 0 : if (!m_bSetOutOfDate)
100 0 : m_xAsSet = _rSource.m_xAsSet;
101 0 : if (!m_bSequenceOutOfDate)
102 0 : m_aAsSequence = _rSource.m_aAsSequence;
103 0 : }
104 :
105 : //--------------------------------------------------------------------
106 0 : sal_Bool ODADescriptorImpl::buildFrom( const Sequence< PropertyValue >& _rValues )
107 : {
108 0 : const MapString2PropertyEntry& rProperties = getPropertyMap();
109 :
110 0 : sal_Bool bValidPropsOnly = sal_True;
111 :
112 : // loop through the sequence, and fill our m_aValues
113 0 : const PropertyValue* pValues = _rValues.getConstArray();
114 0 : const PropertyValue* pValuesEnd = pValues + _rValues.getLength();
115 0 : for (;pValues != pValuesEnd; ++pValues)
116 : {
117 0 : MapString2PropertyEntry::const_iterator aPropPos = rProperties.find( pValues->Name );
118 0 : if ( aPropPos != rProperties.end() )
119 : {
120 0 : DataAccessDescriptorProperty eProperty = (DataAccessDescriptorProperty)aPropPos->second->mnHandle;
121 0 : m_aValues[eProperty] = pValues->Value;
122 : }
123 : else
124 : // unknown property
125 0 : bValidPropsOnly = sal_False;
126 : }
127 :
128 0 : if (bValidPropsOnly)
129 : {
130 0 : m_aAsSequence = _rValues;
131 0 : m_bSequenceOutOfDate = sal_False;
132 : }
133 : else
134 0 : m_bSequenceOutOfDate = sal_True;
135 :
136 0 : return bValidPropsOnly;
137 : }
138 :
139 : //--------------------------------------------------------------------
140 0 : sal_Bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues )
141 : {
142 0 : Reference< XPropertySetInfo > xPropInfo;
143 0 : if (_rxValues.is())
144 0 : xPropInfo = _rxValues->getPropertySetInfo();
145 0 : if (!xPropInfo.is())
146 : {
147 : OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
148 0 : return sal_False;
149 : }
150 :
151 : // build a PropertyValue sequence with the current values
152 0 : Sequence< Property > aProperties = xPropInfo->getProperties();
153 0 : const Property* pProperty = aProperties.getConstArray();
154 0 : const Property* pPropertyEnd = pProperty + aProperties.getLength();
155 :
156 0 : Sequence< PropertyValue > aValues(aProperties.getLength());
157 0 : PropertyValue* pValues = aValues.getArray();
158 :
159 0 : for (;pProperty != pPropertyEnd; ++pProperty, ++pValues)
160 : {
161 0 : pValues->Name = pProperty->Name;
162 0 : pValues->Value = _rxValues->getPropertyValue(pProperty->Name);
163 : }
164 :
165 0 : sal_Bool bValidPropsOnly = buildFrom(aValues);
166 0 : if (bValidPropsOnly)
167 : {
168 0 : m_xAsSet = _rxValues;
169 0 : m_bSetOutOfDate = sal_False;
170 : }
171 : else
172 0 : m_bSetOutOfDate = sal_True;
173 :
174 0 : return bValidPropsOnly;
175 : }
176 :
177 : //--------------------------------------------------------------------
178 0 : void ODADescriptorImpl::invalidateExternRepresentations()
179 : {
180 0 : m_bSetOutOfDate = sal_True;
181 0 : m_bSequenceOutOfDate = sal_True;
182 0 : }
183 :
184 : //--------------------------------------------------------------------
185 0 : const ODADescriptorImpl::MapString2PropertyEntry& ODADescriptorImpl::getPropertyMap( )
186 : {
187 : // the properties we know
188 0 : static MapString2PropertyEntry s_aProperties;
189 0 : if ( s_aProperties.empty() )
190 : {
191 : static PropertyMapEntry s_aDesriptorProperties[] =
192 : {
193 0 : { CONST_CHAR("ActiveConnection"), daConnection, &::getCppuType( static_cast< Reference< XConnection >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
194 0 : { CONST_CHAR("BookmarkSelection"), daBookmarkSelection, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT, 0 },
195 0 : { CONST_CHAR("Column"), daColumnObject, &::getCppuType( static_cast< Reference< XPropertySet >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
196 0 : { CONST_CHAR("ColumnName"), daColumnName, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
197 0 : { CONST_CHAR("Command"), daCommand, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
198 0 : { CONST_CHAR("CommandType"), daCommandType, &::getCppuType( static_cast< sal_Int32* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
199 0 : { CONST_CHAR("Component"), daComponent, &::getCppuType( static_cast< Reference< XContent >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
200 0 : { CONST_CHAR("ConnectionResource"), daConnectionResource, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
201 0 : { CONST_CHAR("Cursor"), daCursor, &::getCppuType( static_cast< Reference< XResultSet>* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
202 0 : { CONST_CHAR("DataSourceName"), daDataSource, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
203 0 : { CONST_CHAR("DatabaseLocation"), daDatabaseLocation, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
204 0 : { CONST_CHAR("EscapeProcessing"), daEscapeProcessing, &::getBooleanCppuType( ), PropertyAttribute::TRANSIENT, 0 },
205 0 : { CONST_CHAR("Filter"), daFilter, &::getCppuType( static_cast< ::rtl::OUString* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
206 0 : { CONST_CHAR("Selection"), daSelection, &::getCppuType( static_cast< Sequence< Any >* >(NULL) ), PropertyAttribute::TRANSIENT, 0 },
207 : { NULL, 0, 0, NULL, 0, 0 }
208 0 : };
209 :
210 0 : PropertyMapEntry* pEntry = s_aDesriptorProperties;
211 0 : while ( pEntry->mpName )
212 : {
213 0 : s_aProperties[ ::rtl::OUString::createFromAscii( pEntry->mpName ) ] = pEntry;
214 0 : ++pEntry;
215 : }
216 : }
217 :
218 0 : return s_aProperties;
219 : }
220 :
221 : //--------------------------------------------------------------------
222 0 : PropertyMapEntry* ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos )
223 : {
224 0 : const MapString2PropertyEntry& rProperties = getPropertyMap();
225 :
226 0 : sal_Int32 nNeededHandle = (sal_Int32)(_rPos->first);
227 :
228 0 : for ( MapString2PropertyEntry::const_iterator loop = rProperties.begin();
229 0 : loop != rProperties.end();
230 : ++loop
231 : )
232 : {
233 0 : if ( nNeededHandle == loop->second->mnHandle )
234 0 : return loop->second;
235 : }
236 0 : throw RuntimeException();
237 : }
238 :
239 : //--------------------------------------------------------------------
240 0 : PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos )
241 : {
242 : // the map entry
243 0 : PropertyMapEntry* pProperty = getPropertyMapEntry( _rPos );
244 :
245 : // build the property value
246 0 : PropertyValue aReturn;
247 0 : aReturn.Name = ::rtl::OUString( pProperty->mpName, pProperty->mnNameLen, RTL_TEXTENCODING_ASCII_US );
248 0 : aReturn.Handle = pProperty->mnHandle;
249 0 : aReturn.Value = _rPos->second;
250 0 : aReturn.State = PropertyState_DIRECT_VALUE;
251 :
252 : // outta here
253 0 : return aReturn;
254 : }
255 :
256 : //--------------------------------------------------------------------
257 0 : void ODADescriptorImpl::updateSequence()
258 : {
259 0 : if (!m_bSequenceOutOfDate)
260 0 : return;
261 :
262 0 : m_aAsSequence.realloc(m_aValues.size());
263 0 : PropertyValue* pValue = m_aAsSequence.getArray();
264 :
265 : // loop through all our values
266 0 : for ( DescriptorValues::const_iterator aLoop = m_aValues.begin();
267 0 : aLoop != m_aValues.end();
268 : ++aLoop, ++pValue
269 : )
270 : {
271 0 : *pValue = buildPropertyValue(aLoop);
272 : }
273 :
274 : // don't need to rebuild next time
275 0 : m_bSequenceOutOfDate = sal_False;
276 : }
277 :
278 : //====================================================================
279 : //= ODataAccessDescriptor
280 : //====================================================================
281 : //--------------------------------------------------------------------
282 0 : ODataAccessDescriptor::ODataAccessDescriptor()
283 0 : :m_pImpl(new ODADescriptorImpl)
284 : {
285 0 : }
286 :
287 : //--------------------------------------------------------------------
288 0 : ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor& _rSource )
289 0 : :m_pImpl(new ODADescriptorImpl(*_rSource.m_pImpl))
290 : {
291 0 : }
292 :
293 : //--------------------------------------------------------------------
294 0 : const ODataAccessDescriptor& ODataAccessDescriptor::operator=(const ODataAccessDescriptor& _rSource)
295 : {
296 0 : delete m_pImpl;
297 0 : m_pImpl = new ODADescriptorImpl(*_rSource.m_pImpl);
298 0 : return *this;
299 : }
300 :
301 : //--------------------------------------------------------------------
302 0 : ODataAccessDescriptor::ODataAccessDescriptor( const Reference< XPropertySet >& _rValues )
303 0 : :m_pImpl(new ODADescriptorImpl)
304 : {
305 0 : m_pImpl->buildFrom(_rValues);
306 0 : }
307 :
308 : //--------------------------------------------------------------------
309 0 : ODataAccessDescriptor::ODataAccessDescriptor( const Any& _rValues )
310 0 : :m_pImpl(new ODADescriptorImpl)
311 : {
312 : // check if we know the format in the Any
313 0 : Sequence< PropertyValue > aValues;
314 0 : Reference< XPropertySet > xValues;
315 0 : if ( _rValues >>= aValues )
316 0 : m_pImpl->buildFrom( aValues );
317 0 : else if ( _rValues >>= xValues )
318 0 : m_pImpl->buildFrom( xValues );
319 0 : }
320 :
321 : //--------------------------------------------------------------------
322 0 : ODataAccessDescriptor::ODataAccessDescriptor( const Sequence< PropertyValue >& _rValues )
323 0 : :m_pImpl(new ODADescriptorImpl)
324 : {
325 0 : m_pImpl->buildFrom(_rValues);
326 0 : }
327 :
328 : //--------------------------------------------------------------------
329 0 : ODataAccessDescriptor::~ODataAccessDescriptor()
330 : {
331 0 : delete m_pImpl;
332 0 : }
333 :
334 : //--------------------------------------------------------------------
335 0 : void ODataAccessDescriptor::clear()
336 : {
337 0 : m_pImpl->m_aValues.clear();
338 0 : }
339 :
340 : //--------------------------------------------------------------------
341 0 : void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich)
342 : {
343 : OSL_ENSURE(has(_eWhich), "ODataAccessDescriptor::erase: invalid call!");
344 0 : if (has(_eWhich))
345 0 : m_pImpl->m_aValues.erase(_eWhich);
346 0 : }
347 :
348 : //--------------------------------------------------------------------
349 0 : sal_Bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich) const
350 : {
351 0 : return m_pImpl->m_aValues.find(_eWhich) != m_pImpl->m_aValues.end();
352 : }
353 :
354 : //--------------------------------------------------------------------
355 0 : const Any& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich ) const
356 : {
357 0 : if (!has(_eWhich))
358 : {
359 : OSL_FAIL("ODataAccessDescriptor::operator[]: invalid acessor!");
360 0 : static const Any aDummy;
361 0 : return aDummy;
362 : }
363 :
364 0 : return m_pImpl->m_aValues[_eWhich];
365 : }
366 :
367 : //--------------------------------------------------------------------
368 0 : Any& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich )
369 : {
370 0 : m_pImpl->invalidateExternRepresentations();
371 0 : return m_pImpl->m_aValues[_eWhich];
372 : }
373 :
374 : //--------------------------------------------------------------------
375 0 : void ODataAccessDescriptor::initializeFrom(const Sequence< PropertyValue >& _rValues, sal_Bool _bClear)
376 : {
377 0 : if (_bClear)
378 0 : clear();
379 0 : m_pImpl->buildFrom(_rValues);
380 0 : }
381 :
382 : //--------------------------------------------------------------------
383 0 : Sequence< PropertyValue > ODataAccessDescriptor::createPropertyValueSequence()
384 : {
385 0 : m_pImpl->updateSequence();
386 0 : return m_pImpl->m_aAsSequence;
387 : }
388 :
389 : //--------------------------------------------------------------------
390 0 : ::rtl::OUString ODataAccessDescriptor::getDataSource() const
391 : {
392 0 : ::rtl::OUString sDataSourceName;
393 0 : if ( has(daDataSource) )
394 0 : (*this)[daDataSource] >>= sDataSourceName;
395 0 : else if ( has(daDatabaseLocation) )
396 0 : (*this)[daDatabaseLocation] >>= sDataSourceName;
397 0 : return sDataSourceName;
398 : }
399 : //--------------------------------------------------------------------
400 0 : void ODataAccessDescriptor::setDataSource(const ::rtl::OUString& _sDataSourceNameOrLocation)
401 : {
402 0 : if ( !_sDataSourceNameOrLocation.isEmpty() )
403 : {
404 0 : INetURLObject aURL(_sDataSourceNameOrLocation);
405 0 : (*this)[ (( aURL.GetProtocol() == INET_PROT_FILE ) ? daDatabaseLocation : daDataSource)] <<= _sDataSourceNameOrLocation;
406 : }
407 : else
408 0 : (*this)[ daDataSource ] <<= ::rtl::OUString();
409 0 : }
410 :
411 : //........................................................................
412 : } // namespace svx
413 : //........................................................................
414 :
415 :
416 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|