1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_extensions.hxx"
31 #include "xsdvalidationhelper.hxx"
32 #include "xsddatatypes.hxx"
33 #include "formstrings.hxx"
35 /** === begin UNO includes === **/
36 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <com/sun/star/xsd/DataTypeClass.hpp>
38 #include <com/sun/star/util/NumberFormat.hpp>
39 #include <com/sun/star/util/XNumberFormatTypes.hpp>
40 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
41 #include <com/sun/star/xforms/XDataTypeRepository.hpp>
42 /** === end UNO includes === **/
43 #include <unotools/syslocale.hxx>
44 #include <tools/diagnose_ex.h>
46 //........................................................................
49 //........................................................................
51 using namespace ::com::sun::star
;
52 using namespace ::com::sun::star::uno
;
53 using namespace ::com::sun::star::beans
;
54 using namespace ::com::sun::star::xsd
;
55 using namespace ::com::sun::star::util
;
56 using namespace ::com::sun::star::lang
;
57 using namespace ::com::sun::star::xforms
;
59 namespace NumberFormat
= ::com::sun::star::util::NumberFormat
;
61 //====================================================================
62 //= XSDValidationHelper
63 //====================================================================
64 //--------------------------------------------------------------------
65 XSDValidationHelper::XSDValidationHelper( ::osl::Mutex
& _rMutex
, const Reference
< XPropertySet
>& _rxIntrospectee
, const Reference
< frame::XModel
>& _rxContextDocument
)
66 :EFormsHelper( _rMutex
, _rxIntrospectee
, _rxContextDocument
)
67 ,m_bInspectingFormattedField( false )
71 Reference
< XPropertySetInfo
> xPSI
;
72 Reference
< XServiceInfo
> xSI( _rxIntrospectee
, UNO_QUERY
);
73 if ( m_xControlModel
.is() )
74 xPSI
= m_xControlModel
->getPropertySetInfo();
76 && xPSI
->hasPropertyByName( PROPERTY_FORMATKEY
)
77 && xPSI
->hasPropertyByName( PROPERTY_FORMATSSUPPLIER
)
79 && xSI
->supportsService( SERVICE_COMPONENT_FORMATTEDFIELD
)
81 m_bInspectingFormattedField
= true;
83 catch( const Exception
& )
85 OSL_ENSURE( sal_False
, "XSDValidationHelper::XSDValidationHelper: caught an exception while examining the introspectee!" );
89 //--------------------------------------------------------------------
90 void XSDValidationHelper::getAvailableDataTypeNames( ::std::vector
< ::rtl::OUString
>& /* [out] */ _rNames
) const SAL_THROW(())
96 Reference
< XDataTypeRepository
> xRepository
= getDataTypeRepository();
97 Sequence
< ::rtl::OUString
> aElements
;
98 if ( xRepository
.is() )
99 aElements
= xRepository
->getElementNames();
101 _rNames
.resize( aElements
.getLength() );
102 ::std::copy( aElements
.getConstArray(), aElements
.getConstArray() + aElements
.getLength(), _rNames
.begin() );
104 catch( const Exception
& )
106 OSL_ENSURE( sal_False
, "XSDValidationHelper::getAvailableDataTypeNames: caught an exception!" );
110 //--------------------------------------------------------------------
111 Reference
< XDataTypeRepository
> XSDValidationHelper::getDataTypeRepository() const SAL_THROW((Exception
))
113 Reference
< XDataTypeRepository
> xRepository
;
115 Reference
< xforms::XModel
> xModel( getCurrentFormModel( ) );
117 xRepository
= xModel
->getDataTypeRepository();
122 //--------------------------------------------------------------------
123 Reference
< XDataTypeRepository
> XSDValidationHelper::getDataTypeRepository( const ::rtl::OUString
& _rModelName
) const SAL_THROW((Exception
))
125 Reference
< XDataTypeRepository
> xRepository
;
127 Reference
< xforms::XModel
> xModel( getFormModelByName( _rModelName
) );
129 xRepository
= xModel
->getDataTypeRepository();
134 //--------------------------------------------------------------------
135 Reference
< XDataType
> XSDValidationHelper::getDataType( const ::rtl::OUString
& _rName
) const SAL_THROW((Exception
))
137 Reference
< XDataType
> xDataType
;
139 if ( _rName
.getLength() )
141 Reference
< XDataTypeRepository
> xRepository
= getDataTypeRepository();
142 if ( xRepository
.is() )
143 xDataType
= xRepository
->getDataType( _rName
);
148 //--------------------------------------------------------------------
149 ::rtl::OUString
XSDValidationHelper::getValidatingDataTypeName( ) const SAL_THROW(())
151 ::rtl::OUString sDataTypeName
;
154 Reference
< XPropertySet
> xBinding( getCurrentBinding() );
155 // it's allowed here to not (yet) have a binding
158 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sDataTypeName
);
161 catch( const Exception
& )
163 OSL_ENSURE( sal_False
, "XSDValidationHelper::getValidatingDataTypeName: caught an exception!" );
165 return sDataTypeName
;
168 //--------------------------------------------------------------------
169 ::rtl::Reference
< XSDDataType
> XSDValidationHelper::getDataTypeByName( const ::rtl::OUString
& _rName
) const SAL_THROW(())
171 ::rtl::Reference
< XSDDataType
> pReturn
;
175 Reference
< XDataType
> xValidatedAgainst
;
177 if ( _rName
.getLength() )
178 xValidatedAgainst
= getDataType( _rName
);
180 if ( xValidatedAgainst
.is() )
181 pReturn
= new XSDDataType( xValidatedAgainst
);
183 catch( const Exception
& )
185 OSL_ENSURE( sal_False
, "XSDValidationHelper::getDataTypeByName: caught an exception!" );
191 //--------------------------------------------------------------------
192 ::rtl::Reference
< XSDDataType
> XSDValidationHelper::getValidatingDataType( ) const SAL_THROW(())
194 return getDataTypeByName( getValidatingDataTypeName() );
197 //--------------------------------------------------------------------
198 bool XSDValidationHelper::cloneDataType( const ::rtl::Reference
< XSDDataType
>& _pDataType
, const ::rtl::OUString
& _rNewName
) const SAL_THROW(())
200 OSL_ENSURE( _pDataType
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type!" );
201 if ( !_pDataType
.is() )
206 Reference
< XDataTypeRepository
> xRepository( getDataTypeRepository() );
207 OSL_ENSURE( xRepository
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
208 if ( !xRepository
.is() )
211 Reference
< XDataType
> xDataType( _pDataType
->getUnoDataType() );
212 OSL_ENSURE( xDataType
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type (II)!" );
213 if ( !xDataType
.is() )
216 xRepository
->cloneDataType( xDataType
->getName(), _rNewName
);
218 catch( const Exception
& )
220 OSL_ENSURE( sal_False
, "XSDValidationHelper::cloneDataType: caught an exception!" );
225 //--------------------------------------------------------------------
226 bool XSDValidationHelper::removeDataTypeFromRepository( const ::rtl::OUString
& _rName
) const SAL_THROW(())
230 Reference
< XDataTypeRepository
> xRepository( getDataTypeRepository() );
231 OSL_ENSURE( xRepository
.is(), "XSDValidationHelper::removeDataTypeFromRepository: invalid data type repository!" );
232 if ( !xRepository
.is() )
235 if ( !xRepository
->hasByName( _rName
) )
237 OSL_ENSURE( sal_False
, "XSDValidationHelper::removeDataTypeFromRepository: invalid repository and/or data type!" );
241 xRepository
->revokeDataType( _rName
);
243 catch( const Exception
& )
245 OSL_ENSURE( sal_False
, "XSDValidationHelper::removeDataTypeFromRepository: caught an exception!" );
251 //--------------------------------------------------------------------
252 void XSDValidationHelper::setValidatingDataTypeByName( const ::rtl::OUString
& _rName
) const SAL_THROW(())
256 Reference
< XPropertySet
> xBinding( getCurrentBinding() );
257 OSL_ENSURE( xBinding
.is(), "XSDValidationHelper::setValidatingDataTypeByName: no active binding - how this?" );
261 // get the old data type - this is necessary for notifying property changes
262 ::rtl::OUString sOldDataTypeName
;
263 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sOldDataTypeName
);
264 Reference
< XPropertySet
> xOldType
;
265 try { xOldType
= xOldType
.query( getDataType( sOldDataTypeName
) ); } catch( const Exception
& ) { }
267 // set the new data type name
268 xBinding
->setPropertyValue( PROPERTY_XSD_DATA_TYPE
, makeAny( _rName
) );
270 // retrieve the new data type object
271 Reference
< XPropertySet
> xNewType( getDataType( _rName
), UNO_QUERY
);
273 // fire any changes in the properties which result from this new type
274 std::set
< ::rtl::OUString
> aFilter
; aFilter
.insert( PROPERTY_NAME
);
275 firePropertyChanges( xOldType
, xNewType
, aFilter
);
277 // fire the change in the Data Type property
278 ::rtl::OUString sNewDataTypeName
;
279 OSL_VERIFY( xBinding
->getPropertyValue( PROPERTY_XSD_DATA_TYPE
) >>= sNewDataTypeName
);
280 firePropertyChange( PROPERTY_XSD_DATA_TYPE
, makeAny( sOldDataTypeName
), makeAny( sNewDataTypeName
) );
283 catch( const Exception
& )
285 DBG_UNHANDLED_EXCEPTION();
289 //--------------------------------------------------------------------
290 void XSDValidationHelper::copyDataType( const ::rtl::OUString
& _rFromModel
, const ::rtl::OUString
& _rToModel
,
291 const ::rtl::OUString
& _rDataTypeName
) const SAL_THROW(())
293 if ( _rFromModel
== _rToModel
)
294 // nothing to do (me thinks)
299 Reference
< XDataTypeRepository
> xFromRepository
, xToRepository
;
300 if ( _rFromModel
.getLength() )
301 xFromRepository
= getDataTypeRepository( _rFromModel
);
302 if ( _rToModel
.getLength() )
303 xToRepository
= getDataTypeRepository( _rToModel
);
305 if ( !xFromRepository
.is() || !xToRepository
.is() )
308 if ( !xFromRepository
->hasByName( _rDataTypeName
) || xToRepository
->hasByName( _rDataTypeName
) )
309 // not existent in the source, or already existent (by name) in the destination
312 // determine the built-in type belonging to the source type
313 ::rtl::Reference
< XSDDataType
> pSourceType
= new XSDDataType( xFromRepository
->getDataType( _rDataTypeName
) );
314 ::rtl::OUString sTargetBaseType
= getBasicTypeNameForClass( pSourceType
->classify(), xToRepository
);
316 // create the target type
317 Reference
< XDataType
> xTargetType
= xToRepository
->cloneDataType( sTargetBaseType
, _rDataTypeName
);
318 ::rtl::Reference
< XSDDataType
> pTargetType
= new XSDDataType( xTargetType
);
321 pTargetType
->copyFacetsFrom( pSourceType
);
323 catch( const Exception
& )
325 OSL_ENSURE( sal_False
, "XSDValidationHelper::copyDataType: caught an exception!" );
329 //--------------------------------------------------------------------
330 void XSDValidationHelper::findDefaultFormatForIntrospectee() SAL_THROW(())
334 ::rtl::Reference
< XSDDataType
> xDataType
= getValidatingDataType();
335 if ( xDataType
.is() )
337 // find a NumberFormat type corresponding to the DataTypeClass
338 sal_Int16 nNumberFormatType
= NumberFormat::NUMBER
;
339 switch ( xDataType
->classify() )
341 case DataTypeClass::DATETIME
:
342 nNumberFormatType
= NumberFormat::DATETIME
;
344 case DataTypeClass::DATE
:
345 nNumberFormatType
= NumberFormat::DATE
;
347 case DataTypeClass::TIME
:
348 nNumberFormatType
= NumberFormat::TIME
;
350 case DataTypeClass::STRING
:
351 case DataTypeClass::anyURI
:
352 case DataTypeClass::QName
:
353 case DataTypeClass::NOTATION
:
354 nNumberFormatType
= NumberFormat::TEXT
;
358 // get the number formatter from the introspectee
359 Reference
< XNumberFormatsSupplier
> xSupplier
;
360 Reference
< XNumberFormatTypes
> xFormatTypes
;
361 OSL_VERIFY( m_xControlModel
->getPropertyValue( PROPERTY_FORMATSSUPPLIER
) >>= xSupplier
);
362 if ( xSupplier
.is() )
363 xFormatTypes
= xFormatTypes
.query( xSupplier
->getNumberFormats() );
364 OSL_ENSURE( xFormatTypes
.is(), "XSDValidationHelper::findDefaultFormatForIntrospectee: no number formats for the introspectee!" );
365 if ( !xFormatTypes
.is() )
368 // and the standard format for the given NumberFormat type
369 sal_Int32 nDesiredFormat
= xFormatTypes
->getStandardFormat( nNumberFormatType
, SvtSysLocale().GetLocaleData().getLocale() );
371 // set this at the introspectee
372 m_xControlModel
->setPropertyValue( PROPERTY_FORMATKEY
, makeAny( nDesiredFormat
) );
375 catch( const Exception
& )
377 OSL_ENSURE( sal_False
, "XSDValidationHelper::findDefaultFormatForIntrospectee: caught an exception!" );
381 //--------------------------------------------------------------------
382 ::rtl::OUString
XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass
) const SAL_THROW(())
384 return getBasicTypeNameForClass( _nClass
, getDataTypeRepository() );
387 //--------------------------------------------------------------------
388 ::rtl::OUString
XSDValidationHelper::getBasicTypeNameForClass( sal_Int16 _nClass
, Reference
< XDataTypeRepository
> _rxRepository
) const SAL_THROW(())
390 ::rtl::OUString sReturn
;
391 OSL_ENSURE( _rxRepository
.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid repository!" );
392 if ( !_rxRepository
.is() )
397 Reference
< XDataType
> xDataType
= _rxRepository
->getBasicDataType( _nClass
);
398 OSL_ENSURE( xDataType
.is(), "XSDValidationHelper::getBasicTypeNameForClass: invalid data type returned!" );
399 if ( xDataType
.is() )
400 sReturn
= xDataType
->getName();
402 catch( const Exception
& )
404 OSL_ENSURE( sal_False
, "XSDValidationHelper::getBasicTypeNameForClass: caught an exception!" );
410 //........................................................................
412 //........................................................................
414 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */