1 28 package net.sf.jasperreports.engine.data; 29 30 import java.text.Collator ; 31 import java.util.ArrayList ; 32 import java.util.Collections ; 33 import java.util.Comparator ; 34 import java.util.HashMap ; 35 import java.util.Iterator ; 36 import java.util.List ; 37 import java.util.Locale ; 38 import java.util.Map ; 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 52 public class JRSortableDataSource implements JRRewindableDataSource 53 { 54 55 56 59 private List records = new ArrayList (); 60 private Iterator iterator = null; 61 private Object [] currentRecord = null; 62 private Map fieldIndexMap = new HashMap (); 63 64 protected Collator collator = null; 65 66 67 70 public JRSortableDataSource(JRDataSource ds, JRField[] fields, JRSortField[] sortFields, Locale locale) throws JRException 71 { 72 if (fields == null) 73 { 74 fields = new JRField[0]; 76 } 77 78 if (sortFields == null) 79 { 80 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 (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 )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 collatorFlags[i] = String .class.getName().equals(field.getValueClassName()); 111 break; 112 } 113 } 114 } 115 116 if (ds != null) 117 { 118 while(ds.next()) 119 { 120 Object [] record = new Object [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 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 [])iterator.next(); 150 } 151 } 152 153 return hasNext; 154 } 155 156 157 160 public Object getFieldValue(JRField jrField) 161 { 162 Integer fieldIndex = (Integer )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 176 public void moveFirst() 177 { 178 iterator = records.iterator(); 179 } 180 181 182 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 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 214 class DataSourceComparator implements Comparator 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 arg1, Object arg2) 228 { 229 Object [] record1 = (Object [])arg1; 230 Object [] record2 = (Object [])arg2; 231 232 int ret = 0; 233 234 for(int i = 0; i < sortIndexes.length; i++) 235 { 236 int sortIndex = sortIndexes[i]; 237 Comparable field1 = (Comparable )record1[sortIndex]; 238 Comparable field2 = (Comparable )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 |