1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
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.
14  *
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).
20  *
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.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_forms.hxx"
30 
31 #ifndef FORMS_SOURCE_XFORMS_DATATYPEREPOSITORY_HXX
32 #include "datatyperepository.hxx"
33 #endif
34 #include "datatypes.hxx"
35 #ifndef _FRM_RESOURCE_HRC_
36 #include "frm_resource.hrc"
37 #endif
38 #include "frm_resource.hxx"
39 #include "frm_strings.hxx"
40 #ifndef _FRM_PROPERTY_HRC_
41 #include "property.hrc"
42 #endif
43 
44 /** === begin UNO includes === **/
45 /** === end UNO includes === **/
46 #include <tools/debug.hxx>
47 #include <comphelper/enumhelper.hxx>
48 
49 #include <functional>
50 #include <algorithm>
51 
52 //........................................................................
53 namespace xforms
54 {
55 //........................................................................
56 
57     using ::com::sun::star::uno::Reference;
58     using ::com::sun::star::uno::RuntimeException;
59     using ::com::sun::star::uno::Any;
60     using ::com::sun::star::uno::Type;
61     using ::com::sun::star::uno::makeAny;
62     using ::com::sun::star::uno::Sequence;
63     using ::com::sun::star::util::VetoException;
64     using ::com::sun::star::container::NoSuchElementException;
65     using ::com::sun::star::container::ElementExistException;
66     using ::com::sun::star::container::XEnumeration;
67     using ::com::sun::star::lang::WrappedTargetException;
68     using ::com::sun::star::xsd::XDataType;
69     using namespace frm;
70 
71     //====================================================================
72 	//= ODataTypeRepository
73 	//====================================================================
74     DBG_NAME( ODataTypeRepository )
75 	//--------------------------------------------------------------------
76     ODataTypeRepository::ODataTypeRepository( )
77     {
78         DBG_CTOR( ODataTypeRepository, NULL );
79 
80         // insert some basic types
81         ::rtl::OUString sName( FRM_RES_STRING( RID_STR_DATATYPE_STRING ) );
82         m_aRepository[ sName ] = new OStringType( sName, ::com::sun::star::xsd::DataTypeClass::STRING );
83 
84         sName = FRM_RES_STRING( RID_STR_DATATYPE_URL );
85         m_aRepository[ sName ] = new OStringType( sName, ::com::sun::star::xsd::DataTypeClass::anyURI );
86 
87         sName = FRM_RES_STRING( RID_STR_DATATYPE_BOOLEAN );
88         m_aRepository[ sName ] = new OBooleanType( sName );
89 
90         sName = FRM_RES_STRING( RID_STR_DATATYPE_DECIMAL );
91         m_aRepository[ sName ] = new ODecimalType( sName, ::com::sun::star::xsd::DataTypeClass::DECIMAL );
92 
93         sName = FRM_RES_STRING( RID_STR_DATATYPE_FLOAT );
94         m_aRepository[ sName ] = new ODecimalType( sName, ::com::sun::star::xsd::DataTypeClass::FLOAT );
95 
96         sName = FRM_RES_STRING( RID_STR_DATATYPE_DOUBLE );
97         m_aRepository[ sName ] = new ODecimalType( sName, ::com::sun::star::xsd::DataTypeClass::DOUBLE );
98 
99         sName = FRM_RES_STRING( RID_STR_DATATYPE_DATE );
100         m_aRepository[ sName ] = new ODateType( sName );
101 
102         sName = FRM_RES_STRING( RID_STR_DATATYPE_TIME );
103         m_aRepository[ sName ] = new OTimeType( sName );
104 
105         sName = FRM_RES_STRING( RID_STR_DATATYPE_DATETIME );
106         m_aRepository[ sName ] = new ODateTimeType( sName );
107 
108         sName = FRM_RES_STRING( RID_STR_DATATYPE_YEAR );
109         m_aRepository[ sName ] = new OShortIntegerType( sName, ::com::sun::star::xsd::DataTypeClass::gYear );
110 
111         sName = FRM_RES_STRING( RID_STR_DATATYPE_MONTH );
112         m_aRepository[ sName ] = new OShortIntegerType( sName, ::com::sun::star::xsd::DataTypeClass::gMonth );
113 
114         sName = FRM_RES_STRING( RID_STR_DATATYPE_DAY );
115         m_aRepository[ sName ] = new OShortIntegerType( sName, ::com::sun::star::xsd::DataTypeClass::gDay );
116     }
117 
118 	//--------------------------------------------------------------------
119     ODataTypeRepository::~ODataTypeRepository( )
120     {
121         DBG_DTOR( ODataTypeRepository, NULL );
122     }
123 
124     //--------------------------------------------------------------------
125     ODataTypeRepository::Repository::iterator ODataTypeRepository::implLocate( const ::rtl::OUString& _rName, bool _bAllowMiss ) SAL_THROW( ( NoSuchElementException ) )
126     {
127         Repository::iterator aTypePos = m_aRepository.find( _rName );
128         if ( aTypePos == m_aRepository.end() && !_bAllowMiss )
129             throw NoSuchElementException( ::rtl::OUString(), *this );
130 
131         return aTypePos;
132     }
133 
134     //--------------------------------------------------------------------
135     Reference< XDataType > SAL_CALL ODataTypeRepository::getBasicDataType( sal_Int16 dataTypeClass ) throw (NoSuchElementException, RuntimeException)
136     {
137         Reference< XDataType > xReturn;
138 
139         for ( Repository::const_iterator lookup = m_aRepository.begin();
140               ( lookup != m_aRepository.end() ) && ! xReturn.is();
141               ++lookup
142             )
143         {
144             if ( lookup->second->getIsBasic() && ( lookup->second->getTypeClass() == dataTypeClass ) )
145                 xReturn = lookup->second.get();
146         }
147 
148         if ( !xReturn.is() )
149             throw NoSuchElementException( ::rtl::OUString(), *this );
150 
151         return xReturn;
152     }
153 
154     //--------------------------------------------------------------------
155     Reference< XDataType > SAL_CALL ODataTypeRepository::cloneDataType( const ::rtl::OUString& sourceName, const ::rtl::OUString& newName ) throw (NoSuchElementException, ElementExistException, RuntimeException)
156     {
157         ::osl::MutexGuard aGuard( m_aMutex );
158 
159         Repository::iterator aTypePos = implLocate( newName, true );
160         if ( aTypePos != m_aRepository.end() )
161             throw ElementExistException( ::rtl::OUString(), *this );
162 
163         aTypePos = implLocate( sourceName );
164         OXSDDataType* pClone = aTypePos->second->clone( newName );
165         m_aRepository[ newName ] = pClone;
166 
167         return pClone;
168     }
169 
170     //--------------------------------------------------------------------
171     void SAL_CALL ODataTypeRepository::revokeDataType( const ::rtl::OUString& typeName ) throw (NoSuchElementException, VetoException, RuntimeException)
172     {
173         ::osl::MutexGuard aGuard( m_aMutex );
174 
175         Repository::iterator aTypePos = implLocate( typeName );
176         if ( aTypePos->second->getIsBasic() )
177             throw VetoException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "This is a built-in type and cannot be removed." ) ), *this );
178             // TODO: localize this error message
179 
180         m_aRepository.erase( aTypePos );
181     }
182 
183     //--------------------------------------------------------------------
184     Reference< XDataType > SAL_CALL ODataTypeRepository::getDataType( const ::rtl::OUString& typeName ) throw (NoSuchElementException, RuntimeException)
185     {
186         ::osl::MutexGuard aGuard( m_aMutex );
187         return implLocate( typeName, false )->second.get();
188     }
189 
190 
191     //--------------------------------------------------------------------
192     Reference< XEnumeration > SAL_CALL ODataTypeRepository::createEnumeration(  ) throw (RuntimeException)
193     {
194         return new ::comphelper::OEnumerationByName( this );
195     }
196 
197     //--------------------------------------------------------------------
198     Any SAL_CALL ODataTypeRepository::getByName( const ::rtl::OUString& aName ) throw (NoSuchElementException, WrappedTargetException, RuntimeException)
199     {
200         return makeAny( getDataType( aName ) );
201     }
202 
203     //--------------------------------------------------------------------
204     Sequence< ::rtl::OUString > SAL_CALL ODataTypeRepository::getElementNames(  ) throw (RuntimeException)
205     {
206         ::osl::MutexGuard aGuard( m_aMutex );
207 
208         Sequence< ::rtl::OUString > aNames( m_aRepository.size() );
209         ::std::transform(
210             m_aRepository.begin(),
211             m_aRepository.end(),
212             aNames.getArray(),
213             ::std::select1st< Repository::value_type >()
214         );
215         return aNames;
216     }
217 
218     //--------------------------------------------------------------------
219     sal_Bool SAL_CALL ODataTypeRepository::hasByName( const ::rtl::OUString& aName ) throw (RuntimeException)
220     {
221         ::osl::MutexGuard aGuard( m_aMutex );
222         return m_aRepository.find( aName ) != m_aRepository.end();
223     }
224 
225     //--------------------------------------------------------------------
226     Type SAL_CALL ODataTypeRepository::getElementType(  ) throw (RuntimeException)
227     {
228         return ::getCppuType( static_cast< Reference< XDataType >* >( NULL ) );
229     }
230 
231     //--------------------------------------------------------------------
232     sal_Bool SAL_CALL ODataTypeRepository::hasElements(  ) throw (RuntimeException)
233     {
234         return !m_aRepository.empty();
235     }
236 
237     //--------------------------------------------------------------------
238     // type specific implementation of registerProperties, using explicit
239     // template instantiations
240 
241     template<>
242     void OValueLimitedType<com::sun::star::util::Date>::registerProperties()
243     {
244         OValueLimitedType_Base::registerProperties();
245 
246         REGISTER_VOID_PROP( XSD_MAX_INCLUSIVE_DATE, m_aMaxInclusive, ValueType );
247         REGISTER_VOID_PROP( XSD_MAX_EXCLUSIVE_DATE, m_aMaxExclusive, ValueType );
248         REGISTER_VOID_PROP( XSD_MIN_INCLUSIVE_DATE, m_aMinInclusive, ValueType );
249         REGISTER_VOID_PROP( XSD_MIN_EXCLUSIVE_DATE, m_aMinExclusive, ValueType );
250     }
251 
252     template<>
253     void OValueLimitedType<com::sun::star::util::Time>::registerProperties()
254     {
255         OValueLimitedType_Base::registerProperties();
256 
257         REGISTER_VOID_PROP( XSD_MAX_INCLUSIVE_TIME, m_aMaxInclusive, ValueType );
258         REGISTER_VOID_PROP( XSD_MAX_EXCLUSIVE_TIME, m_aMaxExclusive, ValueType );
259         REGISTER_VOID_PROP( XSD_MIN_INCLUSIVE_TIME, m_aMinInclusive, ValueType );
260         REGISTER_VOID_PROP( XSD_MIN_EXCLUSIVE_TIME, m_aMinExclusive, ValueType );
261     }
262 
263     template<>
264     void OValueLimitedType<com::sun::star::util::DateTime>::registerProperties()
265     {
266         OValueLimitedType_Base::registerProperties();
267 
268         REGISTER_VOID_PROP( XSD_MAX_INCLUSIVE_DATE_TIME, m_aMaxInclusive, ValueType );
269         REGISTER_VOID_PROP( XSD_MAX_EXCLUSIVE_DATE_TIME, m_aMaxExclusive, ValueType );
270         REGISTER_VOID_PROP( XSD_MIN_INCLUSIVE_DATE_TIME, m_aMinInclusive, ValueType );
271         REGISTER_VOID_PROP( XSD_MIN_EXCLUSIVE_DATE_TIME, m_aMinExclusive, ValueType );
272     }
273 
274     template<>
275     void OValueLimitedType<double>::registerProperties()
276     {
277         OValueLimitedType_Base::registerProperties();
278 
279         REGISTER_VOID_PROP( XSD_MAX_INCLUSIVE_DOUBLE, m_aMaxInclusive, ValueType );
280         REGISTER_VOID_PROP( XSD_MAX_EXCLUSIVE_DOUBLE, m_aMaxExclusive, ValueType );
281         REGISTER_VOID_PROP( XSD_MIN_INCLUSIVE_DOUBLE, m_aMinInclusive, ValueType );
282         REGISTER_VOID_PROP( XSD_MIN_EXCLUSIVE_DOUBLE, m_aMinExclusive, ValueType );
283     }
284 
285     template<>
286     void OValueLimitedType<sal_Int16>::registerProperties()
287     {
288         OValueLimitedType_Base::registerProperties();
289 
290         REGISTER_VOID_PROP( XSD_MAX_INCLUSIVE_INT, m_aMaxInclusive, ValueType );
291         REGISTER_VOID_PROP( XSD_MAX_EXCLUSIVE_INT, m_aMaxExclusive, ValueType );
292         REGISTER_VOID_PROP( XSD_MIN_INCLUSIVE_INT, m_aMinInclusive, ValueType );
293         REGISTER_VOID_PROP( XSD_MIN_EXCLUSIVE_INT, m_aMinExclusive, ValueType );
294     }
295 //........................................................................
296 } // namespace xforms
297 //........................................................................
298 
299