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 <sal/log.hxx>
30 #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/xmltypes.hxx>
42 #include <xmloff/maptype.hxx>
47 using namespace ::com::sun::star::uno
;
48 using namespace ::com::sun::star::beans
;
49 using namespace ::com::sun::star::container
;
50 using namespace ::com::sun::star::xml
;
51 using namespace ::com::sun::star::xml::sax
;
53 using namespace ::xmloff::token
;
54 using ::com::sun::star::lang::IllegalArgumentException
;
55 using ::com::sun::star::lang::WrappedTargetException
;
56 using ::com::sun::star::beans::UnknownPropertyException
;
57 using ::com::sun::star::beans::PropertyVetoException
;
60 SvXMLImportPropertyMapper::SvXMLImportPropertyMapper(
61 rtl::Reference
< XMLPropertySetMapper
> xMapper
,
64 maPropMapper (std::move( xMapper
))
68 SvXMLImportPropertyMapper::~SvXMLImportPropertyMapper()
70 mxNextMapper
= nullptr;
73 void SvXMLImportPropertyMapper::ChainImportMapper(
74 const rtl::Reference
< SvXMLImportPropertyMapper
>& rMapper
)
76 // add map entries from rMapper to current map
77 maPropMapper
->AddMapperEntry( rMapper
->getPropertySetMapper() );
78 // rMapper uses the same map as 'this'
79 rMapper
->maPropMapper
= maPropMapper
;
81 // set rMapper as last mapper in current chain
82 rtl::Reference
< SvXMLImportPropertyMapper
> xNext
= mxNextMapper
;
85 while( xNext
->mxNextMapper
.is())
86 xNext
= xNext
->mxNextMapper
;
87 xNext
->mxNextMapper
= rMapper
;
90 mxNextMapper
= rMapper
;
92 // if rMapper was already chained, correct
93 // map pointer of successors
96 while( xNext
->mxNextMapper
.is())
98 xNext
= xNext
->mxNextMapper
;
99 xNext
->maPropMapper
= maPropMapper
;
103 /** fills the given itemset with the attributes in the given list */
104 void SvXMLImportPropertyMapper::importXML(
105 std::vector
< XMLPropertyState
>& rProperties
,
106 const Reference
< XFastAttributeList
>& xAttrList
,
107 const SvXMLUnitConverter
& rUnitConverter
,
108 const SvXMLNamespaceMap
& rNamespaceMap
,
109 sal_uInt32 nPropType
,
111 sal_Int32 nEndIdx
) const
113 Reference
< XNameContainer
> xAttrContainer
;
115 if( -1 == nStartIdx
)
118 nEndIdx
= maPropMapper
->GetEntryCount();
120 for (auto &aIter
: sax_fastparser::castToFastAttributeList( xAttrList
))
122 sal_Int32 nToken
= aIter
.getToken();
123 if( IsTokenInNamespace(nToken
, XML_NAMESPACE_XMLNS
) )
126 const OUString aPrefix
= SvXMLImport::getNamespacePrefixFromToken(nToken
, &rNamespaceMap
);
127 const OUString aNamespaceURI
= SvXMLImport::getNamespaceURIFromToken(nToken
);
128 OUString sAttrName
= SvXMLImport::getNameFromToken( nToken
);
129 if ( !aPrefix
.isEmpty() )
130 sAttrName
= aPrefix
+ SvXMLImport::aNamespaceSeparator
+ sAttrName
;
132 const OUString sValue
= aIter
.toString();
134 importXMLAttribute(rProperties
, rUnitConverter
, rNamespaceMap
,
135 nPropType
, nStartIdx
, nEndIdx
, xAttrContainer
,
136 sAttrName
, aNamespaceURI
, sValue
);
139 const css::uno::Sequence
< css::xml::Attribute
> unknownAttribs
= xAttrList
->getUnknownAttributes();
140 for (const css::xml::Attribute
& rAttribute
: unknownAttribs
)
142 int nSepIndex
= rAttribute
.Name
.indexOf(SvXMLImport::aNamespaceSeparator
);
145 // If it's an unknown attribute in a known namespace, ignore it.
146 OUString aPrefix
= rAttribute
.Name
.copy(0, nSepIndex
);
147 auto nKey
= rNamespaceMap
.GetKeyByPrefix(aPrefix
);
148 if (nKey
!= USHRT_MAX
&& !(nKey
& XML_NAMESPACE_UNKNOWN_FLAG
))
152 importXMLAttribute(rProperties
, rUnitConverter
, rNamespaceMap
,
153 nPropType
, nStartIdx
, nEndIdx
, xAttrContainer
,
154 rAttribute
.Name
, rAttribute
.NamespaceURL
, rAttribute
.Value
);
157 finished( rProperties
, nStartIdx
, nEndIdx
);
160 void SvXMLImportPropertyMapper::importXMLAttribute(
161 std::vector
< XMLPropertyState
>& rProperties
,
162 const SvXMLUnitConverter
& rUnitConverter
,
163 const SvXMLNamespaceMap
& rNamespaceMap
,
164 const sal_uInt32 nPropType
,
165 const sal_Int32 nStartIdx
,
166 const sal_Int32 nEndIdx
,
167 Reference
< XNameContainer
>& xAttrContainer
,
168 const OUString
& rAttrName
,
169 const OUString
& aNamespaceURI
,
170 const OUString
& sValue
) const
172 OUString aLocalName
, aPrefix
, aNamespace
;
173 sal_uInt16 nPrefix
= rNamespaceMap
.GetKeyByAttrName( rAttrName
, &aPrefix
,
174 &aLocalName
, &aNamespace
);
176 // index of actual property map entry
177 // This looks very strange, but it works well:
178 // If the start index is 0, the new value will become -1, and
179 // GetEntryIndex will start searching with position 0.
180 // Otherwise GetEntryIndex will start with the next position specified.
181 sal_Int32 nIndex
= nStartIdx
- 1;
182 sal_uInt32 nFlags
= 0; // flags of actual property map entry
185 // for better error reporting: this should be set true if no
187 bool bNoWarning
= false;
191 // find an entry for this attribute
192 nIndex
= maPropMapper
->GetEntryIndex( nPrefix
, aLocalName
,
195 if( nIndex
> -1 && nIndex
< nEndIdx
)
197 // create a XMLPropertyState with an empty value
199 nFlags
= maPropMapper
->GetEntryFlags( nIndex
);
200 if( ( nFlags
& MID_FLAG_ELEMENT_ITEM_IMPORT
) == 0 )
202 XMLPropertyState
aNewProperty( nIndex
);
203 sal_Int32 nReference
= -1;
205 // if this is a multi attribute check if another attribute already set
206 // this any. If so use this as an initial value
207 if( ( nFlags
& MID_FLAG_MERGE_PROPERTY
) != 0 )
209 const OUString
aAPIName( maPropMapper
->GetEntryAPIName( nIndex
) );
210 const sal_Int32 nSize
= rProperties
.size();
211 for( nReference
= 0; nReference
< nSize
; nReference
++ )
213 sal_Int32 nRefIdx
= rProperties
[nReference
].mnIndex
;
214 if( (nRefIdx
!= -1) && (nIndex
!= nRefIdx
) &&
215 (maPropMapper
->GetEntryAPIName( nRefIdx
) == aAPIName
))
217 aNewProperty
= rProperties
[nReference
];
218 aNewProperty
.mnIndex
= nIndex
;
223 if( nReference
== nSize
)
228 if( ( nFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) == 0 )
230 // let the XMLPropertySetMapper decide how to import the value
231 bSet
= maPropMapper
->importXML( sValue
, aNewProperty
,
236 sal_uInt32 nOldSize
= rProperties
.size();
238 bSet
= handleSpecialItem( aNewProperty
, rProperties
,
239 sValue
, rUnitConverter
,
242 // no warning if handleSpecialItem added properties
243 bNoWarning
|= ( nOldSize
!= rProperties
.size() );
246 // no warning if we found could set the item. This
247 // 'remembers' bSet across multi properties.
250 // store the property in the given vector
253 if( nReference
== -1 )
254 rProperties
.push_back( aNewProperty
);
256 rProperties
[nReference
] = std::move(aNewProperty
);
260 // warn about unknown value. Unless it's a
261 // multi property: Then we get another chance
264 ((nFlags
& MID_FLAG_MULTI_PROPERTY
) == 0) )
266 m_rImport
.SetError( XMLERROR_FLAG_WARNING
|
267 XMLERROR_STYLE_ATTR_VALUE
,
268 { rAttrName
, sValue
} );
278 SAL_INFO_IF((XML_NAMESPACE_NONE
!= nPrefix
) &&
279 !(XML_NAMESPACE_UNKNOWN_FLAG
& nPrefix
),
281 "unknown attribute: \"" << rAttrName
<< "\"");
282 if( (XML_NAMESPACE_UNKNOWN_FLAG
& nPrefix
) || (XML_NAMESPACE_NONE
== nPrefix
) )
284 if( !xAttrContainer
.is() )
286 // add an unknown attribute container to the properties
287 xAttrContainer
.set(SvUnoAttributeContainer_CreateInstance(), UNO_QUERY
);
289 // find map entry and create new property state
294 case XML_TYPE_PROP_CHART
:
295 nIndex
= maPropMapper
->FindEntryIndex( "ChartUserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
297 case XML_TYPE_PROP_PARAGRAPH
:
298 nIndex
= maPropMapper
->FindEntryIndex( "ParaUserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
300 case XML_TYPE_PROP_TEXT
:
301 nIndex
= maPropMapper
->FindEntryIndex( "TextUserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
306 // other property type or property not found
308 nIndex
= maPropMapper
->FindEntryIndex( "UserDefinedAttributes", XML_NAMESPACE_TEXT
, GetXMLToken(XML_XMLNS
) );
311 // #106963#; use userdefined attribute only if it is in the specified property range
312 if( nIndex
!= -1 && nIndex
>= nStartIdx
&& nIndex
< nEndIdx
)
314 XMLPropertyState
aNewProperty( nIndex
, Any(xAttrContainer
) );
316 // push it on our stack so we export it later
317 rProperties
.push_back( aNewProperty
);
321 if( xAttrContainer
.is() )
324 aData
.Type
= GetXMLToken( XML_CDATA
);
325 aData
.Value
= sValue
;
327 if( XML_NAMESPACE_NONE
!= nPrefix
)
330 aData
.Namespace
= aNamespaceURI
;
334 xAttrContainer
->insertByName( sName
, Any(aData
) );
339 while( ( nIndex
>= 0 && nIndex
+ 1 < nEndIdx
) && (( nFlags
& MID_FLAG_MULTI_PROPERTY
) != 0 ) );
342 /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */
343 bool SvXMLImportPropertyMapper::handleSpecialItem(
344 XMLPropertyState
& rProperty
,
345 std::vector
< XMLPropertyState
>& rProperties
,
346 const OUString
& rValue
,
347 const SvXMLUnitConverter
& rUnitConverter
,
348 const SvXMLNamespaceMap
& rNamespaceMap
) const
350 OSL_ENSURE( mxNextMapper
.is(), "unsupported special item in xml import" );
351 if( mxNextMapper
.is() )
352 return mxNextMapper
->handleSpecialItem( rProperty
, rProperties
, rValue
,
353 rUnitConverter
, rNamespaceMap
);
358 void SvXMLImportPropertyMapper::FillPropertySequence(
359 const ::std::vector
< XMLPropertyState
>& rProperties
,
360 css::uno::Sequence
< css::beans::PropertyValue
>& rValues
)
363 sal_Int32 nCount
= rProperties
.size();
364 sal_Int32 nValueCount
= 0;
365 rValues
.realloc( nCount
);
366 PropertyValue
*pProps
= rValues
.getArray();
367 for( sal_Int32 i
=0; i
< nCount
; i
++ )
369 const XMLPropertyState
& rProp
= rProperties
[i
];
370 sal_Int32 nIdx
= rProp
.mnIndex
;
373 pProps
->Name
= maPropMapper
->GetEntryAPIName( nIdx
);
374 if( !pProps
->Name
.isEmpty() )
376 pProps
->Value
= rProp
.maValue
;
381 if( nValueCount
< nCount
)
382 rValues
.realloc( nValueCount
);
385 void SvXMLImportPropertyMapper::CheckSpecialContext(
386 const ::std::vector
< XMLPropertyState
>& aProperties
,
387 const css::uno::Reference
< css::beans::XPropertySet
>& rPropSet
,
388 ContextID_Index_Pair
* pSpecialContextIds
) const
390 OSL_ENSURE( rPropSet
.is(), "need an XPropertySet" );
391 sal_Int32 nCount
= aProperties
.size();
393 for( sal_Int32 i
=0; i
< nCount
; i
++ )
395 const XMLPropertyState
& rProp
= aProperties
[i
];
396 sal_Int32 nIdx
= rProp
.mnIndex
;
398 // disregard property state if it has an invalid index
402 const sal_Int32 nPropFlags
= maPropMapper
->GetEntryFlags( nIdx
);
404 // handle no-property and special items
405 if( ( pSpecialContextIds
!= nullptr ) &&
406 ( ( 0 != ( nPropFlags
& MID_FLAG_NO_PROPERTY_IMPORT
) ) ||
407 ( 0 != ( nPropFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) ) ) )
409 // maybe it's one of our special context ids?
410 sal_Int16 nContextId
= maPropMapper
->GetEntryContextId(nIdx
);
412 for ( sal_Int32 n
= 0;
413 pSpecialContextIds
[n
].nContextID
!= -1;
416 // found: set index in pSpecialContextIds array
417 if ( pSpecialContextIds
[n
].nContextID
== nContextId
)
419 pSpecialContextIds
[n
].nIndex
= i
;
428 bool SvXMLImportPropertyMapper::FillPropertySet(
429 const std::vector
< XMLPropertyState
>& aProperties
,
430 const Reference
< XPropertySet
>& rPropSet
,
431 ContextID_Index_Pair
* pSpecialContextIds
) const
435 Reference
< XTolerantMultiPropertySet
> xTolPropSet( rPropSet
, UNO_QUERY
);
436 if (xTolPropSet
.is())
437 bSet
= FillTolerantMultiPropertySet_( aProperties
, xTolPropSet
, maPropMapper
, m_rImport
,
438 pSpecialContextIds
);
442 // get property set info
443 Reference
< XPropertySetInfo
> xInfo(rPropSet
->getPropertySetInfo());
445 // check for multi-property set
446 Reference
<XMultiPropertySet
> xMultiPropSet( rPropSet
, UNO_QUERY
);
447 if ( xMultiPropSet
.is() )
449 // Try XMultiPropertySet. If that fails, try the regular route.
450 bSet
= FillMultiPropertySet_( aProperties
, xMultiPropSet
,
452 pSpecialContextIds
);
454 bSet
= FillPropertySet_( aProperties
, rPropSet
,
455 xInfo
, maPropMapper
, m_rImport
,
459 bSet
= FillPropertySet_( aProperties
, rPropSet
, xInfo
,
460 maPropMapper
, m_rImport
,
461 pSpecialContextIds
);
467 bool SvXMLImportPropertyMapper::FillPropertySet_(
468 const std::vector
<XMLPropertyState
> & rProperties
,
469 const Reference
<XPropertySet
> & rPropSet
,
470 const Reference
<XPropertySetInfo
> & rPropSetInfo
,
471 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
472 SvXMLImport
& rImport
,
473 ContextID_Index_Pair
* pSpecialContextIds
)
475 OSL_ENSURE( rPropSet
.is(), "need an XPropertySet" );
476 OSL_ENSURE( rPropSetInfo
.is(), "need an XPropertySetInfo" );
480 sal_Int32 nCount
= rProperties
.size();
482 // iterate over property states that we want to set
483 for( sal_Int32 i
=0; i
< nCount
; i
++ )
485 const XMLPropertyState
& rProp
= rProperties
[i
];
486 sal_Int32 nIdx
= rProp
.mnIndex
;
488 // disregard property state if it has an invalid index
492 const OUString
& rPropName
= rPropMapper
->GetEntryAPIName( nIdx
);
493 const sal_Int32 nPropFlags
= rPropMapper
->GetEntryFlags( nIdx
);
495 if ( ( 0 == ( nPropFlags
& MID_FLAG_NO_PROPERTY
) ) &&
496 ( ( 0 != ( nPropFlags
& MID_FLAG_MUST_EXIST
) ) ||
497 rPropSetInfo
->hasPropertyByName( rPropName
) ) )
499 // try setting the property
502 rPropSet
->setPropertyValue( rPropName
, rProp
.maValue
);
505 catch ( const IllegalArgumentException
& e
)
507 // illegal value: check whether this property is
508 // allowed to throw this exception
509 if ( 0 == ( nPropFlags
& MID_FLAG_PROPERTY_MAY_THROW
) )
511 Sequence
<OUString
> aSeq
{ rPropName
};
513 XMLERROR_STYLE_PROP_VALUE
| XMLERROR_FLAG_ERROR
,
514 aSeq
, e
.Message
, nullptr );
517 catch ( const UnknownPropertyException
& e
)
519 // unknown property: This is always an error!
520 Sequence
<OUString
> aSeq
{ rPropName
};
522 XMLERROR_STYLE_PROP_UNKNOWN
| XMLERROR_FLAG_ERROR
,
523 aSeq
, e
.Message
, nullptr );
525 catch ( const PropertyVetoException
& e
)
527 // property veto: this shouldn't happen
528 Sequence
<OUString
> aSeq
{ rPropName
};
530 XMLERROR_STYLE_PROP_OTHER
| XMLERROR_FLAG_ERROR
,
531 aSeq
, e
.Message
, nullptr );
533 catch ( const WrappedTargetException
& e
)
535 // wrapped target: this shouldn't happen either
536 Sequence
<OUString
> aSeq
{ rPropName
};
538 XMLERROR_STYLE_PROP_OTHER
| XMLERROR_FLAG_ERROR
,
539 aSeq
, e
.Message
, nullptr );
543 // handle no-property and special items
544 if( ( pSpecialContextIds
!= nullptr ) &&
545 ( ( 0 != ( nPropFlags
& MID_FLAG_NO_PROPERTY_IMPORT
) ) ||
546 ( 0 != ( nPropFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) ) ) )
548 // maybe it's one of our special context ids?
549 sal_Int16 nContextId
= rPropMapper
->GetEntryContextId(nIdx
);
551 for ( sal_Int32 n
= 0;
552 pSpecialContextIds
[n
].nContextID
!= -1;
555 // found: set index in pSpecialContextIds array
556 if ( pSpecialContextIds
[n
].nContextID
== nContextId
)
558 pSpecialContextIds
[n
].nIndex
= i
;
569 typedef std::pair
<const OUString
*, const Any
* > PropertyPair
;
573 struct PropertyPairLessFunctor
575 bool operator()( const PropertyPair
& a
, const PropertyPair
& b
) const
577 return (*a
.first
< *b
.first
);
583 void SvXMLImportPropertyMapper::PrepareForMultiPropertySet_(
584 const std::vector
<XMLPropertyState
> & rProperties
,
585 const Reference
<XPropertySetInfo
> & rPropSetInfo
,
586 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
587 ContextID_Index_Pair
* pSpecialContextIds
,
588 Sequence
<OUString
>& rNames
,
589 Sequence
<Any
>& rValues
)
591 sal_Int32 nCount
= rProperties
.size();
593 // property pairs structure stores names + values of properties to be set.
594 std::vector
<PropertyPair
> aPropertyPairs
;
595 aPropertyPairs
.reserve( nCount
);
597 // iterate over property states that we want to set
599 for( i
= 0; i
< nCount
; i
++ )
601 const XMLPropertyState
& rProp
= rProperties
[i
];
602 sal_Int32 nIdx
= rProp
.mnIndex
;
604 // disregard property state if it has an invalid index
608 const OUString
& rPropName
= rPropMapper
->GetEntryAPIName( nIdx
);
609 const sal_Int32 nPropFlags
= rPropMapper
->GetEntryFlags( nIdx
);
611 if ( ( 0 == ( nPropFlags
& MID_FLAG_NO_PROPERTY
) ) &&
612 ( ( 0 != ( nPropFlags
& MID_FLAG_MUST_EXIST
) ) ||
613 !rPropSetInfo
.is() ||
614 rPropSetInfo
->hasPropertyByName(rPropName
) ) )
616 // save property into property pair structure
617 aPropertyPairs
.emplace_back( &rPropName
, &rProp
.maValue
);
620 // handle no-property and special items
621 if( ( pSpecialContextIds
!= nullptr ) &&
622 ( ( 0 != ( nPropFlags
& MID_FLAG_NO_PROPERTY_IMPORT
) ) ||
623 ( 0 != ( nPropFlags
& MID_FLAG_SPECIAL_ITEM_IMPORT
) ) ) )
625 // maybe it's one of our special context ids?
626 sal_Int16 nContextId
= rPropMapper
->GetEntryContextId(nIdx
);
627 for ( sal_Int32 n
= 0;
628 pSpecialContextIds
[n
].nContextID
!= -1;
631 // found: set index in pSpecialContextIds array
632 if ( pSpecialContextIds
[n
].nContextID
== nContextId
)
634 pSpecialContextIds
[n
].nIndex
= i
;
641 // We now need to construct the sequences and actually the set
644 // sort the property pairs
645 sort( aPropertyPairs
.begin(), aPropertyPairs
.end(),
646 PropertyPairLessFunctor());
649 rNames
.realloc( aPropertyPairs
.size() );
650 OUString
* pNamesArray
= rNames
.getArray();
651 rValues
.realloc( aPropertyPairs
.size() );
652 Any
* pValuesArray
= rValues
.getArray();
654 // copy values into sequences
656 for( const auto& rPropertyPair
: aPropertyPairs
)
658 pNamesArray
[i
] = *(rPropertyPair
.first
);
659 pValuesArray
[i
++] = *(rPropertyPair
.second
);
663 bool SvXMLImportPropertyMapper::FillMultiPropertySet_(
664 const std::vector
<XMLPropertyState
> & rProperties
,
665 const Reference
<XMultiPropertySet
> & rMultiPropSet
,
666 const Reference
<XPropertySetInfo
> & rPropSetInfo
,
667 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
668 ContextID_Index_Pair
* pSpecialContextIds
)
670 OSL_ENSURE( rMultiPropSet
.is(), "Need multi property set. ");
671 OSL_ENSURE( rPropSetInfo
.is(), "Need property set info." );
673 bool bSuccessful
= false;
675 Sequence
<OUString
> aNames
;
676 Sequence
<Any
> aValues
;
678 PrepareForMultiPropertySet_(rProperties
, rPropSetInfo
, rPropMapper
, pSpecialContextIds
,
681 // and, finally, try to set the values
684 rMultiPropSet
->setPropertyValues( aNames
, aValues
);
689 OSL_ENSURE(bSuccessful
, "Exception caught; style may not be imported correctly.");
695 bool SvXMLImportPropertyMapper::FillTolerantMultiPropertySet_(
696 const std::vector
<XMLPropertyState
> & rProperties
,
697 const Reference
<XTolerantMultiPropertySet
> & rTolMultiPropSet
,
698 const rtl::Reference
<XMLPropertySetMapper
> & rPropMapper
,
699 SvXMLImport
& rImport
,
700 ContextID_Index_Pair
* pSpecialContextIds
)
702 OSL_ENSURE( rTolMultiPropSet
.is(), "Need tolerant multi property set. ");
704 bool bSuccessful
= false;
706 Sequence
<OUString
> aNames
;
707 Sequence
<Any
> aValues
;
709 PrepareForMultiPropertySet_(rProperties
, Reference
<XPropertySetInfo
>(nullptr), rPropMapper
, pSpecialContextIds
,
712 // and, finally, try to set the values
715 const Sequence
< SetPropertyTolerantFailed
> aResults(rTolMultiPropSet
->setPropertyValuesTolerant( aNames
, aValues
));
716 bSuccessful
= !aResults
.hasElements();
717 for( const auto& rResult
: aResults
)
719 Sequence
<OUString
> aSeq
{ rResult
.Name
};
721 switch (rResult
.Result
)
723 case TolerantPropertySetResultType::UNKNOWN_PROPERTY
:
724 sMessage
= "UNKNOWN_PROPERTY";
726 case TolerantPropertySetResultType::ILLEGAL_ARGUMENT
:
727 sMessage
= "ILLEGAL_ARGUMENT";
729 case TolerantPropertySetResultType::PROPERTY_VETO
:
730 sMessage
= "PROPERTY_VETO";
732 case TolerantPropertySetResultType::WRAPPED_TARGET
:
733 sMessage
= "WRAPPED_TARGET";
737 XMLERROR_STYLE_PROP_OTHER
| XMLERROR_FLAG_ERROR
,
738 aSeq
, sMessage
, nullptr );
743 OSL_ENSURE(bSuccessful
, "Exception caught; style may not be imported correctly.");
749 void SvXMLImportPropertyMapper::finished(
750 std::vector
< XMLPropertyState
>& rProperties
,
751 sal_Int32 nStartIndex
, sal_Int32 nEndIndex
) const
753 // nothing to do here
754 if( mxNextMapper
.is() )
755 mxNextMapper
->finished( rProperties
, nStartIndex
, nEndIndex
);
758 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */