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

Generated by: LCOV version 1.10