LibreOffice Module xmloff (master)  1
xmlimppr.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
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/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
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 .
18  */
19 
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/nmspmap.hxx>
34 #include <xmloff/xmlimppr.hxx>
35 #include <xmloff/xmlimp.hxx>
36 
37 #include <xmloff/unoatrcn.hxx>
38 #include <xmloff/xmlnmspe.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>
44 
45 #include <algorithm>
46 #include <utility>
47 #include <vector>
48 
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;
54 
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;
61 
62 
65  SvXMLImport& rImp ):
66  rImport(rImp),
67  maPropMapper ( rMapper )
68 {
69 }
70 
72 {
73  mxNextMapper = nullptr;
74 }
75 
78 {
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;
83 
84  // set rMapper as last mapper in current chain
86  if( xNext.is())
87  {
88  while( xNext->mxNextMapper.is())
89  xNext = xNext->mxNextMapper;
90  xNext->mxNextMapper = rMapper;
91  }
92  else
93  mxNextMapper = rMapper;
94 
95  // if rMapper was already chained, correct
96  // map pointer of successors
97  xNext = rMapper;
98 
99  while( xNext->mxNextMapper.is())
100  {
101  xNext = xNext->mxNextMapper;
102  xNext->maPropMapper = maPropMapper;
103  }
104 }
105 
108  vector< XMLPropertyState >& rProperties,
109  const Reference< XAttributeList >& xAttrList,
110  const SvXMLUnitConverter& rUnitConverter,
111  const SvXMLNamespaceMap& rNamespaceMap,
112  sal_uInt32 nPropType,
113  sal_Int32 nStartIdx,
114  sal_Int32 nEndIdx ) const
115 {
116  sal_Int16 nAttr = xAttrList->getLength();
117 
118  Reference< XNameContainer > xAttrContainer;
119 
120  if( -1 == nStartIdx )
121  nStartIdx = 0;
122  if( -1 == nEndIdx )
123  nEndIdx = maPropMapper->GetEntryCount();
124  for( sal_Int16 i=0; i < nAttr; i++ )
125  {
126  const OUString& rAttrName = xAttrList->getNameByIndex( i );
127  OUString aLocalName, aPrefix, aNamespace;
128  sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rAttrName, &aPrefix,
129  &aLocalName, &aNamespace );
130 
131  if( XML_NAMESPACE_XMLNS == nPrefix )
132  continue;
133 
134  const OUString& rValue = xAttrList->getValueByIndex( i );
135 
136  // index of actual property map entry
137  // This looks very strange, but it works well:
138  // If the start index is 0, the new value will become -1, and
139  // GetEntryIndex will start searching with position 0.
140  // Otherwise GetEntryIndex will start with the next position specified.
141  sal_Int32 nIndex = nStartIdx - 1;
142  sal_uInt32 nFlags = 0; // flags of actual property map entry
143  bool bFound = false;
144 
145  // for better error reporting: this should be set true if no
146  // warning is needed
147  bool bNoWarning = false;
148  bool bAlienImport = false;
149 
150  do
151  {
152  // find an entry for this attribute
153  nIndex = maPropMapper->GetEntryIndex( nPrefix, aLocalName,
154  nPropType, nIndex );
155 
156  if( nIndex > -1 && nIndex < nEndIdx )
157  {
158  // create a XMLPropertyState with an empty value
159 
160  nFlags = maPropMapper->GetEntryFlags( nIndex );
161  if( (( nFlags & MID_FLAG_NO_PROPERTY ) == MID_FLAG_NO_PROPERTY) && (maPropMapper->GetEntryContextId( nIndex ) == CTF_ALIEN_ATTRIBUTE_IMPORT) )
162  {
163  bAlienImport = true;
164  nIndex = -1;
165  }
166  else
167  {
168  if( ( nFlags & MID_FLAG_ELEMENT_ITEM_IMPORT ) == 0 )
169  {
170  XMLPropertyState aNewProperty( nIndex );
171  sal_Int32 nReference = -1;
172 
173  // if this is a multi attribute check if another attribute already set
174  // this any. If so use this as an initial value
175  if( ( nFlags & MID_FLAG_MERGE_PROPERTY ) != 0 )
176  {
177  const OUString aAPIName( maPropMapper->GetEntryAPIName( nIndex ) );
178  const sal_Int32 nSize = rProperties.size();
179  for( nReference = 0; nReference < nSize; nReference++ )
180  {
181  sal_Int32 nRefIdx = rProperties[nReference].mnIndex;
182  if( (nRefIdx != -1) && (nIndex != nRefIdx) &&
183  (maPropMapper->GetEntryAPIName( nRefIdx ) == aAPIName ))
184  {
185  aNewProperty = rProperties[nReference];
186  aNewProperty.mnIndex = nIndex;
187  break;
188  }
189  }
190 
191  if( nReference == nSize )
192  nReference = -1;
193  }
194 
195  bool bSet = false;
196  if( ( nFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) == 0 )
197  {
198  // let the XMLPropertySetMapper decide how to import the value
199  bSet = maPropMapper->importXML( rValue, aNewProperty,
200  rUnitConverter );
201  }
202  else
203  {
204  sal_uInt32 nOldSize = rProperties.size();
205 
206  bSet = handleSpecialItem( aNewProperty, rProperties,
207  rValue, rUnitConverter,
208  rNamespaceMap );
209 
210  // no warning if handleSpecialItem added properties
211  bNoWarning |= ( nOldSize != rProperties.size() );
212  }
213 
214  // no warning if we found could set the item. This
215  // 'remembers' bSet across multi properties.
216  bNoWarning |= bSet;
217 
218  // store the property in the given vector
219  if( bSet )
220  {
221  if( nReference == -1 )
222  rProperties.push_back( aNewProperty );
223  else
224  rProperties[nReference] = aNewProperty;
225  }
226  else
227  {
228  // warn about unknown value. Unless it's a
229  // multi property: Then we get another chance
230  // to set the value.
231  if( !bNoWarning &&
232  ((nFlags & MID_FLAG_MULTI_PROPERTY) == 0) )
233  {
235  aSeq[0] = rAttrName;
236  aSeq[1] = rValue;
239  aSeq );
240  }
241  }
242  }
243  bFound = true;
244  continue;
245  }
246  }
247 
248  if( !bFound )
249  {
250  SAL_INFO_IF((XML_NAMESPACE_NONE != nPrefix) &&
251  !(XML_NAMESPACE_UNKNOWN_FLAG & nPrefix) &&
252  !bAlienImport, "xmloff.style",
253  "unknown attribute: \"" << rAttrName << "\"");
254  if( (XML_NAMESPACE_UNKNOWN_FLAG & nPrefix) || (XML_NAMESPACE_NONE == nPrefix) || bAlienImport )
255  {
256  if( !xAttrContainer.is() )
257  {
258  // add an unknown attribute container to the properties
259  Reference< XNameContainer > xNew( SvUnoAttributeContainer_CreateInstance(), UNO_QUERY );
260  xAttrContainer = xNew;
261 
262  // find map entry and create new property state
263  if( -1 == nIndex )
264  {
265  switch( nPropType )
266  {
267  case XML_TYPE_PROP_CHART:
268  nIndex = maPropMapper->FindEntryIndex( "ChartUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
269  break;
271  nIndex = maPropMapper->FindEntryIndex( "ParaUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
272  break;
273  case XML_TYPE_PROP_TEXT:
274  nIndex = maPropMapper->FindEntryIndex( "TextUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
275  break;
276  default:
277  break;
278  }
279  // other property type or property not found
280  if( -1 == nIndex )
281  nIndex = maPropMapper->FindEntryIndex( "UserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
282  }
283 
284  // #106963#; use userdefined attribute only if it is in the specified property range
285  if( nIndex != -1 && nIndex >= nStartIdx && nIndex < nEndIdx)
286  {
287  XMLPropertyState aNewProperty( nIndex, Any(xAttrContainer) );
288 
289  // push it on our stack so we export it later
290  rProperties.push_back( aNewProperty );
291  }
292  }
293 
294  if( xAttrContainer.is() )
295  {
296  AttributeData aData;
297  aData.Type = GetXMLToken( XML_CDATA );
298  aData.Value = rValue;
299 
300  OUStringBuffer sName;
301  if( XML_NAMESPACE_NONE != nPrefix )
302  {
303  sName.append( aPrefix );
304  sName.append( ':' );
305  aData.Namespace = aNamespace;
306  }
307 
308  sName.append( aLocalName );
309 
310  xAttrContainer->insertByName( sName.makeStringAndClear(), Any(aData) );
311  }
312  }
313  }
314  }
315  while( ( nIndex >= 0 && nIndex + 1 < nEndIdx ) && (( nFlags & MID_FLAG_MULTI_PROPERTY ) != 0 ) );
316  }
317 
318  finished( rProperties, nStartIdx, nEndIdx );
319 }
320 
323  XMLPropertyState& rProperty,
324  vector< XMLPropertyState >& rProperties,
325  const OUString& rValue,
326  const SvXMLUnitConverter& rUnitConverter,
327  const SvXMLNamespaceMap& rNamespaceMap ) const
328 {
329  OSL_ENSURE( mxNextMapper.is(), "unsupported special item in xml import" );
330  if( mxNextMapper.is() )
331  return mxNextMapper->handleSpecialItem( rProperty, rProperties, rValue,
332  rUnitConverter, rNamespaceMap );
333  else
334  return false;
335 }
336 
338  const ::std::vector< XMLPropertyState >& rProperties,
339  css::uno::Sequence< css::beans::PropertyValue >& rValues )
340  const
341 {
342  sal_Int32 nCount = rProperties.size();
343  sal_Int32 nValueCount = 0;
344  rValues.realloc( nCount );
345  PropertyValue *pProps = rValues.getArray();
346  for( sal_Int32 i=0; i < nCount; i++ )
347  {
348  const XMLPropertyState& rProp = rProperties[i];
349  sal_Int32 nIdx = rProp.mnIndex;
350  if( nIdx == -1 )
351  continue;
352  pProps->Name = maPropMapper->GetEntryAPIName( nIdx );
353  if( !pProps->Name.isEmpty() )
354  {
355  pProps->Value = rProp.maValue;
356  ++pProps;
357  ++nValueCount;
358  }
359  }
360  if( nValueCount < nCount )
361  rValues.realloc( nValueCount );
362 }
363 
365  const ::std::vector< XMLPropertyState >& aProperties,
366  const css::uno::Reference< css::beans::XPropertySet >& rPropSet,
367  ContextID_Index_Pair* pSpecialContextIds ) const
368 {
369  OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
370  sal_Int32 nCount = aProperties.size();
371 
372  for( sal_Int32 i=0; i < nCount; i++ )
373  {
374  const XMLPropertyState& rProp = aProperties[i];
375  sal_Int32 nIdx = rProp.mnIndex;
376 
377  // disregard property state if it has an invalid index
378  if( -1 == nIdx )
379  continue;
380 
381  const sal_Int32 nPropFlags = maPropMapper->GetEntryFlags( nIdx );
382 
383  // handle no-property and special items
384  if( ( pSpecialContextIds != nullptr ) &&
385  ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
386  ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
387  {
388  // maybe it's one of our special context ids?
389  sal_Int16 nContextId = maPropMapper->GetEntryContextId(nIdx);
390 
391  for ( sal_Int32 n = 0;
392  pSpecialContextIds[n].nContextID != -1;
393  n++ )
394  {
395  // found: set index in pSpecialContextIds array
396  if ( pSpecialContextIds[n].nContextID == nContextId )
397  {
398  pSpecialContextIds[n].nIndex = i;
399  break; // early out
400  }
401  }
402  }
403  }
404 
405 }
406 
408  const vector< XMLPropertyState >& aProperties,
409  const Reference< XPropertySet >& rPropSet,
410  ContextID_Index_Pair* pSpecialContextIds ) const
411 {
412  bool bSet = false;
413 
414  Reference< XTolerantMultiPropertySet > xTolPropSet( rPropSet, UNO_QUERY );
415  if (xTolPropSet.is())
416  bSet = FillTolerantMultiPropertySet_( aProperties, xTolPropSet, maPropMapper, rImport,
417  pSpecialContextIds );
418 
419  if (!bSet)
420  {
421  // get property set info
422  Reference< XPropertySetInfo > xInfo(rPropSet->getPropertySetInfo());
423 
424  // check for multi-property set
425  Reference<XMultiPropertySet> xMultiPropSet( rPropSet, UNO_QUERY );
426  if ( xMultiPropSet.is() )
427  {
428  // Try XMultiPropertySet. If that fails, try the regular route.
429  bSet = FillMultiPropertySet_( aProperties, xMultiPropSet,
430  xInfo, maPropMapper,
431  pSpecialContextIds );
432  if ( !bSet )
433  bSet = FillPropertySet_( aProperties, rPropSet,
434  xInfo, maPropMapper, rImport,
435  pSpecialContextIds);
436  }
437  else
438  bSet = FillPropertySet_( aProperties, rPropSet, xInfo,
440  pSpecialContextIds );
441  }
442 
443  return bSet;
444 }
445 
447  const vector<XMLPropertyState> & rProperties,
448  const Reference<XPropertySet> & rPropSet,
449  const Reference<XPropertySetInfo> & rPropSetInfo,
450  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
451  SvXMLImport& rImport,
452  ContextID_Index_Pair* pSpecialContextIds )
453 {
454  OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
455  OSL_ENSURE( rPropSetInfo.is(), "need an XPropertySetInfo" );
456 
457  // preliminaries
458  bool bSet = false;
459  sal_Int32 nCount = rProperties.size();
460 
461  // iterate over property states that we want to set
462  for( sal_Int32 i=0; i < nCount; i++ )
463  {
464  const XMLPropertyState& rProp = rProperties[i];
465  sal_Int32 nIdx = rProp.mnIndex;
466 
467  // disregard property state if it has an invalid index
468  if( -1 == nIdx )
469  continue;
470 
471  const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
472  const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
473 
474  if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
475  ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
476  rPropSetInfo->hasPropertyByName( rPropName ) ) )
477  {
478  // try setting the property
479  try
480  {
481  rPropSet->setPropertyValue( rPropName, rProp.maValue );
482  bSet = true;
483  }
484  catch ( const IllegalArgumentException& e )
485  {
486  // illegal value: check whether this property is
487  // allowed to throw this exception
488  if ( 0 == ( nPropFlags & MID_FLAG_PROPERTY_MAY_THROW ) )
489  {
490  Sequence<OUString> aSeq { rPropName };
491  rImport.SetError(
493  aSeq, e.Message, nullptr );
494  }
495  }
496  catch ( const UnknownPropertyException& e )
497  {
498  // unknown property: This is always an error!
499  Sequence<OUString> aSeq { rPropName };
500  rImport.SetError(
502  aSeq, e.Message, nullptr );
503  }
504  catch ( const PropertyVetoException& e )
505  {
506  // property veto: this shouldn't happen
507  Sequence<OUString> aSeq { rPropName };
508  rImport.SetError(
510  aSeq, e.Message, nullptr );
511  }
512  catch ( const WrappedTargetException& e )
513  {
514  // wrapped target: this shouldn't happen either
515  Sequence<OUString> aSeq { rPropName };
516  rImport.SetError(
518  aSeq, e.Message, nullptr );
519  }
520  }
521 
522  // handle no-property and special items
523  if( ( pSpecialContextIds != nullptr ) &&
524  ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
525  ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
526  {
527  // maybe it's one of our special context ids?
528  sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
529 
530  for ( sal_Int32 n = 0;
531  pSpecialContextIds[n].nContextID != -1;
532  n++ )
533  {
534  // found: set index in pSpecialContextIds array
535  if ( pSpecialContextIds[n].nContextID == nContextId )
536  {
537  pSpecialContextIds[n].nIndex = i;
538  break; // early out
539  }
540  }
541  }
542  }
543 
544  return bSet;
545 }
546 
547 
548 typedef pair<const OUString*, const Any* > PropertyPair;
549 typedef vector<PropertyPair> PropertyPairs;
550 
551 namespace {
552 
553 struct PropertyPairLessFunctor
554 {
555  bool operator()( const PropertyPair& a, const PropertyPair& b ) const
556  {
557  return (*a.first < *b.first);
558  }
559 };
560 
561 }
562 
564  const vector<XMLPropertyState> & rProperties,
565  const Reference<XPropertySetInfo> & rPropSetInfo,
566  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
567  ContextID_Index_Pair* pSpecialContextIds,
568  Sequence<OUString>& rNames,
569  Sequence<Any>& rValues)
570 {
571  sal_Int32 nCount = rProperties.size();
572 
573  // property pairs structure stores names + values of properties to be set.
574  PropertyPairs aPropertyPairs;
575  aPropertyPairs.reserve( nCount );
576 
577  // iterate over property states that we want to set
578  sal_Int32 i;
579  for( i = 0; i < nCount; i++ )
580  {
581  const XMLPropertyState& rProp = rProperties[i];
582  sal_Int32 nIdx = rProp.mnIndex;
583 
584  // disregard property state if it has an invalid index
585  if( -1 == nIdx )
586  continue;
587 
588  const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
589  const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
590 
591  if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
592  ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
593  !rPropSetInfo.is() ||
594  rPropSetInfo->hasPropertyByName(rPropName) ) )
595  {
596  // save property into property pair structure
597  aPropertyPairs.emplace_back( &rPropName, &rProp.maValue );
598  }
599 
600  // handle no-property and special items
601  if( ( pSpecialContextIds != nullptr ) &&
602  ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
603  ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
604  {
605  // maybe it's one of our special context ids?
606  sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
607  for ( sal_Int32 n = 0;
608  pSpecialContextIds[n].nContextID != -1;
609  n++ )
610  {
611  // found: set index in pSpecialContextIds array
612  if ( pSpecialContextIds[n].nContextID == nContextId )
613  {
614  pSpecialContextIds[n].nIndex = i;
615  break; // early out
616  }
617  }
618  }
619  }
620 
621  // We now need to construct the sequences and actually the set
622  // values.
623 
624  // sort the property pairs
625  sort( aPropertyPairs.begin(), aPropertyPairs.end(),
626  PropertyPairLessFunctor());
627 
628  // create sequences
629  rNames.realloc( aPropertyPairs.size() );
630  OUString* pNamesArray = rNames.getArray();
631  rValues.realloc( aPropertyPairs.size() );
632  Any* pValuesArray = rValues.getArray();
633 
634  // copy values into sequences
635  i = 0;
636  for( const auto& rPropertyPair : aPropertyPairs )
637  {
638  pNamesArray[i] = *(rPropertyPair.first);
639  pValuesArray[i++] = *(rPropertyPair.second);
640  }
641 }
642 
644  const vector<XMLPropertyState> & rProperties,
645  const Reference<XMultiPropertySet> & rMultiPropSet,
646  const Reference<XPropertySetInfo> & rPropSetInfo,
647  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
648  ContextID_Index_Pair* pSpecialContextIds )
649 {
650  OSL_ENSURE( rMultiPropSet.is(), "Need multi property set. ");
651  OSL_ENSURE( rPropSetInfo.is(), "Need property set info." );
652 
653  bool bSuccessful = false;
654 
655  Sequence<OUString> aNames;
656  Sequence<Any> aValues;
657 
658  PrepareForMultiPropertySet_(rProperties, rPropSetInfo, rPropMapper, pSpecialContextIds,
659  aNames, aValues);
660 
661  // and, finally, try to set the values
662  try
663  {
664  rMultiPropSet->setPropertyValues( aNames, aValues );
665  bSuccessful = true;
666  }
667  catch ( ... )
668  {
669  OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
670  }
671 
672  return bSuccessful;
673 }
674 
676  const vector<XMLPropertyState> & rProperties,
677  const Reference<XTolerantMultiPropertySet> & rTolMultiPropSet,
678  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
679  SvXMLImport& rImport,
680  ContextID_Index_Pair* pSpecialContextIds )
681 {
682  OSL_ENSURE( rTolMultiPropSet.is(), "Need tolerant multi property set. ");
683 
684  bool bSuccessful = false;
685 
686  Sequence<OUString> aNames;
687  Sequence<Any> aValues;
688 
689  PrepareForMultiPropertySet_(rProperties, Reference<XPropertySetInfo>(nullptr), rPropMapper, pSpecialContextIds,
690  aNames, aValues);
691 
692  // and, finally, try to set the values
693  try
694  {
695  const Sequence< SetPropertyTolerantFailed > aResults(rTolMultiPropSet->setPropertyValuesTolerant( aNames, aValues ));
696  bSuccessful = !aResults.hasElements();
697  for( const auto& rResult : aResults)
698  {
699  Sequence<OUString> aSeq { rResult.Name };
700  OUString sMessage;
701  switch (rResult.Result)
702  {
703  case TolerantPropertySetResultType::UNKNOWN_PROPERTY :
704  sMessage = "UNKNOWN_PROPERTY";
705  break;
706  case TolerantPropertySetResultType::ILLEGAL_ARGUMENT :
707  sMessage = "ILLEGAL_ARGUMENT";
708  break;
709  case TolerantPropertySetResultType::PROPERTY_VETO :
710  sMessage = "PROPERTY_VETO";
711  break;
712  case TolerantPropertySetResultType::WRAPPED_TARGET :
713  sMessage = "WRAPPED_TARGET";
714  break;
715  }
716  rImport.SetError(
718  aSeq, sMessage, nullptr );
719  }
720  }
721  catch ( ... )
722  {
723  OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
724  }
725 
726  return bSuccessful;
727 }
728 
730  vector< XMLPropertyState >& rProperties,
731  sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
732 {
733  // nothing to do here
734  if( mxNextMapper.is() )
735  mxNextMapper->finished( rProperties, nStartIndex, nEndIndex );
736 }
737 
738 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int16 nContextID
Definition: xmlimppr.hxx:56
const sal_uInt16 XML_NAMESPACE_XMLNS
Definition: nmspmap.hxx:36
void CheckSpecialContext(const ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, ContextID_Index_Pair *pSpecialContextIds) const
Definition: xmlimppr.cxx:364
OUString sMessage
sal_Int32 nIndex
vector< PropertyPair > PropertyPairs
Definition: xmlimppr.cxx:549
const char aData[]
SvXMLImportPropertyMapper(SvXMLImportPropertyMapper const &)=delete
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
Definition: xmluconv.hxx:77
#define MID_FLAG_NO_PROPERTY_IMPORT
Definition: xmltypes.hxx:76
#define SAL_INFO_IF(condition, area, stream)
#define XMLERROR_STYLE_ATTR_VALUE
Definition: xmlerror.hxx:53
sal_Int64 n
bool FillPropertySet(const ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, ContextID_Index_Pair *pSpecialContextIds=nullptr) const
Definition: xmlimppr.cxx:407
const sal_uInt16 XML_NAMESPACE_NONE
Definition: nmspmap.hxx:37
sal_Int32 mnIndex
Definition: maptype.hxx:106
void importXML(::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::xml::sax::XAttributeList > &xAttrList, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap, sal_uInt32 nPropType, sal_Int32 nStartIdx, sal_Int32 nEndIdx) const
fills the given itemset with the attributes in the given list the map is only searched within the ran...
Definition: xmlimppr.cxx:107
constexpr sal_uInt16 XML_NAMESPACE_TEXT
Definition: xmlnmspe.hxx:31
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
Definition: nmspmap.cxx:437
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
static bool FillMultiPropertySet_(const ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XMultiPropertySet > &rMultiPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo, const rtl::Reference< XMLPropertySetMapper > &rPropMapper, ContextID_Index_Pair *pSpecialContextIds)
implementation helper for FillPropertySet: fill an XMultiPropertySet.
Definition: xmlimppr.cxx:643
#define XMLERROR_STYLE_PROP_UNKNOWN
Definition: xmlerror.hxx:69
#define XML_TYPE_PROP_PARAGRAPH
Definition: xmltypes.hxx:99
#define XMLERROR_STYLE_PROP_OTHER
Definition: xmlerror.hxx:70
int nCount
#define MID_FLAG_MULTI_PROPERTY
Definition: xmltypes.hxx:64
void FillPropertySequence(const ::std::vector< XMLPropertyState > &aProperties, css::uno::Sequence< css::beans::PropertyValue > &rValues) const
Definition: xmlimppr.cxx:337
const sal_uInt16 XML_NAMESPACE_UNKNOWN_FLAG
Definition: nmspmap.hxx:39
const char * sName
#define XMLERROR_FLAG_WARNING
Definition: xmlerror.hxx:35
SvXMLImport & rImport
Definition: xmlimppr.hxx:64
virtual bool handleSpecialItem(XMLPropertyState &rProperty,::std::vector< XMLPropertyState > &rProperties, const OUString &rValue, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap) const
this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set ...
Definition: xmlimppr.cxx:322
#define XMLERROR_STYLE_PROP_VALUE
Definition: xmlerror.hxx:68
int i
uno_Any a
uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance()
Definition: unoatrcn.cxx:36
virtual void finished(::std::vector< XMLPropertyState > &rProperties, sal_Int32 nStartIndex, sal_Int32 nEndIndex) const
This method is called when all attributes have benn processed.
Definition: xmlimppr.cxx:729
#define MID_FLAG_NO_PROPERTY
Definition: xmltypes.hxx:78
rtl::Reference< XMLPropertySetMapper > maPropMapper
Definition: xmlimppr.hxx:71
#define XML_TYPE_PROP_TEXT
Definition: xmltypes.hxx:98
static bool FillPropertySet_(const ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo, const rtl::Reference< XMLPropertySetMapper > &rPropMapper, SvXMLImport &rImport, ContextID_Index_Pair *pSpecialContextIds)
implementation helper for FillPropertySet: fill an XPropertySet.
Definition: xmlimppr.cxx:446
#define XML_TYPE_PROP_CHART
Definition: xmltypes.hxx:107
#define MID_FLAG_MERGE_PROPERTY
Definition: xmltypes.hxx:61
#define MID_FLAG_PROPERTY_MAY_THROW
Definition: xmltypes.hxx:44
css::uno::Any maValue
Definition: maptype.hxx:107
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3366
Handling of tokens in XML:
#define MID_FLAG_ELEMENT_ITEM_IMPORT
Definition: xmltypes.hxx:68
virtual ~SvXMLImportPropertyMapper() override
Definition: xmlimppr.cxx:71
#define XMLERROR_FLAG_ERROR
Definition: xmlerror.hxx:36
Smart struct to transport an Any with an index to the appropriate property-name.
Definition: maptype.hxx:104
void SetError(sal_Int32 nId, const css::uno::Sequence< OUString > &rMsgParams, const OUString &rExceptionMessage, const css::uno::Reference< css::xml::sax::XLocator > &rLocator)
Record an error condition that occurred during import.
Sequence< sal_Int8 > aSeq
This struct is used as an optional parameter to the static _FillPropertySet() methods.
Definition: xmlimppr.hxx:54
static bool FillTolerantMultiPropertySet_(const ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XTolerantMultiPropertySet > &rTolPropSet, const rtl::Reference< XMLPropertySetMapper > &rPropMapper, SvXMLImport &rImport, ContextID_Index_Pair *pSpecialContextIds)
implementation helper for FillPropertySet: fill an XTolerantMultiPropertySet.
Definition: xmlimppr.cxx:675
#define MID_FLAG_MUST_EXIST
Definition: xmltypes.hxx:52
void ChainImportMapper(const rtl::Reference< SvXMLImportPropertyMapper > &rMapper)
Definition: xmlimppr.cxx:76
rtl::Reference< SvXMLImportPropertyMapper > mxNextMapper
Definition: xmlimppr.hxx:62
static void PrepareForMultiPropertySet_(const ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XPropertySetInfo > &rPropSetInfo, const rtl::Reference< XMLPropertySetMapper > &rPropMapper, ContextID_Index_Pair *pSpecialContextIds, css::uno::Sequence< OUString > &rNames, css::uno::Sequence< css::uno::Any > &rValues)
Definition: xmlimppr.cxx:563
#define CTF_ALIEN_ATTRIBUTE_IMPORT
use together with MID_FLAG_NO_PROPERTY to import the specified attribute into the alien attribute con...
Definition: contextid.hxx:44
#define MID_FLAG_SPECIAL_ITEM_IMPORT
Definition: xmltypes.hxx:82
pair< const OUString *, const Any * > PropertyPair
Definition: xmlimppr.cxx:548