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

Generated by: LCOV version 1.11