1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 #include "xsdvalidationhelper.hxx"
31 #include "xsddatatypes.hxx"
32 #include "formstrings.hxx"
34 /** === begin UNO includes === **/
35 #include <com/sun/star/lang/XServiceInfo.hpp>
36 #include <com/sun/star/xsd/DataTypeClass.hpp>
37 #include <com/sun/star/util/NumberFormat.hpp>
38 #include <com/sun/star/util/XNumberFormatTypes.hpp>
39 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
40 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
41 /** === end UNO includes === **/
42 #include <unotools/syslocale.hxx>
43 #include <tools/diagnose_ex.h>
45 //........................................................................
48 //........................................................................
50 using namespace ::com::sun::star
;
51 using namespace ::com::sun::star::uno
;
52 using namespace ::com::sun::star::beans
;
53 using namespace ::com::sun::star::xsd
;
54 using namespace ::com::sun::star::util
;
55 using namespace ::com::sun::star::lang
;
56 using namespace ::com::sun::star::xforms
;
58 namespace NumberFormat
= ::com::sun::star::util::NumberFormat
;
60 //====================================================================
61 //= XSDValidationHelper
62 //====================================================================
63 //--------------------------------------------------------------------
64 XSDValidationHelper::XSDValidationHelper( ::osl::Mutex
& _rMutex
, const Reference
< XPropertySet
>& _rxIntrospectee
, const Reference
< frame::XModel
>& _rxContextDocument
)
65 :EFormsHelper( _rMutex
, _rxIntrospectee
, _rxContextDocument
)
66 ,m_bInspectingFormattedField( false )
70 Reference
< XPropertySetInfo
> xPSI
;
71 Reference
< XServiceInfo
> xSI( _rxIntrospectee
, UNO_QUERY
);
72 if ( m_xControlModel
.is() )
73 xPSI
= m_xControlModel
->getPropertySetInfo();
75 && xPSI
->hasPropertyByName( PROPERTY_FORMATKEY
)
76 && xPSI
->hasPropertyByName( PROPERTY_FORMATSSUPPLIER
)
78 && xSI
->supportsService( SERVICE_COMPONENT_FORMATTEDFIELD
)
80 m_bInspectingFormattedField
= true;
82 catch( const Exception
& )
84 OSL_ENSURE( sal_False
, "XSDValidationHelper::XSDValidationHelper: caught an exception while examining the introspectee!" );
88 //--------------------------------------------------------------------
89 void XSDValidationHelper::getAvailableDataTypeNames( ::std::vector
< ::rtl::OUString
>& /* [out] */ _rNames
) const SAL_THROW(())
95 Reference
< XDataTypeRepository
> xRepository
= getDataTypeRepository();
96 Sequence
< ::rtl::OUString
> aElements
;
97 if ( xRepository
.is() )
98 aElements
= xRepository
->getElementNames();
100 _rNames
.resize( aElements
.getLength() );
101 ::std::copy( aElements
.getConstArray(), aElements
.getConstArray() + aElements
.getLength(), _rNames
.begin() );
103 catch( const Exception
& )
105 OSL_ENSURE( sal_False
, "XSDValidationHelper::getAvailableDataTypeNames: caught an exception!" );
109 //--------------------------------------------------------------------
110 Reference
< XDataTypeRepository
> XSDValidationHelper::getDataTypeRepository() const SAL_THROW((Exception
))
112 Reference
< XDataTypeRepository
> xRepository
;
114 Reference
< xforms::XModel
> xModel( getCurrentFormModel( ) );
116 xRepository
= xModel
->getDataTypeRepository();
121 //--------------------------------------------------------------------
122 Reference
< XDataTypeRepository
> XSDValidationHelper::getDataTypeRepository( const ::rtl::OUString
& _rModelName
) const SAL_THROW((Exception
))
124 Reference
< XDataTypeRepository
> xRepository
;
126 Reference
< xforms::XModel
> xModel( getFormModelByName( _rModelName
) );
128 xRepository
= xModel
->getDataTypeRepository();
133 //--------------------------------------------------------------------
134 Reference
< XDataType
> XSDValidationHelper::getDataType( const ::rtl::OUString
& _rName
) const SAL_THROW((Exception
))
136 Reference
< XDataType
> xDataType
;
138 if ( _rName
.getLength() )
140 Reference
< XDataTypeRepository
> xRepository
= getDataTypeRepository();
141 if ( xRepository
.is() )
142 xDataType
= xRepository
->getDataType( _rName
);
147 //--------------------------------------------------------------------
148 ::rtl::OUString
XSDValidationHelper::getValidatingDataTypeName( ) const SAL_THROW(())
150 ::rtl::OUString sDataTypeName
;
153 Reference
< XPropertySet
> xBinding( getCurrentBinding() );
154 // it's allowed here to not (yet) have a binding
157 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sDataTypeName
);
160 catch( const Exception
& )
162 OSL_ENSURE( sal_False
, "XSDValidationHelper::getValidatingDataTypeName: caught an exception!" );
164 return sDataTypeName
;
167 //--------------------------------------------------------------------
168 ::rtl::Reference
< XSDDataType
> XSDValidationHelper::getDataTypeByName( const ::rtl::OUString
& _rName
) const SAL_THROW(())
170 ::rtl::Reference
< XSDDataType
> pReturn
;
174 Reference
< XDataType
> xValidatedAgainst
;
176 if ( _rName
.getLength() )
177 xValidatedAgainst
= getDataType( _rName
);
179 if ( xValidatedAgainst
.is() )
180 pReturn
= new XSDDataType( xValidatedAgainst
);
182 catch( const Exception
& )
184 OSL_ENSURE( sal_False
, "XSDValidationHelper::getDataTypeByName: caught an exception!" );
190 //--------------------------------------------------------------------
191 ::rtl::Reference
< XSDDataType
> XSDValidationHelper::getValidatingDataType( ) const SAL_THROW(())
193 return getDataTypeByName( getValidatingDataTypeName() );
196 //--------------------------------------------------------------------
197 bool XSDValidationHelper::cloneDataType( const ::rtl::Reference
< XSDDataType
>& _pDataType
, const ::rtl::OUString
& _rNewName
) const SAL_THROW(())
199 OSL_ENSURE( _pDataType
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type!" );
200 if ( !_pDataType
.is() )
205 Reference
< XDataTypeRepository
> xRepository( getDataTypeRepository() );
206 OSL_ENSURE( xRepository
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
207 if ( !xRepository
.is() )
210 Reference
< XDataType
> xDataType( _pDataType
->getUnoDataType() );
211 OSL_ENSURE( xDataType
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type (II)!" );
212 if ( !xDataType
.is() )
215 xRepository
->cloneDataType( xDataType
->getName(), _rNewName
);
217 catch( const Exception
& )
219 OSL_ENSURE( sal_False
, "XSDValidationHelper::cloneDataType: caught an exception!" );
224 //--------------------------------------------------------------------
225 bool XSDValidationHelper::removeDataTypeFromRepository( const ::rtl::OUString
& _rName
) const SAL_THROW(())
229 Reference
< XDataTypeRepository
> xRepository( getDataTypeRepository() );
230 OSL_ENSURE( xRepository
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
231 if ( !xRepository
.is() )
234 if ( !xRepository
->hasByName( _rName
) )
236 OSL_ENSURE( sal_False
, "XSDValidationHelper::removeDataTypeFromRepository: invalid repository and/or data type!" );
240 xRepository
->revokeDataType( _rName
);
242 catch( const Exception
& )
244 OSL_ENSURE( sal_False
, "XSDValidationHelper::removeDataTypeFromRepository: caught an exception!" );
250 //--------------------------------------------------------------------
251 void XSDValidationHelper::setValidatingDataTypeByName( const ::rtl::OUString
& _rName
) const SAL_THROW(())
255 Reference
< XPropertySet
> xBinding( getCurrentBinding() );
256 OSL_ENSURE( xBinding
.is(), "XSDValidationHelper::setValidatingDataTypeByName: no active binding - how this?" );
260 // get the old data type - this is necessary for notifying property changes
261 ::rtl::OUString sOldDataTypeName
;
262 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sOldDataTypeName
);
263 Reference
< XPropertySet
> xOldType
;
264 try { xOldType
= xOldType
.query( getDataType( sOldDataTypeName
) ); } catch( const Exception
& ) { }
266 // set the new data type name
267 xBinding
->setPropertyValue( PROPERTY_XSD_DATA_TYPE
, makeAny( _rName
) );
269 // retrieve the new data type object
270 Reference
< XPropertySet
> xNewType( getDataType( _rName
), UNO_QUERY
);
272 // fire any changes in the properties which result from this new type
273 std::set
< ::rtl::OUString
> aFilter
; aFilter
.insert( PROPERTY_NAME
);
274 firePropertyChanges( xOldType
, xNewType
, aFilter
);
276 // fire the change in the Data Type property
277 ::rtl::OUString sNewDataTypeName
;
278 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sNewDataTypeName
);
279 firePropertyChange( PROPERTY_XSD_DATA_TYPE
, makeAny( sOldDataTypeName
), makeAny( sNewDataTypeName
) );
282 catch( const Exception
& )
284 DBG_UNHANDLED_EXCEPTION();
288 //--------------------------------------------------------------------
289 void XSDValidationHelper::copyDataType( const ::rtl::OUString
& _rFromModel
, const ::rtl::OUString
& _rToModel
,
290 const ::rtl::OUString
& _rDataTypeName
) const SAL_THROW(())
292 if ( _rFromModel
== _rToModel
)
293 // nothing to do (me thinks)
298 Reference
< XDataTypeRepository
> xFromRepository
, xToRepository
;
299 if ( _rFromModel
.getLength() )
300 xFromRepository
= getDataTypeRepository( _rFromModel
);
301 if ( _rToModel
.getLength() )
302 xToRepository
= getDataTypeRepository( _rToModel
);
304 if ( !xFromRepository
.is() || !xToRepository
.is() )
307 if ( !xFromRepository
->hasByName( _rDataTypeName
) || xToRepository
->hasByName( _rDataTypeName
) )
308 // not existent in the source, or already existent (by name) in the destination
311 // determine the built-in type belonging to the source type
312 ::rtl::Reference
< XSDDataType
> pSourceType
= new XSDDataType( xFromRepository
->getDataType( _rDataTypeName
) );
313 ::rtl::OUString sTargetBaseType
= getBasicTypeNameForClass( pSourceType
->classify(), xToRepository
);
315 // create the target type
316 Reference
< XDataType
> xTargetType
= xToRepository
->cloneDataType( sTargetBaseType
, _rDataTypeName
);
317 ::rtl::Reference
< XSDDataType
> pTargetType
= new XSDDataType( xTargetType
);
320 pTargetType
->copyFacetsFrom( pSourceType
);
322 catch( const Exception
& )
324 OSL_ENSURE( sal_False
, "XSDValidationHelper::copyDataType: caught an exception!" );
328 //--------------------------------------------------------------------
329 void XSDValidationHelper::findDefaultFormatForIntrospectee() SAL_THROW(())
333 ::rtl::Reference
< XSDDataType
> xDataType
= getValidatingDataType();
334 if ( xDataType
.is() )
336 // find a NumberFormat type corresponding to the DataTypeClass
337 sal_Int16 nNumberFormatType
= NumberFormat::NUMBER
;
338 switch ( xDataType
->classify() )
340 case DataTypeClass::DATETIME
:
341 nNumberFormatType
= NumberFormat::DATETIME
;
343 case DataTypeClass::DATE
:
344 nNumberFormatType
= NumberFormat::DATE
;
346 case DataTypeClass::TIME
:
347 nNumberFormatType
= NumberFormat::TIME
;
349 case DataTypeClass::STRING
:
350 case DataTypeClass::anyURI
:
351 case DataTypeClass::QName
:
352 case DataTypeClass::NOTATION
:
353 nNumberFormatType
= NumberFormat::TEXT
;
357 // get the number formatter from the introspectee
358 Reference
< XNumberFormatsSupplier
> xSupplier
;
359 Reference
< XNumberFormatTypes
> xFormatTypes
;
360 OSL_VERIFY( m_xControlModel
->getPropertyValue( PROPERTY_FORMATSSUPPLIER
) >>= xSupplier
);
361 if ( xSupplier
.is() )
362 xFormatTypes
= xFormatTypes
.query( xSupplier
->getNumberFormats() );
363 OSL_ENSURE( xFormatTypes
.is(), "XSDValidationHelper::findDefaultFormatForIntrospectee: no number formats for the introspectee!" );
364 if ( !xFormatTypes
.is() )
367 // and the standard format for the given NumberFormat type
368 sal_Int32 nDesiredFormat
= xFormatTypes
->getStandardFormat( nNumberFormatType
, SvtSysLocale().GetLocaleData().getLocale() );
370 // set this at the introspectee
371 m_xControlModel
->setPropertyValue( PROPERTY_FORMATKEY
, makeAny( nDesiredFormat
) );
374 catch( const Exception
& )
376 OSL_ENSURE( sal_False
, "XSDValidationHelper::findDefaultFormatForIntrospectee: caught an exception!" );
380 //--------------------------------------------------------------------
381 ::rtl::OUString
XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass
) const SAL_THROW(())
383 return getBasicTypeNameForClass( _nClass
, getDataTypeRepository() );
386 //--------------------------------------------------------------------
387 ::rtl::OUString
XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass
, Reference
< XDataTypeRepository
> _rxRepository
) const SAL_THROW(())
389 ::rtl::OUString sReturn
;
390 OSL_ENSURE( _rxRepository
.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid repository!" );
391 if ( !_rxRepository
.is() )
396 Reference
< XDataType
> xDataType
= _rxRepository
->getBasicDataType( _nClass
);
397 OSL_ENSURE( xDataType
.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid data type returned!" );
398 if ( xDataType
.is() )
399 sReturn
= xDataType
->getName();
401 catch( const Exception
& )
403 OSL_ENSURE( sal_False
, "XSDValidationHelper::getBasicTypeNameForClass: caught an exception!" );
409 //........................................................................
411 //........................................................................