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

Generated by: LCOV version 1.10