Update ooo320-m1
[ooovba.git] / xmloff / source / xforms / SchemaRestrictionContext.cxx
blobf48101288fcbd6cf560cf9ff6179d28ec3bfc3e1
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SchemaRestrictionContext.cxx,v $
10 * $Revision: 1.7 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_xmloff.hxx"
34 #include "SchemaRestrictionContext.hxx"
35 #include "xformsapi.hxx"
37 #include <xmloff/xmltoken.hxx>
38 #include <xmloff/nmspmap.hxx>
39 #include <xmlnmspe.hxx>
40 #include <xmloff/xmltkmap.hxx>
41 #include <xmloff/xmluconv.hxx>
42 #include <xmloff/xmlimp.hxx>
44 #include <com/sun/star/beans/XPropertySet.hpp>
45 #include <com/sun/star/uno/Type.hxx>
46 #include <com/sun/star/util/Date.hpp>
47 #include <com/sun/star/util/Time.hpp>
48 #include <com/sun/star/util/DateTime.hpp>
49 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
50 #include <com/sun/star/xsd/DataTypeClass.hpp>
51 #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
53 #include <tools/debug.hxx>
56 using rtl::OUString;
57 using com::sun::star::uno::Reference;
58 using com::sun::star::uno::Exception;
59 using com::sun::star::uno::Any;
60 using com::sun::star::uno::makeAny;
61 using com::sun::star::uno::UNO_QUERY;
62 using com::sun::star::util::Date;
63 using com::sun::star::util::DateTime;
64 using com::sun::star::xml::sax::XAttributeList;
65 using com::sun::star::beans::XPropertySet;
66 using com::sun::star::beans::XPropertySetInfo;
67 using com::sun::star::xforms::XDataTypeRepository;
68 using namespace xmloff::token;
73 static SvXMLTokenMapEntry aAttributes[] =
75 TOKEN_MAP_ENTRY( NONE, BASE ),
76 XML_TOKEN_MAP_END
79 static SvXMLTokenMapEntry aChildren[] =
81 TOKEN_MAP_ENTRY( XSD, LENGTH ),
82 TOKEN_MAP_ENTRY( XSD, MINLENGTH ),
83 TOKEN_MAP_ENTRY( XSD, MAXLENGTH ),
84 TOKEN_MAP_ENTRY( XSD, MININCLUSIVE ),
85 TOKEN_MAP_ENTRY( XSD, MINEXCLUSIVE ),
86 TOKEN_MAP_ENTRY( XSD, MAXINCLUSIVE ),
87 TOKEN_MAP_ENTRY( XSD, MAXEXCLUSIVE ),
88 TOKEN_MAP_ENTRY( XSD, PATTERN ),
89 // ??? XML_ENUMERATION
90 TOKEN_MAP_ENTRY( XSD, WHITESPACE ),
91 TOKEN_MAP_ENTRY( XSD, TOTALDIGITS ),
92 TOKEN_MAP_ENTRY( XSD, FRACTIONDIGITS ),
93 XML_TOKEN_MAP_END
97 SchemaRestrictionContext::SchemaRestrictionContext(
98 SvXMLImport& rImport,
99 USHORT nPrefix,
100 const OUString& rLocalName,
101 Reference<com::sun::star::xforms::XDataTypeRepository>& rRepository,
102 const OUString& sTypeName ) :
103 TokenContext( rImport, nPrefix, rLocalName, aAttributes, aChildren ),
104 mxRepository( rRepository ),
105 msTypeName( sTypeName ),
106 msBaseName()
108 DBG_ASSERT( mxRepository.is(), "need repository" );
111 SchemaRestrictionContext::~SchemaRestrictionContext()
115 void SchemaRestrictionContext::CreateDataType()
117 // only do something if we don't have a data type already
118 if( mxDataType.is() )
119 return;
121 DBG_ASSERT( msBaseName.getLength() > 0, "no base name?" );
122 DBG_ASSERT( mxRepository.is(), "no repository?" );
126 mxDataType =
127 Reference<XPropertySet>(
128 mxRepository->cloneDataType(
129 lcl_getBasicTypeName( mxRepository,
130 GetImport().GetNamespaceMap(),
131 msBaseName ),
132 msTypeName ),
133 UNO_QUERY );
135 catch( const Exception& )
137 DBG_ERROR( "exception during type creation" );
139 DBG_ASSERT( mxDataType.is(), "can't create type" );
142 void SchemaRestrictionContext::HandleAttribute(
143 sal_uInt16 nToken,
144 const OUString& rValue )
146 if( nToken == XML_BASE )
148 msBaseName = rValue;
152 typedef Any (*convert_t)( const OUString& );
154 Any lcl_string( const OUString& rValue )
156 return makeAny( rValue );
159 Any lcl_int32( const OUString& rValue )
161 sal_Int32 nValue;
162 bool bSuccess = SvXMLUnitConverter::convertNumber( nValue, rValue );
163 return bSuccess ? makeAny( nValue ) : Any();
166 Any lcl_int16( const OUString& rValue )
168 sal_Int32 nValue;
169 bool bSuccess = SvXMLUnitConverter::convertNumber( nValue, rValue );
170 return bSuccess ? makeAny( static_cast<sal_Int16>( nValue ) ) : Any();
173 Any lcl_whitespace( const OUString& rValue )
175 Any aValue;
176 if( IsXMLToken( rValue, XML_PRESERVE ) )
177 aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Preserve;
178 else if( IsXMLToken( rValue, XML_REPLACE ) )
179 aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Replace;
180 else if( IsXMLToken( rValue, XML_COLLAPSE ) )
181 aValue <<= com::sun::star::xsd::WhiteSpaceTreatment::Collapse;
182 return aValue;
185 Any lcl_double( const OUString& rValue )
187 double fValue;
188 bool bSuccess = SvXMLUnitConverter::convertDouble( fValue, rValue );
189 return bSuccess ? makeAny( fValue ) : Any();
192 Any lcl_date( const OUString& rValue )
194 Any aAny;
196 // parse ISO date
197 sal_Int32 nPos1 = rValue.indexOf( sal_Unicode('-') );
198 sal_Int32 nPos2 = rValue.indexOf( sal_Unicode('-'), nPos1 + 1 );
199 if( nPos1 > 0 && nPos2 > 0 )
201 Date aDate;
202 aDate.Year = static_cast<sal_uInt16>(
203 rValue.copy( 0, nPos1 ).toInt32() );
204 aDate.Month = static_cast<sal_uInt16>(
205 rValue.copy( nPos1 + 1, nPos2 - nPos1 - 1 ).toInt32() );
206 aDate.Day = static_cast<sal_uInt16>(
207 rValue.copy( nPos2 + 1 ).toInt32() );
208 aAny <<= aDate;
210 return aAny;
213 Any lcl_dateTime( const OUString& rValue )
215 DateTime aDateTime;
216 bool bSuccess = SvXMLUnitConverter::convertDateTime( aDateTime, rValue );
217 return bSuccess ? makeAny( aDateTime ) : Any();
220 Any lcl_time( const OUString& rValue )
222 Any aAny;
223 DateTime aDateTime;
224 if( SvXMLUnitConverter::convertTime( aDateTime, rValue ) )
226 com::sun::star::util::Time aTime;
227 aTime.Hours = aDateTime.Hours;
228 aTime.Minutes = aDateTime.Minutes;
229 aTime.Seconds = aDateTime.Seconds;
230 aTime.HundredthSeconds = aDateTime.HundredthSeconds;
231 aAny <<= aTime;
233 return aAny;
237 SvXMLImportContext* SchemaRestrictionContext::HandleChild(
238 sal_uInt16 nToken,
239 sal_uInt16 nPrefix,
240 const OUString& rLocalName,
241 const Reference<XAttributeList>& xAttrList )
243 // find value
244 OUString sValue;
245 sal_Int16 nLength = xAttrList->getLength();
246 for( sal_Int16 n = 0; n < nLength; n++ )
248 if( IsXMLToken( xAttrList->getNameByIndex( n ), XML_VALUE ) )
249 sValue = xAttrList->getValueByIndex( n );
252 // determine property name + suitable converter
253 OUString sPropertyName;
254 convert_t pConvert = NULL;
255 switch( nToken )
257 case XML_LENGTH:
258 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("Length"));
259 pConvert = &lcl_int32;
260 break;
261 case XML_MINLENGTH:
262 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MinLength"));
263 pConvert = &lcl_int32;
264 break;
265 case XML_MAXLENGTH:
266 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MaxLength"));
267 pConvert = &lcl_int32;
268 break;
269 case XML_TOTALDIGITS:
270 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("TotalDigits"));
271 pConvert = &lcl_int32;
272 break;
273 case XML_FRACTIONDIGITS:
274 sPropertyName =OUString(RTL_CONSTASCII_USTRINGPARAM("FractionDigits"));
275 pConvert = &lcl_int32;
276 break;
277 case XML_PATTERN:
278 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("Pattern"));
279 pConvert = &lcl_string;
280 break;
281 case XML_WHITESPACE:
282 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("WhiteSpace"));
283 pConvert = &lcl_whitespace;
284 break;
285 case XML_MININCLUSIVE:
286 case XML_MINEXCLUSIVE:
287 case XML_MAXINCLUSIVE:
288 case XML_MAXEXCLUSIVE:
290 // these attributes are mapped to different properties.
291 // To determine the property name, we use an attribute
292 // dependent prefix and a type dependent suffix. The
293 // converter is only type dependent.
295 // first, attribute-dependent prefix
296 switch( nToken )
298 case XML_MININCLUSIVE:
299 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MinInclusive"));
300 break;
301 case XML_MINEXCLUSIVE:
302 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MinExclusive"));
303 break;
304 case XML_MAXINCLUSIVE:
305 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MaxInclusive"));
306 break;
307 case XML_MAXEXCLUSIVE:
308 sPropertyName = OUString(RTL_CONSTASCII_USTRINGPARAM("MaxExclusive"));
309 break;
312 // second, type-dependent suffix + converter
313 switch( lcl_getTypeClass( mxRepository,
314 GetImport().GetNamespaceMap(),
315 msBaseName ) )
317 case com::sun::star::xsd::DataTypeClass::DECIMAL:
318 case com::sun::star::xsd::DataTypeClass::DOUBLE:
319 case com::sun::star::xsd::DataTypeClass::FLOAT:
320 sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Double"));
321 pConvert = &lcl_double;
322 break;
323 case com::sun::star::xsd::DataTypeClass::DATETIME:
324 sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("DateTime"));
325 pConvert = &lcl_dateTime;
326 break;
327 case com::sun::star::xsd::DataTypeClass::DATE:
328 sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Date"));
329 pConvert = &lcl_date;
330 break;
331 case com::sun::star::xsd::DataTypeClass::TIME:
332 sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Time"));
333 pConvert = &lcl_time;
334 break;
335 case com::sun::star::xsd::DataTypeClass::gYear:
336 case com::sun::star::xsd::DataTypeClass::gDay:
337 case com::sun::star::xsd::DataTypeClass::gMonth:
338 sPropertyName += OUString(RTL_CONSTASCII_USTRINGPARAM("Int"));
339 pConvert = &lcl_int16;
340 break;
342 case com::sun::star::xsd::DataTypeClass::STRING:
343 case com::sun::star::xsd::DataTypeClass::anyURI:
344 case com::sun::star::xsd::DataTypeClass::BOOLEAN:
345 // invalid: These shouldn't have min/max-inclusive
346 break;
348 /* data types not yet supported:
349 case com::sun::star::xsd::DataTypeClass::DURATION:
350 case com::sun::star::xsd::DataTypeClass::gYearMonth:
351 case com::sun::star::xsd::DataTypeClass::gMonthDay:
352 case com::sun::star::xsd::DataTypeClass::hexBinary:
353 case com::sun::star::xsd::DataTypeClass::base64Binary:
354 case com::sun::star::xsd::DataTypeClass::QName:
355 case com::sun::star::xsd::DataTypeClass::NOTATION:
359 break;
361 default:
362 DBG_ERROR( "unknown facet" );
365 // finally, set the property
366 CreateDataType();
367 if( mxDataType.is()
368 && sPropertyName.getLength() > 0
369 && pConvert != NULL
370 && mxDataType->getPropertySetInfo()->hasPropertyByName(sPropertyName) )
374 mxDataType->setPropertyValue( sPropertyName, pConvert( sValue ) );
376 catch( const Exception& )
378 ; // can't set property? Then ignore.
382 return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );