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/namespacemap.hxx>
34 #include <xmloff/xmlimppr.hxx>
35 #include <xmloff/xmlimp.hxx>
36 
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>
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< XFastAttributeList >& xAttrList,
110  const SvXMLUnitConverter& rUnitConverter,
111  const SvXMLNamespaceMap& rNamespaceMap,
112  sal_uInt32 nPropType,
113  sal_Int32 nStartIdx,
114  sal_Int32 nEndIdx ) const
115 {
116  Reference< XNameContainer > xAttrContainer;
117 
118  if( -1 == nStartIdx )
119  nStartIdx = 0;
120  if( -1 == nEndIdx )
121  nEndIdx = maPropMapper->GetEntryCount();
122 
123  for (auto &aIter : sax_fastparser::castToFastAttributeList( xAttrList ))
124  {
125  sal_Int32 nToken = aIter.getToken();
127  continue;
128 
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;
134 
135  const OUString sValue = aIter.toString();
136 
137  importXMLAttribute(rProperties, rUnitConverter, rNamespaceMap,
138  nPropType, nStartIdx, nEndIdx, xAttrContainer,
139  sAttrName, aNamespaceURI, sValue);
140  }
141 
142  const css::uno::Sequence< css::xml::Attribute > unknownAttribs = xAttrList->getUnknownAttributes();
143  for (const css::xml::Attribute& rAttribute : unknownAttribs)
144  {
145  int nSepIndex = rAttribute.Name.indexOf(SvXMLImport::aNamespaceSeparator);
146  if (nSepIndex != -1)
147  {
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;
153  }
154 
155  importXMLAttribute(rProperties, rUnitConverter, rNamespaceMap,
156  nPropType, nStartIdx, nEndIdx, xAttrContainer,
157  rAttribute.Name, rAttribute.NamespaceURL, rAttribute.Value);
158  }
159 
160  finished( rProperties, nStartIdx, nEndIdx );
161 }
162 
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
174 {
175  OUString aLocalName, aPrefix, aNamespace;
176  sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rAttrName, &aPrefix,
177  &aLocalName, &aNamespace );
178 
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;
187 
188  // for better error reporting: this should be set true if no
189  // warning is needed
190  bool bNoWarning = false;
191 
192  do
193  {
194  // find an entry for this attribute
195  nIndex = maPropMapper->GetEntryIndex( nPrefix, aLocalName,
196  nPropType, nIndex );
197 
198  if( nIndex > -1 && nIndex < nEndIdx )
199  {
200  // create a XMLPropertyState with an empty value
201 
202  nFlags = maPropMapper->GetEntryFlags( nIndex );
203  if( ( nFlags & MID_FLAG_ELEMENT_ITEM_IMPORT ) == 0 )
204  {
205  XMLPropertyState aNewProperty( nIndex );
206  sal_Int32 nReference = -1;
207 
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 )
211  {
212  const OUString aAPIName( maPropMapper->GetEntryAPIName( nIndex ) );
213  const sal_Int32 nSize = rProperties.size();
214  for( nReference = 0; nReference < nSize; nReference++ )
215  {
216  sal_Int32 nRefIdx = rProperties[nReference].mnIndex;
217  if( (nRefIdx != -1) && (nIndex != nRefIdx) &&
218  (maPropMapper->GetEntryAPIName( nRefIdx ) == aAPIName ))
219  {
220  aNewProperty = rProperties[nReference];
221  aNewProperty.mnIndex = nIndex;
222  break;
223  }
224  }
225 
226  if( nReference == nSize )
227  nReference = -1;
228  }
229 
230  bool bSet = false;
231  if( ( nFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) == 0 )
232  {
233  // let the XMLPropertySetMapper decide how to import the value
234  bSet = maPropMapper->importXML( sValue, aNewProperty,
235  rUnitConverter );
236  }
237  else
238  {
239  sal_uInt32 nOldSize = rProperties.size();
240 
241  bSet = handleSpecialItem( aNewProperty, rProperties,
242  sValue, rUnitConverter,
243  rNamespaceMap );
244 
245  // no warning if handleSpecialItem added properties
246  bNoWarning |= ( nOldSize != rProperties.size() );
247  }
248 
249  // no warning if we found could set the item. This
250  // 'remembers' bSet across multi properties.
251  bNoWarning |= bSet;
252 
253  // store the property in the given vector
254  if( bSet )
255  {
256  if( nReference == -1 )
257  rProperties.push_back( aNewProperty );
258  else
259  rProperties[nReference] = aNewProperty;
260  }
261  else
262  {
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) )
268  {
271  { rAttrName, sValue } );
272  }
273  }
274  }
275  bFound = true;
276  continue;
277  }
278 
279  if( !bFound )
280  {
281  SAL_INFO_IF((XML_NAMESPACE_NONE != nPrefix) &&
282  !(XML_NAMESPACE_UNKNOWN_FLAG & nPrefix),
283  "xmloff.style",
284  "unknown attribute: \"" << rAttrName << "\"");
285  if( (XML_NAMESPACE_UNKNOWN_FLAG & nPrefix) || (XML_NAMESPACE_NONE == nPrefix) )
286  {
287  if( !xAttrContainer.is() )
288  {
289  // add an unknown attribute container to the properties
290  Reference< XNameContainer > xNew( SvUnoAttributeContainer_CreateInstance(), UNO_QUERY );
291  xAttrContainer = xNew;
292 
293  // find map entry and create new property state
294  if( -1 == nIndex )
295  {
296  switch( nPropType )
297  {
298  case XML_TYPE_PROP_CHART:
299  nIndex = maPropMapper->FindEntryIndex( "ChartUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
300  break;
302  nIndex = maPropMapper->FindEntryIndex( "ParaUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
303  break;
304  case XML_TYPE_PROP_TEXT:
305  nIndex = maPropMapper->FindEntryIndex( "TextUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
306  break;
307  default:
308  break;
309  }
310  // other property type or property not found
311  if( -1 == nIndex )
312  nIndex = maPropMapper->FindEntryIndex( "UserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
313  }
314 
315  // #106963#; use userdefined attribute only if it is in the specified property range
316  if( nIndex != -1 && nIndex >= nStartIdx && nIndex < nEndIdx)
317  {
318  XMLPropertyState aNewProperty( nIndex, Any(xAttrContainer) );
319 
320  // push it on our stack so we export it later
321  rProperties.push_back( aNewProperty );
322  }
323  }
324 
325  if( xAttrContainer.is() )
326  {
327  AttributeData aData;
328  aData.Type = GetXMLToken( XML_CDATA );
329  aData.Value = sValue;
330  OUString sName;
331  if( XML_NAMESPACE_NONE != nPrefix )
332  {
333  sName = rAttrName;
334  aData.Namespace = aNamespaceURI;
335  }
336  else
337  sName = aLocalName;
338  xAttrContainer->insertByName( sName, Any(aData) );
339  }
340  }
341  }
342  }
343  while( ( nIndex >= 0 && nIndex + 1 < nEndIdx ) && (( nFlags & MID_FLAG_MULTI_PROPERTY ) != 0 ) );
344 }
345 
348  XMLPropertyState& rProperty,
349  vector< XMLPropertyState >& rProperties,
350  const OUString& rValue,
351  const SvXMLUnitConverter& rUnitConverter,
352  const SvXMLNamespaceMap& rNamespaceMap ) const
353 {
354  OSL_ENSURE( mxNextMapper.is(), "unsupported special item in xml import" );
355  if( mxNextMapper.is() )
356  return mxNextMapper->handleSpecialItem( rProperty, rProperties, rValue,
357  rUnitConverter, rNamespaceMap );
358  else
359  return false;
360 }
361 
363  const ::std::vector< XMLPropertyState >& rProperties,
364  css::uno::Sequence< css::beans::PropertyValue >& rValues )
365  const
366 {
367  sal_Int32 nCount = rProperties.size();
368  sal_Int32 nValueCount = 0;
369  rValues.realloc( nCount );
370  PropertyValue *pProps = rValues.getArray();
371  for( sal_Int32 i=0; i < nCount; i++ )
372  {
373  const XMLPropertyState& rProp = rProperties[i];
374  sal_Int32 nIdx = rProp.mnIndex;
375  if( nIdx == -1 )
376  continue;
377  pProps->Name = maPropMapper->GetEntryAPIName( nIdx );
378  if( !pProps->Name.isEmpty() )
379  {
380  pProps->Value = rProp.maValue;
381  ++pProps;
382  ++nValueCount;
383  }
384  }
385  if( nValueCount < nCount )
386  rValues.realloc( nValueCount );
387 }
388 
390  const ::std::vector< XMLPropertyState >& aProperties,
391  const css::uno::Reference< css::beans::XPropertySet >& rPropSet,
392  ContextID_Index_Pair* pSpecialContextIds ) const
393 {
394  OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
395  sal_Int32 nCount = aProperties.size();
396 
397  for( sal_Int32 i=0; i < nCount; i++ )
398  {
399  const XMLPropertyState& rProp = aProperties[i];
400  sal_Int32 nIdx = rProp.mnIndex;
401 
402  // disregard property state if it has an invalid index
403  if( -1 == nIdx )
404  continue;
405 
406  const sal_Int32 nPropFlags = maPropMapper->GetEntryFlags( nIdx );
407 
408  // handle no-property and special items
409  if( ( pSpecialContextIds != nullptr ) &&
410  ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
411  ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
412  {
413  // maybe it's one of our special context ids?
414  sal_Int16 nContextId = maPropMapper->GetEntryContextId(nIdx);
415 
416  for ( sal_Int32 n = 0;
417  pSpecialContextIds[n].nContextID != -1;
418  n++ )
419  {
420  // found: set index in pSpecialContextIds array
421  if ( pSpecialContextIds[n].nContextID == nContextId )
422  {
423  pSpecialContextIds[n].nIndex = i;
424  break; // early out
425  }
426  }
427  }
428  }
429 
430 }
431 
433  const vector< XMLPropertyState >& aProperties,
434  const Reference< XPropertySet >& rPropSet,
435  ContextID_Index_Pair* pSpecialContextIds ) const
436 {
437  bool bSet = false;
438 
439  Reference< XTolerantMultiPropertySet > xTolPropSet( rPropSet, UNO_QUERY );
440  if (xTolPropSet.is())
441  bSet = FillTolerantMultiPropertySet_( aProperties, xTolPropSet, maPropMapper, rImport,
442  pSpecialContextIds );
443 
444  if (!bSet)
445  {
446  // get property set info
447  Reference< XPropertySetInfo > xInfo(rPropSet->getPropertySetInfo());
448 
449  // check for multi-property set
450  Reference<XMultiPropertySet> xMultiPropSet( rPropSet, UNO_QUERY );
451  if ( xMultiPropSet.is() )
452  {
453  // Try XMultiPropertySet. If that fails, try the regular route.
454  bSet = FillMultiPropertySet_( aProperties, xMultiPropSet,
455  xInfo, maPropMapper,
456  pSpecialContextIds );
457  if ( !bSet )
458  bSet = FillPropertySet_( aProperties, rPropSet,
459  xInfo, maPropMapper, rImport,
460  pSpecialContextIds);
461  }
462  else
463  bSet = FillPropertySet_( aProperties, rPropSet, xInfo,
465  pSpecialContextIds );
466  }
467 
468  return bSet;
469 }
470 
472  const vector<XMLPropertyState> & rProperties,
473  const Reference<XPropertySet> & rPropSet,
474  const Reference<XPropertySetInfo> & rPropSetInfo,
475  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
476  SvXMLImport& rImport,
477  ContextID_Index_Pair* pSpecialContextIds )
478 {
479  OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
480  OSL_ENSURE( rPropSetInfo.is(), "need an XPropertySetInfo" );
481 
482  // preliminaries
483  bool bSet = false;
484  sal_Int32 nCount = rProperties.size();
485 
486  // iterate over property states that we want to set
487  for( sal_Int32 i=0; i < nCount; i++ )
488  {
489  const XMLPropertyState& rProp = rProperties[i];
490  sal_Int32 nIdx = rProp.mnIndex;
491 
492  // disregard property state if it has an invalid index
493  if( -1 == nIdx )
494  continue;
495 
496  const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
497  const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
498 
499  if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
500  ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
501  rPropSetInfo->hasPropertyByName( rPropName ) ) )
502  {
503  // try setting the property
504  try
505  {
506  rPropSet->setPropertyValue( rPropName, rProp.maValue );
507  bSet = true;
508  }
509  catch ( const IllegalArgumentException& e )
510  {
511  // illegal value: check whether this property is
512  // allowed to throw this exception
513  if ( 0 == ( nPropFlags & MID_FLAG_PROPERTY_MAY_THROW ) )
514  {
515  Sequence<OUString> aSeq { rPropName };
516  rImport.SetError(
518  aSeq, e.Message, nullptr );
519  }
520  }
521  catch ( const UnknownPropertyException& e )
522  {
523  // unknown property: This is always an error!
524  Sequence<OUString> aSeq { rPropName };
525  rImport.SetError(
527  aSeq, e.Message, nullptr );
528  }
529  catch ( const PropertyVetoException& e )
530  {
531  // property veto: this shouldn't happen
532  Sequence<OUString> aSeq { rPropName };
533  rImport.SetError(
535  aSeq, e.Message, nullptr );
536  }
537  catch ( const WrappedTargetException& e )
538  {
539  // wrapped target: this shouldn't happen either
540  Sequence<OUString> aSeq { rPropName };
541  rImport.SetError(
543  aSeq, e.Message, nullptr );
544  }
545  }
546 
547  // handle no-property and special items
548  if( ( pSpecialContextIds != nullptr ) &&
549  ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
550  ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
551  {
552  // maybe it's one of our special context ids?
553  sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
554 
555  for ( sal_Int32 n = 0;
556  pSpecialContextIds[n].nContextID != -1;
557  n++ )
558  {
559  // found: set index in pSpecialContextIds array
560  if ( pSpecialContextIds[n].nContextID == nContextId )
561  {
562  pSpecialContextIds[n].nIndex = i;
563  break; // early out
564  }
565  }
566  }
567  }
568 
569  return bSet;
570 }
571 
572 
573 typedef pair<const OUString*, const Any* > PropertyPair;
574 
575 namespace {
576 
577 struct PropertyPairLessFunctor
578 {
579  bool operator()( const PropertyPair& a, const PropertyPair& b ) const
580  {
581  return (*a.first < *b.first);
582  }
583 };
584 
585 }
586 
588  const vector<XMLPropertyState> & rProperties,
589  const Reference<XPropertySetInfo> & rPropSetInfo,
590  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
591  ContextID_Index_Pair* pSpecialContextIds,
592  Sequence<OUString>& rNames,
593  Sequence<Any>& rValues)
594 {
595  sal_Int32 nCount = rProperties.size();
596 
597  // property pairs structure stores names + values of properties to be set.
598  vector<PropertyPair> aPropertyPairs;
599  aPropertyPairs.reserve( nCount );
600 
601  // iterate over property states that we want to set
602  sal_Int32 i;
603  for( i = 0; i < nCount; i++ )
604  {
605  const XMLPropertyState& rProp = rProperties[i];
606  sal_Int32 nIdx = rProp.mnIndex;
607 
608  // disregard property state if it has an invalid index
609  if( -1 == nIdx )
610  continue;
611 
612  const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
613  const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
614 
615  if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
616  ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
617  !rPropSetInfo.is() ||
618  rPropSetInfo->hasPropertyByName(rPropName) ) )
619  {
620  // save property into property pair structure
621  aPropertyPairs.emplace_back( &rPropName, &rProp.maValue );
622  }
623 
624  // handle no-property and special items
625  if( ( pSpecialContextIds != nullptr ) &&
626  ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
627  ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) ) ) )
628  {
629  // maybe it's one of our special context ids?
630  sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
631  for ( sal_Int32 n = 0;
632  pSpecialContextIds[n].nContextID != -1;
633  n++ )
634  {
635  // found: set index in pSpecialContextIds array
636  if ( pSpecialContextIds[n].nContextID == nContextId )
637  {
638  pSpecialContextIds[n].nIndex = i;
639  break; // early out
640  }
641  }
642  }
643  }
644 
645  // We now need to construct the sequences and actually the set
646  // values.
647 
648  // sort the property pairs
649  sort( aPropertyPairs.begin(), aPropertyPairs.end(),
650  PropertyPairLessFunctor());
651 
652  // create sequences
653  rNames.realloc( aPropertyPairs.size() );
654  OUString* pNamesArray = rNames.getArray();
655  rValues.realloc( aPropertyPairs.size() );
656  Any* pValuesArray = rValues.getArray();
657 
658  // copy values into sequences
659  i = 0;
660  for( const auto& rPropertyPair : aPropertyPairs )
661  {
662  pNamesArray[i] = *(rPropertyPair.first);
663  pValuesArray[i++] = *(rPropertyPair.second);
664  }
665 }
666 
668  const vector<XMLPropertyState> & rProperties,
669  const Reference<XMultiPropertySet> & rMultiPropSet,
670  const Reference<XPropertySetInfo> & rPropSetInfo,
671  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
672  ContextID_Index_Pair* pSpecialContextIds )
673 {
674  OSL_ENSURE( rMultiPropSet.is(), "Need multi property set. ");
675  OSL_ENSURE( rPropSetInfo.is(), "Need property set info." );
676 
677  bool bSuccessful = false;
678 
679  Sequence<OUString> aNames;
680  Sequence<Any> aValues;
681 
682  PrepareForMultiPropertySet_(rProperties, rPropSetInfo, rPropMapper, pSpecialContextIds,
683  aNames, aValues);
684 
685  // and, finally, try to set the values
686  try
687  {
688  rMultiPropSet->setPropertyValues( aNames, aValues );
689  bSuccessful = true;
690  }
691  catch ( ... )
692  {
693  OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
694  }
695 
696  return bSuccessful;
697 }
698 
700  const vector<XMLPropertyState> & rProperties,
701  const Reference<XTolerantMultiPropertySet> & rTolMultiPropSet,
702  const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
703  SvXMLImport& rImport,
704  ContextID_Index_Pair* pSpecialContextIds )
705 {
706  OSL_ENSURE( rTolMultiPropSet.is(), "Need tolerant multi property set. ");
707 
708  bool bSuccessful = false;
709 
710  Sequence<OUString> aNames;
711  Sequence<Any> aValues;
712 
713  PrepareForMultiPropertySet_(rProperties, Reference<XPropertySetInfo>(nullptr), rPropMapper, pSpecialContextIds,
714  aNames, aValues);
715 
716  // and, finally, try to set the values
717  try
718  {
719  const Sequence< SetPropertyTolerantFailed > aResults(rTolMultiPropSet->setPropertyValuesTolerant( aNames, aValues ));
720  bSuccessful = !aResults.hasElements();
721  for( const auto& rResult : aResults)
722  {
723  Sequence<OUString> aSeq { rResult.Name };
724  OUString sMessage;
725  switch (rResult.Result)
726  {
727  case TolerantPropertySetResultType::UNKNOWN_PROPERTY :
728  sMessage = "UNKNOWN_PROPERTY";
729  break;
730  case TolerantPropertySetResultType::ILLEGAL_ARGUMENT :
731  sMessage = "ILLEGAL_ARGUMENT";
732  break;
733  case TolerantPropertySetResultType::PROPERTY_VETO :
734  sMessage = "PROPERTY_VETO";
735  break;
736  case TolerantPropertySetResultType::WRAPPED_TARGET :
737  sMessage = "WRAPPED_TARGET";
738  break;
739  }
740  rImport.SetError(
742  aSeq, sMessage, nullptr );
743  }
744  }
745  catch ( ... )
746  {
747  OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
748  }
749 
750  return bSuccessful;
751 }
752 
754  vector< XMLPropertyState >& rProperties,
755  sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
756 {
757  // nothing to do here
758  if( mxNextMapper.is() )
759  mxNextMapper->finished( rProperties, nStartIndex, nEndIndex );
760 }
761 
762 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_Int16 nContextID
Definition: xmlimppr.hxx:59
void CheckSpecialContext(const ::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, ContextID_Index_Pair *pSpecialContextIds) const
Definition: xmlimppr.cxx:389
sal_uInt16 GetKeyByPrefix(const OUString &rPrefix) const
OUString sMessage
sal_Int32 nIndex
void importXMLAttribute(std::vector< XMLPropertyState > &rProperties, const SvXMLUnitConverter &rUnitConverter, const SvXMLNamespaceMap &rNamespaceMap, sal_uInt32 nPropType, sal_Int32 nStartIdx, sal_Int32 nEndIdx, css::uno::Reference< css::container::XNameContainer > &xAttrContainer, const OUString &sAttrName, const OUString &aNamespaceURI, const OUString &sValue) const
Definition: xmlimppr.cxx:163
SvXMLImportPropertyMapper(SvXMLImportPropertyMapper const &)=delete
the SvXMLTypeConverter converts values of various types from their internal representation to the tex...
Definition: xmluconv.hxx:82
#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:432
sal_Int32 mnIndex
Definition: maptype.hxx:141
FastAttributeList & castToFastAttributeList(const css::uno::Reference< css::xml::sax::XFastAttributeList > &xAttrList)
sal_uInt16 GetKeyByAttrName(const OUString &rAttrName, OUString *pPrefix, OUString *pLocalName, OUString *pNamespace) const
const sal_uInt16 XML_NAMESPACE_XMLNS
static OUString getNamespaceURIFromToken(sal_Int32 nToken)
Definition: xmlimp.cxx:1983
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:667
#define XMLERROR_STYLE_PROP_UNKNOWN
Definition: xmlerror.hxx:69
#define XML_TYPE_PROP_PARAGRAPH
Definition: xmltypes.hxx:99
static constexpr OUStringLiteral aNamespaceSeparator
Definition: xmlimp.hxx:533
#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:362
const char * sName
#define XMLERROR_FLAG_WARNING
Definition: xmlerror.hxx:35
constexpr OUStringLiteral aData
SvXMLImport & rImport
Definition: xmlimppr.hxx:68
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:347
#define XMLERROR_STYLE_PROP_VALUE
Definition: xmlerror.hxx:68
int i
uno_Any a
uno::Reference< uno::XInterface > SvUnoAttributeContainer_CreateInstance()
Definition: unoatrcn.cxx:36
constexpr sal_uInt16 XML_NAMESPACE_TEXT
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:753
const sal_uInt16 XML_NAMESPACE_UNKNOWN_FLAG
#define MID_FLAG_NO_PROPERTY
Definition: xmltypes.hxx:78
static OUString getNamespacePrefixFromToken(sal_Int32 nToken, const SvXMLNamespaceMap *pMap)
Definition: xmlimp.cxx:1965
rtl::Reference< XMLPropertySetMapper > maPropMapper
Definition: xmlimppr.hxx:75
#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:471
const sal_uInt16 XML_NAMESPACE_NONE
#define XML_TYPE_PROP_CHART
Definition: xmltypes.hxx:107
#define MID_FLAG_MERGE_PROPERTY
Definition: xmltypes.hxx:61
static const OUString & getNameFromToken(sal_Int32 nToken)
Definition: xmlimp.cxx:1950
DefTokenId nToken
#define MID_FLAG_PROPERTY_MAY_THROW
Definition: xmltypes.hxx:44
css::uno::Any maValue
Definition: maptype.hxx:142
constexpr bool IsTokenInNamespace(sal_Int32 nToken, sal_uInt16 nNamespacePrefix)
Definition: xmlimp.hxx:104
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3517
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:139
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:57
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:699
#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:66
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:587
#define MID_FLAG_SPECIAL_ITEM_IMPORT
Definition: xmltypes.hxx:82
void importXML(::std::vector< XMLPropertyState > &rProperties, const css::uno::Reference< css::xml::sax::XFastAttributeList > &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
pair< const OUString *, const Any * > PropertyPair
Definition: xmlimppr.cxx:573