KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jasperreports > engine > data > JRSortableDataSource


1 /*
2  * ============================================================================
3  * GNU Lesser General Public License
4  * ============================================================================
5  *
6  * JasperReports - Free Java report-generating library.
7  * Copyright (C) 2001-2006 JasperSoft Corporation http://www.jaspersoft.com
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * This library 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 GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
22  *
23  * JasperSoft Corporation
24  * 303 Second Street, Suite 450 North
25  * San Francisco, CA 94107
26  * http://www.jaspersoft.com
27  */

28 package net.sf.jasperreports.engine.data;
29
30 import java.text.Collator JavaDoc;
31 import java.util.ArrayList JavaDoc;
32 import java.util.Collections JavaDoc;
33 import java.util.Comparator JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.List JavaDoc;
37 import java.util.Locale JavaDoc;
38 import java.util.Map JavaDoc;
39
40 import net.sf.jasperreports.engine.JRDataSource;
41 import net.sf.jasperreports.engine.JRException;
42 import net.sf.jasperreports.engine.JRField;
43 import net.sf.jasperreports.engine.JRRewindableDataSource;
44 import net.sf.jasperreports.engine.JRRuntimeException;
45 import net.sf.jasperreports.engine.JRSortField;
46
47
48 /**
49  * @author Teodor Danciu (teodord@users.sourceforge.net)
50  * @version $Id: JRCsvDataSource.java,v 1.10 2006/03/20 08:15:51 lucianc Exp $
51  */

52 public class JRSortableDataSource implements JRRewindableDataSource
53 {
54
55
56     /**
57      *
58      */

59     private List JavaDoc records = new ArrayList JavaDoc();
60     private Iterator JavaDoc iterator = null;
61     private Object JavaDoc[] currentRecord = null;
62     private Map JavaDoc fieldIndexMap = new HashMap JavaDoc();
63
64     protected Collator JavaDoc collator = null;
65
66
67     /**
68      *
69      */

70     public JRSortableDataSource(JRDataSource ds, JRField[] fields, JRSortField[] sortFields, Locale JavaDoc locale) throws JRException
71     {
72         if (fields == null)
73         {
74             //avoid testing for null later
75
fields = new JRField[0];
76         }
77         
78         if (sortFields == null)
79         {
80             //avoid testing for null later
81
sortFields = new JRSortField[0];
82         }
83         
84         /* */
85         verifySortFields(fields, sortFields);
86         
87         collator = Collator.getInstance(locale);
88
89         for(int i = 0; i < fields.length; i++)
90         {
91             fieldIndexMap.put(fields[i].getName(), new Integer JavaDoc(i));
92         }
93         
94         int[] sortIndexes = new int[sortFields.length];
95         int[] sortOrders = new int[sortFields.length];
96         boolean[] collatorFlags = new boolean[sortFields.length];
97         for(int i = 0; i < sortFields.length; i++)
98         {
99             JRSortField sortField = sortFields[i];
100             sortIndexes[i] = ((Integer JavaDoc)fieldIndexMap.get(sortField.getName())).intValue();
101             sortOrders[i] = (JRSortField.SORT_ORDER_ASCENDING == sortField.getOrder() ? 1 : -1);
102
103             collatorFlags[i] = false;
104             for(int j = 0; j < fields.length; j++)
105             {
106                 JRField field = fields[j];
107                 if (sortField.getName().equals(field.getName()))
108                 {
109                     //it is certain that a matching field will be found, due to verifySortFields();
110
collatorFlags[i] = String JavaDoc.class.getName().equals(field.getValueClassName());
111                     break;
112                 }
113             }
114         }
115
116         if (ds != null)
117         {
118             while(ds.next())
119             {
120                 Object JavaDoc[] record = new Object JavaDoc[fields.length];
121                 for(int i = 0; i < fields.length; i++)
122                 {
123                     record[i] = ds.getFieldValue(fields[i]);
124                 }
125                 records.add(record);
126             }
127         }
128
129         /* */
130         Collections.sort(records, new DataSourceComparator(sortIndexes, sortOrders, collatorFlags));
131         
132         iterator = records.iterator();
133     }
134
135
136     /**
137      *
138      */

139     public boolean next()
140     {
141         boolean hasNext = false;
142         
143         if (iterator != null)
144         {
145             hasNext = iterator.hasNext();
146             
147             if (hasNext)
148             {
149                 currentRecord = (Object JavaDoc[])iterator.next();
150             }
151         }
152         
153         return hasNext;
154     }
155
156
157     /**
158      *
159      */

160     public Object JavaDoc getFieldValue(JRField jrField)
161     {
162         Integer JavaDoc fieldIndex = (Integer JavaDoc)fieldIndexMap.get(jrField.getName());
163
164         if (fieldIndex == null)
165         {
166             throw new JRRuntimeException("Field \"" + jrField.getName() + "\" not found in sortable data source.");
167         }
168         
169         return currentRecord[fieldIndex.intValue()];
170     }
171
172     
173     /**
174      *
175      */

176     public void moveFirst()
177     {
178         iterator = records.iterator();
179     }
180
181
182     /**
183      *
184      */

185     public static void verifySortFields(JRField[] fields, JRSortField[] sortFields)
186     {
187         if (fields != null && sortFields != null)
188         {
189             for(int i = 0; i < sortFields.length; i++)
190             {
191                 String JavaDoc sortFieldName = sortFields[i].getName();
192                 
193                 boolean isFound = false;
194                 
195                 int j = 0;
196                 while (!isFound && j < fields.length)
197                 {
198                     isFound = sortFieldName.equals(fields[j].getName());
199                     j++;
200                 }
201                 
202                 if (!isFound)
203                 {
204                     throw new JRRuntimeException("Sort field \"" + sortFieldName + "\" not found in the list of data source fields.");
205                 }
206             }
207         }
208     }
209     
210     
211     /**
212      *
213      */

214     class DataSourceComparator implements Comparator JavaDoc
215     {
216         int[] sortIndexes = null;
217         int[] sortOrders = null;
218         boolean[] collatorFlags = null;
219         
220         public DataSourceComparator(int[] sortIndexes, int[] sortOrders, boolean[] collatorFlags)
221         {
222             this.sortIndexes = sortIndexes;
223             this.sortOrders = sortOrders;
224             this.collatorFlags = collatorFlags;
225         }
226         
227         public int compare(Object JavaDoc arg1, Object JavaDoc arg2)
228         {
229             Object JavaDoc[] record1 = (Object JavaDoc[])arg1;
230             Object JavaDoc[] record2 = (Object JavaDoc[])arg2;
231
232             int ret = 0;
233             
234             for(int i = 0; i < sortIndexes.length; i++)
235             {
236                 int sortIndex = sortIndexes[i];
237                 Comparable JavaDoc field1 = (Comparable JavaDoc)record1[sortIndex];
238                 Comparable JavaDoc field2 = (Comparable JavaDoc)record2[sortIndex];
239
240                 if (field1 == null)
241                 {
242                     ret = (field2 == null) ? 0 : -1;
243                 }
244                 else if (field2 == null)
245                 {
246                     ret = 1;
247                 }
248                 else
249                 {
250                     if (collatorFlags[i])
251                     {
252                         ret = collator.compare(field1, field2);
253                     }
254                     else
255                     {
256                         ret = field1.compareTo(field2);
257                     }
258                 }
259
260                 ret = ret * sortOrders[i];
261
262                 if (ret != 0)
263                 {
264                     return ret;
265                 }
266             }
267             
268             return ret;
269         }
270     }
271
272
273 }
274
275
276
Popular Tags