Coverage Report

Created: 2026-02-14 09:37

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/svx/source/form/dataaccessdescriptor.cxx
Line
Count
Source
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 <osl/diagnose.h>
22
#include <com/sun/star/ucb/XContent.hpp>
23
#include <com/sun/star/beans/PropertyValue.hpp>
24
#include <com/sun/star/beans/XPropertySet.hpp>
25
#include <tools/urlobj.hxx>
26
#include <map>
27
28
namespace svx
29
{
30
    using namespace ::com::sun::star::uno;
31
    using namespace ::com::sun::star::beans;
32
33
    typedef std::pair<OUString const, DataAccessDescriptorProperty> PropertyMapEntry;
34
35
    class ODADescriptorImpl
36
    {
37
    protected:
38
        bool                    m_bSetOutOfDate         : 1;
39
        bool                    m_bSequenceOutOfDate    : 1;
40
41
    public:
42
        typedef ::std::map< DataAccessDescriptorProperty, Any >     DescriptorValues;
43
        DescriptorValues            m_aValues;
44
        Sequence< PropertyValue >   m_aAsSequence;
45
46
        typedef ::std::map< OUString, DataAccessDescriptorProperty >    MapString2PropertyEntry;
47
48
    public:
49
        ODADescriptorImpl();
50
        ODADescriptorImpl(const ODADescriptorImpl& _rSource);
51
52
        void invalidateExternRepresentations();
53
54
        void updateSequence();
55
56
        /** builds the descriptor from a property value sequence
57
            @return <TRUE/>
58
                if and only if the sequence contained valid properties only
59
        */
60
        bool buildFrom( const Sequence< PropertyValue >& _rValues );
61
62
        /** builds the descriptor from a property set
63
            @return <TRUE/>
64
                if and only if the set contained valid properties only
65
        */
66
        bool buildFrom( const Reference< XPropertySet >& _rValues );
67
68
    protected:
69
        static PropertyValue                    buildPropertyValue( const DescriptorValues::const_iterator& _rPos );
70
        static const MapString2PropertyEntry&   getPropertyMap( );
71
        static PropertyMapEntry const *         getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos );
72
    };
73
74
    ODADescriptorImpl::ODADescriptorImpl()
75
550
        :m_bSetOutOfDate(true)
76
550
        ,m_bSequenceOutOfDate(true)
77
550
    {
78
550
    }
79
80
    ODADescriptorImpl::ODADescriptorImpl(const ODADescriptorImpl& _rSource)
81
0
        :m_bSetOutOfDate( _rSource.m_bSetOutOfDate )
82
0
        ,m_bSequenceOutOfDate( _rSource.m_bSequenceOutOfDate )
83
0
        ,m_aValues( _rSource.m_aValues )
84
0
    {
85
0
        if (!m_bSequenceOutOfDate)
86
0
            m_aAsSequence = _rSource.m_aAsSequence;
87
0
    }
88
89
    bool ODADescriptorImpl::buildFrom( const Sequence< PropertyValue >& _rValues )
90
0
    {
91
0
        const MapString2PropertyEntry& rProperties = getPropertyMap();
92
93
0
        bool bValidPropsOnly = true;
94
95
        // loop through the sequence, and fill our m_aValues
96
0
        for (const PropertyValue& rValue : _rValues)
97
0
        {
98
0
            MapString2PropertyEntry::const_iterator aPropPos = rProperties.find( rValue.Name );
99
0
            if ( aPropPos != rProperties.end() )
100
0
            {
101
0
                DataAccessDescriptorProperty eProperty = aPropPos->second;
102
0
                m_aValues[eProperty] = rValue.Value;
103
0
            }
104
0
            else
105
                // unknown property
106
0
                bValidPropsOnly = false;
107
0
        }
108
109
0
        if (bValidPropsOnly)
110
0
        {
111
0
            m_aAsSequence = _rValues;
112
0
            m_bSequenceOutOfDate = false;
113
0
        }
114
0
        else
115
0
            m_bSequenceOutOfDate = true;
116
117
0
        return bValidPropsOnly;
118
0
    }
119
120
    bool ODADescriptorImpl::buildFrom( const Reference< XPropertySet >& _rxValues )
121
0
    {
122
0
        Reference< XPropertySetInfo > xPropInfo;
123
0
        if (_rxValues.is())
124
0
            xPropInfo = _rxValues->getPropertySetInfo();
125
0
        if (!xPropInfo.is())
126
0
        {
127
0
            OSL_FAIL("ODADescriptorImpl::buildFrom: invalid property set!");
128
0
            return false;
129
0
        }
130
131
        // build a PropertyValue sequence with the current values
132
0
        const Sequence< Property > aProperties = xPropInfo->getProperties();
133
134
0
        Sequence< PropertyValue > aValues(aProperties.getLength());
135
0
        PropertyValue* pValues = aValues.getArray();
136
137
0
        for (const Property& rProperty : aProperties)
138
0
        {
139
0
            pValues->Name = rProperty.Name;
140
0
            pValues->Value = _rxValues->getPropertyValue(rProperty.Name);
141
0
            ++pValues;
142
0
        }
143
144
0
        bool bValidPropsOnly = buildFrom(aValues);
145
0
        m_bSetOutOfDate = !bValidPropsOnly;
146
147
0
        return bValidPropsOnly;
148
0
    }
