Teach symstore more duplicated DLLs
[LibreOffice.git] / xmloff / source / xforms / SchemaRestrictionContext.cxx
blobf295dff5e3eafbee7ca307a72216a561cf711f3c
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/util/Date.hpp>
34 #include <com/sun/star/util/Time.hpp>
35 #include <com/sun/star/util/DateTime.hpp>
36 #include <com/sun/star/util/Duration.hpp>
37 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
38 #include <com/sun/star/xsd/DataTypeClass.hpp>
39 #include <com/sun/star/xsd/WhiteSpaceTreatment.hpp>
41 #include <osl/diagnose.h>
42 #include <sal/log.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::xforms::XDataTypeRepository;
55 using namespace xmloff::token;
58 static const SvXMLTokenMapEntry aAttributes[] =
60 TOKEN_MAP_ENTRY( NONE, BASE ),
61 XML_TOKEN_MAP_END
64 static const SvXMLTokenMapEntry aChildren[] =
66 TOKEN_MAP_ENTRY( XSD, LENGTH ),
67 TOKEN_MAP_ENTRY( XSD, MINLENGTH ),
68 TOKEN_MAP_ENTRY( XSD, MAXLENGTH ),
69 TOKEN_MAP_ENTRY( XSD, MININCLUSIVE ),
70 TOKEN_MAP_ENTRY( XSD, MINEXCLUSIVE ),
71 TOKEN_MAP_ENTRY( XSD, MAXINCLUSIVE ),
72 TOKEN_MAP_ENTRY( XSD, MAXEXCLUSIVE ),
73 TOKEN_MAP_ENTRY( XSD, PATTERN ),
74 // ??? XML_ENUMERATION
75 TOKEN_MAP_ENTRY( XSD, WHITESPACE ),
76 TOKEN_MAP_ENTRY( XSD, TOTALDIGITS ),
77 TOKEN_MAP_ENTRY( XSD, FRACTIONDIGITS ),
78 XML_TOKEN_MAP_END
82 SchemaRestrictionContext::SchemaRestrictionContext(
83 SvXMLImport& rImport,
84 sal_uInt16 nPrefix,
85 const OUString& rLocalName,
86 Reference<css::xforms::XDataTypeRepository> const & rRepository,
87 const OUString& sTypeName ) :
88 TokenContext( rImport, nPrefix, rLocalName, aAttributes, aChildren ),
89 mxRepository( rRepository ),
90 msTypeName( sTypeName ),
91 msBaseName()
93 SAL_WARN_IF( !mxRepository.is(), "xmloff", "need repository" );
96 void SchemaRestrictionContext::CreateDataType()
98 // only do something if we don't have a data type already
99 if( mxDataType.is() )
100 return;
102 SAL_WARN_IF( msBaseName.isEmpty(), "xmloff", "no base name?" );
103 SAL_WARN_IF( !mxRepository.is(), "xmloff", "no repository?" );
107 mxDataType =
108 mxRepository->cloneDataType(
109 xforms_getBasicTypeName( mxRepository,
110 GetImport().GetNamespaceMap(),
111 msBaseName ),
112 msTypeName );
114 catch( const Exception& )
116 OSL_FAIL( "exception during type creation" );
118 SAL_WARN_IF( !mxDataType.is(), "xmloff", "can't create type" );
121 void SchemaRestrictionContext::HandleAttribute(
122 sal_uInt16 nToken,
123 const OUString& rValue )
125 if( nToken == XML_BASE )
127 msBaseName = rValue;
131 typedef Any (*convert_t)( const OUString& );
133 static Any xforms_string( const OUString& rValue )
135 return makeAny( rValue );
138 static Any xforms_int32( const OUString& rValue )
140 sal_Int32 nValue;
141 bool bSuccess = ::sax::Converter::convertNumber( nValue, rValue );
142 return bSuccess ? makeAny( nValue ) : Any();
145 static Any xforms_int16( const OUString& rValue )
147 sal_Int32 nValue;
148 bool bSuccess = ::sax::Converter::convertNumber( nValue, rValue );
149 return bSuccess ? makeAny( static_cast<sal_Int16>( nValue ) ) : Any();
152 static Any xforms_whitespace( const OUString& rValue )
154 Any aValue;
155 if( IsXMLToken( rValue, XML_PRESERVE ) )
156 aValue <<= css::xsd::WhiteSpaceTreatment::Preserve;
157 else if( IsXMLToken( rValue, XML_REPLACE ) )
158 aValue <<= css::xsd::WhiteSpaceTreatment::Replace;
159 else if( IsXMLToken( rValue, XML_COLLAPSE ) )
160 aValue <<= css::xsd::WhiteSpaceTreatment::Collapse;
161 return aValue;
164 static Any xforms_double( const OUString& rValue )
166 double fValue;
167 bool bSuccess = ::sax::Converter::convertDouble( fValue, rValue );
168 return bSuccess ? makeAny( fValue ) : Any();
171 static Any xforms_date( const OUString& rValue )
173 Any aAny;
175 // parse ISO date
176 sal_Int32 nPos1 = rValue.indexOf( '-' );
177 sal_Int32 nPos2 = rValue.indexOf( '-', nPos1 + 1 );
178 if( nPos1 > 0 && nPos2 > 0 )
180 util::Date aDate;
181 aDate.Year = static_cast<sal_uInt16>(
182 rValue.copy( 0, nPos1 ).toInt32() );
183 aDate.Month = static_cast<sal_uInt16>(
184 rValue.copy( nPos1 + 1, nPos2 - nPos1 - 1 ).toInt32() );
185 aDate.Day = static_cast<sal_uInt16>(
186 rValue.copy( nPos2 + 1 ).toInt32() );
187 aAny <<= aDate;
189 return aAny;
192 static Any xforms_dateTime( const OUString& rValue )
194 util::DateTime aDateTime;
195 bool const bSuccess = ::sax::Converter::parseDateTime(aDateTime, rValue);
196 return bSuccess ? makeAny( aDateTime ) : Any();
199 static Any xforms_time( const OUString& rValue )
201 Any aAny;
202 Duration aDuration;
203 if (::sax::Converter::convertDuration( aDuration, rValue ))
205 css::util::Time aTime;
206 aTime.Hours = aDuration.Hours;
207 aTime.Minutes = aDuration.Minutes;
208 aTime.Seconds = aDuration.Seconds;
209 aTime.NanoSeconds = aDuration.NanoSeconds;
210 aAny <<= aTime;
212 return aAny;
216 SvXMLImportContext* SchemaRestrictionContext::HandleChild(
217 sal_uInt16 nToken,
218 sal_uInt16 nPrefix,
219 const OUString& rLocalName,
220 const Reference<XAttributeList>& xAttrList )
222 // find value
223 OUString sValue;
224 sal_Int16 nLength = xAttrList->getLength();
225 for( sal_Int16 n = 0; n < nLength; n++ )
227 if( IsXMLToken( xAttrList->getNameByIndex( n ), XML_VALUE ) )
228 sValue = xAttrList->getValueByIndex( n );
231 // determine property name + suitable converter
232 OUString sPropertyName;
233 convert_t pConvert = nullptr;
234 switch( nToken )
236 case XML_LENGTH:
237 sPropertyName = "Length";
238 pConvert = &xforms_int32;
239 break;
240 case XML_MINLENGTH:
241 sPropertyName = "MinLength";
242 pConvert = &xforms_int32;
243 break;
244 case XML_MAXLENGTH:
245 sPropertyName = "MaxLength";
246 pConvert = &xforms_int32;
247 break;
248 case XML_TOTALDIGITS:
249 sPropertyName = "TotalDigits";
250 pConvert = &xforms_int32;
251 break;
252 case XML_FRACTIONDIGITS:
253 sPropertyName = "FractionDigits";
254 pConvert = &xforms_int32;
255 break;
256 case XML_PATTERN:
257 sPropertyName = "Pattern";
258 pConvert = &xforms_string;
259 break;
260 case XML_WHITESPACE:
261 sPropertyName = "WhiteSpace";
262 pConvert = &xforms_whitespace;
263 break;
264 case XML_MININCLUSIVE:
265 case XML_MINEXCLUSIVE:
266 case XML_MAXINCLUSIVE:
267 case XML_MAXEXCLUSIVE:
269 // these attributes are mapped to different properties.
270 // To determine the property name, we use an attribute
271 // dependent prefix and a type dependent suffix. The
272 // converter is only type dependent.
274 // first, attribute-dependent prefix
275 switch( nToken )
277 case XML_MININCLUSIVE:
278 sPropertyName = "MinInclusive";
279 break;
280 case XML_MINEXCLUSIVE:
281 sPropertyName = "MinExclusive";
282 break;
283 case XML_MAXINCLUSIVE:
284 sPropertyName = "MaxInclusive";
285 break;
286 case XML_MAXEXCLUSIVE:
287 sPropertyName = "MaxExclusive";
288 break;
291 // second, type-dependent suffix + converter
292 switch( xforms_getTypeClass( mxRepository,
293 GetImport().GetNamespaceMap(),
294 msBaseName ) )
296 case css::xsd::DataTypeClass::DECIMAL:
297 case css::xsd::DataTypeClass::DOUBLE:
298 case css::xsd::DataTypeClass::FLOAT:
299 sPropertyName += "Double";
300 pConvert = &xforms_double;
301 break;
302 case css::xsd::DataTypeClass::DATETIME:
303 sPropertyName += "DateTime";
304 pConvert = &xforms_dateTime;
305 break;
306 case css::xsd::DataTypeClass::DATE:
307 sPropertyName += "Date";
308 pConvert = &xforms_date;
309 break;
310 case css::xsd::DataTypeClass::TIME:
311 sPropertyName += "Time";
312 pConvert = &xforms_time;
313 break;
314 case css::xsd::DataTypeClass::gYear:
315 case css::xsd::DataTypeClass::gDay:
316 case css::xsd::DataTypeClass::gMonth:
317 sPropertyName += "Int";
318 pConvert = &xforms_int16;
319 break;
321 case css::xsd::DataTypeClass::STRING:
322 case css::xsd::DataTypeClass::anyURI:
323 case css::xsd::DataTypeClass::BOOLEAN:
324 // invalid: These shouldn't have min/max-inclusive
325 break;
327 /* data types not yet supported:
328 case css::xsd::DataTypeClass::DURATION:
329 case css::xsd::DataTypeClass::gYearMonth:
330 case css::xsd::DataTypeClass::gMonthDay:
331 case css::xsd::DataTypeClass::hexBinary:
332 case css::xsd::DataTypeClass::base64Binary:
333 case css::xsd::DataTypeClass::QName:
334 case css::xsd::DataTypeClass::NOTATION:
338 break;
340 default:
341 OSL_FAIL( "unknown facet" );
344 // finally, set the property
345 CreateDataType();
346 if( mxDataType.is()
347 && !sPropertyName.isEmpty()
348 && pConvert != nullptr
349 && mxDataType->getPropertySetInfo()->hasPropertyByName(sPropertyName) )
353 mxDataType->setPropertyValue( sPropertyName, pConvert( sValue ) );
355 catch( const Exception& )
357 ; // can't set property? Then ignore.
361 return new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
364 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */