1 28 package net.sf.jasperreports.engine.data; 29 30 import java.util.HashMap ; 31 import java.util.Map ; 32 33 import net.sf.jasperreports.engine.JRDataSource; 34 import net.sf.jasperreports.engine.JRException; 35 import net.sf.jasperreports.engine.JRField; 36 import net.sf.jasperreports.engine.JRRuntimeException; 37 import net.sf.jasperreports.engine.query.JRHibernateQueryExecuter; 38 39 import org.apache.commons.beanutils.PropertyUtils; 40 import org.hibernate.type.Type; 41 42 48 public abstract class JRHibernateAbstractDataSource implements JRDataSource 49 { 50 private final boolean useFieldDescription; 51 private final Map fieldReaders; 52 protected final JRHibernateQueryExecuter queryExecuter; 53 private Object currentReturnValue; 54 55 56 63 protected JRHibernateAbstractDataSource(JRHibernateQueryExecuter queryExecuter, boolean useFieldDescription, boolean useIndexOnSingleReturn) 64 { 65 this.useFieldDescription = useFieldDescription; 66 67 this.queryExecuter = queryExecuter; 68 69 fieldReaders = assignReaders(useIndexOnSingleReturn); 70 } 71 72 79 protected Map assignReaders(boolean useIndexOnSingleReturn) 80 { 81 Map readers = new HashMap (); 82 83 JRField[] fields = queryExecuter.getDataset().getFields(); 84 Type[] returnTypes = queryExecuter.getReturnTypes(); 85 String [] aliases = queryExecuter.getReturnAliases(); 86 87 Map aliasesMap = new HashMap (); 88 if (aliases != null) 89 { 90 for (int i = 0; i < aliases.length; i++) 91 { 92 aliasesMap.put(aliases[i], new Integer (i)); 93 } 94 } 95 96 if (returnTypes.length == 1) 97 { 98 if (returnTypes[0].isEntityType() || returnTypes[0].isComponentType()) 99 { 100 for (int i = 0; i < fields.length; i++) 101 { 102 JRField field = fields[i]; 103 readers.put(field.getName(), getFieldReaderSingleReturn(aliasesMap, field, useIndexOnSingleReturn)); 104 } 105 } 106 else 107 { 108 if (fields.length > 1) 109 { 110 throw new JRRuntimeException("The HQL query returns only one non-entity and non-component result but there are more than one fields."); 111 } 112 113 if (fields.length == 1) 114 { 115 JRField field = fields[0]; 116 if (useIndexOnSingleReturn) 117 { 118 readers.put(field.getName(), new IndexFieldReader(0)); 119 } 120 else 121 { 122 readers.put(field.getName(), new IdentityFieldReader()); 123 } 124 } 125 } 126 } 127 else 128 { 129 for (int i = 0; i < fields.length; i++) 130 { 131 JRField field = fields[i]; 132 readers.put(field.getName(), getFieldReader(returnTypes, aliasesMap, field)); 133 } 134 } 135 136 return readers; 137 } 138 139 protected FieldReader getFieldReaderSingleReturn(Map aliasesMap, JRField field, boolean useIndex) 140 { 141 FieldReader reader; 142 143 String fieldMapping = getFieldMapping(field); 144 if (aliasesMap.containsKey(fieldMapping)) 145 { 146 if (useIndex) 147 { 148 reader = new IndexFieldReader(0); 149 } 150 else 151 { 152 reader = new IdentityFieldReader(); 153 } 154 } 155 else 156 { 157 int firstNestedIdx = fieldMapping.indexOf(PropertyUtils.NESTED_DELIM); 158 159 if (firstNestedIdx >= 0 && aliasesMap.containsKey(fieldMapping.substring(0, firstNestedIdx))) 160 { 161 fieldMapping = fieldMapping.substring(firstNestedIdx + 1); 162 } 163 164 if (useIndex) 165 { 166 reader = new IndexPropertyFieldReader(0, fieldMapping); 167 } 168 else 169 { 170 reader = new PropertyFieldReader(fieldMapping); 171 } 172 } 173 174 return reader; 175 } 176 177 protected FieldReader getFieldReader(Type[] returnTypes, Map aliasesMap, JRField field) 178 { 179 FieldReader reader; 180 181 String fieldMapping = getFieldMapping(field); 182 Integer fieldIdx = (Integer ) aliasesMap.get(fieldMapping); 183 if (fieldIdx == null) 184 { 185 int firstNestedIdx = fieldMapping.indexOf(PropertyUtils.NESTED_DELIM); 186 187 if (firstNestedIdx < 0) 188 { 189 throw new JRRuntimeException("Unknown HQL return alias \"" + fieldMapping + "\"."); 190 } 191 192 String fieldAlias = fieldMapping.substring(0, firstNestedIdx); 193 String fieldProperty = fieldMapping.substring(firstNestedIdx + 1); 194 195 fieldIdx = (Integer ) aliasesMap.get(fieldAlias); 196 if (fieldIdx == null) 197 { 198 throw new JRRuntimeException("The HQL query does not have a \"" + fieldAlias + "\" alias."); 199 } 200 201 Type type = returnTypes[fieldIdx.intValue()]; 202 if (!type.isEntityType() && !type.isComponentType()) 203 { 204 throw new JRRuntimeException("The HQL query does not have a \"" + fieldAlias + "\" alias."); 205 } 206 207 reader = new IndexPropertyFieldReader(fieldIdx.intValue(), fieldProperty); 208 } 209 else 210 { 211 reader = new IndexFieldReader(fieldIdx.intValue()); 212 } 213 214 return reader; 215 } 216 217 218 223 protected void setCurrentRowValue(Object currentReturnValue) 224 { 225 this.currentReturnValue = currentReturnValue; 226 } 227 228 229 public Object getFieldValue(JRField jrField) throws JRException 230 { 231 FieldReader reader = (FieldReader) fieldReaders.get(jrField.getName()); 232 if (reader == null) 233 { 234 throw new JRRuntimeException("No filed reader for " + jrField.getName()); 235 } 236 return reader.getFieldValue(currentReturnValue); 237 } 238 239 240 protected String getFieldMapping(JRField field) 241 { 242 return (useFieldDescription ? 243 JRAbstractBeanDataSource.FIELD_DESCRIPTION_PROPERTY_NAME_PROVIDER : 244 JRAbstractBeanDataSource.FIELD_NAME_PROPERTY_NAME_PROVIDER) 245 .getPropertyName(field); 246 } 247 248 249 252 protected static interface FieldReader 253 { 254 Object getFieldValue(Object resultValue) throws JRException; 255 } 256 257 protected static class IdentityFieldReader implements FieldReader 258 { 259 public Object getFieldValue(Object resultValue) 260 { 261 return resultValue; 262 } 263 } 264 265 protected static class IndexFieldReader implements FieldReader 266 { 267 private final int idx; 268 269 protected IndexFieldReader(int idx) 270 { 271 this.idx = idx; 272 } 273 274 public Object getFieldValue(Object resultValue) 275 { 276 return ((Object []) resultValue)[idx]; 277 } 278 } 279 280 protected static class PropertyFieldReader implements FieldReader 281 { 282 private final String property; 283 284 protected PropertyFieldReader(String property) 285 { 286 this.property = property; 287 } 288 289 public Object getFieldValue(Object resultValue) throws JRException 290 { 291 return JRAbstractBeanDataSource.getBeanProperty(resultValue, property); 292 } 293 } 294 295 protected static class IndexPropertyFieldReader implements FieldReader 296 { 297 private final int idx; 298 private final String property; 299 300 protected IndexPropertyFieldReader(int idx, String property) 301 { 302 this.idx = idx; 303 this.property = property; 304 } 305 306 public Object getFieldValue(Object resultValue) throws JRException 307 { 308 return JRAbstractBeanDataSource.getBeanProperty(((Object []) resultValue)[idx], property); 309 } 310 } 311 } 312 | Popular Tags |