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 <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>
33 #include <xmloff/xmlprmap.hxx>
34 #include <xmloff/namespacemap.hxx>
35 #include <xmloff/xmlimppr.hxx>
36 #include <xmloff/xmlimp.hxx>
38 #include <xmloff/unoatrcn.hxx>
39 #include <xmloff/xmlnamespace.hxx>
40 #include <xmloff/xmltoken.hxx>
41 #include <xmloff/xmlerror.hxx>
42 #include <xmloff/contextid.hxx>
43 #include <xmloff/xmltypes.hxx>
44 #include <xmloff/maptype.hxx>
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 ::xmloff::token
;
56 using ::com::sun::star::lang::IllegalArgumentException
;
57 using ::com::sun::star::lang::WrappedTargetException
;
58 using ::com::sun::star::beans::UnknownPropertyException
;
59 using ::com::sun::star::beans::PropertyVetoException
;
62 SvXMLImportPropertyMapper::SvXMLImportPropertyMapper(
63 rtl::Reference
< XMLPropertySetMapper
> xMapper
,
66 maPropMapper (std::move( xMapper
))
70 SvXMLImportPropertyMapper::~SvXMLImportPropertyMapper()
72 mxNextMapper
= nullptr;
75 void SvXMLImportPropertyMapper::ChainImportMapper(
76 const rtl::Reference
< SvXMLImportPropertyMapper
>& rMapper
)
78 // add map entries from rMapper to current map
79 maPropMapper
->AddMapperEntry( rMapper
->getPropertySetMapper() );
80 // rMapper uses the same map as 'this'
81 rMapper
->maPropMapper
= maPropMapper
;
83 // set rMapper as last mapper in current chain
84 rtl::Reference
< SvXMLImportPropertyMapper
> xNext
= mxNextMapper
;
87 while( xNext
->mxNextMapper
.is())
88 xNext
= xNext
->mxNextMapper
;
89 xNext
->mxNextMapper
= rMapper
;
92 mxNextMapper
= rMapper
;
94 // if rMapper was already chained, correct
95 // map pointer of successors
98 while( xNext
->mxNextMapper
.is())
100 xNext
= xNext
->mxNextMapper
;
101 xNext
->maPropMapper
= maPropMapper
;
105 /** fills the given itemset with the attributes in the given list */
106 void SvXMLImportPropertyMapper::importXML(
107 std::vector
< XMLPropertyState
>& rProperties
,
108 const Reference
< XFastAttributeList
>& xAttrList
,
109 const SvXMLUnitConverter
& rUnitConverter
,
110 const SvXMLNamespaceMap
& rNamespaceMap
,
111 sal_uInt32 nPropType
,
113 sal_Int32 nEndIdx
) const
115 Reference
< XNameContainer
> xAttrContainer
;
117 if( -1 == nStartIdx
)
120 nEndIdx
= maPropMapper
->GetEntryCount();
122 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
124 sal_Int32 nToken
= aIter
.getToken();
125 if( IsTokenInNamespace(nToken
, XML_NAMESPACE_XMLNS
) )
128 const OUString aPrefix
= SvXMLImport::getNamespacePrefixFromToken(nToken
, &rNamespaceMap
);
129 const OUString aNamespaceURI
= SvXMLImport::getNamespaceURIFromToken(nToken
);
130 OUString sAttrName
= SvXMLImport::getNameFromToken( nToken
);
131 if ( !aPrefix
.isEmpty() )
132 sAttrName
= aPrefix
+ SvXMLImport::aNamespaceSeparator
+ sAttrName
;
134 const OUString sValue
= aIter
.toString();
136 importXMLAttribute(rProperties
, rUnitConverter
, rNamespaceMap
,
137 nPropType
, nStartIdx
, nEndIdx
, xAttrContainer
,
138 sAttrName
, aNamespaceURI
, sValue
);
141 const css::uno::Sequence
< css::xml::Attribute
> unknownAttribs
= xAttrList
->getUnknownAttributes();
142 for (const css::xml::Attribute
& rAttribute
: unknownAttribs
)
144 int nSepIndex
= rAttribute
.Name
.indexOf(SvXMLImport::aNamespaceSeparator
);
147 // If it's an unknown attribute in a known namespace, ignore it.
148 OUString aPrefix
= rAttribute
.Name
.copy(0, nSepIndex
);
149 auto nKey
= rNamespaceMap
.GetKeyByPrefix(aPrefix
);
150 if (nKey
!= USHRT_MAX
&& !(nKey
& XML_NAMESPACE_UNKNOWN_FLAG
))
154 importXMLAttribute(rProperties
, rUnitConverter
, rNamespaceMap
,
155 nPropType
, nStartIdx
, nEndIdx
, xAttrContainer
,
156 rAttribute
.Name
, rAttribute
.NamespaceURL
, rAttribute
.Value
);
159 finished( rProperties
, nStartIdx
, nEndIdx
);
162 void SvXMLImportPropertyMapper::importXMLAttribute(
163 std::vector
< XMLPropertyState
>& rProperties
,
164 const SvXMLUnitConverter
& rUnitConverter
,
165 const SvXMLNamespaceMap
& rNamespaceMap
,
166 const sal_uInt32 nPropType
,
167 const sal_Int32 nStartIdx
,
168 const sal_Int32 nEndIdx
,
169 Reference
< XNameContainer
>& xAttrContainer
,
170 const OUString
& rAttrName
,
171 const OUString
& aNamespaceURI
,
172 const OUString
& sValue
) const
174 OUString aLocalName
, aPrefix
, aNamespace
;
175 sal_uInt16 nPrefix
= rNamespaceMap
.GetKeyByAttrName( rAttrName
, &aPrefix
,
176 &aLocalName
, &aNamespace
);
178 // index of actual property map entry
179 // This looks very strange, but it works well:
180 // If the start index is 0, the new value will become -1, and
181 // GetEntryIndex will start searching with position 0.
182 // Otherwise GetEntryIndex will start with the next position specified.
183 sal_Int32 nIndex
= nStartIdx
- 1;
184 sal_uInt32 nFlags
= 0; // flags of actual property map entry
187 // for better error reporting: this should be set true if no
189 bool bNoWarning
= false;
193 // find an entry for this attribute
194 nIndex
= maPropMapper
->GetEntryIndex( nPrefix
, aLocalName
,
197 if( nIndex
> -1 && nIndex
< nEndIdx
)
199 // create a XMLPropertyState with an empty value
201 nFlags
= maPropMapper
->GetEntryFlags( nIndex
);
202 if( ( nFlags
& MID_FLAG_ELEMENT_ITEM_IMPORT
) == 0 )
204 XMLPropertyState
aNewProperty( nIndex
);
205 sal_Int32 nReference
= -1;
207 // if this is a multi attribute check if another attribute already set
208 // this any. If so use this as an initial value
209 if( ( nFlags
& MID_FLAG_MERGE_PROPERTY
) != 0 )
211 const OUString
aAPIName( maPropMapper
->GetEntryAPIName( nIndex
) );
212 const sal_Int32 nSize
= rProperties
.size();
213 for( nReference
= 0; nReference
< nSize
; nReference
++ )
215 sal_Int32 nRefIdx
= rProperties
[nReference
].mnIndex
;
216 if( (nRefIdx
!= -1) && (nIndex
!= nRefIdx
) &&
217 (maPropMapper
->GetEntryAPIName( nRefIdx
) == aAPIName
))
219 aNewProperty
= rProperties
[nReference
];
220 aNewProperty
.mnIndex
= nIndex
;
225 if( nReference
== nSize
)
230 if( ( nFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) == 0 )
232 // let the XMLPropertySetMapper decide how to import the value
233 bSet
= maPropMapper
->importXML( sValue
, aNewProperty
,
238 sal_uInt32 nOldSize
= rProperties
.size();
240 bSet
= handleSpecialItem( aNewProperty
, rProperties
,
241 sValue
, rUnitConverter
,
244 // no warning if handleSpecialItem added properties
245 bNoWarning
|= ( nOldSize
!= rProperties
.size() );
248 // no warning if we found could set the item. This
249 // 'remembers' bSet across multi properties.
252 // store the property in the given vector
255 if( nReference
== -1 )
256 rProperties
.push_back( aNewProperty
);
258 rProperties
[nReference
] = aNewProperty
;
262 // warn about unknown value. Unless it's a
263 // multi property: Then we get another chance
266 ((nFlags
& MID_FLAG_MULTI_PROPERTY
) == 0) )
268 m_rImport
.SetError( XMLERROR_FLAG_WARNING
|
269 XMLERROR_STYLE_ATTR_VALUE
,
270 { rAttrName
, sValue
} );
280 SAL_INFO_IF((XML_NAMESPACE_NONE
!= nPrefix
) &&
281 !(XML_NAMESPACE_UNKNOWN_FLAG
& nPrefix
),
283 "unknown attribute: \"" << rAttrName
<< "\"");
284 if( (XML_NAMESPACE_UNKNOWN_FLAG
& nPrefix
) || (XML_NAMESPACE_NONE
== nPrefix
) )
286 if( !xAttrContainer
.is() )
288 // add an unknown attribute container to the properties
289 Reference
< XNameContainer
> xNew( SvUnoAttributeContainer_CreateInstance(), UNO_QUERY
);
290 xAttrContainer
= xNew
;
292 // find map entry and create new property state
297 case XML_TYPE_PROP_CHART
:
298 nIndex
= maPropMapper
->FindEntryIndex( "ChartUserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
300 case XML_TYPE_PROP_PARAGRAPH
:
301 nIndex
= maPropMapper
->FindEntryIndex( "ParaUserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
303 case XML_TYPE_PROP_TEXT
:
304 nIndex
= maPropMapper
->FindEntryIndex( "TextUserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
309 // other property type or property not found
311 nIndex
= maPropMapper
->FindEntryIndex( "UserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
314 // #106963#; use userdefined attribute only if it is in the specified property range
315 if( nIndex
!= -1 && nIndex
>= nStartIdx
&& nIndex
< nEndIdx
)
317 XMLPropertyState
aNewProperty( nIndex
, Any(xAttrContainer
) );
319 // push it on our stack so we export it later
320 rProperties
.push_back( aNewProperty
);
324 if( xAttrContainer
.is() )
327 aData
.Type
= GetXMLToken( XML_CDATA
);
328 aData
.Value
= sValue
;
330 if( XML_NAMESPACE_NONE
!= nPrefix
)
333 aData
.Namespace
= aNamespaceURI
;
337 xAttrContainer
->insertByName( sName
, Any(aData
) );
342 while( ( nIndex
>= 0 && nIndex
+ 1 < nEndIdx
) && (( nFlags
& MID_FLAG_MULTI_PROPERTY
) != 0 ) );
345 /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */
346 bool SvXMLImportPropertyMapper::handleSpecialItem(
347 XMLPropertyState
& rProperty
,
348 std::vector
< XMLPropertyState
>& rProperties
,
349 const OUString
& rValue
,
350 const SvXMLUnitConverter
& rUnitConverter
,
351 const SvXMLNamespaceMap
& rNamespaceMap
) const
353 OSL_ENSURE( mxNextMapper
.is(), "unsupported special item in xml import" );
354 if( mxNextMapper
.is() )
355 return mxNextMapper
->handleSpecialItem( rProperty
, rProperties
, rValue
,
356 rUnitConverter
, rNamespaceMap
);
361 void SvXMLImportPropertyMapper::FillPropertySequence(
362 const ::std::vector
< XMLPropertyState
>& rProperties
,
363 css::uno::Sequence
< css::beans::PropertyValue
>& rValues
)
366 sal_Int32 nCount
= rProperties
.size();
367 sal_Int32 nValueCount
= 0;
368 rValues
.realloc( nCount
);
369 PropertyValue
*pProps
= rValues
.getArray();
370 for( sal_Int32 i
=0; i
< nCount
; i
++ )
372 const XMLPropertyState
& rProp
= rProperties
[i
];
373 sal_Int32 nIdx
= rProp
.mnIndex
;
376 pProps
->Name
= maPropMapper
->GetEntryAPIName( nIdx
);
377 if( !pProps
->Name
.isEmpty() )
379 pProps
->Value
= rProp
.maValue
;
384 if( nValueCount
< nCount
)
385 rValues
.realloc( nValueCount
);
388 void SvXMLImportPropertyMapper::CheckSpecialContext(
389 const ::std::vector
< XMLPropertyState
>& aProperties
,
390 const css::uno::Reference
< css::beans::XPropertySet
>& rPropSet
,
391 ContextID_Index_Pair
* pSpecialContextIds
) const
393 OSL_ENSURE( rPropSet
.is(), "need an XPropertySet" );
394 sal_Int32 nCount
= aProperties
.size();
396 for( sal_Int32 i
=0; i
< nCount
; i
++ )
398 const XMLPropertyState
& rProp
= aProperties
[i
];
399 sal_Int32 nIdx
= rProp
.mnIndex
;
401 // disregard property state if it has an invalid index
405 const sal_Int32 nPropFlags
= maPropMapper
->GetEntryFlags( nIdx
);
407 // handle no-property and special items
408 if( ( pSpecialContextIds
!= nullptr ) &&
409 ( ( 0 != ( nPropFlags
& MID_FLAG_NO_PROPERTY_IMPORT
) ) ||
410 ( 0 != ( nPropFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) ) ) )
412 // maybe it's one of our special context ids?
413 sal_Int16 nContextId
= maPropMapper
->GetEntryContextId(nIdx
);
415 for ( sal_Int32 n
= 0;
416 pSpecialContextIds
[n
].nContextID
!= -1;
419 // found: set index in pSpecialContextIds array
420 if ( pSpecialContextIds
[n
].nContextID
== nContextId
)
422 pSpecialContextIds
[n
].nIndex
= i
;
431 bool SvXMLImportPropertyMapper::FillPropertySet(
432 const std::vector
< XMLPropertyState
>& aProperties
,
433 const Reference
< XPropertySet
>& rPropSet
,
434 ContextID_Index_Pair
* pSpecialContextIds
) const
438 Reference
< XTolerantMultiPropertySet
> xTolPropSet( rPropSet
, UNO_QUERY
);
439 if (xTolPropSet
.is())
440 bSet
= FillTolerantMultiPropertySet_( aProperties
, xTolPropSet
, maPropMapper
, m_rImport
,
441 pSpecialContextIds
);
445 // get property set info
446 Reference
< XPropertySetInfo
> xInfo(rPropSet
->getPropertySetInfo());
448 // check for multi-property set
449 Reference
<XMultiPropertySet
> xMultiPropSet( rPropSet
, UNO_QUERY
);
450 if ( xMultiPropSet
.is() )
452 // Try XMultiPropertySet. If that fails, try the regular route.
453 bSet
= FillMultiPropertySet_( aProperties
, xMultiPropSet
,
455 pSpecialContextIds
);
457 bSet
= FillPropertySet_( aProperties
, rPropSet
,
458 xInfo
, maPropMapper
, m_rImport
,
462 bSet
= FillPropertySet_( aProperties
, rPropSet
, xInfo
,
463 maPropMapper
, m_rImport
,
464 pSpecialContextIds
);
470 bool SvXMLImportPropertyMapper::FillPropertySet_(
471 const std::vector
<XMLPropertyState
> & rProperties
,
472 const Reference
<XPropertySet
> & rPropSet
,
473 const Reference
<XPropertySetInfo
> & rPropSetInfo
,
474 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
475 SvXMLImport
& rImport
,
476 ContextID_Index_Pair
* pSpecialContextIds
)
478 OSL_ENSURE( rPropSet
.is(), "need an XPropertySet" );
479 OSL_ENSURE( rPropSetInfo
.is(), "need an XPropertySetInfo" );
483 sal_Int32 nCount
= rProperties
.size();
485 // iterate over property states that we want to set
486 for( sal_Int32 i
=0; i
< nCount
; i
++ )
488 const XMLPropertyState
& rProp
= rProperties
[i
];
489 sal_Int32 nIdx
= rProp
.mnIndex
;
491 // disregard property state if it has an invalid index
495 const OUString
& rPropName
= rPropMapper
->GetEntryAPIName( nIdx
);
496 const sal_Int32 nPropFlags
= rPropMapper
->GetEntryFlags( nIdx
);
498 if ( ( 0 == ( nPropFlags
& MID_FLAG_NO_PROPERTY
) ) &&
499 ( ( 0 != ( nPropFlags
& MID_FLAG_MUST_EXIST
) ) ||
500 rPropSetInfo
->hasPropertyByName( rPropName
) ) )
502 // try setting the property
505 rPropSet
->setPropertyValue( rPropName
, rProp
.maValue
);
508 catch ( const IllegalArgumentException
& e
)
510 // illegal value: check whether this property is
511 // allowed to throw this exception
512 if ( 0 == ( nPropFlags
& MID_FLAG_PROPERTY_MAY_THROW
) )
514 Sequence
<OUString
> aSeq
{ rPropName
};
516 XMLERROR_STYLE_PROP_VALUE
| XMLERROR_FLAG_ERROR
,
517 aSeq
, e
.Message
, nullptr );
520 catch ( const UnknownPropertyException
& e
)
522 // unknown property: This is always an error!
523 Sequence
<OUString
> aSeq
{ rPropName
};
525 XMLERROR_STYLE_PROP_UNKNOWN
| XMLERROR_FLAG_ERROR
,
526 aSeq
, e
.Message
, nullptr );
528 catch ( const PropertyVetoException
& e
)
530 // property veto: this shouldn't happen
531 Sequence
<OUString
> aSeq
{ rPropName
};
533 XMLERROR_STYLE_PROP_OTHER
| XMLERROR_FLAG_ERROR
,
534 aSeq
, e
.Message
, nullptr );
536 catch ( const WrappedTargetException
& e
)
538 // wrapped target: this shouldn't happen either
539 Sequence
<OUString
> aSeq
{ rPropName
};
541 XMLERROR_STYLE_PROP_OTHER
| XMLERROR_FLAG_ERROR
,
542 aSeq
, e
.Message
, nullptr );
546 // handle no-property and special items
547 if( ( pSpecialContextIds
!= nullptr ) &&
548 ( ( 0 != ( nPropFlags
& MID_FLAG_NO_PROPERTY_IMPORT
) ) ||
549 ( 0 != ( nPropFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) ) ) )
551 // maybe it's one of our special context ids?
552 sal_Int16 nContextId
= rPropMapper
->GetEntryContextId(nIdx
);
554 for ( sal_Int32 n
= 0;
555 pSpecialContextIds
[n
].nContextID
!= -1;
558 // found: set index in pSpecialContextIds array
559 if ( pSpecialContextIds
[n
].nContextID
== nContextId
)
561 pSpecialContextIds
[n
].nIndex
= i
;
572 typedef std::pair
<const OUString
*, const Any
* > PropertyPair
;
576 struct PropertyPairLessFunctor
578 bool operator()( const PropertyPair
& a
, const PropertyPair
& b
) const
580 return (*a
.first
< *b
.first
);
586 void SvXMLImportPropertyMapper::PrepareForMultiPropertySet_(
587 const std::vector
<XMLPropertyState
> & rProperties
,
588 const Reference
<XPropertySetInfo
> & rPropSetInfo
,
589 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
590 ContextID_Index_Pair
* pSpecialContextIds
,
591 Sequence
<OUString
>& rNames
,
592 Sequence
<Any
>& rValues
)
594 sal_Int32 nCount
= rProperties
.size();
596 // property pairs structure stores names + values of properties to be set.
597 std::vector
<PropertyPair
> aPropertyPairs
;
598 aPropertyPairs
.reserve( nCount
);
600 // iterate over property states that we want to set
602 for( i
= 0; i
< nCount
; i
++ )
604 const XMLPropertyState
& rProp
= rProperties
[i
];
605 sal_Int32 nIdx
= rProp
.mnIndex
;
607 // disregard property state if it has an invalid index
611 const OUString
& rPropName
= rPropMapper
->GetEntryAPIName( nIdx
);
612 const sal_Int32 nPropFlags
= rPropMapper
->GetEntryFlags( nIdx
);
614 if ( ( 0 == ( nPropFlags
& MID_FLAG_NO_PROPERTY
) ) &&
615 ( ( 0 != ( nPropFlags
& MID_FLAG_MUST_EXIST
) ) ||
616 !rPropSetInfo
.is() ||
617 rPropSetInfo
->hasPropertyByName(rPropName
) ) )
619 // save property into property pair structure
620 aPropertyPairs
.emplace_back( &rPropName
, &rProp
.maValue
);
623 // handle no-property and special items
624 if( ( pSpecialContextIds
!= nullptr ) &&
625 ( ( 0 != ( nPropFlags
& MID_FLAG_NO_PROPERTY_IMPORT
) ) ||
626 ( 0 != ( nPropFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) ) ) )
628 // maybe it's one of our special context ids?
629 sal_Int16 nContextId
= rPropMapper
->GetEntryContextId(nIdx
);
630 for ( sal_Int32 n
= 0;
631 pSpecialContextIds
[n
].nContextID
!= -1;
634 // found: set index in pSpecialContextIds array
635 if ( pSpecialContextIds
[n
].nContextID
== nContextId
)
637 pSpecialContextIds
[n
].nIndex
= i
;
644 // We now need to construct the sequences and actually the set
647 // sort the property pairs
648 sort( aPropertyPairs
.begin(), aPropertyPairs
.end(),
649 PropertyPairLessFunctor());
652 rNames
.realloc( aPropertyPairs
.size() );
653 OUString
* pNamesArray
= rNames
.getArray();
654 rValues
.realloc( aPropertyPairs
.size() );
655 Any
* pValuesArray
= rValues
.getArray();
657 // copy values into sequences
659 for( const auto& rPropertyPair
: aPropertyPairs
)
661 pNamesArray
[i
] = *(rPropertyPair
.first
);
662 pValuesArray
[i
++] = *(rPropertyPair
.second
);
666 bool SvXMLImportPropertyMapper::FillMultiPropertySet_(
667 const std::vector
<XMLPropertyState
> & rProperties
,
668 const Reference
<XMultiPropertySet
> & rMultiPropSet
,
669 const Reference
<XPropertySetInfo
> & rPropSetInfo
,
670 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
671 ContextID_Index_Pair
* pSpecialContextIds
)
673 OSL_ENSURE( rMultiPropSet
.is(), "Need multi property set. ");
674 OSL_ENSURE( rPropSetInfo
.is(), "Need property set info." );
676 bool bSuccessful
= false;
678 Sequence
<OUString
> aNames
;
679 Sequence
<Any
> aValues
;
681 PrepareForMultiPropertySet_(rProperties
, rPropSetInfo
, rPropMapper
, pSpecialContextIds
,
684 // and, finally, try to set the values
687 rMultiPropSet
->setPropertyValues( aNames
, aValues
);
692 OSL_ENSURE(bSuccessful
, "Exception caught; style may not be imported correctly.");
698 bool SvXMLImportPropertyMapper::FillTolerantMultiPropertySet_(
699 const std::vector
<XMLPropertyState
> & rProperties
,
700 const Reference
<XTolerantMultiPropertySet
> & rTolMultiPropSet
,
701 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
702 SvXMLImport
& rImport
,
703 ContextID_Index_Pair
* pSpecialContextIds
)
705 OSL_ENSURE( rTolMultiPropSet
.is(), "Need tolerant multi property set. ");
707 bool bSuccessful
= false;
709 Sequence
<OUString
> aNames
;
710 Sequence
<Any
> aValues
;
712 PrepareForMultiPropertySet_(rProperties
, Reference
<XPropertySetInfo
>(nullptr), rPropMapper
, pSpecialContextIds
,
715 // and, finally, try to set the values
718 const Sequence
< SetPropertyTolerantFailed
> aResults(rTolMultiPropSet
->setPropertyValuesTolerant( aNames
, aValues
));
719 bSuccessful
= !aResults
.hasElements();
720 for( const auto& rResult
: aResults
)
722 Sequence
<OUString
> aSeq
{ rResult
.Name
};
724 switch (rResult
.Result
)
726 case TolerantPropertySetResultType::UNKNOWN_PROPERTY
:
727 sMessage
= "UNKNOWN_PROPERTY";
729 case TolerantPropertySetResultType::ILLEGAL_ARGUMENT
:
730 sMessage
= "ILLEGAL_ARGUMENT";
732 case TolerantPropertySetResultType::PROPERTY_VETO
:
733 sMessage
= "PROPERTY_VETO";
735 case TolerantPropertySetResultType::WRAPPED_TARGET
:
736 sMessage
= "WRAPPED_TARGET";
740 XMLERROR_STYLE_PROP_OTHER
| XMLERROR_FLAG_ERROR
,
741 aSeq
, sMessage
, nullptr );
746 OSL_ENSURE(bSuccessful
, "Exception caught; style may not be imported correctly.");
752 void SvXMLImportPropertyMapper::finished(
753 std::vector
< XMLPropertyState
>& rProperties
,
754 sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) const
756 // nothing to do here
757 if( mxNextMapper
.is() )
758 mxNextMapper
->finished( rProperties
, nStartIndex
, nEndIndex
);
761 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */