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 <xmloff/xmlprmap.hxx>
21 : #include <xmloff/xmlprhdl.hxx>
22 : #include <xmloff/xmltypes.hxx>
23 : #include <xmloff/xmltoken.hxx>
24 : #include <xmloff/maptype.hxx>
25 : #include <xmloff/prhdlfac.hxx>
26 : #include <tools/debug.hxx>
27 :
28 : #include "xmlbahdl.hxx"
29 :
30 : #include <com/sun/star/beans/XPropertySet.hpp>
31 : #include <com/sun/star/beans/XPropertyState.hpp>
32 : #include <com/sun/star/uno/Any.hxx>
33 : #include <com/sun/star/uno/Sequence.hxx>
34 :
35 : #include <vector>
36 :
37 : using namespace ::std;
38 :
39 : using namespace ::com::sun::star::uno;
40 : using namespace ::com::sun::star::beans;
41 : using ::xmloff::token::GetXMLToken;
42 :
43 : /** Helper-class for XML-im/export:
44 : - Holds a pointer to a given array of XMLPropertyMapEntry
45 : - Provides several methods to access data from this array
46 : - Holds a Sequence of XML-names (for properties)
47 : - The filter takes all properties of the XPropertySet which are also
48 : in the XMLPropertyMapEntry and which are have not a default value
49 : and put them into a vector of XMLPropertyStae
50 : - this class knows how to compare, im/export properties
51 :
52 : Attention: At all methods, which get an index as parameter, there is no
53 : range validation to save runtime !!
54 : */
55 13989799 : struct XMLPropertySetMapperEntry_Impl
56 : {
57 : OUString sXMLAttributeName;
58 : OUString sAPIPropertyName;
59 : sal_Int32 nType;
60 : sal_uInt16 nXMLNameSpace;
61 : sal_Int16 nContextId;
62 : SvtSaveOptions::ODFDefaultVersion nEarliestODFVersionForExport;
63 : bool bImportOnly;
64 : const XMLPropertyHandler *pHdl;
65 :
66 : XMLPropertySetMapperEntry_Impl(
67 : const XMLPropertyMapEntry& rMapEntry,
68 : const rtl::Reference< XMLPropertyHandlerFactory >& rFactory );
69 :
70 : XMLPropertySetMapperEntry_Impl(
71 : const XMLPropertySetMapperEntry_Impl& rEntry );
72 :
73 17420313 : sal_uInt32 GetPropType() const { return nType & XML_TYPE_PROP_MASK; }
74 : };
75 :
76 3318180 : XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
77 : const XMLPropertyMapEntry& rMapEntry,
78 : const rtl::Reference< XMLPropertyHandlerFactory >& rFactory ) :
79 3318180 : sXMLAttributeName( GetXMLToken(rMapEntry.meXMLName) ),
80 : sAPIPropertyName( OUString(rMapEntry.msApiName, rMapEntry.nApiNameLength,
81 : RTL_TEXTENCODING_ASCII_US ) ),
82 : nType( rMapEntry.mnType ),
83 : nXMLNameSpace( rMapEntry.mnNameSpace ),
84 : nContextId( rMapEntry.mnContextId ),
85 : nEarliestODFVersionForExport( rMapEntry.mnEarliestODFVersionForExport ),
86 : bImportOnly( rMapEntry.mbImportOnly),
87 3318180 : pHdl( rFactory->GetPropertyHandler( rMapEntry.mnType & MID_FLAG_MASK ) )
88 : {
89 : assert(pHdl);
90 3318180 : }
91 :
92 10647416 : XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
93 : const XMLPropertySetMapperEntry_Impl& rEntry ) :
94 : sXMLAttributeName( rEntry.sXMLAttributeName),
95 : sAPIPropertyName( rEntry.sAPIPropertyName),
96 : nType( rEntry.nType),
97 : nXMLNameSpace( rEntry.nXMLNameSpace),
98 : nContextId( rEntry.nContextId),
99 : nEarliestODFVersionForExport( rEntry.nEarliestODFVersionForExport ),
100 : bImportOnly( rEntry.bImportOnly),
101 10647416 : pHdl( rEntry.pHdl)
102 : {
103 : assert(pHdl);
104 10647416 : }
105 :
106 35567 : struct XMLPropertySetMapper::Impl
107 : {
108 : std::vector<XMLPropertySetMapperEntry_Impl> maMapEntries;
109 : std::vector<rtl::Reference <XMLPropertyHandlerFactory> > maHdlFactories;
110 :
111 : bool mbOnlyExportMappings;
112 :
113 35577 : explicit Impl( bool bForExport ) : mbOnlyExportMappings(bForExport) {}
114 : };
115 :
116 : // Ctor
117 35577 : XMLPropertySetMapper::XMLPropertySetMapper(
118 : const XMLPropertyMapEntry* pEntries, const rtl::Reference<XMLPropertyHandlerFactory>& rFactory,
119 : bool bForExport ) :
120 35577 : mpImpl(new Impl(bForExport))
121 : {
122 35577 : mpImpl->maHdlFactories.push_back(rFactory);
123 35577 : if( pEntries )
124 : {
125 35577 : const XMLPropertyMapEntry* pIter = pEntries;
126 :
127 35577 : if (mpImpl->mbOnlyExportMappings)
128 : {
129 1414753 : while( pIter->msApiName )
130 : {
131 1387273 : if (!pIter->mbImportOnly)
132 : {
133 1314672 : XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
134 1314672 : mpImpl->maMapEntries.push_back( aEntry );
135 : }
136 1387273 : pIter++;
137 : }
138 : }
139 : else
140 : {
141 2047182 : while( pIter->msApiName )
142 : {
143 2003508 : XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
144 2003508 : mpImpl->maMapEntries.push_back( aEntry );
145 2003508 : pIter++;
146 2003508 : }
147 : }
148 : }
149 35577 : }
150 :
151 77801 : XMLPropertySetMapper::~XMLPropertySetMapper()
152 : {
153 35567 : delete mpImpl;
154 42234 : }
155 :
156 7796 : void XMLPropertySetMapper::AddMapperEntry(
157 : const rtl::Reference < XMLPropertySetMapper >& rMapper )
158 : {
159 51000 : for( vector < rtl::Reference < XMLPropertyHandlerFactory > >::iterator
160 7796 : aFIter = rMapper->mpImpl->maHdlFactories.begin();
161 34000 : aFIter != rMapper->mpImpl->maHdlFactories.end();
162 : ++aFIter )
163 : {
164 9204 : mpImpl->maHdlFactories.push_back(*aFIter);
165 : }
166 :
167 3371520 : for( vector < XMLPropertySetMapperEntry_Impl >::iterator
168 7796 : aEIter = rMapper->mpImpl->maMapEntries.begin();
169 2247680 : aEIter != rMapper->mpImpl->maMapEntries.end();
170 : ++aEIter )
171 : {
172 1116044 : if (!mpImpl->mbOnlyExportMappings || !(*aEIter).bImportOnly)
173 1116044 : mpImpl->maMapEntries.push_back( *aEIter );
174 : }
175 7796 : }
176 :
177 645717 : sal_Int32 XMLPropertySetMapper::GetEntryCount() const
178 : {
179 645717 : return mpImpl->maMapEntries.size();
180 : }
181 :
182 3076029 : sal_uInt32 XMLPropertySetMapper::GetEntryFlags( sal_Int32 nIndex ) const
183 : {
184 : assert((0 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
185 3076029 : return mpImpl->maMapEntries[nIndex].nType & ~MID_FLAG_MASK;
186 : }
187 :
188 17448 : sal_uInt32 XMLPropertySetMapper::GetEntryType( sal_Int32 nIndex, bool bWithFlags ) const
189 : {
190 : assert((0 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
191 17448 : sal_uInt32 nType = mpImpl->maMapEntries[nIndex].nType;
192 17448 : if( !bWithFlags )
193 0 : nType = nType & MID_FLAG_MASK;
194 17448 : return nType;
195 : }
196 :
197 63518 : sal_uInt16 XMLPropertySetMapper::GetEntryNameSpace( sal_Int32 nIndex ) const
198 : {
199 : assert((0 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
200 63518 : return mpImpl->maMapEntries[nIndex].nXMLNameSpace;
201 : }
202 :
203 63518 : const OUString& XMLPropertySetMapper::GetEntryXMLName( sal_Int32 nIndex ) const
204 : {
205 : assert((0 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
206 63518 : return mpImpl->maMapEntries[nIndex].sXMLAttributeName;
207 : }
208 :
209 3496646 : const OUString& XMLPropertySetMapper::GetEntryAPIName( sal_Int32 nIndex ) const
210 : {
211 : assert((0 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
212 3496646 : return mpImpl->maMapEntries[nIndex].sAPIPropertyName;
213 : }
214 :
215 1105793 : sal_Int16 XMLPropertySetMapper::GetEntryContextId( sal_Int32 nIndex ) const
216 : {
217 : assert((-1 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
218 1105793 : return nIndex == -1 ? 0 : mpImpl->maMapEntries[nIndex].nContextId;
219 : }
220 :
221 566905 : SvtSaveOptions::ODFDefaultVersion XMLPropertySetMapper::GetEarliestODFVersionForExport( sal_Int32 nIndex ) const
222 : {
223 : assert((-1 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
224 566905 : return nIndex == -1 ? SvtSaveOptions::ODFVER_UNKNOWN : mpImpl->maMapEntries[nIndex].nEarliestODFVersionForExport;
225 : }
226 :
227 220316 : const XMLPropertyHandler* XMLPropertySetMapper::GetPropertyHandler( sal_Int32 nIndex ) const
228 : {
229 : assert((0 <= nIndex) && (nIndex < static_cast<sal_Int32>(mpImpl->maMapEntries.size())));
230 220316 : return mpImpl->maMapEntries[nIndex].pHdl;
231 : }
232 :
233 : // Export a Property
234 58528 : bool XMLPropertySetMapper::exportXML(
235 : OUString& rStrExpValue,
236 : const XMLPropertyState& rProperty,
237 : const SvXMLUnitConverter& rUnitConverter ) const
238 : {
239 58528 : bool bRet = false;
240 :
241 58528 : const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
242 :
243 : assert(pHdl);
244 58528 : if( pHdl )
245 : bRet = pHdl->exportXML( rStrExpValue, rProperty.maValue,
246 58528 : rUnitConverter );
247 :
248 58528 : return bRet;
249 : }
250 :
251 : // Import a Property
252 152766 : bool XMLPropertySetMapper::importXML(
253 : const OUString& rStrImpValue,
254 : XMLPropertyState& rProperty,
255 : const SvXMLUnitConverter& rUnitConverter ) const
256 : {
257 152766 : bool bRet = false;
258 :
259 152766 : const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
260 :
261 152766 : if( pHdl )
262 : bRet = pHdl->importXML( rStrImpValue, rProperty.maValue,
263 152766 : rUnitConverter );
264 :
265 152766 : return bRet;
266 : }
267 :
268 : // Search for the given name and the namespace in the list and return
269 : // the index of the entry
270 : // If there is no matching entry the method returns -1
271 184458 : sal_Int32 XMLPropertySetMapper::GetEntryIndex(
272 : sal_uInt16 nNamespace,
273 : const OUString& rStrName,
274 : sal_uInt32 nPropType,
275 : sal_Int32 nStartAt /* = -1 */ ) const
276 : {
277 184458 : sal_Int32 nEntries = GetEntryCount();
278 184458 : sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;
279 :
280 184458 : if ( nEntries && nIndex < nEntries )
281 : {
282 17259821 : do
283 : {
284 17425378 : const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
285 42116165 : if( (!nPropType || nPropType == rEntry.GetPropType()) &&
286 28050944 : rEntry.nXMLNameSpace == nNamespace &&
287 3355092 : rStrName == rEntry.sXMLAttributeName )
288 165557 : return nIndex;
289 : else
290 17259821 : nIndex++;
291 :
292 : } while( nIndex<nEntries );
293 : }
294 :
295 18901 : return -1;
296 : }
297 :
298 : /** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
299 1190 : sal_Int32 XMLPropertySetMapper::FindEntryIndex(
300 : const sal_Char* sApiName,
301 : sal_uInt16 nNameSpace,
302 : const OUString& sXMLName ) const
303 : {
304 1190 : sal_Int32 nIndex = 0;
305 1190 : sal_Int32 nEntries = GetEntryCount();
306 :
307 100371 : do
308 : {
309 101561 : const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
310 271340 : if( rEntry.nXMLNameSpace == nNameSpace &&
311 103816 : rEntry.sXMLAttributeName.equals( sXMLName ) &&
312 2255 : rEntry.sAPIPropertyName.equalsAscii( sApiName ) )
313 1190 : return nIndex;
314 : else
315 100371 : nIndex++;
316 :
317 : } while( nIndex < nEntries );
318 :
319 0 : return -1;
320 : }
321 :
322 6377 : sal_Int32 XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId ) const
323 : {
324 6377 : const sal_Int32 nEntries = GetEntryCount();
325 :
326 6377 : if ( nEntries )
327 : {
328 6377 : sal_Int32 nIndex = 0;
329 419276 : do
330 : {
331 425653 : const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
332 425653 : if( rEntry.nContextId == nContextId )
333 6377 : return nIndex;
334 : else
335 419276 : nIndex++;
336 :
337 : } while( nIndex < nEntries );
338 : }
339 :
340 0 : return -1;
341 : }
342 :
343 86 : void XMLPropertySetMapper::RemoveEntry( sal_Int32 nIndex )
344 : {
345 86 : const sal_Int32 nEntries = GetEntryCount();
346 86 : if( nIndex>=nEntries || nIndex<0 )
347 86 : return;
348 86 : vector < XMLPropertySetMapperEntry_Impl >::iterator aEIter = mpImpl->maMapEntries.begin();
349 13330 : for( sal_Int32 nN=0; nN<nIndex; nN++ )
350 13244 : ++aEIter;
351 86 : mpImpl->maMapEntries.erase( aEIter );
352 : }
353 :
354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|