LCOV - code coverage report
Current view: top level - xmloff/source/style - xmlimppr.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 247 297 83.2 %
Date: 2014-11-03 Functions: 15 15 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <rtl/ustrbuf.hxx>
      28             : #include <xmloff/xmlprmap.hxx>
      29             : #include <xmloff/nmspmap.hxx>
      30             : #include <xmloff/xmlimppr.hxx>
      31             : #include <xmloff/xmlimp.hxx>
      32             : 
      33             : #include <xmloff/unoatrcn.hxx>
      34             : #include <xmloff/xmlnmspe.hxx>
      35             : #include <xmloff/xmltoken.hxx>
      36             : #include <xmloff/xmlerror.hxx>
      37             : #include <xmloff/contextid.hxx>
      38             : #include <xmloff/xmltypes.hxx>
      39             : #include <xmloff/maptype.hxx>
      40             : 
      41             : #include <algorithm>
      42             : #include <functional>
      43             : #include <utility>
      44             : #include <vector>
      45             : 
      46             : using namespace ::com::sun::star::uno;
      47             : using namespace ::com::sun::star::beans;
      48             : using namespace ::com::sun::star::container;
      49             : using namespace ::com::sun::star::xml;
      50             : using namespace ::com::sun::star::xml::sax;
      51             : 
      52             : using namespace ::std;
      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;
      58             : 
      59             : 
      60       27190 : SvXMLImportPropertyMapper::SvXMLImportPropertyMapper(
      61             :         const rtl::Reference< XMLPropertySetMapper >& rMapper,
      62             :         SvXMLImport& rImp ):
      63             :     rImport(rImp),
      64       27190 :     maPropMapper  ( rMapper )
      65             : {
      66       27190 : }
      67             : 
      68       63212 : SvXMLImportPropertyMapper::~SvXMLImportPropertyMapper()
      69             : {
      70       27190 :     mxNextMapper = 0;
      71       36022 : }
      72             : 
      73        7278 : void SvXMLImportPropertyMapper::ChainImportMapper(
      74             :         const rtl::Reference< SvXMLImportPropertyMapper>& rMapper )
      75             : {
      76             :     // add map entries from rMapper to current map
      77        7278 :     maPropMapper->AddMapperEntry( rMapper->getPropertySetMapper() );
      78             :     // rMapper uses the same map as 'this'
      79        7278 :     rMapper->maPropMapper = maPropMapper;
      80             : 
      81             :     // set rMapper as last mapper in current chain
      82        7278 :     rtl::Reference< SvXMLImportPropertyMapper > xNext = mxNextMapper;
      83        7278 :     if( xNext.is())
      84             :     {
      85        5838 :         while( xNext->mxNextMapper.is())
      86         730 :             xNext = xNext->mxNextMapper;
      87        2554 :         xNext->mxNextMapper = rMapper;
      88             :     }
      89             :     else
      90        4724 :         mxNextMapper = rMapper;
      91             : 
      92             :     // if rMapper was already chained, correct
      93             :     // map pointer of successors
      94        7278 :     xNext = rMapper;
      95             : 
      96       16624 :     while( xNext->mxNextMapper.is())
      97             :     {
      98        2068 :         xNext = xNext->mxNextMapper;
      99        2068 :         xNext->maPropMapper = maPropMapper;
     100        7278 :     }
     101        7278 : }
     102             : 
     103             : /** fills the given itemset with the attributes in the given list */
     104       31292 : void SvXMLImportPropertyMapper::importXML(
     105             :         vector< XMLPropertyState >& rProperties,
     106             :            Reference< XAttributeList > xAttrList,
     107             :            const SvXMLUnitConverter& rUnitConverter,
     108             :         const SvXMLNamespaceMap& rNamespaceMap,
     109             :         sal_uInt32 nPropType,
     110             :         sal_Int32 nStartIdx,
     111             :         sal_Int32 nEndIdx ) const
     112             : {
     113       31292 :     sal_Int16 nAttr = xAttrList->getLength();
     114             : 
     115       31292 :     Reference< XNameContainer > xAttrContainer;
     116             : 
     117       31292 :     if( -1 == nStartIdx )
     118       28604 :         nStartIdx = 0;
     119       31292 :     if( -1 == nEndIdx )
     120       28604 :         nEndIdx = maPropMapper->GetEntryCount();
     121      186850 :     for( sal_Int16 i=0; i < nAttr; i++ )
     122             :     {
     123      155558 :         const OUString& rAttrName = xAttrList->getNameByIndex( i );
     124      311116 :         OUString aLocalName, aPrefix, aNamespace;
     125             :         sal_uInt16 nPrefix = rNamespaceMap.GetKeyByAttrName( rAttrName, &aPrefix,
     126      155558 :                                                     &aLocalName, &aNamespace );
     127             : 
     128      155558 :         if( XML_NAMESPACE_XMLNS == nPrefix )
     129           0 :             continue;
     130             : 
     131      311116 :         const OUString& rValue = xAttrList->getValueByIndex( i );
     132             : 
     133             :         // index of actual property map entry
     134             :         // This looks very strange, but it works well:
     135             :         // If the start index is 0, the new value will become -1, and
     136             :         // GetEntryIndex will start searching with position 0.
     137             :         // Otherwise GetEntryIndex will start with the next position specified.
     138      155558 :         sal_Int32 nIndex =  nStartIdx - 1;
     139      155558 :         sal_uInt32 nFlags = 0;  // flags of actual property map entry
     140      155558 :         bool bFound = false;
     141             : 
     142             :         // for better error reporting: this should be set true if no
     143             :         // warning is needed
     144      155558 :         bool bNoWarning = false;
     145      155558 :         bool bAlienImport = false;
     146             : 
     147      225558 :         do
     148             :         {
     149             :             // find an entry for this attribute
     150             :             nIndex = maPropMapper->GetEntryIndex( nPrefix, aLocalName,
     151      225558 :                                                   nPropType, nIndex );
     152             : 
     153      225558 :             if( nIndex > -1 && nIndex < nEndIdx  )
     154             :             {
     155             :                 // create a XMLPropertyState with an empty value
     156             : 
     157      198942 :                 nFlags = maPropMapper->GetEntryFlags( nIndex );
     158      198942 :                 if( (( nFlags & MID_FLAG_NO_PROPERTY ) == MID_FLAG_NO_PROPERTY) && (maPropMapper->GetEntryContextId( nIndex ) == CTF_ALIEN_ATTRIBUTE_IMPORT) )
     159             :                 {
     160           0 :                     bAlienImport = true;
     161           0 :                     nIndex = -1;
     162             :                 }
     163             :                 else
     164             :                 {
     165      198942 :                     if( ( nFlags & MID_FLAG_ELEMENT_ITEM_IMPORT ) == 0 )
     166             :                     {
     167      198942 :                         XMLPropertyState aNewProperty( nIndex );
     168      198942 :                         sal_Int32 nReference = -1;
     169             : 
     170             :                         // if this is a multi attribute check if another attribute already set
     171             :                         // this any. If so use this as a initial value
     172      198942 :                         if( ( nFlags & MID_FLAG_MERGE_PROPERTY ) != 0 )
     173             :                         {
     174       18430 :                             const OUString aAPIName( maPropMapper->GetEntryAPIName( nIndex ) );
     175       18430 :                             const sal_Int32 nSize = rProperties.size();
     176      257868 :                             for( nReference = 0; nReference < nSize; nReference++ )
     177             :                             {
     178      246050 :                                 sal_Int32 nRefIdx = rProperties[nReference].mnIndex;
     179      484786 :                                 if( (nRefIdx != -1) && (nIndex != nRefIdx) &&
     180      238736 :                                     (maPropMapper->GetEntryAPIName( nRefIdx ) == aAPIName ))
     181             :                                 {
     182        6612 :                                     aNewProperty = rProperties[nReference];
     183        6612 :                                     aNewProperty.mnIndex = nIndex;
     184        6612 :                                     break;
     185             :                                 }
     186             :                             }
     187             : 
     188       18430 :                             if( nReference == nSize )
     189       11818 :                                 nReference = -1;
     190             :                         }
     191             : 
     192      198942 :                         bool bSet = false;
     193      198942 :                         if( ( nFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) == 0 )
     194             :                         {
     195             :                             // let the XMLPropertySetMapper decide how to import the value
     196      181986 :                             bSet = maPropMapper->importXML( rValue, aNewProperty,
     197      181986 :                                                      rUnitConverter );
     198             :                         }
     199             :                         else
     200             :                         {
     201       16956 :                             sal_uInt32 nOldSize = rProperties.size();
     202             : 
     203             :                             bSet = handleSpecialItem( aNewProperty, rProperties,
     204             :                                                       rValue, rUnitConverter,
     205       16956 :                                                          rNamespaceMap );
     206             : 
     207             :                             // no warning if handleSpecialItem added properties
     208       16956 :                             bNoWarning |= ( nOldSize != rProperties.size() );
     209             :                         }
     210             : 
     211             :                         // no warning if we found could set the item. This
     212             :                         // 'remembers' bSet across multi properties.
     213      198942 :                         bNoWarning |= bSet;
     214             : 
     215             :                         // store the property in the given vector
     216      198942 :                         if( bSet )
     217             :                         {
     218      150168 :                             if( nReference == -1 )
     219      143590 :                                 rProperties.push_back( aNewProperty );
     220             :                             else
     221        6578 :                                 rProperties[nReference] = aNewProperty;
     222             :                         }
     223             :                         else
     224             :                         {
     225             :                             // warn about unknown value. Unless it's a
     226             :                             // multi property: Then we get another chance
     227             :                             // to set the value.
     228       50458 :                             if( !bNoWarning &&
     229        1684 :                                 ((nFlags & MID_FLAG_MULTI_PROPERTY) == 0) )
     230             :                             {
     231         146 :                                 Sequence<OUString> aSeq(2);
     232         146 :                                 aSeq[0] = rAttrName;
     233         146 :                                 aSeq[1] = rValue;
     234             :                                 rImport.SetError( XMLERROR_FLAG_WARNING |
     235             :                                                   XMLERROR_STYLE_ATTR_VALUE,
     236         146 :                                                   aSeq );
     237             :                             }
     238      198942 :                         }
     239             :                     }
     240      198942 :                     bFound = true;
     241      198942 :                     continue;
     242             :                 }
     243             :             }
     244             : 
     245       26616 :             if( !bFound )
     246             :             {
     247             :                 SAL_INFO_IF((XML_NAMESPACE_NONE != nPrefix) &&
     248             :                             !(XML_NAMESPACE_UNKNOWN_FLAG & nPrefix) &&
     249             :                             !bAlienImport, "xmloff.style",
     250             :                             "unknown attribute: \"" << rAttrName << "\"");
     251        2196 :                 if( (XML_NAMESPACE_UNKNOWN_FLAG & nPrefix) || (XML_NAMESPACE_NONE == nPrefix) || bAlienImport )
     252             :                 {
     253           0 :                     if( !xAttrContainer.is() )
     254             :                     {
     255             :                         // add an unknown attribute container to the properties
     256           0 :                         Reference< XNameContainer > xNew( SvUnoAttributeContainer_CreateInstance(), UNO_QUERY );
     257           0 :                         xAttrContainer = xNew;
     258             : 
     259             :                         // find map entry and create new property state
     260           0 :                         if( -1 == nIndex )
     261             :                         {
     262           0 :                             switch( nPropType )
     263             :                             {
     264             :                                 case XML_TYPE_PROP_CHART:
     265           0 :                                     nIndex = maPropMapper->FindEntryIndex( "ChartUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
     266           0 :                                     break;
     267             :                                 case XML_TYPE_PROP_PARAGRAPH:
     268           0 :                                     nIndex = maPropMapper->FindEntryIndex( "ParaUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
     269           0 :                                     break;
     270             :                                 case  XML_TYPE_PROP_TEXT:
     271           0 :                                     nIndex = maPropMapper->FindEntryIndex( "TextUserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
     272           0 :                                     break;
     273             :                                 default:
     274           0 :                                     break;
     275             :                             }
     276             :                             // other property type or property not found
     277           0 :                             if( -1 == nIndex )
     278           0 :                                 nIndex = maPropMapper->FindEntryIndex( "UserDefinedAttributes", XML_NAMESPACE_TEXT, GetXMLToken(XML_XMLNS) );
     279             :                         }
     280             : 
     281             :                         // #106963#; use userdefined attribute only if it is in the specified property range
     282           0 :                         if( nIndex != -1 && nIndex >= nStartIdx && nIndex < nEndIdx)
     283             :                         {
     284           0 :                             Any aAny;
     285           0 :                             aAny <<= xAttrContainer;
     286           0 :                             XMLPropertyState aNewProperty( nIndex, aAny );
     287             : 
     288             :                             // push it on our stack so we export it later
     289           0 :                             rProperties.push_back( aNewProperty );
     290           0 :                         }
     291             :                     }
     292             : 
     293           0 :                     if( xAttrContainer.is() )
     294             :                     {
     295           0 :                         AttributeData aData;
     296           0 :                         aData.Type = GetXMLToken( XML_CDATA );
     297           0 :                         aData.Value = rValue;
     298             : 
     299           0 :                         OUStringBuffer sName;
     300           0 :                         if( XML_NAMESPACE_NONE != nPrefix )
     301             :                         {
     302           0 :                             sName.append( aPrefix );
     303           0 :                             sName.append( ':' );
     304           0 :                             aData.Namespace = aNamespace;
     305             :                         }
     306             : 
     307           0 :                         sName.append( aLocalName );
     308             : 
     309           0 :                         Any aAny;
     310           0 :                         aAny <<= aData;
     311           0 :                         xAttrContainer->insertByName( sName.makeStringAndClear(), aAny );
     312             :                     }
     313             :                 }
     314             :             }
     315             :         }
     316      198942 :         while( ( nIndex >= 0 && nIndex + 1 < nEndIdx ) && (( nFlags & MID_FLAG_MULTI_PROPERTY ) != 0 ) );
     317      155558 :     }
     318             : 
     319       31292 :     finished( rProperties, nStartIdx, nEndIdx );
     320       31292 : }
     321             : 
     322             : /** this method is called for every item that has the MID_FLAG_SPECIAL_ITEM_IMPORT flag set */
     323        7206 : bool SvXMLImportPropertyMapper::handleSpecialItem(
     324             :         XMLPropertyState& rProperty,
     325             :         vector< XMLPropertyState >& rProperties,
     326             :         const OUString& rValue,
     327             :         const SvXMLUnitConverter& rUnitConverter,
     328             :         const SvXMLNamespaceMap& rNamespaceMap ) const
     329             : {
     330             :     OSL_ENSURE( mxNextMapper.is(), "unsupported special item in xml import" );
     331        7206 :     if( mxNextMapper.is() )
     332        7206 :         return mxNextMapper->handleSpecialItem( rProperty, rProperties, rValue,
     333        7206 :                                                rUnitConverter, rNamespaceMap );
     334             :     else
     335           0 :         return false;
     336             : }
     337             : 
     338        2698 : void SvXMLImportPropertyMapper::FillPropertySequence(
     339             :             const ::std::vector< XMLPropertyState >& rProperties,
     340             :             ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rValues )
     341             :             const
     342             : {
     343        2698 :     sal_Int32 nCount = rProperties.size();
     344        2698 :     sal_Int32 nValueCount = 0;
     345        2698 :     rValues.realloc( nCount );
     346        2698 :     PropertyValue *pProps = rValues.getArray();
     347       36958 :     for( sal_Int32 i=0; i < nCount; i++ )
     348             :     {
     349       34260 :         const XMLPropertyState& rProp = rProperties[i];
     350       34260 :         sal_Int32 nIdx = rProp.mnIndex;
     351       34260 :         if( nIdx == -1 )
     352          88 :             continue;
     353       34172 :         pProps->Name = maPropMapper->GetEntryAPIName( nIdx );
     354       34172 :         if( !pProps->Name.isEmpty() )
     355             :         {
     356       34172 :             pProps->Value <<= rProp.maValue;
     357       34172 :             ++pProps;
     358       34172 :             ++nValueCount;
     359             :         }
     360             :     }
     361        2698 :     if( nValueCount < nCount )
     362          42 :         rValues.realloc( nValueCount );
     363        2698 : }
     364             : 
     365       11834 : void SvXMLImportPropertyMapper::CheckSpecialContext(
     366             :             const ::std::vector< XMLPropertyState >& aProperties,
     367             :             const ::com::sun::star::uno::Reference<
     368             :                     ::com::sun::star::beans::XPropertySet > rPropSet,
     369             :             _ContextID_Index_Pair* pSpecialContextIds ) const
     370             : {
     371             :     OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
     372       11834 :     sal_Int32 nCount = aProperties.size();
     373             : 
     374       11834 :     Reference< XPropertySetInfo > xInfo(rPropSet->getPropertySetInfo());
     375             : 
     376      181124 :     for( sal_Int32 i=0; i < nCount; i++ )
     377             :     {
     378      169290 :         const XMLPropertyState& rProp = aProperties[i];
     379      169290 :         sal_Int32 nIdx = rProp.mnIndex;
     380             : 
     381             :         // disregard property state if it has an invalid index
     382      169290 :         if( -1 == nIdx )
     383          82 :             continue;
     384             : 
     385      169208 :         const sal_Int32 nPropFlags = maPropMapper->GetEntryFlags( nIdx );
     386             : 
     387             :         // handle no-property and special items
     388      338416 :         if( ( pSpecialContextIds != NULL ) &&
     389      338416 :             ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
     390             :               ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) )   ) )
     391             :         {
     392             :             // maybe it's one of our special context ids?
     393       20382 :             sal_Int16 nContextId = maPropMapper->GetEntryContextId(nIdx);
     394             : 
     395      244096 :             for ( sal_Int32 n = 0;
     396      122048 :                   pSpecialContextIds[n].nContextID != -1;
     397             :                   n++ )
     398             :             {
     399             :                 // found: set index in pSpecialContextIds array
     400      122020 :                 if ( pSpecialContextIds[n].nContextID == nContextId )
     401             :                 {
     402       20354 :                     pSpecialContextIds[n].nIndex = i;
     403       20354 :                     break; // early out
     404             :                 }
     405             :             }
     406             :         }
     407       11834 :     }
     408             : 
     409       11834 : }
     410             : 
     411       37632 : bool SvXMLImportPropertyMapper::FillPropertySet(
     412             :             const vector< XMLPropertyState >& aProperties,
     413             :             const Reference< XPropertySet > rPropSet,
     414             :             _ContextID_Index_Pair* pSpecialContextIds ) const
     415             : {
     416       37632 :     bool bSet = false;
     417             : 
     418       37632 :     Reference< XTolerantMultiPropertySet > xTolPropSet( rPropSet, UNO_QUERY );
     419       37632 :     if (xTolPropSet.is())
     420             :         bSet = _FillTolerantMultiPropertySet( aProperties, xTolPropSet, maPropMapper, rImport,
     421        2300 :                                             pSpecialContextIds );
     422             : 
     423       37632 :     if (!bSet)
     424             :     {
     425             :         // get property set info
     426       35432 :         Reference< XPropertySetInfo > xInfo(rPropSet->getPropertySetInfo());
     427             : 
     428             :         // check for multi-property set
     429       70864 :         Reference<XMultiPropertySet> xMultiPropSet( rPropSet, UNO_QUERY );
     430       35432 :         if ( xMultiPropSet.is() )
     431             :         {
     432             :             // Try XMultiPropertySet. If that fails, try the regular route.
     433             :             bSet = _FillMultiPropertySet( aProperties, xMultiPropSet,
     434             :                                         xInfo, maPropMapper,
     435       23104 :                                         pSpecialContextIds );
     436       23104 :             if ( !bSet )
     437             :                 bSet = _FillPropertySet( aProperties, rPropSet,
     438             :                                         xInfo, maPropMapper, rImport,
     439          40 :                                         pSpecialContextIds);
     440             :         }
     441             :         else
     442             :             bSet = _FillPropertySet( aProperties, rPropSet, xInfo,
     443             :                                     maPropMapper, rImport,
     444       47760 :                                     pSpecialContextIds );
     445             :     }
     446             : 
     447       37632 :     return bSet;
     448             : }
     449             : 
     450       12368 : bool SvXMLImportPropertyMapper::_FillPropertySet(
     451             :     const vector<XMLPropertyState> & rProperties,
     452             :     const Reference<XPropertySet> & rPropSet,
     453             :     const Reference<XPropertySetInfo> & rPropSetInfo,
     454             :     const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
     455             :     SvXMLImport& rImport,
     456             :     _ContextID_Index_Pair* pSpecialContextIds )
     457             : {
     458             :     OSL_ENSURE( rPropSet.is(), "need an XPropertySet" );
     459             :     OSL_ENSURE( rPropSetInfo.is(), "need an XPropertySetInfo" );
     460             : 
     461             :     // preliminaries
     462       12368 :     bool bSet = false;
     463       12368 :     sal_Int32 nCount = rProperties.size();
     464             : 
     465             :     // iterate over property states that we want to set
     466       79444 :     for( sal_Int32 i=0; i < nCount; i++ )
     467             :     {
     468       67076 :         const XMLPropertyState& rProp = rProperties[i];
     469       67076 :         sal_Int32 nIdx = rProp.mnIndex;
     470             : 
     471             :         // disregard property state if it has an invalid index
     472       67076 :         if( -1 == nIdx )
     473       14760 :             continue;
     474             : 
     475       52316 :         const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
     476       52316 :         const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
     477             : 
     478      152816 :         if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
     479      102280 :              ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
     480       51140 :                rPropSetInfo->hasPropertyByName( rPropName ) )    )
     481             :         {
     482             :             // try setting the property
     483             :             try
     484             :             {
     485       49360 :                 rPropSet->setPropertyValue( rPropName, rProp.maValue );
     486       49284 :                 bSet = true;
     487             :             }
     488          80 :             catch ( const IllegalArgumentException& e )
     489             :             {
     490             :                 // illegal value: check whether this property is
     491             :                 // allowed to throw this exception
     492          40 :                 if ( 0 == ( nPropFlags & MID_FLAG_PROPERTY_MAY_THROW ) )
     493             :                 {
     494          40 :                     Sequence<OUString> aSeq(1);
     495          40 :                     aSeq[0] = rPropName;
     496             :                     rImport.SetError(
     497             :                         XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_ERROR,
     498          40 :                         aSeq, e.Message, NULL );
     499             :                 }
     500             :             }
     501          72 :             catch ( const UnknownPropertyException& e )
     502             :             {
     503             :                 // unknown property: This is always an error!
     504          36 :                 Sequence<OUString> aSeq(1);
     505          36 :                 aSeq[0] = rPropName;
     506             :                 rImport.SetError(
     507             :                     XMLERROR_STYLE_PROP_UNKNOWN | XMLERROR_FLAG_ERROR,
     508          36 :                     aSeq, e.Message, NULL );
     509             :             }
     510           0 :             catch ( const PropertyVetoException& e )
     511             :             {
     512             :                 // property veto: this shouldn't happen
     513           0 :                 Sequence<OUString> aSeq(1);
     514           0 :                 aSeq[0] = rPropName;
     515             :                 rImport.SetError(
     516             :                     XMLERROR_STYLE_PROP_OTHER | XMLERROR_FLAG_ERROR,
     517           0 :                     aSeq, e.Message, NULL );
     518             :             }
     519           0 :             catch ( const WrappedTargetException& e )
     520             :             {
     521             :                 // wrapped target: this shouldn't happen either
     522           0 :                 Sequence<OUString> aSeq(1);
     523           0 :                 aSeq[0] = rPropName;
     524             :                 rImport.SetError(
     525             :                     XMLERROR_STYLE_PROP_OTHER | XMLERROR_FLAG_ERROR,
     526           0 :                     aSeq, e.Message, NULL );
     527             :             }
     528             :         }
     529             : 
     530             :         // handle no-property and special items
     531       88384 :         if( ( pSpecialContextIds != NULL ) &&
     532       70960 :             ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
     533             :               ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) )   ) )
     534             :         {
     535             :             // maybe it's one of our special context ids?
     536        3656 :             sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
     537             : 
     538       60708 :             for ( sal_Int32 n = 0;
     539       30354 :                   pSpecialContextIds[n].nContextID != -1;
     540             :                   n++ )
     541             :             {
     542             :                 // found: set index in pSpecialContextIds array
     543       28452 :                 if ( pSpecialContextIds[n].nContextID == nContextId )
     544             :                 {
     545        1754 :                     pSpecialContextIds[n].nIndex = i;
     546        1754 :                     break; // early out
     547             :                 }
     548             :             }
     549             :         }
     550             :     }
     551             : 
     552       12368 :     return bSet;
     553             : }
     554             : 
     555             : 
     556             : 
     557             : typedef pair<const OUString*, const Any* > PropertyPair;
     558             : typedef vector<PropertyPair> PropertyPairs;
     559             : 
     560             : struct PropertyPairLessFunctor :
     561             :     public std::binary_function<PropertyPair, PropertyPair, bool>
     562             : {
     563     1102296 :     bool operator()( const PropertyPair& a, const PropertyPair& b ) const
     564             :     {
     565     1102296 :         return (*a.first < *b.first);
     566             :     }
     567             : };
     568             : 
     569       25404 : void SvXMLImportPropertyMapper::_PrepareForMultiPropertySet(
     570             :     const vector<XMLPropertyState> & rProperties,
     571             :     const Reference<XPropertySetInfo> & rPropSetInfo,
     572             :     const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
     573             :     _ContextID_Index_Pair* pSpecialContextIds,
     574             :     Sequence<OUString>& rNames,
     575             :     Sequence<Any>& rValues)
     576             : {
     577       25404 :     sal_Int32 nCount = rProperties.size();
     578             : 
     579             :     // property pairs structure stores names + values of properties to be set.
     580       25404 :     PropertyPairs aPropertyPairs;
     581       25404 :     aPropertyPairs.reserve( nCount );
     582             : 
     583             :     // iterate over property states that we want to set
     584             :     sal_Int32 i;
     585      281330 :     for( i = 0; i < nCount; i++ )
     586             :     {
     587      255926 :         const XMLPropertyState& rProp = rProperties[i];
     588      255926 :         sal_Int32 nIdx = rProp.mnIndex;
     589             : 
     590             :         // disregard property state if it has an invalid index
     591      255926 :         if( -1 == nIdx )
     592        9254 :             continue;
     593             : 
     594      246672 :         const OUString& rPropName = rPropMapper->GetEntryAPIName( nIdx );
     595      246672 :         const sal_Int32 nPropFlags = rPropMapper->GetEntryFlags( nIdx );
     596             : 
     597      733166 :         if ( ( 0 == ( nPropFlags & MID_FLAG_NO_PROPERTY ) ) &&
     598      492208 :              ( ( 0 != ( nPropFlags & MID_FLAG_MUST_EXIST ) ) ||
     599      463556 :                !rPropSetInfo.is() ||
     600      434904 :                (rPropSetInfo.is() && rPropSetInfo->hasPropertyByName( rPropName )) ) )
     601             :         {
     602             :             // save property into property pair structure
     603      240390 :             aPropertyPairs.push_back( PropertyPair( &rPropName, &rProp.maValue ) );
     604             :         }
     605             : 
     606             :         // handle no-property and special items
     607      440262 :         if( ( pSpecialContextIds != NULL ) &&
     608      386612 :             ( ( 0 != ( nPropFlags & MID_FLAG_NO_PROPERTY_IMPORT ) ) ||
     609             :               ( 0 != ( nPropFlags & MID_FLAG_SPECIAL_ITEM_IMPORT ) )   ) )
     610             :         {
     611             :             // maybe it's one of our special context ids?
     612       21482 :             sal_Int16 nContextId = rPropMapper->GetEntryContextId(nIdx);
     613      353888 :             for ( sal_Int32 n = 0;
     614      176944 :                   pSpecialContextIds[n].nContextID != -1;
     615             :                   n++ )
     616             :             {
     617             :                 // found: set index in pSpecialContextIds array
     618      169762 :                 if ( pSpecialContextIds[n].nContextID == nContextId )
     619             :                 {
     620       14300 :                     pSpecialContextIds[n].nIndex = i;
     621       14300 :                     break; // early out
     622             :                 }
     623             :             }
     624             :         }
     625             :     }
     626             : 
     627             :     // We now need to construct the sequences and actually the set
     628             :     // values.
     629             : 
     630             :     // sort the property pairs
     631             :     sort( aPropertyPairs.begin(), aPropertyPairs.end(),
     632       25404 :           PropertyPairLessFunctor());
     633             : 
     634             :     // create sequences
     635       25404 :     rNames.realloc( aPropertyPairs.size() );
     636       25404 :     OUString* pNamesArray = rNames.getArray();
     637       25404 :     rValues.realloc( aPropertyPairs.size() );
     638       25404 :     Any* pValuesArray = rValues.getArray();
     639             : 
     640             :     // copy values into sequences
     641       25404 :     i = 0;
     642      797382 :     for( PropertyPairs::iterator aIter = aPropertyPairs.begin();
     643      531588 :          aIter != aPropertyPairs.end();
     644             :          ++aIter )
     645             :     {
     646      240390 :         pNamesArray[i] = *(aIter->first);
     647      240390 :         pValuesArray[i++] = *(aIter->second);
     648       25404 :     }
     649       25404 : }
     650             : 
     651       23104 : bool SvXMLImportPropertyMapper::_FillMultiPropertySet(
     652             :     const vector<XMLPropertyState> & rProperties,
     653             :     const Reference<XMultiPropertySet> & rMultiPropSet,
     654             :     const Reference<XPropertySetInfo> & rPropSetInfo,
     655             :     const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
     656             :     _ContextID_Index_Pair* pSpecialContextIds )
     657             : {
     658             :     OSL_ENSURE( rMultiPropSet.is(), "Need multi property set. ");
     659             :     OSL_ENSURE( rPropSetInfo.is(), "Need property set info." );
     660             : 
     661       23104 :     bool bSuccessful = false;
     662             : 
     663       23104 :     Sequence<OUString> aNames;
     664       46208 :     Sequence<Any> aValues;
     665             : 
     666             :     _PrepareForMultiPropertySet(rProperties, rPropSetInfo, rPropMapper, pSpecialContextIds,
     667       23104 :         aNames, aValues);
     668             : 
     669             :     // and, finally, try to set the values
     670             :     try
     671             :     {
     672       23104 :         rMultiPropSet->setPropertyValues( aNames, aValues );
     673       23064 :         bSuccessful = true;
     674             :     }
     675          40 :     catch ( ... )
     676             :     {
     677             :         OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
     678             :     }
     679             : 
     680       46208 :     return bSuccessful;
     681             : }
     682             : 
     683        2300 : bool SvXMLImportPropertyMapper::_FillTolerantMultiPropertySet(
     684             :     const vector<XMLPropertyState> & rProperties,
     685             :     const Reference<XTolerantMultiPropertySet> & rTolMultiPropSet,
     686             :     const rtl::Reference<XMLPropertySetMapper> & rPropMapper,
     687             :     SvXMLImport& rImport,
     688             :     _ContextID_Index_Pair* pSpecialContextIds )
     689             : {
     690             :     OSL_ENSURE( rTolMultiPropSet.is(), "Need tolerant multi property set. ");
     691             : 
     692        2300 :     bool bSuccessful = false;
     693             : 
     694        2300 :     Sequence<OUString> aNames;
     695        4600 :     Sequence<Any> aValues;
     696             : 
     697             :     _PrepareForMultiPropertySet(rProperties, Reference<XPropertySetInfo>(NULL), rPropMapper, pSpecialContextIds,
     698        2300 :         aNames, aValues);
     699             : 
     700             :     // and, finally, try to set the values
     701             :     try
     702             :     {
     703        2300 :         Sequence< SetPropertyTolerantFailed > aResults(rTolMultiPropSet->setPropertyValuesTolerant( aNames, aValues ));
     704        2300 :         if (aResults.getLength() == 0)
     705        2200 :             bSuccessful = true;
     706             :         else
     707             :         {
     708         100 :             sal_Int32 nCount(aResults.getLength());
     709         260 :             for( sal_Int32 i = 0; i < nCount; ++i)
     710             :             {
     711         160 :                 Sequence<OUString> aSeq(1);
     712         160 :                 aSeq[0] = aResults[i].Name;
     713         320 :                 OUString sMessage;
     714         160 :                 switch (aResults[i].Result)
     715             :                 {
     716             :                 case TolerantPropertySetResultType::UNKNOWN_PROPERTY :
     717         120 :                     sMessage = "UNKNOWN_PROPERTY";
     718         120 :                     break;
     719             :                 case TolerantPropertySetResultType::ILLEGAL_ARGUMENT :
     720          40 :                     sMessage = "ILLEGAL_ARGUMENT";
     721          40 :                     break;
     722             :                 case TolerantPropertySetResultType::PROPERTY_VETO :
     723           0 :                     sMessage = "PROPERTY_VETO";
     724           0 :                     break;
     725             :                 case TolerantPropertySetResultType::WRAPPED_TARGET :
     726           0 :                     sMessage = "WRAPPED_TARGET";
     727           0 :                     break;
     728             :                 };
     729             :                 rImport.SetError(
     730             :                     XMLERROR_STYLE_PROP_OTHER | XMLERROR_FLAG_ERROR,
     731         160 :                     aSeq, sMessage, NULL );
     732         160 :             }
     733        2300 :         }
     734             :     }
     735           0 :     catch ( ... )
     736             :     {
     737             :         OSL_ENSURE(bSuccessful, "Exception caught; style may not be imported correctly.");
     738             :     }
     739             : 
     740        4600 :     return bSuccessful;
     741             : }
     742             : 
     743       16220 : void SvXMLImportPropertyMapper::finished(
     744             :         vector< XMLPropertyState >& rProperties,
     745             :         sal_Int32 nStartIndex, sal_Int32 nEndIndex ) const
     746             : {
     747             :     // nothing to do here
     748       16220 :     if( mxNextMapper.is() )
     749        9618 :         mxNextMapper->finished( rProperties, nStartIndex, nEndIndex );
     750       16220 : }
     751             : 
     752             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10