nss: upgrade to release 3.73
[LibreOffice.git] / xmloff / source / style / xmlimppr.cxx
blob0b327c73e6cc53e64888e44d54b76bc354ababa4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <com/sun/star/xml/AttributeData.hpp>
21 #include <com/sun/star/beans/XMultiPropertySet.hpp>
22 #include <com/sun/star/lang/IllegalArgumentException.hpp>
23 #include <com/sun/star/lang/WrappedTargetException.hpp>
24 #include <com/sun/star/beans/UnknownPropertyException.hpp>
25 #include <com/sun/star/beans/PropertyVetoException.hpp>
26 #include <com/sun/star/beans/TolerantPropertySetResultType.hpp>
27 #include <com/sun/star/beans/XTolerantMultiPropertySet.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <rtl/ustrbuf.hxx>
30 #include <sal/log.hxx>
31 #include <osl/diagnose.h>
32 #include <xmloff/xmlprmap.hxx>
33 #include <xmloff/namespacemap.hxx>
34 #include <xmloff/xmlimppr.hxx>
35 #include <xmloff/xmlimp.hxx>
37 #include <xmloff/unoatrcn.hxx>
38 #include <xmloff/xmlnamespace.hxx>
39 #include <xmloff/xmltoken.hxx>
40 #include <xmloff/xmlerror.hxx>
41 #include <xmloff/contextid.hxx>
42 #include <xmloff/xmltypes.hxx>
43 #include <xmloff/maptype.hxx>
45 #include <algorithm>
46 #include <utility>
47 #include <vector>
49 using namespace ::com::sun::star::uno;
50 using namespace ::com::sun::star::beans;
51 using namespace ::com::sun::star::container;
52 using namespace ::com::sun::star::xml;
53 using namespace ::com::sun::star::xml::sax;
55 using namespace ::std;
56 using namespace ::xmloff::token;
57 using ::com::sun::star::lang::IllegalArgumentException;
58 using ::com::sun::star::lang::WrappedTargetException;
59 using ::com::sun::star::beans::UnknownPropertyException;
60 using ::com::sun::star::beans::PropertyVetoException;
63 SvXMLImportPropertyMapper::SvXMLImportPropertyMapper(
64 const rtl::Reference< XMLPropertySetMapper >& rMapper,
65 SvXMLImport& rImp ):
66 rImport(rImp),
67 maPropMapper ( rMapper )
71 SvXMLImportPropertyMapper::~SvXMLImportPropertyMapper()
73 mxNextMapper = nullptr;
76 void SvXMLImportPropertyMapper::ChainImportMapper(
77 const rtl::Reference< SvXMLImportPropertyMapper>& rMapper )
79 // add map entries from rMapper to current map
80 maPropMapper->AddMapperEntry( rMapper->getPropertySetMapper() );
81 // rMapper uses the same map as 'this'
82 rMapper->maPropMapper = maPropMapper;
84 // set rMapper as last mapper in current chain
85 rtl::Reference< SvXMLImportPropertyMapper > xNext = mxNextMapper;
86 if( xNext.is())
88 while( xNext->mxNextMapper.is())
89 xNext = xNext->mxNextMapper;
90 xNext->mxNextMapper = rMapper;
92 else
93 mxNextMapper = rMapper;
95 // if rMapper was already chained, correct
96 // map pointer of successors
97 xNext = rMapper;
99 while( xNext->mxNextMapper.is())
101 xNext = xNext->mxNextMapper;
102 xNext->maPropMapper = maPropMapper;
106 /** fills the given itemset with the attributes in the given list */
107 void SvXMLImportPropertyMapper::importXML(
108 vector< XMLPropertyState >& rProperties,
109 const Reference< XFastAttributeList >& xAttrList,
110 const SvXMLUnitConverter& rUnitConverter,
111 const SvXMLNamespaceMap& rNamespaceMap,
112 sal_uInt32 nPropType,
113 sal_Int32 nStartIdx,
114 sal_Int32 nEndIdx ) const
116 Reference< XNameContainer > xAttrContainer;
118 if( -1 == nStartIdx )
119 nStartIdx = 0;
120 if( -1 == nEndIdx )
121 nEndIdx = maPropMapper->GetEntryCount();
123 for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
125 sal_Int32 nToken = aIter.getToken();
126 if( IsTokenInNamespace(nToken, XML_NAMESPACE_XMLNS) )
127 continue;
129 const OUString aPrefix = SvXMLImport::getNamespacePrefixFromToken(nToken, &rNamespaceMap);
130 const OUString aNamespaceURI = SvXMLImport::getNamespaceURIFromToken(nToken);
131 OUString sAttrName = SvXMLImport::getNameFromToken( nToken );
132 if ( !aPrefix.isEmpty() )
133 sAttrName = aPrefix + SvXMLImport::aNamespaceSeparator + sAttrName;
135 const OUString sValue = aIter.toString();
137 importXMLAttribute(rProperties, rUnitConverter, rNamespaceMap,
138 nPropType, nStartIdx, nEndIdx, xAttrContainer,
139 sAttrName, aNamespaceURI, sValue);
142 const css::uno::Sequence< css::xml::Attribute > unknownAttribs = xAttrList->getUnknownAttributes();
143 for (const css::xml::Attribute& rAttribute : unknownAttribs)
145 int nSepIndex = rAttribute.Name.indexOf(SvXMLImport::aNamespaceSeparator);
146 if (nSepIndex != -1)
148 // If it's an unknown attribute in a known namespace, ignore it.
149 OUString aPrefix = rAttribute.Name.copy(0, nSepIndex);
150 auto nKey = rNamespaceMap.GetKeyByPrefix(aPrefix);
151 if (nKey != USHRT_MAX && !(nKey & XML_NAMESPACE_UNKNOWN_FLAG))
152 continue;
155 importXMLAttribute(rProperties, rUnitConverter, rNamespaceMap,
156 nPropType, nStartIdx, nEndIdx, xAttrContainer,
157 rAttribute.Name, rAttribute.NamespaceURL, rAttribute.Value);
160 finished( rProperties, nStartIdx, nEndIdx );
163 void SvXMLImportPropertyMapper::importXMLAttribute(
164 vector< XMLPropertyState >& rProperties,
165 const SvXMLUnitConverter& rUnitConverter,
166 const SvXMLNamespaceMap& rNamespaceMap,
167 const sal_uInt32 nPropType,
168 const sal_Int32 nStartIdx,
169 const sal_Int32 nEndIdx,
170 Reference< XNameContainer >& xAttrContainer,
171 const OUString& rAttrName,
172 const OUString& aNamespaceURI,
173 const OUString& sValue) const
175 OUString aLocalName, aPrefix, aNamespace;
176 sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rAttrName, &aPrefix,
177 &aLocalName, &aNamespace );
179 // index of actual property map entry
180 // This looks very strange, but it works well:
181 // If the start index is 0, the new value will become -1, and
182 // GetEntryIndex will start searching with position 0.
183 // Otherwise GetEntryIndex will start with the next position specified.
184 sal_Int32 nIndex = nStartIdx - 1;
185 sal_uInt32 nFlags = 0; // flags of actual property map entry
186 bool bFound = false;
188 // for better error reporting: this should be set true if no
189 // warning is needed
190 bool bNoWarning = false;
194 // find an entry for this attribute
195 nIndex = maPropMapper->GetEntryIndex( nPrefix, aLocalName,
196 nPropType, nIndex );
198 if( nIndex > -1 && nIndex < nEndIdx )
200 // create a XMLPropertyState with an empty value
202 nFlags = maPropMapper->GetEntryFlags( nIndex );
203 if( ( nFlags & MID_FLAG_ELEMENT_ITEM_IMPORT ) == 0 )
205 XMLPropertyState aNewProperty( nIndex );
206 sal_Int32 nReference = -1;
208 // if this is a multi attribute check if another attribute already set
209 // this any. If so use this as an initial value
210 if( ( nFlags & MID_FLAG_MERGE_PROPERTY ) != 0 )
212 const OUString aAPIName( maPropMapper->GetEntryAPIName( nIndex ) );
213 const sal_Int32 nSize = rProperties.size();
214 for( nReference = 0; nReference < nSize; nReference++ )
216 sal_Int32 nRefIdx = rProperties[nReference].mnIndex;
217 if( (nRefIdx != -1) && (nIndex != nRefIdx) &&
218 (maPropMapper->GetEntryAPIName( nRefIdx ) == aAPIName ))
220 aNewProperty = rProperties[nReference];
221 aNewProperty.mnIndex = nIndex;
222 break;
226 if( nReference == nSize )
227 nReference = -1;
230 bool bSet = false;
231 if( ( nFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) == 0 )
233 // let the XMLPropertySetMapper decide how to import the value
234 bSet = maPropMapper->importXML( sValue, aNewProperty,
235 rUnitConverter );
237 else
239 sal_uInt32 nOldSize = rProperties.size();
241 bSet = handleSpecialItem( aNewProperty, rProperties,
242 sValue, rUnitConverter,
243 rNamespaceMap );
245 // no warning if handleSpecialItem added properties
246 bNoWarning |= ( nOldSize != rProperties.size() );
249 // no warning if we found could set the item. This
250 // 'remembers' bSet across multi properties.
251 bNoWarning |= bSet;
253 // store the property in the given vector
254 if( bSet )
256 if( nReference == -1 )
257 rProperties.push_back( aNewProperty );
258 else
259 rProperties[nReference] = aNewProperty;
261 else
263 // warn about unknown value. Unless it's a
264 // multi property: Then we get another chance
265 // to set the value.
266 if( !bNoWarning &&
267 ((nFlags & MID_FLAG_MULTI_PROPERTY) == 0) )
269 Sequence<OUString> aSeq(2);
270 aSeq[0] = rAttrName;
271 aSeq[1] = sValue;
272 rImport.SetError( XMLERROR_FLAG_WARNING |
273 XMLERROR_STYLE_ATTR_VALUE,
274 aSeq );
278 bFound = true;
279 continue;
282 if( !bFound )
284 SAL_INFO_IF((XML_NAMESPACE_NONE != nPrefix) &&
285 !(XML_NAMESPACE_UNKNOWN_FLAG & nPrefix),
286 "xmloff.style",
287 "unknown attribute: \"" << rAttrName << "\"");
288 if( (XML_NAMESPACE_UNKNOWN_FLAG & nPrefix) || (XML_NAMESPACE_NONE == nPrefix) )
290 if( !xAttrContainer.is() )
292 // add an unknown attribute container to the properties
293 Reference< XNameContainer > xNew( SvUnoAttributeContainer_CreateInstance(), UNO_QUERY );
294 xAttrContainer = xNew;
296 // find map entry and create new property state
297 if( -1 == nIndex )
299 switch( nPropType )
301 case XML_TYPE_PROP_CHART:
302 nIndex = maPropMapper->FindEntryIndex( "ChartUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
303 break;
304 case XML_TYPE_PROP_PARAGRAPH:
305 nIndex = maPropMapper->FindEntryIndex( "ParaUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
306 break;
307 case XML_TYPE_PROP_TEXT:
308 nIndex = maPropMapper->FindEntryIndex( "TextUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
309 break;
310 default:
311 break;
313 // other property type or property not found
314 if( -1 == nIndex )
315 nIndex = maPropMapper->FindEntryIndex( "UserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
318 // #106963#; use userdefined attribute only if it is in the specified property range
319 if( nIndex != -1 && nIndex >= nStartIdx && nIndex < nEndIdx)
321 XMLPropertyState aNewProperty( nIndex, Any(xAttrContainer) );
323 // push it on our stack so we export it later
324 rProperties.push_back( aNewProperty );
328 if( xAttrContainer.is() )
330 AttributeData aData;
331 aData.Type = GetXMLToken( XML_CDATA );
332 aData.Value = sValue;
333 OUString sName;
334 if( XML_NAMESPACE_NONE != nPrefix )
336 sName = rAttrName;
337 aData.Namespace = aNamespaceURI;
339 else
340 sName = aLocalName;
341 xAttrContainer->insertByName( sName, Any(aData) );
346 while( ( nIndex >= 0 && nIndex + 1 < nEndIdx ) && (( nFlags & MID_FLAG_MULTI_PROPERTY ) != 0 ) );
349 /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */
350 bool SvXMLImportPropertyMapper::handleSpecialItem(
351 XMLPropertyState& rProperty,
352 vector< XMLPropertyState >& rProperties,
353 const OUString& rValue,
354 const SvXMLUnitConverter& rUnitConverter,
355 const SvXMLNamespaceMap& rNamespaceMap ) const
357 OSL_ENSURE( mxNextMapper.is(), "unsupported special item in xml import" );
358 if( mxNextMapper.is() )
359 return mxNextMapper->handleSpecialItem( rProperty, rProperties, rValue,
360 rUnitConverter, rNamespaceMap );
361 else
362 return false;
365 void SvXMLImportPropertyMapper::FillPropertySequence(
366 const ::std::vector< XMLPropertyState >& rProperties,
367 css::uno::Sequence< css::beans::PropertyValue >& rValues )
368 const
370 sal_Int32 nCount = rProperties.size();
371 sal_Int32 nValueCount = 0;
372 rValues.realloc( nCount );
373 PropertyValue *pProps = rValues.getArray();
374 for( sal_Int32 i=0; i < nCount; i++ )
376 const XMLPropertyState& rProp = rProperties[i];
377 sal_Int32 nIdx = rProp.mnIndex;
378 if( nIdx == -1 )
379 continue;
380 pProps->Name = maPropMapper->GetEntryAPIName( nIdx );
381 if( !pProps->Name.isEmpty() )
383 pProps->Value = rProp.maValue;
384 ++pProps;
385 ++nValueCount;
388 if( nValueCount < nCount )
389 rValues.realloc( nValueCount );
392 void SvXMLImportPropertyMapper::CheckSpecialContext(
393 const ::std::vector< XMLPropertyState >& aProperties,
394 const css::uno::Reference< css::beans::XPropertySet >& rPropSet,
395 ContextID_Index_Pair* pSpecialContextIds ) const
397 OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
398 sal_Int32 nCount = aProperties.size();
400 for( sal_Int32 i=0; i < nCount; i++ )
402 const XMLPropertyState& rProp = aProperties[i];
403 sal_Int32 nIdx = rProp.mnIndex;
405 // disregard property state if it has an invalid index
406 if( -1 == nIdx )
407 continue;
409 const sal_Int32 nPropFlags = maPropMapper->GetEntryFlags( nIdx );
411 // handle no-property and special items
412 if( ( pSpecialContextIds != nullptr ) &&
413 ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
414 ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
416 // maybe it's one of our special context ids?
417 sal_Int16 nContextId = maPropMapper->GetEntryContextId(nIdx);
419 for ( sal_Int32 n = 0;
420 pSpecialContextIds[n].nContextID != -1;
421 n++ )
423 // found: set index in pSpecialContextIds array
424 if ( pSpecialContextIds[n].nContextID == nContextId )
426 pSpecialContextIds[n].nIndex = i;
427 break; // early out
435 bool SvXMLImportPropertyMapper::FillPropertySet(
436 const vector< XMLPropertyState >& aProperties,
437 const Reference< XPropertySet >& rPropSet,
438 ContextID_Index_Pair* pSpecialContextIds ) const
440 bool bSet = false;
442 Reference< XTolerantMultiPropertySet > xTolPropSet( rPropSet, UNO_QUERY );
443 if (xTolPropSet.is())
444 bSet = FillTolerantMultiPropertySet_( aProperties, xTolPropSet, maPropMapper, rImport,
445 pSpecialContextIds );
447 if (!bSet)
449 // get property set info
450 Reference< XPropertySetInfo > xInfo(rPropSet->getPropertySetInfo());
452 // check for multi-property set
453 Reference<XMultiPropertySet> xMultiPropSet( rPropSet, UNO_QUERY );
454 if ( xMultiPropSet.is() )
456 // Try XMultiPropertySet. If that fails, try the regular route.
457 bSet = FillMultiPropertySet_( aProperties, xMultiPropSet,
458 xInfo, maPropMapper,
459 pSpecialContextIds );
460 if ( !bSet )
461 bSet = FillPropertySet_( aProperties, rPropSet,
462 xInfo, maPropMapper, rImport,
463 pSpecialContextIds);
465 else
466 bSet = FillPropertySet_( aProperties, rPropSet, xInfo,
467 maPropMapper, rImport,
468 pSpecialContextIds );
471 return bSet;
474 bool SvXMLImportPropertyMapper::FillPropertySet_(
475 const vector<XMLPropertyState> & rProperties,
476 const Reference<XPropertySet> & rPropSet,
477 const Reference<XPropertySetInfo> & rPropSetInfo,
478 const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
479 SvXMLImport& rImport,
480 ContextID_Index_Pair* pSpecialContextIds )
482 OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
483 OSL_ENSURE( rPropSetInfo.is(), "need an XPropertySetInfo" );
485 // preliminaries
486 bool bSet = false;
487 sal_Int32 nCount = rProperties.size();
489 // iterate over property states that we want to set
490 for( sal_Int32 i=0; i < nCount; i++ )
492 const XMLPropertyState& rProp = rProperties[i];
493 sal_Int32 nIdx = rProp.mnIndex;
495 // disregard property state if it has an invalid index
496 if( -1 == nIdx )
497 continue;
499 const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
500 const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
502 if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
503 ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
504 rPropSetInfo->hasPropertyByName( rPropName ) ) )
506 // try setting the property
509 rPropSet->setPropertyValue( rPropName, rProp.maValue );
510 bSet = true;
512 catch ( const IllegalArgumentException& e )
514 // illegal value: check whether this property is
515 // allowed to throw this exception
516 if ( 0 == ( nPropFlags & MID_FLAG_PROPERTY_MAY_THROW ) )
518 Sequence<OUString> aSeq { rPropName };
519 rImport.SetError(
520 XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_ERROR,
521 aSeq, e.Message, nullptr );
524 catch ( const UnknownPropertyException& e )
526 // unknown property: This is always an error!
527 Sequence<OUString> aSeq { rPropName };
528 rImport.SetError(
529 XMLERROR_STYLE_PROP_UNKNOWN | XMLERROR_FLAG_ERROR,
530 aSeq, e.Message, nullptr );
532 catch ( const PropertyVetoException& e )
534 // property veto: this shouldn't happen
535 Sequence<OUString> aSeq { rPropName };
536 rImport.SetError(
537 XMLERROR_STYLE_PROP_OTHER | XMLERROR_FLAG_ERROR,
538 aSeq, e.Message, nullptr );
540 catch ( const WrappedTargetException& e )
542 // wrapped target: this shouldn't happen either
543 Sequence<OUString> aSeq { rPropName };
544 rImport.SetError(
545 XMLERROR_STYLE_PROP_OTHER | XMLERROR_FLAG_ERROR,
546 aSeq, e.Message, nullptr );
550 // handle no-property and special items
551 if( ( pSpecialContextIds != nullptr ) &&
552 ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
553 ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
555 // maybe it's one of our special context ids?
556 sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
558 for ( sal_Int32 n = 0;
559 pSpecialContextIds[n].nContextID != -1;
560 n++ )
562 // found: set index in pSpecialContextIds array
563 if ( pSpecialContextIds[n].nContextID == nContextId )
565 pSpecialContextIds[n].nIndex = i;
566 break; // early out
572 return bSet;
576 typedef pair<const OUString*, const Any* > PropertyPair;
577 typedef vector<PropertyPair> PropertyPairs;
579 namespace {
581 struct PropertyPairLessFunctor
583 bool operator()( const PropertyPair& a, const PropertyPair& b ) const
585 return (*a.first < *b.first);
591 void SvXMLImportPropertyMapper::PrepareForMultiPropertySet_(
592 const vector<XMLPropertyState> & rProperties,
593 const Reference<XPropertySetInfo> & rPropSetInfo,
594 const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
595 ContextID_Index_Pair* pSpecialContextIds,
596 Sequence<OUString>& rNames,
597 Sequence<Any>& rValues)
599 sal_Int32 nCount = rProperties.size();
601 // property pairs structure stores names + values of properties to be set.
602 PropertyPairs aPropertyPairs;
603 aPropertyPairs.reserve( nCount );
605 // iterate over property states that we want to set
606 sal_Int32 i;
607 for( i = 0; i < nCount; i++ )
609 const XMLPropertyState& rProp = rProperties[i];
610 sal_Int32 nIdx = rProp.mnIndex;
612 // disregard property state if it has an invalid index
613 if( -1 == nIdx )
614 continue;
616 const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
617 const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
619 if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
620 ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
621 !rPropSetInfo.is() ||
622 rPropSetInfo->hasPropertyByName(rPropName) ) )
624 // save property into property pair structure
625 aPropertyPairs.emplace_back( &rPropName, &rProp.maValue );
628 // handle no-property and special items
629 if( ( pSpecialContextIds != nullptr ) &&
630 ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
631 ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
633 // maybe it's one of our special context ids?
634 sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
635 for ( sal_Int32 n = 0;
636 pSpecialContextIds[n].nContextID != -1;
637 n++ )
639 // found: set index in pSpecialContextIds array
640 if ( pSpecialContextIds[n].nContextID == nContextId )
642 pSpecialContextIds[n].nIndex = i;
643 break; // early out
649 // We now need to construct the sequences and actually the set
650 // values.
652 // sort the property pairs
653 sort( aPropertyPairs.begin(), aPropertyPairs.end(),
654 PropertyPairLessFunctor());
656 // create sequences
657 rNames.realloc( aPropertyPairs.size() );
658 OUString* pNamesArray = rNames.getArray();
659 rValues.realloc( aPropertyPairs.size() );
660 Any* pValuesArray = rValues.getArray();
662 // copy values into sequences
663 i = 0;
664 for( const auto& rPropertyPair : aPropertyPairs )
666 pNamesArray[i] = *(rPropertyPair.first);
667 pValuesArray[i++] = *(rPropertyPair.second);
671 bool SvXMLImportPropertyMapper::FillMultiPropertySet_(
672 const vector<XMLPropertyState> & rProperties,
673 const Reference<XMultiPropertySet> & rMultiPropSet,
674 const Reference<XPropertySetInfo> & rPropSetInfo,
675 const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
676 ContextID_Index_Pair* pSpecialContextIds )
678 OSL_ENSURE( rMultiPropSet.is(), "Need multi property set. ");
679 OSL_ENSURE( rPropSetInfo.is(), "Need property set info." );
681 bool bSuccessful = false;
683 Sequence<OUString> aNames;
684 Sequence<Any> aValues;
686 PrepareForMultiPropertySet_(rProperties, rPropSetInfo, rPropMapper, pSpecialContextIds,
687 aNames, aValues);
689 // and, finally, try to set the values
692 rMultiPropSet->setPropertyValues( aNames, aValues );
693 bSuccessful = true;
695 catch ( ... )
697 OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
700 return bSuccessful;
703 bool SvXMLImportPropertyMapper::FillTolerantMultiPropertySet_(
704 const vector<XMLPropertyState> & rProperties,
705 const Reference<XTolerantMultiPropertySet> & rTolMultiPropSet,
706 const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
707 SvXMLImport& rImport,
708 ContextID_Index_Pair* pSpecialContextIds )
710 OSL_ENSURE( rTolMultiPropSet.is(), "Need tolerant multi property set. ");
712 bool bSuccessful = false;
714 Sequence<OUString> aNames;
715 Sequence<Any> aValues;
717 PrepareForMultiPropertySet_(rProperties, Reference<XPropertySetInfo>(nullptr), rPropMapper, pSpecialContextIds,
718 aNames, aValues);
720 // and, finally, try to set the values
723 const Sequence< SetPropertyTolerantFailed > aResults(rTolMultiPropSet->setPropertyValuesTolerant( aNames, aValues ));
724 bSuccessful = !aResults.hasElements();
725 for( const auto& rResult : aResults)
727 Sequence<OUString> aSeq { rResult.Name };
728 OUString sMessage;
729 switch (rResult.Result)
731 case TolerantPropertySetResultType::UNKNOWN_PROPERTY :
732 sMessage = "UNKNOWN_PROPERTY";
733 break;
734 case TolerantPropertySetResultType::ILLEGAL_ARGUMENT :
735 sMessage = "ILLEGAL_ARGUMENT";
736 break;
737 case TolerantPropertySetResultType::PROPERTY_VETO :
738 sMessage = "PROPERTY_VETO";
739 break;
740 case TolerantPropertySetResultType::WRAPPED_TARGET :
741 sMessage = "WRAPPED_TARGET";
742 break;
744 rImport.SetError(
745 XMLERROR_STYLE_PROP_OTHER | XMLERROR_FLAG_ERROR,
746 aSeq, sMessage, nullptr );
749 catch ( ... )
751 OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
754 return bSuccessful;
757 void SvXMLImportPropertyMapper::finished(
758 vector< XMLPropertyState >& rProperties,
759 sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
761 // nothing to do here
762 if( mxNextMapper.is() )
763 mxNextMapper->finished( rProperties, nStartIndex, nEndIndex );
766 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */