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 ::std
;
37 using namespace ::com::sun::star::uno
;
38 using namespace ::com::sun::star::beans
;
39 using ::xmloff::token::GetXMLToken
;
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
52 Attention: At all methods, which get an index as parameter, there is no
53 range validation to save runtime !!
55 struct XMLPropertySetMapperEntry_Impl
57 OUString sXMLAttributeName
;
58 OUString sAPIPropertyName
;
60 sal_uInt16 nXMLNameSpace
;
62 SvtSaveOptions::ODFSaneDefaultVersion nEarliestODFVersionForExport
;
64 const XMLPropertyHandler
*pHdl
;
66 XMLPropertySetMapperEntry_Impl(
67 const XMLPropertyMapEntry
& rMapEntry
,
68 const rtl::Reference
< XMLPropertyHandlerFactory
>& rFactory
);
70 sal_uInt32
GetPropType() const { return nType
& XML_TYPE_PROP_MASK
; }
75 XMLPropertySetMapperEntry_Impl::XMLPropertySetMapperEntry_Impl(
76 const XMLPropertyMapEntry
& rMapEntry
,
77 const rtl::Reference
< XMLPropertyHandlerFactory
>& rFactory
) :
78 sXMLAttributeName( GetXMLToken(rMapEntry
.meXMLName
) ),
79 sAPIPropertyName( rMapEntry
.getApiName() ),
80 nType( rMapEntry
.mnType
),
81 nXMLNameSpace( rMapEntry
.mnNameSpace
),
82 nContextId( rMapEntry
.mnContextId
),
83 nEarliestODFVersionForExport( rMapEntry
.mnEarliestODFVersionForExport
),
84 bImportOnly( rMapEntry
.mbImportOnly
),
85 pHdl( rFactory
->GetPropertyHandler( rMapEntry
.mnType
& MID_FLAG_MASK
) )
90 struct XMLPropertySetMapper::Impl
92 std::vector
<XMLPropertySetMapperEntry_Impl
> maMapEntries
;
93 std::vector
<rtl::Reference
<XMLPropertyHandlerFactory
> > maHdlFactories
;
95 bool mbOnlyExportMappings
;
97 explicit Impl( bool bForExport
) : mbOnlyExportMappings(bForExport
) {}
101 XMLPropertySetMapper::XMLPropertySetMapper(
102 const XMLPropertyMapEntry
* pEntries
, const rtl::Reference
<XMLPropertyHandlerFactory
>& rFactory
,
104 mpImpl(new Impl(bForExport
))
106 mpImpl
->maHdlFactories
.push_back(rFactory
);
110 const XMLPropertyMapEntry
* pIter
= pEntries
;
112 if (mpImpl
->mbOnlyExportMappings
)
114 while( !pIter
->IsEnd() )
116 if (!pIter
->mbImportOnly
)
118 XMLPropertySetMapperEntry_Impl
aEntry( *pIter
, rFactory
);
119 mpImpl
->maMapEntries
.push_back( aEntry
);
126 while( !pIter
->IsEnd() )
128 XMLPropertySetMapperEntry_Impl
aEntry( *pIter
, rFactory
);
129 mpImpl
->maMapEntries
.push_back( aEntry
);
135 XMLPropertySetMapper::~XMLPropertySetMapper()
139 void XMLPropertySetMapper::AddMapperEntry(
140 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
)
142 for( const auto& rHdlFactory
: rMapper
->mpImpl
->maHdlFactories
)
144 mpImpl
->maHdlFactories
.push_back(rHdlFactory
);
147 for( const auto& rMapEntry
: rMapper
->mpImpl
->maMapEntries
)
149 if (!mpImpl
->mbOnlyExportMappings
|| !rMapEntry
.bImportOnly
)
150 mpImpl
->maMapEntries
.push_back( rMapEntry
);
154 sal_Int32
XMLPropertySetMapper::GetEntryCount() const
156 return mpImpl
->maMapEntries
.size();
159 sal_uInt32
XMLPropertySetMapper::GetEntryFlags( sal_Int32 nIndex
) const
161 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
162 return mpImpl
->maMapEntries
[nIndex
].nType
& ~MID_FLAG_MASK
;
165 sal_uInt32
XMLPropertySetMapper::GetEntryType( sal_Int32 nIndex
) const
167 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
168 sal_uInt32 nType
= mpImpl
->maMapEntries
[nIndex
].nType
;
172 sal_uInt16
XMLPropertySetMapper::GetEntryNameSpace( sal_Int32 nIndex
) const
174 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
175 return mpImpl
->maMapEntries
[nIndex
].nXMLNameSpace
;
178 const OUString
& XMLPropertySetMapper::GetEntryXMLName( sal_Int32 nIndex
) const
180 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
181 return mpImpl
->maMapEntries
[nIndex
].sXMLAttributeName
;
184 const OUString
& XMLPropertySetMapper::GetEntryAPIName( sal_Int32 nIndex
) const
186 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
187 return mpImpl
->maMapEntries
[nIndex
].sAPIPropertyName
;
190 sal_Int16
XMLPropertySetMapper::GetEntryContextId( sal_Int32 nIndex
) const
192 assert((-1 <= nIndex
) && (nIndex
< static_cast<sal_Int32
>(mpImpl
->maMapEntries
.size())));
193 return nIndex
== -1 ? 0 : mpImpl
->maMapEntries
[nIndex
].nContextId
;
196 SvtSaveOptions::ODFSaneDefaultVersion
197 XMLPropertySetMapper::GetEarliestODFVersionForExport(sal_Int32
const nIndex
) const
199 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
200 return mpImpl
->maMapEntries
[nIndex
].nEarliestODFVersionForExport
;
203 const XMLPropertyHandler
* XMLPropertySetMapper::GetPropertyHandler( sal_Int32 nIndex
) const
205 assert((0 <= nIndex
) && (o3tl::make_unsigned(nIndex
) < mpImpl
->maMapEntries
.size()));
206 return mpImpl
->maMapEntries
[nIndex
].pHdl
;
210 bool XMLPropertySetMapper::exportXML(
211 OUString
& rStrExpValue
,
212 const XMLPropertyState
& rProperty
,
213 const SvXMLUnitConverter
& rUnitConverter
) const
217 const XMLPropertyHandler
* pHdl
= GetPropertyHandler( rProperty
.mnIndex
);
221 bRet
= pHdl
->exportXML( rStrExpValue
, rProperty
.maValue
,
228 bool XMLPropertySetMapper::importXML(
229 const OUString
& rStrImpValue
,
230 XMLPropertyState
& rProperty
,
231 const SvXMLUnitConverter
& rUnitConverter
) const
235 const XMLPropertyHandler
* pHdl
= GetPropertyHandler( rProperty
.mnIndex
);
238 bRet
= pHdl
->importXML( rStrImpValue
, rProperty
.maValue
,
244 // Search for the given name and the namespace in the list and return
245 // the index of the entry
246 // If there is no matching entry the method returns -1
247 sal_Int32
XMLPropertySetMapper::GetEntryIndex(
248 sal_uInt16 nNamespace
,
249 std::u16string_view rStrName
,
250 sal_uInt32 nPropType
,
251 sal_Int32 nStartAt
/* = -1 */ ) const
253 sal_Int32 nEntries
= GetEntryCount();
254 sal_Int32 nIndex
= nStartAt
== - 1? 0 : nStartAt
+1;
256 if ( nEntries
&& nIndex
< nEntries
)
260 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
261 if( (!nPropType
|| nPropType
== rEntry
.GetPropType()) &&
262 rEntry
.nXMLNameSpace
== nNamespace
&&
263 rStrName
== rEntry
.sXMLAttributeName
)
268 } while( nIndex
<nEntries
);
274 // Search for the given name and the namespace in the list and return
275 // the index of the entry
276 // If there is no matching entry the method returns -1
277 sal_Int32
XMLPropertySetMapper::GetEntryIndex(
279 sal_uInt32 nPropType
,
280 sal_Int32 nStartAt
/* = -1 */ ) const
282 sal_Int32 nEntries
= GetEntryCount();
283 sal_Int32 nIndex
= nStartAt
== - 1? 0 : nStartAt
+1;
285 if ( nEntries
&& nIndex
< nEntries
)
287 sal_uInt16 nNamespace
= (nElement
>> NMSP_SHIFT
) - 1;
288 const OUString
& rStrName
= SvXMLImport::getNameFromToken(nElement
);
291 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
292 if( (!nPropType
|| nPropType
== rEntry
.GetPropType()) &&
293 rEntry
.nXMLNameSpace
== nNamespace
&&
294 rStrName
== rEntry
.sXMLAttributeName
)
299 } while( nIndex
<nEntries
);
305 /** searches for an entry that matches the given api name, namespace and local name or -1 if nothing found */
306 sal_Int32
XMLPropertySetMapper::FindEntryIndex(
307 const char* sApiName
,
308 sal_uInt16 nNameSpace
,
309 std::u16string_view sXMLName
) const
311 sal_Int32 nIndex
= 0;
312 sal_Int32 nEntries
= GetEntryCount();
316 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
317 if( rEntry
.nXMLNameSpace
== nNameSpace
&&
318 rEntry
.sXMLAttributeName
== sXMLName
&&
319 rEntry
.sAPIPropertyName
.equalsAscii( sApiName
) )
324 } while( nIndex
< nEntries
);
329 sal_Int32
XMLPropertySetMapper::FindEntryIndex( const sal_Int16 nContextId
) const
331 const sal_Int32 nEntries
= GetEntryCount();
335 sal_Int32 nIndex
= 0;
338 const XMLPropertySetMapperEntry_Impl
& rEntry
= mpImpl
->maMapEntries
[nIndex
];
339 if( rEntry
.nContextId
== nContextId
)
344 } while( nIndex
< nEntries
);
350 void XMLPropertySetMapper::RemoveEntry( sal_Int32 nIndex
)
352 const sal_Int32 nEntries
= GetEntryCount();
353 if( nIndex
>=nEntries
|| nIndex
<0 )
355 vector
< XMLPropertySetMapperEntry_Impl
>::iterator aEIter
= mpImpl
->maMapEntries
.begin();
356 std::advance(aEIter
, nIndex
);
357 mpImpl
->maMapEntries
.erase( aEIter
);
360 void XMLPropertySetMapper::GetEntryAPINames( o3tl::sorted_vector
<OUString
>& rNames
) const
362 for (const XMLPropertySetMapperEntry_Impl
& rMapEntry
: mpImpl
->maMapEntries
)
363 rNames
.insert(rMapEntry
.sAPIPropertyName
);
366 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */