1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SchemaRestrictionContext.cxx,v $
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>
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
),
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
),
97 SchemaRestrictionContext::SchemaRestrictionContext(
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
),
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() )
121 DBG_ASSERT( msBaseName
.getLength() > 0, "no base name?" );
122 DBG_ASSERT( mxRepository
.is(), "no repository?" );
127 Reference
<XPropertySet
>(
128 mxRepository
->cloneDataType(
129 lcl_getBasicTypeName( mxRepository
,
130 GetImport().GetNamespaceMap(),
135 catch( const Exception
& )
137 DBG_ERROR( "exception during type creation" );
139 DBG_ASSERT( mxDataType
.is(), "can't create type" );
142 void SchemaRestrictionContext::HandleAttribute(
144 const OUString
& rValue
)
146 if( nToken
== XML_BASE
)
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
)
162 bool bSuccess
= SvXMLUnitConverter::convertNumber( nValue
, rValue
);
163 return bSuccess
? makeAny( nValue
) : Any();
166 Any
lcl_int16( const OUString
& rValue
)
169 bool bSuccess
= SvXMLUnitConverter::convertNumber( nValue
, rValue
);
170 return bSuccess
? makeAny( static_cast<sal_Int16
>( nValue
) ) : Any();
173 Any
lcl_whitespace( const OUString
& rValue
)
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
;
185 Any
lcl_double( const OUString
& rValue
)
188 bool bSuccess
= SvXMLUnitConverter::convertDouble( fValue
, rValue
);
189 return bSuccess
? makeAny( fValue
) : Any();
192 Any
lcl_date( const OUString
& rValue
)
197 sal_Int32 nPos1
= rValue
.indexOf( sal_Unicode('-') );
198 sal_Int32 nPos2
= rValue
.indexOf( sal_Unicode('-'), nPos1
+ 1 );
199 if( nPos1
> 0 && nPos2
> 0 )
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() );
213 Any
lcl_dateTime( const OUString
& rValue
)
216 bool bSuccess
= SvXMLUnitConverter::convertDateTime( aDateTime
, rValue
);
217 return bSuccess
? makeAny( aDateTime
) : Any();
220 Any
lcl_time( const OUString
& rValue
)
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
;
237 SvXMLImportContext
* SchemaRestrictionContext::HandleChild(
240 const OUString
& rLocalName
,
241 const Reference
<XAttributeList
>& xAttrList
)
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
;
258 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("Length"));
259 pConvert
= &lcl_int32
;
262 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("MinLength"));
263 pConvert
= &lcl_int32
;
266 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("MaxLength"));
267 pConvert
= &lcl_int32
;
269 case XML_TOTALDIGITS
:
270 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("TotalDigits"));
271 pConvert
= &lcl_int32
;
273 case XML_FRACTIONDIGITS
:
274 sPropertyName
=OUString(RTL_CONSTASCII_USTRINGPARAM("FractionDigits"));
275 pConvert
= &lcl_int32
;
278 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("Pattern"));
279 pConvert
= &lcl_string
;
282 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("WhiteSpace"));
283 pConvert
= &lcl_whitespace
;
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
298 case XML_MININCLUSIVE
:
299 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("MinInclusive"));
301 case XML_MINEXCLUSIVE
:
302 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("MinExclusive"));
304 case XML_MAXINCLUSIVE
:
305 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("MaxInclusive"));
307 case XML_MAXEXCLUSIVE
:
308 sPropertyName
= OUString(RTL_CONSTASCII_USTRINGPARAM("MaxExclusive"));
312 // second, type-dependent suffix + converter
313 switch( lcl_getTypeClass( mxRepository
,
314 GetImport().GetNamespaceMap(),
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
;
323 case com::sun::star::xsd::DataTypeClass::DATETIME
:
324 sPropertyName
+= OUString(RTL_CONSTASCII_USTRINGPARAM("DateTime"));
325 pConvert
= &lcl_dateTime
;
327 case com::sun::star::xsd::DataTypeClass::DATE
:
328 sPropertyName
+= OUString(RTL_CONSTASCII_USTRINGPARAM("Date"));
329 pConvert
= &lcl_date
;
331 case com::sun::star::xsd::DataTypeClass::TIME
:
332 sPropertyName
+= OUString(RTL_CONSTASCII_USTRINGPARAM("Time"));
333 pConvert
= &lcl_time
;
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
;
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
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:
362 DBG_ERROR( "unknown facet" );
365 // finally, set the property
368 && sPropertyName
.getLength() > 0
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
);