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