1 /*************************************************************************
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * Copyright 2000, 2010 Oracle and/or its affiliates.
5  *
6  * OpenOffice.org - a multi-platform office productivity suite
7  *
8  * This file is part of OpenOffice.org.
9  *
10  * OpenOffice.org is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License version 3
12  * only, as published by the Free Software Foundation.
13  *
14  * OpenOffice.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License version 3 for more details
18  * (a copy is included in the LICENSE file that accompanied this code).
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * version 3 along with OpenOffice.org.  If not, see
22  * <http://www.openoffice.org/license.html>
23  * for a copy of the LGPLv3 License.
24  *
25  ************************************************************************/
26 
27 #include "precompiled_comphelper.hxx"
28 
29 #include "comphelper/anycompare.hxx"
30 
31 /** === begin UNO includes === **/
32 #include <com/sun/star/util/Date.hpp>
33 #include <com/sun/star/util/Time.hpp>
34 #include <com/sun/star/util/DateTime.hpp>
35 /** === end UNO includes === **/
36 
37 //......................................................................................................................
38 namespace comphelper
39 {
40 //......................................................................................................................
41 
42 	/** === begin UNO using === **/
43 	using ::com::sun::star::uno::Reference;
44 	using ::com::sun::star::uno::XInterface;
45 	using ::com::sun::star::uno::UNO_QUERY;
46 	using ::com::sun::star::uno::UNO_QUERY_THROW;
47 	using ::com::sun::star::uno::UNO_SET_THROW;
48 	using ::com::sun::star::uno::Exception;
49 	using ::com::sun::star::uno::RuntimeException;
50 	using ::com::sun::star::uno::Any;
51 	using ::com::sun::star::uno::makeAny;
52 	using ::com::sun::star::uno::Sequence;
53 	using ::com::sun::star::uno::Type;
54     using ::com::sun::star::uno::TypeClass_CHAR;
55     using ::com::sun::star::uno::TypeClass_BOOLEAN;
56     using ::com::sun::star::uno::TypeClass_BYTE;
57     using ::com::sun::star::uno::TypeClass_SHORT;
58     using ::com::sun::star::uno::TypeClass_UNSIGNED_SHORT;
59     using ::com::sun::star::uno::TypeClass_LONG;
60     using ::com::sun::star::uno::TypeClass_UNSIGNED_LONG;
61     using ::com::sun::star::uno::TypeClass_HYPER;
62     using ::com::sun::star::uno::TypeClass_UNSIGNED_HYPER;
63     using ::com::sun::star::uno::TypeClass_FLOAT;
64     using ::com::sun::star::uno::TypeClass_DOUBLE;
65     using ::com::sun::star::uno::TypeClass_STRING;
66     using ::com::sun::star::uno::TypeClass_TYPE;
67     using ::com::sun::star::uno::TypeClass_ENUM;
68     using ::com::sun::star::uno::TypeClass_INTERFACE;
69     using ::com::sun::star::uno::TypeClass_STRUCT;
70     using ::com::sun::star::i18n::XCollator;
71     using ::com::sun::star::util::Date;
72     using ::com::sun::star::util::Time;
73     using ::com::sun::star::util::DateTime;
74 	/** === end UNO using === **/
75 
76 	//==================================================================================================================
77 	//= DatePredicateLess
78 	//==================================================================================================================
79     class DatePredicateLess : public IKeyPredicateLess
80     {
81     public:
82         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
83         {
84             Date lhs, rhs;
85             if  (   !( _lhs >>= lhs )
86                 ||  !( _rhs >>= rhs )
87                 )
88                 throw ::com::sun::star::lang::IllegalArgumentException();
89 
90             if ( lhs.Year < rhs.Year )
91                 return true;
92             if ( lhs.Year > rhs.Year )
93                 return false;
94 
95             if ( lhs.Month < rhs.Month )
96                 return true;
97             if ( lhs.Month > rhs.Month )
98                 return false;
99 
100             if ( lhs.Day < rhs.Day )
101                 return true;
102             return false;
103         }
104     };
105 
106 	//==================================================================================================================
107 	//= TimePredicateLess
108 	//==================================================================================================================
109     class TimePredicateLess : public IKeyPredicateLess
110     {
111     public:
112         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
113         {
114             Time lhs, rhs;
115             if  (   !( _lhs >>= lhs )
116                 ||  !( _rhs >>= rhs )
117                 )
118                 throw ::com::sun::star::lang::IllegalArgumentException();
119 
120             if ( lhs.Hours < rhs.Hours )
121                 return true;
122             if ( lhs.Hours > rhs.Hours )
123                 return false;
124 
125             if ( lhs.Minutes < rhs.Minutes )
126                 return true;
127             if ( lhs.Minutes > rhs.Minutes )
128                 return false;
129 
130             if ( lhs.Seconds < rhs.Seconds )
131                 return true;
132             if ( lhs.Seconds > rhs.Seconds )
133                 return false;
134 
135             if ( lhs.HundredthSeconds < rhs.HundredthSeconds )
136                 return true;
137             return false;
138         }
139     };
140 
141 	//==================================================================================================================
142 	//= DateTimePredicateLess
143 	//==================================================================================================================
144     class DateTimePredicateLess : public IKeyPredicateLess
145     {
146     public:
147         virtual bool isLess( ::com::sun::star::uno::Any const & _lhs, ::com::sun::star::uno::Any const & _rhs ) const
148         {
149             DateTime lhs, rhs;
150             if  (   !( _lhs >>= lhs )
151                 ||  !( _rhs >>= rhs )
152                 )
153                 throw ::com::sun::star::lang::IllegalArgumentException();
154 
155             if ( lhs.Year < rhs.Year )
156                 return true;
157             if ( lhs.Year > rhs.Year )
158                 return false;
159 
160             if ( lhs.Month < rhs.Month )
161                 return true;
162             if ( lhs.Month > rhs.Month )
163                 return false;
164 
165             if ( lhs.Day < rhs.Day )
166                 return true;
167             if ( lhs.Day > rhs.Day )
168                 return false;
169 
170             if ( lhs.Hours < rhs.Hours )
171                 return true;
172             if ( lhs.Hours > rhs.Hours )
173                 return false;
174 
175             if ( lhs.Minutes < rhs.Minutes )
176                 return true;
177             if ( lhs.Minutes > rhs.Minutes )
178                 return false;
179 
180             if ( lhs.Seconds < rhs.Seconds )
181                 return true;
182             if ( lhs.Seconds > rhs.Seconds )
183                 return false;
184 
185             if ( lhs.HundredthSeconds < rhs.HundredthSeconds )
186                 return true;
187             return false;
188         }
189     };
190 
191 	//------------------------------------------------------------------------------------------------------------------
192     ::std::auto_ptr< IKeyPredicateLess > getStandardLessPredicate( Type const & i_type, Reference< XCollator > const & i_collator )
193     {
194         ::std::auto_ptr< IKeyPredicateLess > pComparator;
195         switch ( i_type.getTypeClass() )
196         {
197         case TypeClass_CHAR:
198 			pComparator.reset( new ScalarPredicateLess< sal_Unicode >() );
199             break;
200         case TypeClass_BOOLEAN:
201 			pComparator.reset( new ScalarPredicateLess< sal_Bool >() );
202             break;
203         case TypeClass_BYTE:
204 			pComparator.reset( new ScalarPredicateLess< sal_Int8 >() );
205             break;
206         case TypeClass_SHORT:
207 			pComparator.reset( new ScalarPredicateLess< sal_Int16 >() );
208             break;
209         case TypeClass_UNSIGNED_SHORT:
210 			pComparator.reset( new ScalarPredicateLess< sal_uInt16 >() );
211             break;
212         case TypeClass_LONG:
213 			pComparator.reset( new ScalarPredicateLess< sal_Int32 >() );
214             break;
215         case TypeClass_UNSIGNED_LONG:
216 			pComparator.reset( new ScalarPredicateLess< sal_uInt32 >() );
217             break;
218         case TypeClass_HYPER:
219 			pComparator.reset( new ScalarPredicateLess< sal_Int64 >() );
220             break;
221         case TypeClass_UNSIGNED_HYPER:
222 			pComparator.reset( new ScalarPredicateLess< sal_uInt64 >() );
223             break;
224         case TypeClass_FLOAT:
225             pComparator.reset( new ScalarPredicateLess< float >() );
226             break;
227         case TypeClass_DOUBLE:
228             pComparator.reset( new ScalarPredicateLess< double >() );
229             break;
230         case TypeClass_STRING:
231             if ( i_collator.is() )
232                 pComparator.reset( new StringCollationPredicateLess( i_collator ) );
233             else
234                 pComparator.reset( new StringPredicateLess() );
235             break;
236         case TypeClass_TYPE:
237             pComparator.reset( new TypePredicateLess() );
238             break;
239         case TypeClass_ENUM:
240             pComparator.reset( new EnumPredicateLess( i_type ) );
241             break;
242         case TypeClass_INTERFACE:
243             pComparator.reset( new InterfacePredicateLess() );
244             break;
245         case TypeClass_STRUCT:
246             if ( i_type.equals( ::cppu::UnoType< Date >::get() ) )
247                 pComparator.reset( new DatePredicateLess() );
248             else if ( i_type.equals( ::cppu::UnoType< Time >::get() ) )
249                 pComparator.reset( new TimePredicateLess() );
250             else if ( i_type.equals( ::cppu::UnoType< DateTime >::get() ) )
251                 pComparator.reset( new DateTimePredicateLess() );
252             break;
253         default:
254             break;
255         }
256         return pComparator;
257     }
258 
259 //......................................................................................................................
260 } // namespace comphelper
261 //......................................................................................................................
262