149
150
    void ODADescriptorImpl::invalidateExternRepresentations()
151
226
    {
152
226
        m_bSetOutOfDate = true;
153
226
        m_bSequenceOutOfDate = true;
154
226
    }
155
156
    const ODADescriptorImpl::MapString2PropertyEntry& ODADescriptorImpl::getPropertyMap( )
157
0
    {
158
        // the properties we know
159
0
        static MapString2PropertyEntry s_aProperties
160
0
            {
161
0
                { u"ActiveConnection"_ustr,   DataAccessDescriptorProperty::Connection,            },
162
0
                { u"BookmarkSelection"_ustr,  DataAccessDescriptorProperty::BookmarkSelection,     },
163
0
                { u"Column"_ustr,             DataAccessDescriptorProperty::ColumnObject,          },
164
0
                { u"ColumnName"_ustr,         DataAccessDescriptorProperty::ColumnName,            },
165
0
                { u"Command"_ustr,            DataAccessDescriptorProperty::Command,               },
166
0
                { u"CommandType"_ustr,        DataAccessDescriptorProperty::CommandType,           },
167
0
                { u"Component"_ustr,          DataAccessDescriptorProperty::Component,             },
168
0
                { u"ConnectionResource"_ustr, DataAccessDescriptorProperty::ConnectionResource,    },
169
0
                { u"Cursor"_ustr,             DataAccessDescriptorProperty::Cursor,                },
170
0
                { u"DataSourceName"_ustr,     DataAccessDescriptorProperty::DataSource,            },
171
0
                { u"DatabaseLocation"_ustr,   DataAccessDescriptorProperty::DatabaseLocation,      },
172
0
                { u"EscapeProcessing"_ustr,   DataAccessDescriptorProperty::EscapeProcessing,      },
173
0
                { u"Filter"_ustr,             DataAccessDescriptorProperty::Filter,                },
174
0
                { u"Selection"_ustr,          DataAccessDescriptorProperty::Selection,             }
175
0
            };
176
177
0
        return s_aProperties;
178
0
    }
179
180
    PropertyMapEntry const * ODADescriptorImpl::getPropertyMapEntry( const DescriptorValues::const_iterator& _rPos )
181
0
    {
182
0
        const MapString2PropertyEntry& rProperties = getPropertyMap();
183
184
0
        DataAccessDescriptorProperty nNeededHandle = _rPos->first;
185
186
0
        auto loop = std::find_if(rProperties.begin(), rProperties.end(),
187
0
            [&nNeededHandle](const MapString2PropertyEntry::value_type& rProp) { return nNeededHandle == rProp.second; });
188
0
        if (loop != rProperties.end())
189
0
            return &*loop;
190
0
        throw RuntimeException();
191
0
    }
192
193
    PropertyValue ODADescriptorImpl::buildPropertyValue( const DescriptorValues::const_iterator& _rPos )
194
0
    {
195
        // the map entry
196
0
        PropertyMapEntry const * pProperty = getPropertyMapEntry( _rPos );
197
198
        // build the property value
199
0
        PropertyValue aReturn;
200
0
        aReturn.Name    = pProperty->first;
201
0
        aReturn.Handle  = static_cast<sal_Int32>(pProperty->second);
202
0
        aReturn.Value   = _rPos->second;
203
0
        aReturn.State   = PropertyState_DIRECT_VALUE;
204
205
        // outta here
206
0
        return aReturn;
207
0
    }
208
209
    void ODADescriptorImpl::updateSequence()
210
0
    {
211
0
        if (!m_bSequenceOutOfDate)
212
0
            return;
213
214
0
        m_aAsSequence.realloc(m_aValues.size());
215
0
        PropertyValue* pValue = m_aAsSequence.getArray();
216
217
        // loop through all our values
218
0
        for (   DescriptorValues::const_iterator aLoop = m_aValues.begin();
219
0
                aLoop != m_aValues.end();
220
0
                ++aLoop, ++pValue
221
0
            )
222
0
        {
223
0
            *pValue = buildPropertyValue(aLoop);
224
0
        }
225
226
        // don't need to rebuild next time
227
0
        m_bSequenceOutOfDate = false;
228
0
    }
229
230
    ODataAccessDescriptor::ODataAccessDescriptor()
231
550
        :m_pImpl(new ODADescriptorImpl)
232
550
    {
233
550
    }
234
235
    ODataAccessDescriptor::ODataAccessDescriptor( const ODataAccessDescriptor& _rSource )
236
0
        :m_pImpl(new ODADescriptorImpl(*_rSource.m_pImpl))
237
0
    {
238
0
    }
239
240
    ODataAccessDescriptor::ODataAccessDescriptor(ODataAccessDescriptor&& _rSource) noexcept
241
0
        :m_pImpl(std::move(_rSource.m_pImpl))
242
0
    {
243
0
    }
