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