001package com.hfg.util;
002
003//------------------------------------------------------------------------------
004
005import java.awt.*;
006import java.util.ArrayList;
007import java.util.Collection;
008import java.util.Collections;
009import java.util.List;
010import java.util.Map;
011import java.util.Set;
012
013import com.hfg.graphics.ColorUtil;
014
015/**
016 Basic null-safe compare() methods.
017
018 @author J. Alex Taylor, hairyfatguy.com
019 */
020//------------------------------------------------------------------------------
021// com.hfg XML/HTML Coding Library
022//
023// This library is free software; you can redistribute it and/or
024// modify it under the terms of the GNU Lesser General Public
025// License as published by the Free Software Foundation; either
026// version 2.1 of the License, or (at your option) any later version.
027//
028// This library is distributed in the hope that it will be useful,
029// but WITHOUT ANY WARRANTY; without even the implied warranty of
030// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
031// Lesser General Public License for more details.
032//
033// You should have received a copy of the GNU Lesser General Public
034// License along with this library; if not, write to the Free Software
035// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
036//
037// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
038// jataylor@hairyfatguy.com
039//------------------------------------------------------------------------------
040
041public class CompareUtil
042{
043   //---------------------------------------------------------------------------
044   public static <T extends Comparable> int compare(T inValue1, T inValue2)
045   {
046      int result = 0;
047
048      if (inValue1 != null)
049      {
050         if (inValue2 != null)
051         {
052            result =  inValue1.compareTo(inValue2);
053         }
054         else
055         {
056            result = -1;
057         }
058      }
059      else if (inValue2 != null)
060      {
061         result = 1;
062      }
063
064      return result;
065   }
066
067   //---------------------------------------------------------------------------
068   public static <T extends Number> int compare(T inValue1, T inValue2)
069   {
070      int result = 0;
071
072      if (inValue1 != null)
073      {
074         if (inValue2 != null)
075         {
076            result = CompareUtil.compare(inValue1.doubleValue(), inValue2.doubleValue());
077         }
078         else
079         {
080            result = -1;
081         }
082      }
083      else if (inValue2 != null)
084      {
085         result = 1;
086      }
087
088      return result;
089   }
090
091   //---------------------------------------------------------------------------
092   public static int compare(String inValue1, String inValue2)
093   {
094      int result = 0;
095
096      if (inValue1 != null)
097      {
098         if (inValue2 != null)
099         {
100            result =  inValue1.compareTo(inValue2);
101         }
102         else
103         {
104            result = -1;
105         }
106      }
107      else if (inValue2 != null)
108      {
109         result = 1;
110      }
111
112      return result;
113   }
114
115   //---------------------------------------------------------------------------
116   public static int compareIgnoreCase(String inValue1, String inValue2)
117   {
118      int result = 0;
119
120      if (inValue1 != null)
121      {
122         String lc1 = inValue1.toLowerCase();
123
124         if (inValue2 != null)
125         {
126            String lc2 = inValue2.toLowerCase();
127
128            result =  lc1.compareTo(lc2);
129         }
130         else
131         {
132            result = -1;
133         }
134      }
135      else if (inValue2 != null)
136      {
137         result = 1;
138      }
139
140      return result;
141   }
142
143   //---------------------------------------------------------------------------
144   public static int compare(double inValue1, double inValue2)
145   {
146      int result = 0;
147
148      if (inValue1 < inValue2)
149      {
150         result = -1;
151      }
152      else if (inValue1 > inValue2)
153      {
154         result = 1;
155      }
156
157      return result;
158   }
159
160   //---------------------------------------------------------------------------
161   public static int compare(int inValue1, int inValue2)
162   {
163      int result = 0;
164
165      if (inValue1 < inValue2)
166      {
167         result = -1;
168      }
169      else if (inValue1 > inValue2)
170      {
171         result = 1;
172      }
173
174      return result;
175   }
176
177   //---------------------------------------------------------------------------
178   public static int compare(Integer inValue1, Integer inValue2)
179   {
180      int result = 0;
181
182      if (inValue1 != null)
183      {
184         if (inValue2 != null)
185         {
186            if (inValue1 < inValue2)
187            {
188               result = -1;
189            }
190            else if (inValue1 > inValue2)
191            {
192               result = 1;
193            }
194         }
195         else
196         {
197            result = -1;
198         }
199      }
200      else if (inValue2 != null)
201      {
202         result = 1;
203      }
204
205      return result;
206   }
207
208   //---------------------------------------------------------------------------
209   public static int compare(char inValue1, char inValue2)
210   {
211      int result = 0;
212
213      if (inValue1 < inValue2)
214      {
215         result = -1;
216      }
217      else if (inValue1 > inValue2)
218      {
219         result = 1;
220      }
221
222      return result;
223   }
224
225   //---------------------------------------------------------------------------
226   public static int compareIgnoreCase(char inValue1, char inValue2)
227   {
228      int result = 0;
229
230      char lc1 = Character.toLowerCase(inValue1);
231      char lc2 = Character.toLowerCase(inValue2);
232
233      if (lc1 < lc2)
234      {
235         result = -1;
236      }
237      else if (lc1 > lc2)
238      {
239         result = 1;
240      }
241
242      return result;
243   }
244
245   //---------------------------------------------------------------------------
246   public static int compare(Float inValue1, Float inValue2)
247   {
248      int result = 0;
249
250      if (inValue1 != null)
251      {
252         if (inValue2 != null)
253         {
254            if (inValue1 < inValue2)
255            {
256               result = -1;
257            }
258            else if (inValue1 > inValue2)
259            {
260               result = 1;
261            }
262         }
263         else
264         {
265            result = -1;
266         }
267      }
268      else if (inValue2 != null)
269      {
270         result = 1;
271      }
272
273      return result;
274   }
275
276   //---------------------------------------------------------------------------
277   public static int compare(Long inValue1, Long inValue2)
278   {
279      int result = 0;
280
281      if (inValue1 != null)
282      {
283         if (inValue2 != null)
284         {
285            if (inValue1 < inValue2)
286            {
287               result = -1;
288            }
289            else if (inValue1 > inValue2)
290            {
291               result = 1;
292            }
293         }
294         else
295         {
296            result = -1;
297         }
298      }
299      else if (inValue2 != null)
300      {
301         result = 1;
302      }
303
304      return result;
305   }
306
307   //---------------------------------------------------------------------------
308   public static int compare(Short inValue1, Short inValue2)
309   {
310      int result = 0;
311
312      if (inValue1 != null)
313      {
314         if (inValue2 != null)
315         {
316            if (inValue1 < inValue2)
317            {
318               result = -1;
319            }
320            else if (inValue1 > inValue2)
321            {
322               result = 1;
323            }
324         }
325         else
326         {
327            result = -1;
328         }
329      }
330      else if (inValue2 != null)
331      {
332         result = 1;
333      }
334
335      return result;
336   }
337
338   //---------------------------------------------------------------------------
339   public static int compare(Double inValue1, Double inValue2)
340   {
341      int result = 0;
342
343      if (inValue1 != null)
344      {
345         if (inValue2 != null)
346         {
347            if (inValue1 < inValue2)
348            {
349               result = -1;
350            }
351            else if (inValue1 > inValue2)
352            {
353               result = 1;
354            }
355         }
356         else
357         {
358            result = -1;
359         }
360      }
361      else if (inValue2 != null)
362      {
363         result = 1;
364      }
365
366      return result;
367   }
368
369   //---------------------------------------------------------------------------
370   public static <T extends Comparable<T>> int compare(List<T> inValue1, List<T> inValue2)
371   {
372      int result = 0;
373
374      if (inValue1 != null)
375      {
376         if (inValue2 != null)
377         {
378            if (inValue1.size() < inValue2.size())
379            {
380               result = -1;
381            }
382            else if (inValue1.size() > inValue2.size())
383            {
384               result = 1;
385            }
386            else
387            {
388               for (int i = 0; i < inValue1.size(); i++)
389               {
390                  result = compareValues(inValue1.get(i), inValue2.get(i));
391                  
392                  if (result != 0)
393                  {
394                     break;
395                  }
396               }
397            }
398         }
399         else
400         {
401            result = -1;
402         }
403      }
404      else if (inValue2 != null)
405      {
406         result = 1;
407      }
408
409      return result;
410   }
411
412   //---------------------------------------------------------------------------
413   public static <T extends Comparable<T>> int compare(Set<T> inValue1, Set<T> inValue2)
414   {
415      int result = 0;
416
417      if (inValue1 != null)
418      {
419         if (inValue2 != null)
420         {
421            if (inValue1.size() < inValue2.size())
422            {
423               result = -1;
424            }
425            else if (inValue1.size() > inValue2.size())
426            {
427               result = 1;
428            }
429            else
430            {
431               for (T value : inValue1)
432               {
433                  if (! inValue2.contains(value))
434                  {
435                     // Comparing sorted lists to ensure consistency
436                     List<T> sorted1 = new ArrayList<>(inValue1);
437                     Collections.sort(sorted1);
438
439                     List<T> sorted2 = new ArrayList<>(inValue2);
440                     Collections.sort(sorted2);
441
442                     result = CompareUtil.compare(sorted1, sorted2);
443                     break;
444                  }
445               }
446            }
447         }
448         else
449         {
450            result = -1;
451         }
452      }
453      else if (inValue2 != null)
454      {
455         result = 1;
456      }
457
458      return result;
459   }
460
461   //---------------------------------------------------------------------------
462   public static <T extends Comparable<T>> int compare(Collection<T> inValue1, Collection<T> inValue2)
463   {
464      int result = 0;
465
466      if (inValue1 != null)
467      {
468         if (inValue2 != null)
469         {
470            if (inValue1.size() < inValue2.size())
471            {
472               result = -1;
473            }
474            else if (inValue1.size() > inValue2.size())
475            {
476               result = 1;
477            }
478            else
479            {
480               for (T value : inValue1)
481               {
482                  if (! inValue2.contains(value))
483                  {
484                     // Comparing sorted lists to ensure consistency
485                     List<T> sorted1 = new ArrayList<>(inValue1);
486                     Collections.sort(sorted1);
487
488                     List<T> sorted2 = new ArrayList<>(inValue2);
489                     Collections.sort(sorted2);
490
491                     result = CompareUtil.compare(sorted1, sorted2);
492                     break;
493                  }
494               }
495            }
496         }
497         else
498         {
499            result = -1;
500         }
501      }
502      else if (inValue2 != null)
503      {
504         result = 1;
505      }
506
507      return result;
508   }
509
510   //---------------------------------------------------------------------------
511   public static <K extends Comparable<K>, V extends Comparable<V>> int compare(Map<K, V> inValue1, Map<K, V> inValue2)
512   {
513      int result = 0;
514
515      if (inValue1 != null)
516      {
517         if (inValue2 != null)
518         {
519            if (inValue1.size() < inValue2.size())
520            {
521               result = -1;
522            }
523            else if (inValue1.size() > inValue2.size())
524            {
525               result = 1;
526            }
527            else
528            {
529               // The two maps are the same size.
530
531               // Compare the keys
532               List<K> sortedKeys1 = new ArrayList<>(inValue1.keySet());
533               Collections.sort(sortedKeys1);
534
535               List<K> sortedKeys2 = new ArrayList<>(inValue2.keySet());
536               Collections.sort(sortedKeys2);
537
538               result = CompareUtil.compare(sortedKeys1, sortedKeys2);
539
540               if (0 == result)
541               {
542                  // Compare the values
543                  List<V> orderedValues1 = new ArrayList<>(sortedKeys1.size());
544                  for (K key : sortedKeys1)
545                  {
546                     orderedValues1.add(inValue1.get(key));
547                  }
548
549                  List<V> orderedValues2 = new ArrayList<>(sortedKeys2.size());
550                  for (K key : sortedKeys2)
551                  {
552                     orderedValues2.add(inValue2.get(key));
553                  }
554
555                  result = CompareUtil.compare(orderedValues1, orderedValues2);
556               }
557            }
558         }
559         else
560         {
561            result = -1;
562         }
563      }
564      else if (inValue2 != null)
565      {
566         result = 1;
567      }
568
569      return result;
570   }
571
572   //---------------------------------------------------------------------------
573   public static int compare(Color inValue1, Color inValue2)
574   {
575      int result = 0;
576
577      if (inValue1 != null)
578      {
579         if (inValue2 != null)
580         {
581            result = CompareUtil.compare(ColorUtil.colorToHex(inValue1), ColorUtil.colorToHex(inValue2));
582         }
583         else
584         {
585            result = -1;
586         }
587      }
588      else if (inValue2 != null)
589      {
590         result = 1;
591      }
592
593      return result;
594   }
595
596   //---------------------------------------------------------------------------
597   public static int compare(byte[] inValue1, byte[] inValue2)
598   {
599      int result = 0;
600
601      if (inValue1 != null)
602      {
603         if (inValue2 != null)
604         {
605            result = CompareUtil.compare(inValue1.length, inValue2.length);
606            if (0 == result)
607            {
608               for (int i = 0; i < inValue1.length; i++)
609               {
610                  result = CompareUtil.compare(inValue1[i], inValue2[i]);
611                  if (result != 0)
612                  {
613                     break;
614                  }
615               }
616            }
617         }
618         else
619         {
620            result = -1;
621         }
622      }
623      else if (inValue2 != null)
624      {
625         result = 1;
626      }
627
628      return result;
629   }
630
631   //---------------------------------------------------------------------------
632   private static int compareValues(Object inObj1, Object inObj2)
633   {
634      int result = -1;
635
636      if (inObj1 instanceof Comparable
637            && inObj2 instanceof Comparable)
638      {
639         result = CompareUtil.compare((Comparable) inObj1, (Comparable) inObj2);
640      }
641      else if (inObj1 instanceof byte[]
642            && inObj2 instanceof byte[])
643      {
644         result = CompareUtil.compare((byte[]) inObj1, (byte[]) inObj2);
645      }
646      else if (inObj1.equals(inObj2))
647      {
648         result = 0;
649      }
650      else
651      {
652         if (inObj1 != null)
653         {
654            if (inObj2 != null)
655            {
656               result = inObj1.toString().compareTo(inObj2.toString());
657            }
658            else
659            {
660               result = -1;
661            }
662         }
663         else if (inObj2 != null)
664         {
665            result = 1;
666         }
667         else
668         {
669            result = 0;
670         }
671      }
672      
673      return result;
674   }
675}