KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > josql > functions > GroupingFunctions


1 /*
2  * Copyright 2004-2005 Gary Bentley
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may
5  * not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */

15 package org.josql.functions;
16
17 import java.util.List JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Collections JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.Iterator JavaDoc;
23
24 import com.gentlyweb.utils.Getter;
25
26 import org.josql.QueryExecutionException;
27
28 import org.josql.internal.Utilities;
29
30 import org.josql.expressions.Expression;
31
32 import org.josql.Query;
33
34 public class GroupingFunctions extends AbstractFunctionHandler
35 {
36
37     public static final String JavaDoc VALUE = "value";
38
39     public static final String JavaDoc HANDLER_ID = "_internal_grouping";
40
41     public Object JavaDoc least (List JavaDoc allobjs,
42              Expression exp,
43              String JavaDoc saveValueName)
44                          throws QueryExecutionException
45     {
46
47     if (saveValueName != null)
48     {
49
50         Object JavaDoc o = this.q.getSaveValue (saveValueName);
51
52         if (o != null)
53         {
54
55         return o;
56
57         }
58
59     }
60
61     if (allobjs.size () == 0)
62     {
63
64         return null;
65
66     }
67
68     Object JavaDoc g = null;
69
70     int s = allobjs.size ();
71
72     for (int i = 0; i < s; i++)
73     {
74
75         Object JavaDoc o = allobjs.get (i);
76
77         Object JavaDoc v = null;
78
79         try
80         {
81
82         v = exp.getValue (o,
83                   this.q);
84
85         } catch (Exception JavaDoc e) {
86
87         throw new QueryExecutionException ("Unable to get value from expression: " +
88                            exp +
89                            " for maximum value" +
90                            e);
91
92         }
93
94         if (g == null)
95         {
96
97         g = v;
98
99         } else {
100
101         int c = Utilities.compare (v,
102                        g);
103
104         if (c < 0)
105         {
106
107             g = v;
108
109         }
110
111         }
112
113     }
114
115     if ((saveValueName != null)
116         &&
117         (q != null)
118        )
119     {
120
121         q.setSaveValue (saveValueName,
122                 g);
123
124     }
125
126     return g;
127
128     }
129
130     public Object JavaDoc minObject (Expression exp)
131                          throws QueryExecutionException
132     {
133
134     return this.minObject ((List JavaDoc) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
135                    exp);
136
137     }
138
139     public Object JavaDoc minObject (List JavaDoc allobjs,
140                  Expression exp)
141                              throws QueryExecutionException
142     {
143
144     return this.leastObject (allobjs,
145                  exp);
146
147     }
148
149     public Object JavaDoc leastObject (List JavaDoc allobjs,
150                    Expression exp)
151                                throws QueryExecutionException
152     {
153
154     if (allobjs.size () == 0)
155     {
156
157         return null;
158
159     }
160
161     Object JavaDoc l = null;
162     Object JavaDoc lo = null;
163
164     int s = allobjs.size ();
165
166     for (int i = 0; i < s; i++)
167     {
168
169         Object JavaDoc o = allobjs.get (i);
170
171         Object JavaDoc v = null;
172
173         try
174         {
175
176         v = exp.getValue (o,
177                   this.q);
178
179         } catch (Exception JavaDoc e) {
180
181         throw new QueryExecutionException ("Unable to get value from expression: " +
182                            exp +
183                            " for maximum value" +
184                            e);
185
186         }
187
188         if (l == null)
189         {
190
191         l = v;
192         lo = o;
193
194         } else {
195
196         int c = Utilities.compare (v,
197                        l);
198
199         if (c < 0)
200         {
201
202             l = v;
203             lo = o;
204
205         }
206
207         }
208
209     }
210
211     return lo;
212
213     }
214
215     public Object JavaDoc maxObject (List JavaDoc allobjs,
216                  Expression exp)
217                              throws QueryExecutionException
218     {
219
220     return this.greatestObject (allobjs,
221                     exp);
222
223     }
224
225     public Object JavaDoc maxObject (Expression exp)
226                          throws QueryExecutionException
227     {
228
229     return this.maxObject ((List JavaDoc) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
230                    exp);
231
232     }
233
234     public Object JavaDoc greatestObject (List JavaDoc allobjs,
235                   Expression exp)
236                                   throws QueryExecutionException
237     {
238
239     if (allobjs.size () == 0)
240     {
241
242         return null;
243
244     }
245
246     Object JavaDoc g = null;
247     Object JavaDoc go = null;
248
249     int s = allobjs.size ();
250
251     for (int i = 0; i < s; i++)
252     {
253
254         Object JavaDoc o = allobjs.get (i);
255
256         Object JavaDoc v = null;
257
258         try
259         {
260
261         v = exp.getValue (o,
262                   this.q);
263
264         } catch (Exception JavaDoc e) {
265
266         throw new QueryExecutionException ("Unable to get value from expression: " +
267                            exp +
268                            " for maximum value" +
269                            e);
270
271         }
272
273         if (g == null)
274         {
275
276         g = v;
277         go = o;
278
279         } else {
280
281         int c = Utilities.compare (v,
282                        g);
283
284         if (c > 0)
285         {
286
287             g = v;
288             go = o;
289
290         }
291
292         }
293
294     }
295
296     return go;
297
298     }
299
300     public Object JavaDoc least (List JavaDoc allobjs,
301              Expression exp)
302                          throws QueryExecutionException
303     {
304
305     return this.least (allobjs,
306                exp,
307                null);
308
309     }
310
311     public Object JavaDoc min (Expression exp)
312                    throws QueryExecutionException
313     {
314
315     return this.min ((List JavaDoc) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
316              exp);
317
318     }
319
320     public Object JavaDoc min (List JavaDoc allobjs,
321                Expression exp)
322                        throws QueryExecutionException
323     {
324
325     return this.least (allobjs,
326                exp,
327                null);
328
329     }
330
331     public Object JavaDoc min (List JavaDoc allobjs,
332                Expression exp,
333                String JavaDoc saveValueName)
334                        throws QueryExecutionException
335     {
336
337     return this.least (allobjs,
338                exp,
339                saveValueName);
340
341     }
342
343     public Map.Entry JavaDoc maxEntry (Map JavaDoc m,
344                    String JavaDoc type)
345     {
346
347     int t = 0;
348
349     if (type.equals (GroupingFunctions.VALUE))
350     {
351
352         t = 1;
353
354     }
355
356     Map.Entry JavaDoc r = null;
357     Map.Entry JavaDoc le = null;
358
359     Iterator JavaDoc iter = m.entrySet ().iterator ();
360
361     while (iter.hasNext ())
362     {
363
364         r = (Map.Entry JavaDoc) iter.next ();
365
366         if (le != null)
367         {
368
369         if (t == 0)
370         {
371
372             if (Utilities.isGTEquals (r.getKey (),
373                           le.getKey ()))
374             {
375
376             le = r;
377
378             }
379
380         } else {
381
382             if (Utilities.isGTEquals (r.getValue (),
383                           le.getValue ()))
384             {
385
386             le = r;
387
388             }
389
390         }
391
392         } else {
393
394         le = r;
395
396         }
397
398     }
399
400     return le;
401
402     }
403
404     public Map.Entry JavaDoc minEntry (Object JavaDoc m,
405                    String JavaDoc type)
406                            throws QueryExecutionException
407     {
408
409     if (!(m instanceof Map JavaDoc))
410     {
411
412         throw new QueryExecutionException ("Only instances of: " +
413                            Map JavaDoc.class.getName () +
414                            " are supported, passed: " +
415                            m.getClass ().getName ());
416
417     }
418
419     return this.minEntry ((Map JavaDoc) m,
420                   type);
421
422     }
423
424     public Map.Entry JavaDoc minEntry (Map JavaDoc m,
425                    String JavaDoc type)
426     {
427
428     int t = 0;
429
430     if (type.equals (GroupingFunctions.VALUE))
431     {
432
433         t = 1;
434
435     }
436
437     Map.Entry JavaDoc r = null;
438     Map.Entry JavaDoc le = null;
439
440     Iterator JavaDoc iter = m.entrySet ().iterator ();
441
442     while (iter.hasNext ())
443     {
444
445         r = (Map.Entry JavaDoc) iter.next ();
446
447         if (le != null)
448         {
449
450         if (t == 0)
451         {
452
453             if (Utilities.isLTEquals (r.getKey (),
454                           le.getKey ()))
455             {
456
457             le = r;
458
459             }
460
461         } else {
462
463             if (Utilities.isLTEquals (r.getValue (),
464                           le.getValue ()))
465             {
466
467             le = r;
468
469             }
470
471         }
472
473         } else {
474
475         le = r;
476
477         }
478
479     }
480
481     return le;
482
483     }
484
485     public Object JavaDoc max (List JavaDoc allobjs,
486                Expression exp,
487                String JavaDoc saveValueName)
488                        throws QueryExecutionException
489     {
490
491     return this.greatest (allobjs,
492                   exp,
493                   saveValueName);
494
495     }
496
497     public Object JavaDoc greatest (List JavaDoc allobjs,
498                 Expression exp,
499                 String JavaDoc saveValueName)
500                             throws QueryExecutionException
501     {
502
503     if (saveValueName != null)
504     {
505
506         Object JavaDoc o = this.q.getSaveValue (saveValueName);
507
508         if (o != null)
509         {
510
511         return (Double JavaDoc) o;
512
513         }
514
515     }
516
517     if (allobjs.size () == 0)
518     {
519
520         return null;
521
522     }
523
524     Object JavaDoc g = null;
525
526     int s = allobjs.size ();
527
528     for (int i = 0; i < s; i++)
529     {
530
531         Object JavaDoc o = allobjs.get (i);
532
533         Object JavaDoc v = null;
534
535         try
536         {
537
538         v = exp.getValue (o,
539                   this.q);
540
541         } catch (Exception JavaDoc e) {
542
543         throw new QueryExecutionException ("Unable to get value from expression: " +
544                            exp +
545                            " for maximum value" +
546                            e);
547
548         }
549
550         if (g == null)
551         {
552
553         g = v;
554
555         } else {
556
557         int c = Utilities.compare (v,
558                        g);
559
560         if (c > 0)
561         {
562
563             g = v;
564
565         }
566
567         }
568
569     }
570
571     if (saveValueName != null)
572     {
573
574         this.q.setSaveValue (saveValueName,
575                  g);
576
577     }
578
579     return g;
580
581     }
582
583     public Object JavaDoc greatest (List JavaDoc allobjs,
584                 Expression exp)
585                             throws QueryExecutionException
586     {
587
588     return this.greatest (allobjs,
589                   exp,
590                   null);
591
592     }
593
594     public Object JavaDoc max (Expression exp)
595                    throws QueryExecutionException
596     {
597
598     return this.max ((List JavaDoc) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
599              exp);
600
601     }
602
603     public Object JavaDoc max (List JavaDoc allobjs,
604                Expression exp)
605                        throws QueryExecutionException
606     {
607
608     return this.greatest (allobjs,
609                   exp,
610                   null);
611
612     }
613
614     private double getTotal (List JavaDoc allobjs,
615                  Expression exp)
616                          throws QueryExecutionException
617     {
618
619     Object JavaDoc currObj = this.q.getCurrentObject ();
620
621     double total = 0;
622
623     int size = allobjs.size ();
624
625     for (int i = 0; i < size; i++)
626     {
627
628         Object JavaDoc o = allobjs.get (i);
629
630         this.q.setCurrentObject (o);
631
632         Number JavaDoc n = null;
633
634         try
635         {
636
637         n = (Number JavaDoc) exp.getValue (o,
638                        this.q);
639
640         } catch (Exception JavaDoc e) {
641
642         throw new QueryExecutionException ("Unable to get value from expression: " +
643                            exp +
644                            " for item: " +
645                            i +
646                            " from the list of objects.",
647                            e);
648
649         }
650
651         total += n.doubleValue ();
652
653     }
654
655     this.q.setCurrentObject (currObj);
656
657     return total;
658
659     }
660
661     public void checkType (Object JavaDoc o,
662                Class JavaDoc expected,
663                Expression exp)
664                            throws QueryExecutionException
665     {
666
667     if (!expected.isInstance (o))
668     {
669
670         throw new QueryExecutionException ("Expression: " +
671                            exp +
672                            " returns type: " +
673                            o.getClass ().getName () +
674                            " however must return instance of: " +
675                            expected.getName ());
676
677     }
678
679     }
680
681     public Double JavaDoc sum (List JavaDoc allobjs,
682                        Expression exp,
683                        String JavaDoc saveValueName)
684                        throws QueryExecutionException
685     {
686
687     if (saveValueName != null)
688     {
689
690         Object JavaDoc o = this.q.getSaveValue (saveValueName);
691
692         if (o != null)
693         {
694
695         return (Double JavaDoc) o;
696
697         }
698
699     }
700
701     if ((allobjs == null)
702         ||
703         (allobjs.size () == 0)
704        )
705     {
706
707         return new Double JavaDoc (0);
708
709     }
710
711     double total = this.getTotal (allobjs,
712                       exp);
713
714     Double JavaDoc d = new Double JavaDoc (total);
715
716     if ((saveValueName != null)
717         &&
718         (q != null)
719        )
720     {
721
722         this.q.setSaveValue (saveValueName,
723                  d);
724
725     }
726
727     return d;
728
729     }
730
731     public Double JavaDoc sum (Expression exp)
732                    throws QueryExecutionException
733     {
734
735     return this.sum ((List JavaDoc) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
736              exp);
737
738     }
739
740     public Double JavaDoc sum (List JavaDoc objs,
741                Expression exp)
742                    throws QueryExecutionException
743     {
744
745     Class JavaDoc c = null;
746
747     try
748     {
749
750         c = exp.getExpectedReturnType (this.q);
751
752     } catch (Exception JavaDoc e) {
753
754         throw new QueryExecutionException ("Unable to determine expected return type for expression: " +
755                            exp,
756                            e);
757
758     }
759
760     boolean dyn = false;
761
762     if (!c.getName ().equals (Object JavaDoc.class.getName ()))
763     {
764
765         // Should return a number...
766
if (!Utilities.isNumber (c))
767         {
768
769         throw new QueryExecutionException ("This function expects the expression: " +
770                            exp +
771                            " to return a number (sub-class of: " +
772                            Number JavaDoc.class.getName () +
773                            ") but evaluation of the expression will return an instance of: " +
774                            c.getName ());
775
776         }
777
778     } else {
779
780         dyn = true;
781
782     }
783
784     Object JavaDoc co = this.q.getCurrentObject ();
785
786     int s = objs.size () - 1;
787
788     double d = 0;
789
790     for (int i = s; i > -1; i--)
791     {
792
793         Object JavaDoc o = objs.get (i);
794
795         this.q.setCurrentObject (o);
796
797         Object JavaDoc v = null;
798
799         try
800         {
801
802         v = exp.getValue (o,
803                   this.q);
804
805         } catch (Exception JavaDoc e) {
806
807         throw new QueryExecutionException ("Unable to evaluate expression: " +
808                            exp +
809                            " on item: " +
810                            i,
811                            e);
812
813         }
814
815         if (v == null)
816         {
817
818         // Skip... i.e. assume it's zero.
819
continue;
820
821         }
822
823         if (dyn)
824         {
825
826         if (!(Utilities.isNumber (v)))
827         {
828
829             throw new QueryExecutionException ("Expected expression: " +
830                                exp +
831                                " to return a number (sub-class of: " +
832                                Number JavaDoc.class.getName () +
833                                ") but returns instance of: " +
834                                o.getClass ().getName () +
835                                " for item: " +
836                                i +
837                                " (class: " +
838                                v.getClass ().getName () +
839                                ")");
840
841         }
842
843         }
844
845         d += ((Number JavaDoc) v).doubleValue ();
846
847     }
848
849     this.q.setCurrentObject (co);
850
851     return new Double JavaDoc (d);
852
853     }
854
855     /**
856      * This function allows you to specify your own accessor as a string that will
857      * be used to access the relevant value for each of the objects in the <b>objs</b>
858      * List.
859      *
860      * @param objs The List of objects you wish to sum over.
861      * @param acc The accessor to create for accessing the value in each of the objects in <b>objs</b>.
862      * @return The summed value.
863      * @throws QueryExecutionException If the accessor is not valid for the objects in the list or
864      * if the accessor throws an exception.
865      */

866     public Double JavaDoc sum (List JavaDoc objs,
867                String JavaDoc acc)
868                    throws QueryExecutionException
869     {
870
871     if ((objs == null)
872         ||
873         (objs.size () == 0)
874        )
875     {
876
877         return new Double JavaDoc (0);
878
879     }
880
881     // Get the first object.
882
Object JavaDoc o = objs.get (0);
883
884     Getter get = null;
885
886     try
887     {
888
889         get = new Getter (acc,
890                   o.getClass ());
891
892     } catch (Exception JavaDoc e) {
893
894         throw new QueryExecutionException ("Unable to create accessor for: " +
895                            acc +
896                            " with class: " +
897                            o.getClass ().getName (),
898                            e);
899
900     }
901
902     if (!get.getType ().getName ().equals (Object JavaDoc.class.getName ()))
903     {
904
905         // Should return a number...
906
if (!Utilities.isNumber (get.getType ()))
907         {
908
909         throw new QueryExecutionException ("This function expects the accessor (second parm): " +
910                            acc +
911                            " to return a number (sub-class of: " +
912                            Number JavaDoc.class.getName () +
913                            ") but evaluation of the accessor will return an instance of: " +
914                            get.getType ().getName ());
915
916         }
917
918     }
919
920     int s = objs.size () - 1;
921
922     double d = 0;
923
924     for (int i = s; i > -1; i--)
925     {
926
927         o = objs.get (i);
928
929         Object JavaDoc v = null;
930
931         try
932         {
933
934         v = get.getValue (o);
935
936         } catch (Exception JavaDoc e) {
937
938         throw new QueryExecutionException ("Unable to evaluate accessor: " +
939                            acc +
940                            " on item: " +
941                            i,
942                            e);
943
944         }
945
946         if (v == null)
947         {
948
949         // Skip... i.e. assume it's zero.
950
continue;
951
952         }
953
954         d += ((Number JavaDoc) v).doubleValue ();
955
956     }
957
958     return new Double JavaDoc (d);
959
960     }
961
962     public String JavaDoc concat (List JavaDoc allobjs,
963               Expression exp,
964               String JavaDoc sep,
965               String JavaDoc saveValueName)
966                           throws QueryExecutionException
967     {
968
969     if (saveValueName != null)
970     {
971
972         Object JavaDoc o = this.q.getSaveValue (saveValueName);
973
974         if (o != null)
975         {
976
977         return (String JavaDoc) o;
978
979         }
980
981     }
982
983     StringBuffer JavaDoc buf = new StringBuffer JavaDoc ();
984
985     int size = allobjs.size ();
986     int size1 = size - 1;
987
988     for (int i = 0; i < size; i++)
989     {
990
991         Object JavaDoc o = allobjs.get (i);
992
993         Object JavaDoc v = null;
994
995         try
996         {
997
998         v = exp.getValue (o,
999                   this.q);
1000
1001        } catch (Exception JavaDoc e) {
1002
1003        throw new QueryExecutionException ("Unable to get value from expression: " +
1004                           exp +
1005                           " for item: " +
1006                           i +
1007                           " from the list of objects.",
1008                           e);
1009
1010        }
1011
1012        buf.append (v);
1013
1014        if ((sep != null)
1015        &&
1016        (i < size1)
1017           )
1018        {
1019
1020        buf.append (sep);
1021
1022        }
1023
1024    }
1025
1026    String JavaDoc r = buf.toString ();
1027
1028    if ((saveValueName != null)
1029        &&
1030        (q != null)
1031       )
1032    {
1033
1034        q.setSaveValue (saveValueName,
1035                r);
1036
1037    }
1038
1039    return r;
1040
1041    }
1042
1043    public String JavaDoc concat (List JavaDoc allobjs,
1044                          Expression exp,
1045              String JavaDoc sep)
1046                          throws QueryExecutionException
1047    {
1048
1049    return this.concat (allobjs,
1050                exp,
1051                sep,
1052                null);
1053
1054    }
1055
1056    public String JavaDoc concat (Expression exp)
1057                      throws QueryExecutionException
1058    {
1059
1060    return this.concat ((List JavaDoc) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
1061                exp);
1062
1063    }
1064
1065    public String JavaDoc concat (List JavaDoc allobjs,
1066                          Expression exp)
1067                          throws QueryExecutionException
1068    {
1069
1070    return this.concat (allobjs,
1071                exp,
1072                null,
1073                null);
1074
1075    }
1076
1077    public Double JavaDoc avg (List JavaDoc allobjs,
1078                       Expression exp,
1079                       String JavaDoc saveValueName)
1080                       throws QueryExecutionException
1081    {
1082
1083    if (saveValueName != null)
1084    {
1085
1086        Object JavaDoc o = this.q.getSaveValue (saveValueName);
1087
1088        if (o != null)
1089        {
1090
1091        return (Double JavaDoc) o;
1092
1093        }
1094
1095    }
1096
1097    if ((allobjs == null)
1098        ||
1099        (allobjs.size () == 0)
1100       )
1101    {
1102
1103        return new Double JavaDoc (0);
1104
1105    }
1106
1107    double total = this.getTotal (allobjs,
1108                      exp);
1109
1110    double avg = total / allobjs.size ();
1111
1112    Double JavaDoc d = new Double JavaDoc (avg);
1113
1114    if (saveValueName != null)
1115    {
1116
1117        q.setSaveValue (saveValueName,
1118                d);
1119
1120    }
1121
1122    return d;
1123
1124    }
1125
1126    public Double JavaDoc avg (Expression exp)
1127                   throws QueryExecutionException
1128    {
1129
1130    return this.avg ((List JavaDoc) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
1131             exp);
1132
1133    }
1134
1135    public Double JavaDoc avg (List JavaDoc allobjs,
1136                       Expression exp)
1137                       throws QueryExecutionException
1138    {
1139
1140    return this.avg (allobjs,
1141             exp,
1142             null);
1143
1144    }
1145
1146    /**
1147     * A function that will take each item from the passed in List and
1148     * determine a "count" for each item, i.e. how many times each item appears.
1149     *
1150     * @param objs The List of objects to operate on.
1151     * @return A Map of object to a count of the number of times the object appears in the list.
1152     * @throws QueryExecutionException Won't happen in this method.
1153     */

1154    public Map JavaDoc occurrence (List JavaDoc objs)
1155                       throws QueryExecutionException
1156    {
1157
1158    return this.occurrence (objs,
1159                null);
1160
1161    }
1162
1163    /*
1164    public Map occurrence (Expression exp)
1165                       throws QueryExecutionException
1166    {
1167
1168    return this.occurrence ((List) this.q.getVariable (Query.ALL_OBJS_VAR_NAME),
1169                exp);
1170
1171    }
1172    */

1173
1174    /**
1175     * A function that will take each item from the passed in List and
1176     * determine a "count" for each item, i.e. how many times each item appears.
1177     *
1178     * @param objs The List of objects to operate on.
1179     * @param exp An optional expression that should be performed on each object
1180     * and the value returned used instead.
1181     * @return A Map of object to a count of the number of times the object appears in the list.
1182     * @throws QueryExecutionException If the expression cannot be evaluated.
1183     */

1184    public Map JavaDoc occurrence (List JavaDoc objs,
1185               Expression exp)
1186                       throws QueryExecutionException
1187    {
1188
1189    Map JavaDoc occs = new HashMap JavaDoc ();
1190
1191    if (objs == null)
1192    {
1193
1194        return occs;
1195
1196    }
1197
1198    int s = objs.size ();
1199
1200    for (int i = 0; i < s; i++)
1201    {
1202
1203        Object JavaDoc o = objs.get (i);
1204
1205        if (exp != null)
1206        {
1207
1208        try
1209        {
1210
1211            o = exp.getValue (o,
1212                      this.q);
1213
1214        } catch (Exception JavaDoc e) {
1215
1216            throw new QueryExecutionException ("Unable to get value for expression: " +
1217                               exp +
1218                               " for object: " +
1219                               i +
1220                               " from the list of objects.",
1221                               e);
1222
1223        }
1224
1225        }
1226
1227        Integer JavaDoc c = (Integer JavaDoc) occs.get (o);
1228
1229        int co = 1;
1230
1231        if (c != null)
1232        {
1233
1234        co = c.intValue ();
1235
1236        co++;
1237
1238        }
1239
1240        occs.put (o,
1241              new Integer JavaDoc (co));
1242
1243    }
1244
1245    return occs;
1246
1247    }
1248
1249    /**
1250     * This is the same as {@link #occurrence(List,Expression)} except that the
1251     * second expression should evaluate to a number that will be used to limit the
1252     * results, the occurrence count must be greater than or equal to the value from
1253     * the expression.
1254     *
1255     * @param objs The List of objects to operate on.
1256     * @param exp An optional expression that should be performed on each object
1257     * and the value returned used instead.
1258     * @param limitExp An expression that when evaluated should return a number, this
1259     * will then be used to limit the results returned to those that have an
1260     * occurrence count >= that number.
1261     * @return A Map of object to a count of the number of times the object appears in the list.
1262     * @throws QueryExecutionException If the expression cannot be evaluated or the <b>limitExp</b>
1263     * arg does not evaulate to a number.
1264     */

1265    public Map JavaDoc occurrence (List JavaDoc objs,
1266               Expression exp,
1267               Expression limitExp)
1268                       throws QueryExecutionException
1269    {
1270
1271    Map JavaDoc rs = this.occurrence (objs,
1272                  exp);
1273
1274    // Evaluate the limit expression.
1275
Object JavaDoc o = limitExp.getValue (this.q.getCurrentObject (),
1276                      this.q);
1277
1278    if (!(o instanceof Number JavaDoc))
1279    {
1280
1281        throw new QueryExecutionException ("Limit expression: " +
1282                           limitExp +
1283                           " does not evaluate to a number");
1284
1285    }
1286
1287    int i = ((Number JavaDoc) o).intValue ();
1288
1289    Map JavaDoc ret = new HashMap JavaDoc ();
1290
1291    Iterator JavaDoc iter = rs.keySet ().iterator ();
1292
1293    while (iter.hasNext ())
1294    {
1295
1296        Object JavaDoc k = iter.next ();
1297
1298        Integer JavaDoc c = (Integer JavaDoc) rs.get (k);
1299
1300        if (c.intValue () >= i)
1301        {
1302
1303        ret.put (k,
1304             c);
1305
1306        }
1307
1308    }
1309
1310    return ret;
1311
1312    }
1313
1314}
1315
Popular Tags