merged tag ooo/OOO330_m14
[LibreOffice.git] / extensions / source / propctrlr / xsdvalidationhelper.cxx
blobf203b36bcffa5b7cb272ada48f42b36f56256678
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 //........................................................................
46 namespace pcr
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 )
68 try
70 Reference< XPropertySetInfo > xPSI;
71 Reference< XServiceInfo > xSI( _rxIntrospectee, UNO_QUERY );
72 if ( m_xControlModel.is() )
73 xPSI = m_xControlModel->getPropertySetInfo();
74 if ( xPSI.is()
75 && xPSI->hasPropertyByName( PROPERTY_FORMATKEY )
76 && xPSI->hasPropertyByName( PROPERTY_FORMATSSUPPLIER )
77 && xSI.is()
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(())
91 _rNames.resize( 0 );
93 try
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( ) );
115 if ( xModel.is() )
116 xRepository = xModel->getDataTypeRepository();
118 return xRepository;
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 ) );
127 if ( xModel.is() )
128 xRepository = xModel->getDataTypeRepository();
130 return xRepository;
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 );
144 return xDataType;
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
155 if ( xBinding.is() )
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!" );
187 return pReturn;
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() )
201 return false;
205 Reference< XDataTypeRepository > xRepository( getDataTypeRepository() );
206 OSL_ENSURE( xRepository.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
207 if ( !xRepository.is() )
208 return false;
210 Reference< XDataType > xDataType( _pDataType->getUnoDataType() );
211 OSL_ENSURE( xDataType.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type (II)!" );
212 if ( !xDataType.is() )
213 return false;
215 xRepository->cloneDataType( xDataType->getName(), _rNewName );
217 catch( const Exception& )
219 OSL_ENSURE( sal_False, "XSDValidationHelper::cloneDataType: caught an exception!" );
221 return true;
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() )
232 return false;
234 if ( !xRepository->hasByName( _rName ) )
236 OSL_ENSURE( sal_False, "XSDValidationHelper::removeDataTypeFromRepository: invalid repository and/or data type!" );
237 return false;
240 xRepository->revokeDataType( _rName );
242 catch( const Exception& )
244 OSL_ENSURE( sal_False, "XSDValidationHelper::removeDataTypeFromRepository: caught an exception!" );
245 return false;
247 return true;
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?" );
258 if ( xBinding.is() )
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)
294 return;
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() )
305 return;
307 if ( !xFromRepository->hasByName( _rDataTypeName ) || xToRepository->hasByName( _rDataTypeName ) )
308 // not existent in the source, or already existent (by name) in the destination
309 return;
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 );
319 // copy the facets
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;
342 break;
343 case DataTypeClass::DATE:
344 nNumberFormatType = NumberFormat::DATE;
345 break;
346 case DataTypeClass::TIME:
347 nNumberFormatType = NumberFormat::TIME;
348 break;
349 case DataTypeClass::STRING:
350 case DataTypeClass::anyURI:
351 case DataTypeClass::QName:
352 case DataTypeClass::NOTATION:
353 nNumberFormatType = NumberFormat::TEXT;
354 break;
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() )
365 return;
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() )
392 return sReturn;
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!" );
406 return sReturn;
409 //........................................................................
410 } // namespace pcr
411 //........................................................................