1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <o3tl/safeint.hxx>
21 #include <rtl/ref.hxx>
23 #include <xmloff/xmlprmap.hxx>
24 #include <xmloff/xmlprhdl.hxx>
25 #include <xmloff/xmltypes.hxx>
26 #include <xmloff/xmltoken.hxx>
27 #include <xmloff/maptype.hxx>
28 #include <xmloff/prhdlfac.hxx>
29 #include <xmloff/xmlimp.hxx>
31 #include <com/sun/star/beans/XPropertySet.hpp>
35 using namespace ::com::sun::star::uno
;
36 using namespace ::com::sun::star::beans
;
37 using ::xmloff::token::GetXMLToken
;
41 /** Helper-class for XML-im/export:
42 - Holds a pointer to a given array of XMLPropertyMapEntry
43 - Provides several methods to access data from this array
44 - Holds a Sequence of XML-names (for properties)
45 - The filter takes all properties of the XPropertySet which are also
46 in the XMLPropertyMapEntry and which are have not a default value
47 and put them into a vector of XMLPropertyStae
48 - this class knows how to compare, im/export properties
50 Attention: At all methods, which get an index as parameter, there is no
51 range validation to save runtime !!
53 struct XMLPropertySetMapperEntry_Impl
55 OUString sXMLAttributeName
;
56 OUString sAPIPropertyName
;
58 sal_uInt16 nXMLNameSpace
;
60 SvtSaveOptions::ODFSaneDefaultVersion nEarliestODFVersionForExport
;
62 const XMLPropertyHandler
*pHdl
;
64 XMLPropertySetMapperEntry_Impl(
65 const XMLPropertyMapEntry
& rMapEntry
,
66 const rtl::Reference
< XMLPropertyHandlerFactory
>& rFactory
);
68 sal_uInt32
GetPropType() const { return nType
& XML_TYPE_PROP_MASK
; }
73 XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
74 const XMLPropertyMapEntry
& rMapEntry
,
75 const rtl::Reference
< XMLPropertyHandlerFactory
>& rFactory
) :
76 sXMLAttributeName( GetXMLToken(rMapEntry
.meXMLName
) ),
77 sAPIPropertyName( rMapEntry
.getApiName() ),
78 nType( rMapEntry
.mnType
),
79 nXMLNameSpace( rMapEntry
.mnNameSpace
),
80 nContextId( rMapEntry
.mnContextId
),
81 nEarliestODFVersionForExport( rMapEntry
.mnEarliestODFVersionForExport
),
82 bImportOnly( rMapEntry
.mbImportOnly
),
83 pHdl( rFactory
->GetPropertyHandler( rMapEntry
.mnType
& MID_FLAG_MASK
) )
88 struct XMLPropertySetMapper::Impl
90 std::vector
<XMLPropertySetMapperEntry_Impl
> maMapEntries
;
91 std::vector
<rtl::Reference
<XMLPropertyHandlerFactory
> > maHdlFactories
;
93 bool mbOnlyExportMappings
;
95 explicit Impl( bool bForExport
) : mbOnlyExportMappings(bForExport
) {}
99 XMLPropertySetMapper::XMLPropertySetMapper(
100 const XMLPropertyMapEntry
* pEntries
, const rtl::Reference
<XMLPropertyHandlerFactory
>& rFactory
,
102 mpImpl(new Impl(bForExport
))
104 mpImpl
->maHdlFactories
.push_back(rFactory
);
108 const XMLPropertyMapEntry
* pIter
= pEntries
;
110 if (mpImpl
->mbOnlyExportMappings
)
112 while( !pIter
->IsEnd() )
114 if (!pIter
->mbImportOnly
)
116 XMLPropertySetMapperEntry_Impl
aEntry( *pIter
, rFactory
);
117 mpImpl
->maMapEntries
.push_back( aEntry
);
124 while( !pIter
->IsEnd() )
126 XMLPropertySetMapperEntry_Impl
aEntry( *pIter
, rFactory
);
127 mpImpl
->maMapEntries
.push_back( aEntry
);
133 XMLPropertySetMapper::~XMLPropertySetMapper()
137 void XMLPropertySetMapper::AddMapperEntry(
138 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
140 for( const auto& rHdlFactory
: rMapper
->mpImpl
->maHdlFactories
)
142 mpImpl
->maHdlFactories
.push_back(rHdlFactory
);
145 for( const auto& rMapEntry
: rMapper
->mpImpl
->maMapEntries
)
147 if (!mpImpl
->mbOnlyExportMappings
|| !rMapEntry
.bImportOnly
)
148 mpImpl
->maMapEntries
.push_back( rMapEntry
);
152 sal_Int32
XMLPropertySetMapper::GetEntryCount() const
154 return mpImpl
->maMapEntries
.size();
157 sal_uInt32
XMLPropertySetMapper::GetEntryFlags( sal_Int32 nIndex
) const
159 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
160 return mpImpl
->maMapEntries
[nIndex
].nType
& ~MID_FLAG_MASK
;
163 sal_uInt32
XMLPropertySetMapper::GetEntryType( sal_Int32 nIndex
) const
165 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
166 sal_uInt32 nType
= mpImpl
->maMapEntries
[nIndex
].nType
;
170 sal_uInt16
XMLPropertySetMapper::GetEntryNameSpace( sal_Int32 nIndex
) const
172 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
173 return mpImpl
->maMapEntries
[nIndex
].nXMLNameSpace
;
176 const OUString
& XMLPropertySetMapper::GetEntryXMLName( sal_Int32 nIndex
) const
178 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
179 return mpImpl
->maMapEntries
[nIndex
].sXMLAttributeName
;
182 const OUString
& XMLPropertySetMapper::GetEntryAPIName( sal_Int32 nIndex
) const
184 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
185 return mpImpl
->maMapEntries
[nIndex
].sAPIPropertyName
;
188 sal_Int16
XMLPropertySetMapper::GetEntryContextId( sal_Int32 nIndex
) const
190 assert((-1 <= nIndex
) && (nIndex
< static_cast<sal_Int32
>(mpImpl
->maMapEntries
.size())));
191 return nIndex
== -1 ? 0 : mpImpl
->maMapEntries
[nIndex
].nContextId
;
194 SvtSaveOptions::ODFSaneDefaultVersion
195 XMLPropertySetMapper::GetEarliestODFVersionForExport(sal_Int32
const nIndex
) const
197 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
198 return mpImpl
->maMapEntries
[nIndex
].nEarliestODFVersionForExport
;
201 const XMLPropertyHandler
* XMLPropertySetMapper::GetPropertyHandler( sal_Int32 nIndex
) const
203 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
204 return mpImpl
->maMapEntries
[nIndex
].pHdl
;
208 bool XMLPropertySetMapper::exportXML(
209 OUString
& rStrExpValue
,
210 const XMLPropertyState
& rProperty
,
211 const SvXMLUnitConverter
& rUnitConverter
) const
215 const XMLPropertyHandler
* pHdl
= GetPropertyHandler( rProperty
.mnIndex
);
219 bRet
= pHdl
->exportXML( rStrExpValue
, rProperty
.maValue
,
226 bool XMLPropertySetMapper::importXML(
227 const OUString
& rStrImpValue
,
228 XMLPropertyState
& rProperty
,
229 const SvXMLUnitConverter
& rUnitConverter
) const
233 const XMLPropertyHandler
* pHdl
= GetPropertyHandler( rProperty
.mnIndex
);
236 bRet
= pHdl
->importXML( rStrImpValue
, rProperty
.maValue
,
242 // Search for the given name and the namespace in the list and return
243 // the index of the entry
244 // If there is no matching entry the method returns -1
245 sal_Int32
XMLPropertySetMapper::GetEntryIndex(
246 sal_uInt16 nNamespace
,
247 std::u16string_view rStrName
,
248 sal_uInt32 nPropType
,
249 sal_Int32 nStartAt
/* = -1 */ ) const
251 sal_Int32 nEntries
= GetEntryCount();
252 sal_Int32 nIndex
= nStartAt
== - 1? 0 : nStartAt
+1;
254 if ( nEntries
&& nIndex
< nEntries
)
258 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
259 if( (!nPropType
|| nPropType
== rEntry
.GetPropType()) &&
260 rEntry
.nXMLNameSpace
== nNamespace
&&
261 rStrName
== rEntry
.sXMLAttributeName
)
266 } while( nIndex
<nEntries
);
272 // Search for the given name and the namespace in the list and return
273 // the index of the entry
274 // If there is no matching entry the method returns -1
275 sal_Int32
XMLPropertySetMapper::GetEntryIndex(
277 sal_uInt32 nPropType
,
278 sal_Int32 nStartAt
/* = -1 */ ) const
280 sal_Int32 nEntries
= GetEntryCount();
281 sal_Int32 nIndex
= nStartAt
== - 1? 0 : nStartAt
+1;
283 if ( nEntries
&& nIndex
< nEntries
)
285 sal_uInt16 nNamespace
= (nElement
>> NMSP_SHIFT
) - 1;
286 const OUString
& rStrName
= SvXMLImport::getNameFromToken(nElement
);
289 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
290 if( (!nPropType
|| nPropType
== rEntry
.GetPropType()) &&
291 rEntry
.nXMLNameSpace
== nNamespace
&&
292 rStrName
== rEntry
.sXMLAttributeName
)
297 } while( nIndex
<nEntries
);
303 /** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
304 sal_Int32
XMLPropertySetMapper::FindEntryIndex(
305 const char* sApiName
,
306 sal_uInt16 nNameSpace
,
307 std::u16string_view sXMLName
) const
309 sal_Int32 nIndex
= 0;
310 sal_Int32 nEntries
= GetEntryCount();
314 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
315 if( rEntry
.nXMLNameSpace
== nNameSpace
&&
316 rEntry
.sXMLAttributeName
== sXMLName
&&
317 rEntry
.sAPIPropertyName
.equalsAscii( sApiName
) )
322 } while( nIndex
< nEntries
);
327 sal_Int32
XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId
) const
329 const sal_Int32 nEntries
= GetEntryCount();
333 sal_Int32 nIndex
= 0;
336 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
337 if( rEntry
.nContextId
== nContextId
)
342 } while( nIndex
< nEntries
);
348 void XMLPropertySetMapper::RemoveEntry( sal_Int32 nIndex
)
350 const sal_Int32 nEntries
= GetEntryCount();
351 if( nIndex
>=nEntries
|| nIndex
<0 )
353 std::vector
< XMLPropertySetMapperEntry_Impl
>::iterator aEIter
= mpImpl
->maMapEntries
.begin();
354 std::advance(aEIter
, nIndex
);
355 mpImpl
->maMapEntries
.erase( aEIter
);
358 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */