fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / xmloff / source / xforms / SchemaRestrictionContext.cxx
blob34b64ae12fcba55bcdad5fca7a31692abe19782a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "SchemaRestrictionContext.hxx"
22 #include "xformsapi.hxx"
24 #include <xmloff/xmltoken.hxx>
25 #include <xmloff/nmspmap.hxx>
26 #include <xmloff/xmlnmspe.hxx>
27 #include <xmloff/xmltkmap.hxx>
28 #include <xmloff/xmlimp.hxx>
30 #include <sax/tools/converter.hxx>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/uno/Type.hxx>
34 #include <com/sun/star/util/Date.hpp>
35 #include <com/sun/star/util/Time.hpp>
36 #include <com/sun/star/util/DateTime.hpp>
37 #include <com/sun/star/util/Duration.hpp>
38 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
39 #include <com/sun/star/xsd/DataTypeClass.hpp>
40 #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
42 #include <tools/debug.hxx>
45 using com::sun::star::uno::Reference;
46 using com::sun::star::uno::Exception;
47 using com::sun::star::uno::Any;
48 using com::sun::star::uno::makeAny;
49 using com::sun::star::uno::UNO_QUERY;
50 using namespace com::sun::star;
51 using com::sun::star::util::Duration;
52 using com::sun::star::xml::sax::XAttributeList;
53 using com::sun::star::beans::XPropertySet;
54 using com::sun::star::beans::XPropertySetInfo;
55 using com::sun::star::xforms::XDataTypeRepository;
56 using namespace xmloff::token;
61 static SvXMLTokenMapEntry aAttributes[] =
63 TOKEN_MAP_ENTRY( NONE, BASE ),
64 XML_TOKEN_MAP_END
67 static SvXMLTokenMapEntry aChildren[] =
69 TOKEN_MAP_ENTRY( XSD, LENGTH ),
70 TOKEN_MAP_ENTRY( XSD, MINLENGTH ),
71 TOKEN_MAP_ENTRY( XSD, MAXLENGTH ),
72 TOKEN_MAP_ENTRY( XSD, MININCLUSIVE ),
73 TOKEN_MAP_ENTRY( XSD, MINEXCLUSIVE ),
74 TOKEN_MAP_ENTRY( XSD, MAXINCLUSIVE ),
75 TOKEN_MAP_ENTRY( XSD, MAXEXCLUSIVE ),
76 TOKEN_MAP_ENTRY( XSD, PATTERN ),
77 // ??? XML_ENUMERATION
78 TOKEN_MAP_ENTRY( XSD, WHITESPACE ),
79 TOKEN_MAP_ENTRY( XSD, TOTALDIGITS ),
80 TOKEN_MAP_ENTRY( XSD, FRACTIONDIGITS ),
81 XML_TOKEN_MAP_END
85 SchemaRestrictionContext::SchemaRestrictionContext(
86 SvXMLImport& rImport,
87 sal_uInt16 nPrefix,
88 const OUString& rLocalName,
89 Reference<com::sun::star::xforms::XDataTypeRepository>& rRepository,
90 const OUString& sTypeName ) :
91 TokenContext( rImport, nPrefix, rLocalName, aAttributes, aChildren ),
92 mxRepository( rRepository ),
93 msTypeName( sTypeName ),
94 msBaseName()
96 DBG_ASSERT( mxRepository.is(), "need repository" );
99 SchemaRestrictionContext::~SchemaRestrictionContext()
103 void SchemaRestrictionContext::CreateDataType()
105 // only do something if we don't have a data type already
106 if( mxDataType.is() )
107 return;
109 DBG_ASSERT( !msBaseName.isEmpty(), "no base name?" );
110 DBG_ASSERT( mxRepository.is(), "no repository?" );
114 mxDataType =
115 Reference<XPropertySet>(
116 mxRepository->cloneDataType(
117 xforms_getBasicTypeName( mxRepository,
118 GetImport().GetNamespaceMap(),
119 msBaseName ),
120 msTypeName ),
121 UNO_QUERY );
123 catch( const Exception& )
125 OSL_FAIL( "exception during type creation" );
127 DBG_ASSERT( mxDataType.is(), "can't create type" );
130 void SchemaRestrictionContext::HandleAttribute(
131 sal_uInt16 nToken,
132 const OUString& rValue )
134 if( nToken == XML_BASE )
136 msBaseName = rValue;
140 typedef Any (*convert_t)( const OUString& );
142 Any xforms_string( const OUString& rValue )
144 return makeAny( rValue );
147 Any xforms_int32( const OUString& rValue )
149 sal_Int32 nValue;
150 bool bSuccess = ::sax::Converter::convertNumber( nValue, rValue );
151 return bSuccess ? makeAny( nValue ) : Any();
154 Any xforms_int16( const OUString& rValue )
156 sal_Int32 nValue;
157 bool bSuccess = ::sax::Converter::convertNumber( nValue, rValue );
158 return bSuccess ? makeAny( static_cast<sal_Int16>( nValue ) ) : Any();
161 Any xforms_whitespace( const OUString& rValue )
163 Any aValue;
164 if( IsXMLToken( rValue, XML_PRESERVE ) )
165 aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Preserve;
166 else if( IsXMLToken( rValue, XML_REPLACE ) )
167 aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Replace;
168 else if( IsXMLToken( rValue, XML_COLLAPSE ) )
169 aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Collapse;
170 return aValue;
173 Any xforms_double( const OUString& rValue )
175 double fValue;
176 bool bSuccess = ::sax::Converter::convertDouble( fValue, rValue );
177 return bSuccess ? makeAny( fValue ) : Any();
180 Any xforms_date( const OUString& rValue )
182 Any aAny;
184 // parse ISO date
185 sal_Int32 nPos1 = rValue.indexOf( sal_Unicode('-') );
186 sal_Int32 nPos2 = rValue.indexOf( sal_Unicode('-'), nPos1 + 1 );
187 if( nPos1 > 0 && nPos2 > 0 )
189 util::Date aDate;
190 aDate.Year = static_cast<sal_uInt16>(
191 rValue.copy( 0, nPos1 ).toInt32() );
192 aDate.Month = static_cast<sal_uInt16>(
193 rValue.copy( nPos1 + 1, nPos2 - nPos1 - 1 ).toInt32() );
194 aDate.Day = static_cast<sal_uInt16>(
195 rValue.copy( nPos2 + 1 ).toInt32() );
196 aAny <<= aDate;
198 return aAny;
201 Any xforms_dateTime( const OUString& rValue )
203 util::DateTime aDateTime;
204 bool const bSuccess = ::sax::Converter::convertDateTime(aDateTime, rValue);
205 return bSuccess ? makeAny( aDateTime ) : Any();
208 Any xforms_time( const OUString& rValue )
210 Any aAny;
211 Duration aDuration;
212 if (::sax::Converter::convertDuration( aDuration, rValue ))
214 com::sun::star::util::Time aTime;
215 aTime.Hours = aDuration.Hours;
216 aTime.Minutes = aDuration.Minutes;
217 aTime.Seconds = aDuration.Seconds;
218 aTime.NanoSeconds = aDuration.NanoSeconds;
219 aAny <<= aTime;
221 return aAny;
225 SvXMLImportContext* SchemaRestrictionContext::HandleChild(
226 sal_uInt16 nToken,
227 sal_uInt16 nPrefix,
228 const OUString& rLocalName,
229 const Reference<XAttributeList>& xAttrList )
231 // find value
232 OUString sValue;
233 sal_Int16 nLength = xAttrList->getLength();
234 for( sal_Int16 n = 0; n < nLength; n++ )
236 if( IsXMLToken( xAttrList->getNameByIndex( n ), XML_VALUE ) )
237 sValue = xAttrList->getValueByIndex( n );
240 // determine property name + suitable converter
241 OUString sPropertyName;
242 convert_t pConvert = NULL;
243 switch( nToken )
245 case XML_LENGTH:
246 sPropertyName = "Length";
247 pConvert = &xforms_int32;
248 break;
249 case XML_MINLENGTH:
250 sPropertyName = "MinLength";
251 pConvert = &xforms_int32;
252 break;
253 case XML_MAXLENGTH:
254 sPropertyName = "MaxLength";
255 pConvert = &xforms_int32;
256 break;
257 case XML_TOTALDIGITS:
258 sPropertyName = "TotalDigits";
259 pConvert = &xforms_int32;
260 break;
261 case XML_FRACTIONDIGITS:
262 sPropertyName = "FractionDigits";
263 pConvert = &xforms_int32;
264 break;
265 case XML_PATTERN:
266 sPropertyName = "Pattern";
267 pConvert = &xforms_string;
268 break;
269 case XML_WHITESPACE:
270 sPropertyName = "WhiteSpace";
271 pConvert = &xforms_whitespace;
272 break;
273 case XML_MININCLUSIVE:
274 case XML_MINEXCLUSIVE:
275 case XML_MAXINCLUSIVE:
276 case XML_MAXEXCLUSIVE:
278 // these attributes are mapped to different properties.
279 // To determine the property name, we use an attribute
280 // dependent prefix and a type dependent suffix. The
281 // converter is only type dependent.
283 // first, attribute-dependent prefix
284 switch( nToken )
286 case XML_MININCLUSIVE:
287 sPropertyName = "MinInclusive";
288 break;
289 case XML_MINEXCLUSIVE:
290 sPropertyName = "MinExclusive";
291 break;
292 case XML_MAXINCLUSIVE:
293 sPropertyName = "MaxInclusive";
294 break;
295 case XML_MAXEXCLUSIVE:
296 sPropertyName = "MaxExclusive";
297 break;
300 // second, type-dependent suffix + converter
301 switch( xforms_getTypeClass( mxRepository,
302 GetImport().GetNamespaceMap(),
303 msBaseName ) )
305 case com::sun::star::xsd::DataTypeClass::DECIMAL:
306 case com::sun::star::xsd::DataTypeClass::DOUBLE:
307 case com::sun::star::xsd::DataTypeClass::FLOAT:
308 sPropertyName += "Double";
309 pConvert = &xforms_double;
310 break;
311 case com::sun::star::xsd::DataTypeClass::DATETIME:
312 sPropertyName += "DateTime";
313 pConvert = &xforms_dateTime;
314 break;
315 case com::sun::star::xsd::DataTypeClass::DATE:
316 sPropertyName += "Date";
317 pConvert = &xforms_date;
318 break;
319 case com::sun::star::xsd::DataTypeClass::TIME:
320 sPropertyName += "Time";
321 pConvert = &xforms_time;
322 break;
323 case com::sun::star::xsd::DataTypeClass::gYear:
324 case com::sun::star::xsd::DataTypeClass::gDay:
325 case com::sun::star::xsd::DataTypeClass::gMonth:
326 sPropertyName += "Int";
327 pConvert = &xforms_int16;
328 break;
330 case com::sun::star::xsd::DataTypeClass::STRING:
331 case com::sun::star::xsd::DataTypeClass::anyURI:
332 case com::sun::star::xsd::DataTypeClass::BOOLEAN:
333 // invalid: These shouldn't have min/max-inclusive
334 break;
336 /* data types not yet supported:
337 case com::sun::star::xsd::DataTypeClass::DURATION:
338 case com::sun::star::xsd::DataTypeClass::gYearMonth:
339 case com::sun::star::xsd::DataTypeClass::gMonthDay:
340 case com::sun::star::xsd::DataTypeClass::hexBinary:
341 case com::sun::star::xsd::DataTypeClass::base64Binary:
342 case com::sun::star::xsd::DataTypeClass::QName:
343 case com::sun::star::xsd::DataTypeClass::NOTATION:
347 break;
349 default:
350 OSL_FAIL( "unknown facet" );
353 // finally, set the property
354 CreateDataType();
355 if( mxDataType.is()
356 && !sPropertyName.isEmpty()
357 && pConvert != NULL
358 && mxDataType->getPropertySetInfo()->hasPropertyByName(sPropertyName) )
362 mxDataType->setPropertyValue( sPropertyName, pConvert( sValue ) );
364 catch( const Exception& )
366 ; // can't set property? Then ignore.
370 return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
373 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */