xref: /AOO41X/main/xmloff/source/forms/propertyimport.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "propertyimport.hxx"
27 #include <xmloff/xmlimp.hxx>
28 #include <xmloff/xmluconv.hxx>
29 #include <xmloff/nmspmap.hxx>
30 #include <osl/diagnose.h>
31 #include <comphelper/extract.hxx>
32 #include "callbacks.hxx"
33 #include "xmloff/xmlnmspe.hxx"
34 #include <tools/date.hxx>
35 #include <tools/time.hxx>
36 #include <tools/datetime.hxx>
37 #include <com/sun/star/util/Date.hpp>
38 #include <com/sun/star/util/Time.hpp>
39 #include <com/sun/star/util/DateTime.hpp>
40 #include <unotools/datetime.hxx>
41 #include <rtl/logfile.hxx>
42 
43 #if OSL_DEBUG_LEVEL > 0
44     #ifndef _OSL_THREAD_H_
45     #include <osl/thread.h>
46     #endif
47 #endif
48 
49 //.........................................................................
50 namespace xmloff
51 {
52 //.........................................................................
53 
54     using namespace ::com::sun::star::uno;
55     using namespace ::com::sun::star::beans;
56     using namespace ::com::sun::star::xml;
57 
58     // NO using namespace ...util !!!
59     // need a tools Date/Time/DateTime below, which would conflict with the uno types then
60 
61 #define TYPE_DATE       1
62 #define TYPE_TIME       2
63 #define TYPE_DATETIME   3
64 
65 //=====================================================================
66 //= PropertyConversion
67 //=====================================================================
68 namespace
69 {
70     //---------------------------------------------------------------------
lcl_getTime(double _nValue)71     ::com::sun::star::util::Time lcl_getTime(double _nValue)
72     {
73         ::com::sun::star::util::Time aTime;
74         sal_uInt32 nIntValue = sal_Int32(_nValue * 8640000);
75         nIntValue *= 8640000;
76         aTime.HundredthSeconds = (sal_uInt16)( nIntValue % 100 );
77         nIntValue /= 100;
78         aTime.Seconds = (sal_uInt16)( nIntValue % 60 );
79         nIntValue /= 60;
80         aTime.Minutes = (sal_uInt16)( nIntValue % 60 );
81         nIntValue /= 60;
82         OSL_ENSURE(nIntValue < 24, "lcl_getTime: more than a day?");
83         aTime.Hours = static_cast< sal_uInt16 >( nIntValue );
84 
85         return aTime;
86     }
87 
88     //---------------------------------------------------------------------
lcl_getDate(double _nValue)89     static ::com::sun::star::util::Date lcl_getDate( double _nValue )
90     {
91         Date aToolsDate((sal_uInt32)_nValue);
92         ::com::sun::star::util::Date aDate;
93         ::utl::typeConvert(aToolsDate, aDate);
94         return aDate;
95     }
96 }
97 
98 //---------------------------------------------------------------------
convertString(SvXMLImport & _rImporter,const::com::sun::star::uno::Type & _rExpectedType,const::rtl::OUString & _rReadCharacters,const SvXMLEnumMapEntry * _pEnumMap,const sal_Bool _bInvertBoolean)99 Any PropertyConversion::convertString( SvXMLImport& _rImporter, const ::com::sun::star::uno::Type& _rExpectedType,
100     const ::rtl::OUString& _rReadCharacters, const SvXMLEnumMapEntry* _pEnumMap, const sal_Bool _bInvertBoolean )
101 {
102     Any aReturn;
103     sal_Bool bEnumAsInt = sal_False;
104     switch (_rExpectedType.getTypeClass())
105     {
106         case TypeClass_BOOLEAN:     // sal_Bool
107         {
108             sal_Bool bValue;
109         #if OSL_DEBUG_LEVEL > 0
110             sal_Bool bSuccess =
111         #endif
112             _rImporter.GetMM100UnitConverter().convertBool(bValue, _rReadCharacters);
113             OSL_ENSURE(bSuccess,
114                     ::rtl::OString("PropertyConversion::convertString: could not convert \"")
115                 +=  ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
116                 +=  ::rtl::OString("\" into a boolean!"));
117             aReturn = ::cppu::bool2any(_bInvertBoolean ? !bValue : bValue);
118         }
119         break;
120         case TypeClass_SHORT:       // sal_Int16
121         case TypeClass_LONG:        // sal_Int32
122             if (!_pEnumMap)
123             {   // it's a real int32/16 property
124                 sal_Int32 nValue(0);
125         #if OSL_DEBUG_LEVEL > 0
126                 sal_Bool bSuccess =
127         #endif
128                 _rImporter.GetMM100UnitConverter().convertNumber(nValue, _rReadCharacters);
129                 OSL_ENSURE(bSuccess,
130                         ::rtl::OString("PropertyConversion::convertString: could not convert \"")
131                     +=  ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
132                     +=  ::rtl::OString("\" into an integer!"));
133                 if (TypeClass_SHORT == _rExpectedType.getTypeClass())
134                     aReturn <<= (sal_Int16)nValue;
135                 else
136                     aReturn <<= (sal_Int32)nValue;
137                 break;
138             }
139             bEnumAsInt = sal_True;
140             // NO BREAK! handle it as enum
141         case TypeClass_ENUM:
142         {
143             sal_uInt16 nEnumValue(0);
144         #if OSL_DEBUG_LEVEL > 0
145             sal_Bool bSuccess =
146         #endif
147             _rImporter.GetMM100UnitConverter().convertEnum(nEnumValue, _rReadCharacters, _pEnumMap);
148             OSL_ENSURE(bSuccess, "PropertyConversion::convertString: could not convert to an enum value!");
149             if (bEnumAsInt)
150                 if (TypeClass_SHORT == _rExpectedType.getTypeClass())
151                     aReturn <<= (sal_Int16)nEnumValue;
152                 else
153                     aReturn <<= (sal_Int32)nEnumValue;
154             else
155                 aReturn = ::cppu::int2enum((sal_Int32)nEnumValue, _rExpectedType);
156         }
157         break;
158         case TypeClass_HYPER:
159         {
160             OSL_ENSURE(sal_False, "PropertyConversion::convertString: 64-bit integers not implemented yet!");
161         }
162         break;
163         case TypeClass_DOUBLE:
164         {
165             double nValue;
166         #if OSL_DEBUG_LEVEL > 0
167             sal_Bool bSuccess =
168         #endif
169             _rImporter.GetMM100UnitConverter().convertDouble(nValue, _rReadCharacters);
170             OSL_ENSURE(bSuccess,
171                     ::rtl::OString("PropertyConversion::convertString: could not convert \"")
172                 +=  ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
173                 +=  ::rtl::OString("\" into a double!"));
174             aReturn <<= (double)nValue;
175         }
176         break;
177         case TypeClass_STRING:
178             aReturn <<= _rReadCharacters;
179             break;
180         case TypeClass_STRUCT:
181         {
182             sal_Int32 nType = 0;
183             if ( _rExpectedType.equals( ::cppu::UnoType< ::com::sun::star::util::Date >::get() ) )
184                 nType = TYPE_DATE;
185             else if ( _rExpectedType.equals( ::cppu::UnoType< ::com::sun::star::util::Time >::get() ) )
186                 nType = TYPE_TIME;
187             else  if ( _rExpectedType.equals( ::cppu::UnoType< ::com::sun::star::util::DateTime >::get() ) )
188                 nType = TYPE_DATETIME;
189 
190             if ( nType )
191             {
192                 // first extract the double
193                 double nValue = 0;
194             #if OSL_DEBUG_LEVEL > 0
195                 sal_Bool bSuccess =
196             #endif
197                 _rImporter.GetMM100UnitConverter().convertDouble(nValue, _rReadCharacters);
198                 OSL_ENSURE(bSuccess,
199                         ::rtl::OString("PropertyConversion::convertString: could not convert \"")
200                     +=  ::rtl::OString(_rReadCharacters.getStr(), _rReadCharacters.getLength(), RTL_TEXTENCODING_ASCII_US)
201                     +=  ::rtl::OString("\" into a double!"));
202 
203                 // then convert it into the target type
204                 switch (nType)
205                 {
206                     case TYPE_DATE:
207                     {
208                         OSL_ENSURE(((sal_uInt32)nValue) - nValue == 0,
209                             "PropertyConversion::convertString: a Date value with a fractional part?");
210                         aReturn <<= lcl_getDate(nValue);
211                     }
212                     break;
213                     case TYPE_TIME:
214                     {
215                         OSL_ENSURE(((sal_uInt32)nValue) == 0,
216                             "PropertyConversion::convertString: a Time value with more than a fractional part?");
217                         aReturn <<= lcl_getTime(nValue);
218                     }
219                     break;
220                     case TYPE_DATETIME:
221                     {
222                         ::com::sun::star::util::Time aTime = lcl_getTime(nValue);
223                         ::com::sun::star::util::Date aDate = lcl_getDate(nValue);
224 
225                         ::com::sun::star::util::DateTime aDateTime;
226                         aDateTime.HundredthSeconds = aTime.HundredthSeconds;
227                         aDateTime.Seconds = aTime.Seconds;
228                         aDateTime.Minutes = aTime.Minutes;
229                         aDateTime.Hours = aTime.Hours;
230                         aDateTime.Day = aDate.Day;
231                         aDateTime.Month = aDate.Month;
232                         aDateTime.Year = aDate.Year;
233                         aReturn <<= aDateTime;
234                     }
235                     break;
236                 }
237             }
238             else
239                 OSL_ENSURE(sal_False, "PropertyConversion::convertString: unsupported property type!");
240         }
241         break;
242         default:
243             OSL_ENSURE(sal_False, "PropertyConversion::convertString: invalid type class!");
244     }
245 
246     return aReturn;
247 }
248 
249 //---------------------------------------------------------------------
xmlTypeToUnoType(const::rtl::OUString & _rType)250 Type PropertyConversion::xmlTypeToUnoType( const ::rtl::OUString& _rType )
251 {
252     Type aUnoType( ::getVoidCppuType() );
253 
254     DECLARE_STL_USTRINGACCESS_MAP( ::com::sun::star::uno::Type, MapString2Type );
255     static MapString2Type s_aTypeNameMap;
256     if ( s_aTypeNameMap.empty() )
257     {
258         s_aTypeNameMap[ token::GetXMLToken( token::XML_BOOLEAN ) ] = ::getBooleanCppuType();
259         s_aTypeNameMap[ token::GetXMLToken( token::XML_FLOAT )   ] = ::getCppuType( static_cast< double* >(NULL) );
260         s_aTypeNameMap[ token::GetXMLToken( token::XML_STRING )  ] = ::getCppuType( static_cast< ::rtl::OUString* >(NULL) );
261         s_aTypeNameMap[ token::GetXMLToken( token::XML_VOID )    ] = ::getVoidCppuType();
262     }
263 
264     const ConstMapString2TypeIterator aTypePos = s_aTypeNameMap.find( _rType );
265     OSL_ENSURE( s_aTypeNameMap.end() != aTypePos, "PropertyConversion::xmlTypeToUnoType: invalid property name!" );
266     if ( s_aTypeNameMap.end() != aTypePos )
267         aUnoType = aTypePos->second;
268 
269     return aUnoType;
270 }
271 
272 //=====================================================================
273 //= OPropertyImport
274 //=====================================================================
275 //---------------------------------------------------------------------
OPropertyImport(OFormLayerXMLImport_Impl & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName)276 OPropertyImport::OPropertyImport(OFormLayerXMLImport_Impl& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName)
277     :SvXMLImportContext(_rImport.getGlobalContext(), _nPrefix, _rName)
278     ,m_rContext(_rImport)
279     ,m_bTrackAttributes(sal_False)
280 {
281 }
282 
283 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> & _rxAttrList)284 SvXMLImportContext* OPropertyImport::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName,
285     const Reference< sax::XAttributeList >& _rxAttrList)
286 {
287     if( token::IsXMLToken( _rLocalName, token::XML_PROPERTIES) )
288     {
289         return new OPropertyElementsContext( m_rContext.getGlobalContext(),
290                                              _nPrefix, _rLocalName, this);
291     }
292     else
293     {
294         OSL_ENSURE(sal_False,
295                 ::rtl::OString("OPropertyImport::CreateChildContext: unknown sub element (only \"properties\" is recognized, but it is ")
296             +=  ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
297             +=  ::rtl::OString(")!"));
298         return SvXMLImportContext::CreateChildContext(_nPrefix, _rLocalName, _rxAttrList);
299     }
300 }
301 
302 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)303 void OPropertyImport::StartElement(const Reference< sax::XAttributeList >& _rxAttrList)
304 {
305     OSL_ENSURE(_rxAttrList.is(), "OPropertyImport::StartElement: invalid attribute list!");
306     const sal_Int32 nAttributeCount = _rxAttrList->getLength();
307 
308     // assume the 'worst' case: all attributes describe properties. This should save our property array
309     // some reallocs
310     m_aValues.reserve(nAttributeCount);
311 
312     const SvXMLNamespaceMap& rMap = m_rContext.getGlobalContext().GetNamespaceMap();
313     sal_uInt16 nNamespace;
314     ::rtl::OUString sLocalName;
315     for (sal_Int16 i=0; i<nAttributeCount; ++i)
316     {
317         nNamespace = rMap.GetKeyByAttrName(_rxAttrList->getNameByIndex(i), &sLocalName);
318         handleAttribute(nNamespace, sLocalName, _rxAttrList->getValueByIndex(i));
319 
320         if (m_bTrackAttributes)
321             m_aEncounteredAttributes.insert(sLocalName);
322     }
323 
324     // TODO: create PropertyValues for all the attributes which were not present, because they were implied
325     // this is necessary as soon as we have properties where the XML default is different from the property
326     // default
327 }
328 
329 //---------------------------------------------------------------------
encounteredAttribute(const::rtl::OUString & _rAttributeName) const330 sal_Bool OPropertyImport::encounteredAttribute(const ::rtl::OUString& _rAttributeName) const
331 {
332     OSL_ENSURE(m_bTrackAttributes, "OPropertyImport::encounteredAttribute: attribute tracking not enabled!");
333     return m_aEncounteredAttributes.end() != m_aEncounteredAttributes.find(_rAttributeName);
334 }
335 
336 //---------------------------------------------------------------------
Characters(const::rtl::OUString & _rChars)337 void OPropertyImport::Characters(const ::rtl::OUString&
338 #if OSL_DEBUG_LEVEL > 0
339 _rChars
340 #endif
341 )
342 {
343     // ignore them (should be whitespaces only)
344     OSL_ENSURE(0 == _rChars.trim().getLength(), "OPropertyImport::Characters: non-whitespace characters!");
345 }
346 
347 //---------------------------------------------------------------------
handleAttribute(sal_uInt16,const::rtl::OUString & _rLocalName,const::rtl::OUString & _rValue)348 bool OPropertyImport::handleAttribute(sal_uInt16 /*_nNamespaceKey*/, const ::rtl::OUString& _rLocalName, const ::rtl::OUString& _rValue)
349 {
350     const OAttribute2Property::AttributeAssignment* pProperty = m_rContext.getAttributeMap().getAttributeTranslation(_rLocalName);
351     if (pProperty)
352     {
353         // create and store a new PropertyValue
354         PropertyValue aNewValue;
355         aNewValue.Name = pProperty->sPropertyName;
356 
357         // convert the value string into the target type
358         aNewValue.Value = PropertyConversion::convertString(m_rContext.getGlobalContext(), pProperty->aPropertyType, _rValue, pProperty->pEnumMap, pProperty->bInverseSemantics);
359         implPushBackPropertyValue( aNewValue );
360         return true;
361     }
362     if (!token::IsXMLToken(_rLocalName, token::XML_TYPE))  // xlink:type is valid but ignored for <form:form>
363     {
364 #if OSL_DEBUG_LEVEL > 0
365         ::rtl::OString sMessage( "OPropertyImport::handleAttribute: Can't handle the following:\n" );
366         sMessage += ::rtl::OString( "  Attribute name: " );
367         sMessage += ::rtl::OString( _rLocalName.getStr(), _rLocalName.getLength(), osl_getThreadTextEncoding() );
368         sMessage += ::rtl::OString( "\n  value: " );
369         sMessage += ::rtl::OString( _rValue.getStr(), _rValue.getLength(), osl_getThreadTextEncoding() );
370         OSL_ENSURE( sal_False, sMessage.getStr() );
371 #endif
372         return false;
373     }
374     return true;
375 }
376 
377 //=====================================================================
378 //= OPropertyElementsContext
379 //=====================================================================
380 //---------------------------------------------------------------------
OPropertyElementsContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OPropertyImportRef & _rPropertyImporter)381 OPropertyElementsContext::OPropertyElementsContext(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName,
382         const OPropertyImportRef& _rPropertyImporter)
383     :SvXMLImportContext(_rImport, _nPrefix, _rName)
384     ,m_xPropertyImporter(_rPropertyImporter)
385 {
386 }
387 
388 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> &)389 SvXMLImportContext* OPropertyElementsContext::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName,
390     const Reference< sax::XAttributeList >&)
391 {
392     if( token::IsXMLToken( _rLocalName, token::XML_PROPERTY ) )
393     {
394         return new OSinglePropertyContext(GetImport(), _nPrefix, _rLocalName, m_xPropertyImporter);
395     }
396     else if( token::IsXMLToken( _rLocalName, token::XML_LIST_PROPERTY ) )
397     {
398         return new OListPropertyContext( GetImport(), _nPrefix, _rLocalName, m_xPropertyImporter );
399     }
400     else
401     {
402         OSL_ENSURE(sal_False,
403                 ::rtl::OString("OPropertyElementsContext::CreateChildContext: unknown child element (\"")
404             +=  ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
405             +=  ::rtl::OString("\")!"));
406         return new SvXMLImportContext(GetImport(), _nPrefix, _rLocalName);
407     }
408 }
409 
410 #if OSL_DEBUG_LEVEL > 0
411     //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)412     void OPropertyElementsContext::StartElement(const Reference< sax::XAttributeList >& _rxAttrList)
413     {
414         OSL_ENSURE(0 == _rxAttrList->getLength(), "OPropertyElementsContext::StartElement: the form:properties element should not have attributes!");
415         SvXMLImportContext::StartElement(_rxAttrList);
416     }
417 
418     //---------------------------------------------------------------------
Characters(const::rtl::OUString & _rChars)419     void OPropertyElementsContext::Characters(const ::rtl::OUString& _rChars)
420     {
421         OSL_ENSURE(0 == _rChars.trim(), "OPropertyElementsContext::Characters: non-whitespace characters detected!");
422         SvXMLImportContext::Characters(_rChars);
423     }
424 
425 #endif
426 
427 //=====================================================================
428 //= OSinglePropertyContext
429 //=====================================================================
430 //---------------------------------------------------------------------
OSinglePropertyContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OPropertyImportRef & _rPropertyImporter)431 OSinglePropertyContext::OSinglePropertyContext(SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName,
432         const OPropertyImportRef& _rPropertyImporter)
433     :SvXMLImportContext(_rImport, _nPrefix, _rName)
434     ,m_xPropertyImporter(_rPropertyImporter)
435 {
436 }
437 
438 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> &)439 SvXMLImportContext* OSinglePropertyContext::CreateChildContext(sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName,
440         const Reference< sax::XAttributeList >&)
441 {
442     OSL_ENSURE(sal_False,
443             ::rtl::OString("OSinglePropertyContext::CreateChildContext: unknown child element (\"")
444         +=  ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
445         +=  ::rtl::OString("\")!"));
446     return new SvXMLImportContext(GetImport(), _nPrefix, _rLocalName);
447 }
448 
449 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)450 void OSinglePropertyContext::StartElement(const Reference< sax::XAttributeList >& _rxAttrList)
451 {
452     ::com::sun::star::beans::PropertyValue aPropValue;      // the property the instance imports currently
453     ::com::sun::star::uno::Type aPropType;          // the type of the property the instance imports currently
454 
455     ::rtl::OUString sType, sValue;
456     const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap();
457     const sal_Int16 nAttrCount = _rxAttrList.is() ? _rxAttrList->getLength() : 0;
458     for( sal_Int16 i=0; i < nAttrCount; i++ )
459     {
460         const ::rtl::OUString& rAttrName = _rxAttrList->getNameByIndex( i );
461         //const ::rtl::OUString& rValue = _rxAttrList->getValueByIndex( i );
462 
463         ::rtl::OUString aLocalName;
464         sal_uInt16 nPrefix =
465             rMap.GetKeyByAttrName( rAttrName,
466                                                             &aLocalName );
467         if( XML_NAMESPACE_FORM == nPrefix )
468         {
469             if( token::IsXMLToken( aLocalName, token::XML_PROPERTY_NAME ) )
470                 aPropValue.Name = _rxAttrList->getValueByIndex( i );
471 
472         }
473         else if( XML_NAMESPACE_OFFICE == nPrefix )
474         {
475             if( token::IsXMLToken( aLocalName, token::XML_VALUE_TYPE ) )
476                 sType = _rxAttrList->getValueByIndex( i );
477             else if( token::IsXMLToken( aLocalName,
478                                         token::XML_VALUE ) ||
479                      token::IsXMLToken( aLocalName,
480                                         token::XML_BOOLEAN_VALUE ) ||
481                      token::IsXMLToken( aLocalName,
482                                         token::XML_STRING_VALUE ) )
483                 sValue = _rxAttrList->getValueByIndex( i );
484         }
485     }
486 
487     // the name of the property
488     OSL_ENSURE(aPropValue.Name.getLength(), "OSinglePropertyContext::StartElement: invalid property name!");
489 
490     // needs to be translated into a ::com::sun::star::uno::Type
491     aPropType = PropertyConversion::xmlTypeToUnoType( sType );
492     if( TypeClass_VOID == aPropType.getTypeClass() )
493     {
494         aPropValue.Value = Any();
495     }
496     else
497     {
498         aPropValue.Value =
499             PropertyConversion::convertString(GetImport(), aPropType,
500                                            sValue);
501     }
502 
503     // now that we finally have our property value, add it to our parent object
504     if( aPropValue.Name.getLength() )
505         m_xPropertyImporter->implPushBackGenericPropertyValue(aPropValue);
506 }
507 
508 //=====================================================================
509 //= OListPropertyContext
510 //=====================================================================
511 //---------------------------------------------------------------------
OListPropertyContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,const OPropertyImportRef & _rPropertyImporter)512 OListPropertyContext::OListPropertyContext( SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName,
513     const OPropertyImportRef& _rPropertyImporter )
514     :SvXMLImportContext( _rImport, _nPrefix, _rName )
515     ,m_xPropertyImporter( _rPropertyImporter )
516 {
517 }
518 
519 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)520 void OListPropertyContext::StartElement( const Reference< sax::XAttributeList >& _rxAttrList )
521 {
522     sal_Int32 nAttributeCount = _rxAttrList->getLength();
523 
524     sal_uInt16 nNamespace;
525     ::rtl::OUString sAttributeName;
526     const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap();
527     for ( sal_Int16 i = 0; i < nAttributeCount; ++i )
528     {
529         nNamespace = rMap.GetKeyByAttrName( _rxAttrList->getNameByIndex( i ), &sAttributeName );
530         if  (   ( XML_NAMESPACE_FORM == nNamespace )
531             &&  ( token::IsXMLToken( sAttributeName, token::XML_PROPERTY_NAME ) )
532             )
533         {
534             m_sPropertyName = _rxAttrList->getValueByIndex( i );
535         }
536         else if (   ( XML_NAMESPACE_OFFICE == nNamespace )
537                 &&  ( token::IsXMLToken( sAttributeName, token::XML_VALUE_TYPE ) )
538                 )
539         {
540             m_sPropertyType = _rxAttrList->getValueByIndex( i );
541         }
542         else
543         {
544             OSL_ENSURE( false,
545                     ::rtl::OString( "OListPropertyContext::StartElement: unknown child element (\"")
546                 +=  ::rtl::OString( sAttributeName.getStr(), sAttributeName.getLength(), RTL_TEXTENCODING_ASCII_US )
547                 +=  ::rtl::OString( "\")!" ) );
548         }
549     }
550 }
551 
552 //---------------------------------------------------------------------
EndElement()553 void OListPropertyContext::EndElement()
554 {
555     OSL_ENSURE( m_sPropertyName.getLength() && m_sPropertyType.getLength(),
556         "OListPropertyContext::EndElement: no property name or type!" );
557 
558     if ( !m_sPropertyName.getLength() || !m_sPropertyType.getLength() )
559         return;
560 
561     Sequence< Any > aListElements( m_aListValues.size() );
562     Any* pListElement = aListElements.getArray();
563     com::sun::star::uno::Type aType = PropertyConversion::xmlTypeToUnoType( m_sPropertyType );
564     for (   ::std::vector< ::rtl::OUString >::const_iterator values = m_aListValues.begin();
565             values != m_aListValues.end();
566             ++values, ++pListElement
567         )
568     {
569         *pListElement = PropertyConversion::convertString( GetImport(), aType, *values );
570     }
571 
572     PropertyValue aSequenceValue;
573     aSequenceValue.Name = m_sPropertyName;
574     aSequenceValue.Value <<= aListElements;
575 
576     m_xPropertyImporter->implPushBackGenericPropertyValue( aSequenceValue );
577 }
578 
579 //---------------------------------------------------------------------
CreateChildContext(sal_uInt16 _nPrefix,const::rtl::OUString & _rLocalName,const Reference<sax::XAttributeList> &)580 SvXMLImportContext* OListPropertyContext::CreateChildContext( sal_uInt16 _nPrefix, const ::rtl::OUString& _rLocalName, const Reference< sax::XAttributeList >& /*_rxAttrList*/ )
581 {
582     if ( token::IsXMLToken( _rLocalName, token::XML_LIST_VALUE ) )
583     {
584         m_aListValues.resize( m_aListValues.size() + 1 );
585         return new OListValueContext( GetImport(), _nPrefix, _rLocalName, *m_aListValues.rbegin() );
586     }
587     else
588     {
589         OSL_ENSURE( sal_False,
590                 ::rtl::OString("OListPropertyContext::CreateChildContext: unknown child element (\"")
591             +=  ::rtl::OString(_rLocalName.getStr(), _rLocalName.getLength(), RTL_TEXTENCODING_ASCII_US)
592             +=  ::rtl::OString("\")!"));
593         return new SvXMLImportContext( GetImport(), _nPrefix, _rLocalName );
594     }
595 }
596 
597 //=====================================================================
598 //= OListValueContext
599 //=====================================================================
600 //---------------------------------------------------------------------
OListValueContext(SvXMLImport & _rImport,sal_uInt16 _nPrefix,const::rtl::OUString & _rName,::rtl::OUString & _rListValueHolder)601 OListValueContext::OListValueContext( SvXMLImport& _rImport, sal_uInt16 _nPrefix, const ::rtl::OUString& _rName, ::rtl::OUString& _rListValueHolder )
602     :SvXMLImportContext( _rImport, _nPrefix, _rName )
603     ,m_rListValueHolder( _rListValueHolder )
604 {
605 }
606 
607 //---------------------------------------------------------------------
StartElement(const Reference<sax::XAttributeList> & _rxAttrList)608 void OListValueContext::StartElement( const Reference< sax::XAttributeList >& _rxAttrList )
609 {
610     const sal_Int32 nAttributeCount = _rxAttrList->getLength();
611 
612     sal_uInt16 nNamespace;
613     ::rtl::OUString sAttributeName;
614     const SvXMLNamespaceMap& rMap = GetImport().GetNamespaceMap();
615     for ( sal_Int16 i = 0; i < nAttributeCount; ++i )
616     {
617         nNamespace = rMap.GetKeyByAttrName( _rxAttrList->getNameByIndex( i ), &sAttributeName );
618         if ( XML_NAMESPACE_OFFICE == nNamespace )
619         {
620             if  (   token::IsXMLToken( sAttributeName, token::XML_VALUE )
621                ||   token::IsXMLToken( sAttributeName, token::XML_STRING_VALUE )
622                ||   token::IsXMLToken( sAttributeName, token::XML_BOOLEAN_VALUE )
623                 )
624             {
625                 m_rListValueHolder = _rxAttrList->getValueByIndex( i );
626                 continue;
627             }
628         }
629 
630         OSL_ENSURE( false,
631                 ::rtl::OString( "OListValueContext::StartElement: unknown child element (\"")
632             +=  ::rtl::OString( sAttributeName.getStr(), sAttributeName.getLength(), RTL_TEXTENCODING_ASCII_US )
633             +=  ::rtl::OString( "\")!" ) );
634     }
635 }
636 
637 //.........................................................................
638 }   // namespace xmloff
639 //.........................................................................
640 
641