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 20416692 : 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 20944700 : sal_uInt32 GetPropType() const { return nType & XML_TYPE_PROP_MASK; }
74 : };
75 :
76 4941676 : XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
77 : const XMLPropertyMapEntry& rMapEntry,
78 : const rtl::Reference< XMLPropertyHandlerFactory >& rFactory ) :
79 4941676 : 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 4941676 : pHdl( rFactory->GetPropertyHandler( rMapEntry.mnType & MID_FLAG_MASK ) )
88 : {
89 4941676 : }
90 :
91 15408932 : XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
92 : const XMLPropertySetMapperEntry_Impl& rEntry ) :
93 : sXMLAttributeName( rEntry.sXMLAttributeName),
94 : sAPIPropertyName( rEntry.sAPIPropertyName),
95 : nType( rEntry.nType),
96 : nXMLNameSpace( rEntry.nXMLNameSpace),
97 : nContextId( rEntry.nContextId),
98 : nEarliestODFVersionForExport( rEntry.nEarliestODFVersionForExport ),
99 : bImportOnly( rEntry.bImportOnly),
100 15408932 : pHdl( rEntry.pHdl)
101 : {
102 : DBG_ASSERT( pHdl, "Unknown XML property type handler!" );
103 15408932 : }
104 :
105 54212 : struct XMLPropertySetMapper::Impl
106 : {
107 : std::vector<XMLPropertySetMapperEntry_Impl> maMapEntries;
108 : std::vector<rtl::Reference <XMLPropertyHandlerFactory> > maHdlFactories;
109 :
110 : bool mbOnlyExportMappings;
111 :
112 54232 : Impl( bool bForExport ) : mbOnlyExportMappings(bForExport) {}
113 : };
114 :
115 : // Ctor
116 54232 : XMLPropertySetMapper::XMLPropertySetMapper(
117 : const XMLPropertyMapEntry* pEntries, const rtl::Reference<XMLPropertyHandlerFactory>& rFactory,
118 : bool bForExport ) :
119 54232 : mpImpl(new Impl(bForExport))
120 : {
121 54232 : mpImpl->maHdlFactories.push_back(rFactory);
122 54232 : if( pEntries )
123 : {
124 54232 : const XMLPropertyMapEntry* pIter = pEntries;
125 :
126 54232 : if (mpImpl->mbOnlyExportMappings)
127 : {
128 2403744 : while( pIter->msApiName )
129 : {
130 2355572 : if (!pIter->mbImportOnly)
131 : {
132 2335856 : XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
133 2335856 : mpImpl->maMapEntries.push_back( aEntry );
134 : }
135 2355572 : pIter++;
136 : }
137 : }
138 : else
139 : {
140 2666112 : while( pIter->msApiName )
141 : {
142 2605820 : XMLPropertySetMapperEntry_Impl aEntry( *pIter, rFactory );
143 2605820 : mpImpl->maMapEntries.push_back( aEntry );
144 2605820 : pIter++;
145 2605820 : }
146 : }
147 : }
148 54232 : }
149 :
150 118950 : XMLPropertySetMapper::~XMLPropertySetMapper()
151 : {
152 54212 : delete mpImpl;
153 64738 : }
154 :
155 11962 : void XMLPropertySetMapper::AddMapperEntry(
156 : const rtl::Reference < XMLPropertySetMapper >& rMapper )
157 : {
158 77976 : for( vector < rtl::Reference < XMLPropertyHandlerFactory > >::iterator
159 11962 : aFIter = rMapper->mpImpl->maHdlFactories.begin();
160 51984 : aFIter != rMapper->mpImpl->maHdlFactories.end();
161 : ++aFIter )
162 : {
163 14030 : mpImpl->maHdlFactories.push_back(*aFIter);
164 : }
165 :
166 5180340 : for( vector < XMLPropertySetMapperEntry_Impl >::iterator
167 11962 : aEIter = rMapper->mpImpl->maMapEntries.begin();
168 3453560 : aEIter != rMapper->mpImpl->maMapEntries.end();
169 : ++aEIter )
170 : {
171 1714818 : if (!mpImpl->mbOnlyExportMappings || !(*aEIter).bImportOnly)
172 1714818 : mpImpl->maMapEntries.push_back( *aEIter );
173 : }
174 11962 : }
175 :
176 830150 : sal_Int32 XMLPropertySetMapper::GetEntryCount() const
177 : {
178 830150 : return mpImpl->maMapEntries.size();
179 : }
180 :
181 5314722 : sal_uInt32 XMLPropertySetMapper::GetEntryFlags( sal_Int32 nIndex ) const
182 : {
183 : DBG_ASSERT( (nIndex >= 0) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
184 5314722 : return mpImpl->maMapEntries[nIndex].nType & ~MID_FLAG_MASK;
185 : }
186 :
187 20610 : sal_uInt32 XMLPropertySetMapper::GetEntryType( sal_Int32 nIndex, bool bWithFlags ) const
188 : {
189 : DBG_ASSERT( (nIndex >= 0) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
190 20610 : sal_uInt32 nType = mpImpl->maMapEntries[nIndex].nType;
191 20610 : if( !bWithFlags )
192 0 : nType = nType & MID_FLAG_MASK;
193 20610 : return nType;
194 : }
195 :
196 96302 : sal_uInt16 XMLPropertySetMapper::GetEntryNameSpace( sal_Int32 nIndex ) const
197 : {
198 : DBG_ASSERT( (nIndex >= 0) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
199 96302 : return mpImpl->maMapEntries[nIndex].nXMLNameSpace;
200 : }
201 :
202 96302 : const OUString& XMLPropertySetMapper::GetEntryXMLName( sal_Int32 nIndex ) const
203 : {
204 : DBG_ASSERT( (nIndex >= 0) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
205 96302 : return mpImpl->maMapEntries[nIndex].sXMLAttributeName;
206 : }
207 :
208 5376522 : const OUString& XMLPropertySetMapper::GetEntryAPIName( sal_Int32 nIndex ) const
209 : {
210 : DBG_ASSERT( (nIndex >= 0) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
211 5376522 : return mpImpl->maMapEntries[nIndex].sAPIPropertyName;
212 : }
213 :
214 1600946 : sal_Int16 XMLPropertySetMapper::GetEntryContextId( sal_Int32 nIndex ) const
215 : {
216 : DBG_ASSERT( (nIndex >= -1) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
217 1600946 : return nIndex == -1 ? 0 : mpImpl->maMapEntries[nIndex].nContextId;
218 : }
219 :
220 943840 : SvtSaveOptions::ODFDefaultVersion XMLPropertySetMapper::GetEarliestODFVersionForExport( sal_Int32 nIndex ) const
221 : {
222 : DBG_ASSERT( (nIndex >= -1) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
223 943840 : return nIndex == -1 ? SvtSaveOptions::ODFVER_UNKNOWN : mpImpl->maMapEntries[nIndex].nEarliestODFVersionForExport;
224 : }
225 :
226 281420 : const XMLPropertyHandler* XMLPropertySetMapper::GetPropertyHandler( sal_Int32 nIndex ) const
227 : {
228 : DBG_ASSERT( (nIndex >= 0) && (nIndex < (sal_Int32)mpImpl->maMapEntries.size() ), "illegal access to invalid entry!" );
229 281420 : return mpImpl->maMapEntries[nIndex].pHdl;
230 : }
231 :
232 : // Export a Property
233 87182 : bool XMLPropertySetMapper::exportXML(
234 : OUString& rStrExpValue,
235 : const XMLPropertyState& rProperty,
236 : const SvXMLUnitConverter& rUnitConverter ) const
237 : {
238 87182 : bool bRet = false;
239 :
240 87182 : const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
241 :
242 : DBG_ASSERT( pHdl, "Unknown XML Type!" );
243 87182 : if( pHdl )
244 : bRet = pHdl->exportXML( rStrExpValue, rProperty.maValue,
245 87182 : rUnitConverter );
246 :
247 87182 : return bRet;
248 : }
249 :
250 : // Import a Property
251 185146 : bool XMLPropertySetMapper::importXML(
252 : const OUString& rStrImpValue,
253 : XMLPropertyState& rProperty,
254 : const SvXMLUnitConverter& rUnitConverter ) const
255 : {
256 185146 : bool bRet = false;
257 :
258 185146 : const XMLPropertyHandler* pHdl = GetPropertyHandler( rProperty.mnIndex );
259 :
260 185146 : if( pHdl )
261 : bRet = pHdl->importXML( rStrImpValue, rProperty.maValue,
262 185146 : rUnitConverter );
263 :
264 185146 : return bRet;
265 : }
266 :
267 : // Search for the given name and the namespace in the list and return
268 : // the index of the entry
269 : // If there is no matching entry the method returns -1
270 229052 : sal_Int32 XMLPropertySetMapper::GetEntryIndex(
271 : sal_uInt16 nNamespace,
272 : const OUString& rStrName,
273 : sal_uInt32 nPropType,
274 : sal_Int32 nStartAt /* = -1 */ ) const
275 : {
276 229052 : sal_Int32 nEntries = GetEntryCount();
277 229052 : sal_Int32 nIndex= nStartAt == - 1? 0 : nStartAt+1;
278 :
279 229052 : if ( nEntries && nIndex < nEntries )
280 : {
281 20749872 : do
282 : {
283 20952308 : const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
284 50388306 : if( (!nPropType || nPropType == rEntry.GetPropType()) &&
285 33730668 : rEntry.nXMLNameSpace == nNamespace &&
286 4287062 : rStrName == rEntry.sXMLAttributeName )
287 202436 : return nIndex;
288 : else
289 20749872 : nIndex++;
290 :
291 : } while( nIndex<nEntries );
292 : }
293 :
294 26616 : return -1;
295 : }
296 :
297 : /** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
298 2240 : sal_Int32 XMLPropertySetMapper::FindEntryIndex(
299 : const sal_Char* sApiName,
300 : sal_uInt16 nNameSpace,
301 : const OUString& sXMLName ) const
302 : {
303 2240 : sal_Int32 nIndex = 0;
304 2240 : sal_Int32 nEntries = GetEntryCount();
305 :
306 195124 : do
307 : {
308 197364 : const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
309 519176 : if( rEntry.nXMLNameSpace == nNameSpace &&
310 201540 : rEntry.sXMLAttributeName.equals( sXMLName ) &&
311 4176 : rEntry.sAPIPropertyName.equalsAscii( sApiName ) )
312 2240 : return nIndex;
313 : else
314 195124 : nIndex++;
315 :
316 : } while( nIndex < nEntries );
317 :
318 0 : return -1;
319 : }
320 :
321 10052 : sal_Int32 XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId ) const
322 : {
323 10052 : const sal_Int32 nEntries = GetEntryCount();
324 :
325 10052 : if ( nEntries )
326 : {
327 10052 : sal_Int32 nIndex = 0;
328 695394 : do
329 : {
330 704546 : const XMLPropertySetMapperEntry_Impl& rEntry = mpImpl->maMapEntries[nIndex];
331 704546 : if( rEntry.nContextId == nContextId )
332 9152 : return nIndex;
333 : else
334 695394 : nIndex++;
335 :
336 : } while( nIndex < nEntries );
337 : }
338 :
339 900 : return -1;
340 : }
341 :
342 244 : void XMLPropertySetMapper::RemoveEntry( sal_Int32 nIndex )
343 : {
344 244 : const sal_Int32 nEntries = GetEntryCount();
345 244 : if( nIndex>=nEntries || nIndex<0 )
346 244 : return;
347 244 : vector < XMLPropertySetMapperEntry_Impl >::iterator aEIter = mpImpl->maMapEntries.begin();
348 37088 : for( sal_Int32 nN=0; nN<nIndex; nN++ )
349 36844 : ++aEIter;
350 244 : mpImpl->maMapEntries.erase( aEIter );
351 : }
352 :
353 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|