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: xsdvalidationhelper.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_extensions.hxx"
33 #include "xsdvalidationhelper.hxx"
34 #include "xsddatatypes.hxx"
35 #include "formstrings.hxx"
37 /** === begin UNO includes === **/
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/xsd/DataTypeClass.hpp>
40 #include <com/sun/star/util/NumberFormat.hpp>
41 #include <com/sun/star/util/XNumberFormatTypes.hpp>
42 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
43 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
44 /** === end UNO includes === **/
45 #include <svtools/syslocale.hxx>
46 #include <tools/diagnose_ex.h>
48 //........................................................................
51 //........................................................................
53 using namespace ::com::sun::star
;
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::beans
;
56 using namespace ::com::sun::star::xsd
;
57 using namespace ::com::sun::star::util
;
58 using namespace ::com::sun::star::lang
;
59 using namespace ::com::sun::star::xforms
;
61 namespace NumberFormat
= ::com::sun::star::util::NumberFormat
;
63 //====================================================================
64 //= XSDValidationHelper
65 //====================================================================
66 //--------------------------------------------------------------------
67 XSDValidationHelper::XSDValidationHelper( ::osl::Mutex
& _rMutex
, const Reference
< XPropertySet
>& _rxIntrospectee
, const Reference
< frame::XModel
>& _rxContextDocument
)
68 :EFormsHelper( _rMutex
, _rxIntrospectee
, _rxContextDocument
)
69 ,m_bInspectingFormattedField( false )
73 Reference
< XPropertySetInfo
> xPSI
;
74 Reference
< XServiceInfo
> xSI( _rxIntrospectee
, UNO_QUERY
);
75 if ( m_xControlModel
.is() )
76 xPSI
= m_xControlModel
->getPropertySetInfo();
78 && xPSI
->hasPropertyByName( PROPERTY_FORMATKEY
)
79 && xPSI
->hasPropertyByName( PROPERTY_FORMATSSUPPLIER
)
81 && xSI
->supportsService( SERVICE_COMPONENT_FORMATTEDFIELD
)
83 m_bInspectingFormattedField
= true;
85 catch( const Exception
& )
87 OSL_ENSURE( sal_False
, "XSDValidationHelper::XSDValidationHelper: caught an exception while examining the introspectee!" );
91 //--------------------------------------------------------------------
92 void XSDValidationHelper::getAvailableDataTypeNames( ::std::vector
< ::rtl::OUString
>& /* [out] */ _rNames
) const SAL_THROW(())
98 Reference
< XDataTypeRepository
> xRepository
= getDataTypeRepository();
99 Sequence
< ::rtl::OUString
> aElements
;
100 if ( xRepository
.is() )
101 aElements
= xRepository
->getElementNames();
103 _rNames
.resize( aElements
.getLength() );
104 ::std::copy( aElements
.getConstArray(), aElements
.getConstArray() + aElements
.getLength(), _rNames
.begin() );
106 catch( const Exception
& )
108 OSL_ENSURE( sal_False
, "XSDValidationHelper::getAvailableDataTypeNames: caught an exception!" );
112 //--------------------------------------------------------------------
113 Reference
< XDataTypeRepository
> XSDValidationHelper::getDataTypeRepository() const SAL_THROW((Exception
))
115 Reference
< XDataTypeRepository
> xRepository
;
117 Reference
< xforms::XModel
> xModel( getCurrentFormModel( ) );
119 xRepository
= xModel
->getDataTypeRepository();
124 //--------------------------------------------------------------------
125 Reference
< XDataTypeRepository
> XSDValidationHelper::getDataTypeRepository( const ::rtl::OUString
& _rModelName
) const SAL_THROW((Exception
))
127 Reference
< XDataTypeRepository
> xRepository
;
129 Reference
< xforms::XModel
> xModel( getFormModelByName( _rModelName
) );
131 xRepository
= xModel
->getDataTypeRepository();
136 //--------------------------------------------------------------------
137 Reference
< XDataType
> XSDValidationHelper::getDataType( const ::rtl::OUString
& _rName
) const SAL_THROW((Exception
))
139 Reference
< XDataType
> xDataType
;
141 if ( _rName
.getLength() )
143 Reference
< XDataTypeRepository
> xRepository
= getDataTypeRepository();
144 if ( xRepository
.is() )
145 xDataType
= xRepository
->getDataType( _rName
);
150 //--------------------------------------------------------------------
151 ::rtl::OUString
XSDValidationHelper::getValidatingDataTypeName( ) const SAL_THROW(())
153 ::rtl::OUString sDataTypeName
;
156 Reference
< XPropertySet
> xBinding( getCurrentBinding() );
157 // it's allowed here to not (yet) have a binding
160 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sDataTypeName
);
163 catch( const Exception
& )
165 OSL_ENSURE( sal_False
, "XSDValidationHelper::getValidatingDataTypeName: caught an exception!" );
167 return sDataTypeName
;
170 //--------------------------------------------------------------------
171 ::rtl::Reference
< XSDDataType
> XSDValidationHelper::getDataTypeByName( const ::rtl::OUString
& _rName
) const SAL_THROW(())
173 ::rtl::Reference
< XSDDataType
> pReturn
;
177 Reference
< XDataType
> xValidatedAgainst
;
179 if ( _rName
.getLength() )
180 xValidatedAgainst
= getDataType( _rName
);
182 if ( xValidatedAgainst
.is() )
183 pReturn
= new XSDDataType( xValidatedAgainst
);
185 catch( const Exception
& )
187 OSL_ENSURE( sal_False
, "XSDValidationHelper::getDataTypeByName: caught an exception!" );
193 //--------------------------------------------------------------------
194 ::rtl::Reference
< XSDDataType
> XSDValidationHelper::getValidatingDataType( ) const SAL_THROW(())
196 return getDataTypeByName( getValidatingDataTypeName() );
199 //--------------------------------------------------------------------
200 bool XSDValidationHelper::cloneDataType( const ::rtl::Reference
< XSDDataType
>& _pDataType
, const ::rtl::OUString
& _rNewName
) const SAL_THROW(())
202 OSL_ENSURE( _pDataType
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type!" );
203 if ( !_pDataType
.is() )
208 Reference
< XDataTypeRepository
> xRepository( getDataTypeRepository() );
209 OSL_ENSURE( xRepository
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
210 if ( !xRepository
.is() )
213 Reference
< XDataType
> xDataType( _pDataType
->getUnoDataType() );
214 OSL_ENSURE( xDataType
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type (II)!" );
215 if ( !xDataType
.is() )
218 xRepository
->cloneDataType( xDataType
->getName(), _rNewName
);
220 catch( const Exception
& )
222 OSL_ENSURE( sal_False
, "XSDValidationHelper::cloneDataType: caught an exception!" );
227 //--------------------------------------------------------------------
228 bool XSDValidationHelper::removeDataTypeFromRepository( const ::rtl::OUString
& _rName
) const SAL_THROW(())
232 Reference
< XDataTypeRepository
> xRepository( getDataTypeRepository() );
233 OSL_ENSURE( xRepository
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
234 if ( !xRepository
.is() )
237 if ( !xRepository
->hasByName( _rName
) )
239 OSL_ENSURE( sal_False
, "XSDValidationHelper::removeDataTypeFromRepository: invalid repository and/or data type!" );
243 xRepository
->revokeDataType( _rName
);
245 catch( const Exception
& )
247 OSL_ENSURE( sal_False
, "XSDValidationHelper::removeDataTypeFromRepository: caught an exception!" );
253 //--------------------------------------------------------------------
254 void XSDValidationHelper::setValidatingDataTypeByName( const ::rtl::OUString
& _rName
) const SAL_THROW(())
258 Reference
< XPropertySet
> xBinding( getCurrentBinding() );
259 OSL_ENSURE( xBinding
.is(), "XSDValidationHelper::setValidatingDataTypeByName: no active binding - how this?" );
263 // get the old data type - this is necessary for notifying property changes
264 ::rtl::OUString sOldDataTypeName
;
265 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sOldDataTypeName
);
266 Reference
< XPropertySet
> xOldType
;
267 try { xOldType
= xOldType
.query( getDataType( sOldDataTypeName
) ); } catch( const Exception
& ) { }
269 // set the new data type name
270 xBinding
->setPropertyValue( PROPERTY_XSD_DATA_TYPE
, makeAny( _rName
) );
272 // retrieve the new data type object
273 Reference
< XPropertySet
> xNewType( getDataType( _rName
), UNO_QUERY
);
275 // fire any changes in the properties which result from this new type
276 std::set
< ::rtl::OUString
> aFilter
; aFilter
.insert( PROPERTY_NAME
);
277 firePropertyChanges( xOldType
, xNewType
, aFilter
);
279 // fire the change in the Data Type property
280 ::rtl::OUString sNewDataTypeName
;
281 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sNewDataTypeName
);
282 firePropertyChange( PROPERTY_XSD_DATA_TYPE
, makeAny( sOldDataTypeName
), makeAny( sNewDataTypeName
) );
285 catch( const Exception
& )
287 DBG_UNHANDLED_EXCEPTION();
291 //--------------------------------------------------------------------
292 void XSDValidationHelper::copyDataType( const ::rtl::OUString
& _rFromModel
, const ::rtl::OUString
& _rToModel
,
293 const ::rtl::OUString
& _rDataTypeName
) const SAL_THROW(())
295 if ( _rFromModel
== _rToModel
)
296 // nothing to do (me thinks)
301 Reference
< XDataTypeRepository
> xFromRepository
, xToRepository
;
302 if ( _rFromModel
.getLength() )
303 xFromRepository
= getDataTypeRepository( _rFromModel
);
304 if ( _rToModel
.getLength() )
305 xToRepository
= getDataTypeRepository( _rToModel
);
307 if ( !xFromRepository
.is() || !xToRepository
.is() )
310 if ( !xFromRepository
->hasByName( _rDataTypeName
) || xToRepository
->hasByName( _rDataTypeName
) )
311 // not existent in the source, or already existent (by name) in the destination
314 // determine the built-in type belonging to the source type
315 ::rtl::Reference
< XSDDataType
> pSourceType
= new XSDDataType( xFromRepository
->getDataType( _rDataTypeName
) );
316 ::rtl::OUString sTargetBaseType
= getBasicTypeNameForClass( pSourceType
->classify(), xToRepository
);
318 // create the target type
319 Reference
< XDataType
> xTargetType
= xToRepository
->cloneDataType( sTargetBaseType
, _rDataTypeName
);
320 ::rtl::Reference
< XSDDataType
> pTargetType
= new XSDDataType( xTargetType
);
323 pTargetType
->copyFacetsFrom( pSourceType
);
325 catch( const Exception
& )
327 OSL_ENSURE( sal_False
, "XSDValidationHelper::copyDataType: caught an exception!" );
331 //--------------------------------------------------------------------
332 void XSDValidationHelper::findDefaultFormatForIntrospectee() SAL_THROW(())
336 ::rtl::Reference
< XSDDataType
> xDataType
= getValidatingDataType();
337 if ( xDataType
.is() )
339 // find a NumberFormat type corresponding to the DataTypeClass
340 sal_Int16 nNumberFormatType
= NumberFormat::NUMBER
;
341 switch ( xDataType
->classify() )
343 case DataTypeClass::DATETIME
:
344 nNumberFormatType
= NumberFormat::DATETIME
;
346 case DataTypeClass::DATE
:
347 nNumberFormatType
= NumberFormat::DATE
;
349 case DataTypeClass::TIME
:
350 nNumberFormatType
= NumberFormat::TIME
;
352 case DataTypeClass::STRING
:
353 case DataTypeClass::anyURI
:
354 case DataTypeClass::QName
:
355 case DataTypeClass::NOTATION
:
356 nNumberFormatType
= NumberFormat::TEXT
;
360 // get the number formatter from the introspectee
361 Reference
< XNumberFormatsSupplier
> xSupplier
;
362 Reference
< XNumberFormatTypes
> xFormatTypes
;
363 OSL_VERIFY( m_xControlModel
->getPropertyValue( PROPERTY_FORMATSSUPPLIER
) >>= xSupplier
);
364 if ( xSupplier
.is() )
365 xFormatTypes
= xFormatTypes
.query( xSupplier
->getNumberFormats() );
366 OSL_ENSURE( xFormatTypes
.is(), "XSDValidationHelper::findDefaultFormatForIntrospectee: no number formats for the introspectee!" );
367 if ( !xFormatTypes
.is() )
370 // and the standard format for the given NumberFormat type
371 sal_Int32 nDesiredFormat
= xFormatTypes
->getStandardFormat( nNumberFormatType
, SvtSysLocale().GetLocaleData().getLocale() );
373 // set this at the introspectee
374 m_xControlModel
->setPropertyValue( PROPERTY_FORMATKEY
, makeAny( nDesiredFormat
) );
377 catch( const Exception
& )
379 OSL_ENSURE( sal_False
, "XSDValidationHelper::findDefaultFormatForIntrospectee: caught an exception!" );
383 //--------------------------------------------------------------------
384 ::rtl::OUString
XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass
) const SAL_THROW(())
386 return getBasicTypeNameForClass( _nClass
, getDataTypeRepository() );
389 //--------------------------------------------------------------------
390 ::rtl::OUString
XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass
, Reference
< XDataTypeRepository
> _rxRepository
) const SAL_THROW(())
392 ::rtl::OUString sReturn
;
393 OSL_ENSURE( _rxRepository
.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid repository!" );
394 if ( !_rxRepository
.is() )
399 Reference
< XDataType
> xDataType
= _rxRepository
->getBasicDataType( _nClass
);
400 OSL_ENSURE( xDataType
.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid data type returned!" );
401 if ( xDataType
.is() )
402 sReturn
= xDataType
->getName();
404 catch( const Exception
& )
406 OSL_ENSURE( sal_False
, "XSDValidationHelper::getBasicTypeNameForClass: caught an exception!" );
412 //........................................................................
414 //........................................................................