244
245
    ODataAccessDescriptor& ODataAccessDescriptor::operator=(const ODataAccessDescriptor& _rSource)
246
0
    {
247
0
        if (this != &_rSource)
248
0
            m_pImpl.reset(new ODADescriptorImpl(*_rSource.m_pImpl));
249
0
        return *this;
250
0
    }
251
252
    ODataAccessDescriptor& ODataAccessDescriptor::operator=(ODataAccessDescriptor&& _rSource) noexcept
253
0
    {
254
0
        m_pImpl = std::move(_rSource.m_pImpl);
255
0
        return *this;
256
0
    }
257
258
    ODataAccessDescriptor::ODataAccessDescriptor( const Reference< XPropertySet >& _rValues )
259
0
        :m_pImpl(new ODADescriptorImpl)
260
0
    {
261
0
        m_pImpl->buildFrom(_rValues);
262
0
    }
263
264
    ODataAccessDescriptor::ODataAccessDescriptor( const Any& _rValues )
265
0
        :m_pImpl(new ODADescriptorImpl)
266
0
    {
267
        // check if we know the format in the Any
268
0
        Sequence< PropertyValue > aValues;
269
0
        Reference< XPropertySet > xValues;
270
0
        if ( _rValues >>= aValues )
271
0
            m_pImpl->buildFrom( aValues );
272
0
        else if ( _rValues >>= xValues )
273
0
            m_pImpl->buildFrom( xValues );
274
0
    }
275
276
    ODataAccessDescriptor::ODataAccessDescriptor( const Sequence< PropertyValue >& _rValues )
277
0
        :m_pImpl(new ODADescriptorImpl)
278
0
    {
279
0
        m_pImpl->buildFrom(_rValues);
280
0
    }
281
282
    ODataAccessDescriptor::~ODataAccessDescriptor()
283
550
    {
284
550
    }
285
286
    void ODataAccessDescriptor::clear()
287
0
    {
288
0
        m_pImpl->m_aValues.clear();
289
0
    }
290
291
    void ODataAccessDescriptor::erase(DataAccessDescriptorProperty _eWhich)
292
0
    {
293
0
        OSL_ENSURE(has(_eWhich), "ODataAccessDescriptor::erase: invalid call!");
294
0
        if (has(_eWhich))
295
0
            m_pImpl->m_aValues.erase(_eWhich);
296
0
    }
297
298
    bool ODataAccessDescriptor::has(DataAccessDescriptorProperty _eWhich) const
299
1.10k
    {
300
1.10k
        return m_pImpl->m_aValues.find(_eWhich) != m_pImpl->m_aValues.end();
301
1.10k
    }
302
303
    const Any& ODataAccessDescriptor::operator [] ( DataAccessDescriptorProperty _eWhich ) const
304
226
    {
305
226
        if (!has(_eWhich))
306
0
        {
307
0
            OSL_FAIL("ODataAccessDescriptor::operator[]: invalid accessor!");
308
0
            static const Any aDummy;
309
0
            return aDummy;
310
0
        }
311
312
226
        return m_pImpl->m_aValues[_eWhich];
313
226
    }
314
315
    Any& ODataAccessDescriptor::operator[] ( DataAccessDescriptorProperty _eWhich )
316
226
    {
317
226
        m_pImpl->invalidateExternRepresentations();
318
226
        return m_pImpl->m_aValues[_eWhich];
319
226
    }
320
321
    void ODataAccessDescriptor::initializeFrom(const Sequence< PropertyValue >& _rValues)
322
0
    {
323
0
        clear();
324
0
        m_pImpl->buildFrom(_rValues);
325
0
    }
326
327
    Sequence< PropertyValue > const & ODataAccessDescriptor::createPropertyValueSequence()
328
0
    {
329
0
        m_pImpl->updateSequence();
330
0
        return m_pImpl->m_aAsSequence;
331
0
    }
332
333
    OUString ODataAccessDescriptor::getDataSource() const
334
550
    {
335
550
        OUString sDataSourceName;
336
550
        if ( has(DataAccessDescriptorProperty::DataSource) )
337
226
            (*this)[DataAccessDescriptorProperty::DataSource] >>= sDataSourceName;
338
324
        else if ( has(DataAccessDescriptorProperty::DatabaseLocation) )
339
0
            (*this)[DataAccessDescriptorProperty::DatabaseLocation] >>= sDataSourceName;
340
550
        return sDataSourceName;
341
550
    }
342
343
    void ODataAccessDescriptor::setDataSource(const OUString& _sDataSourceNameOrLocation)
344
0
    {
345
0
        if ( !_sDataSourceNameOrLocation.isEmpty() )
346
0
        {
347
0
            INetURLObject aURL(_sDataSourceNameOrLocation);
348
0
            (*this)[ (( aURL.GetProtocol() == INetProtocol::File ) ? DataAccessDescriptorProperty::DatabaseLocation : DataAccessDescriptorProperty::DataSource)] <<= _sDataSourceNameOrLocation;
349
0
        }
350
0
        else
351
0
            (*this)[ DataAccessDescriptorProperty::DataSource ] <<= OUString();
352
0
    }
353
}
354
355
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */