1 14 package org.compiere.report.core; 15 16 import java.util.*; 17 import java.math.*; 18 import java.sql.*; 19 20 import org.compiere.util.*; 21 import org.compiere.model.MRole; 22 23 31 class RModelData 32 { 33 37 public RModelData (String TableName) 38 { 39 m_TableName = TableName; 40 } 42 43 public ArrayList rows = new ArrayList(); 44 45 private ArrayList m_rows = new ArrayList(); 46 47 48 public ArrayList rowsMeta = new ArrayList(); 49 50 public ArrayList cols = new ArrayList(); 51 52 53 54 private String m_TableName; 55 56 57 public HashMap functions = new HashMap(); 58 59 public ArrayList groups = new ArrayList(); 60 61 62 private ArrayList m_groupRows = new ArrayList(); 63 private ArrayList m_groupRowsIndicator = null; 64 65 66 private static final BigDecimal ONE = new BigDecimal(1.0); 67 68 71 public void dispose() 72 { 73 rows.clear(); 74 m_rows.clear(); 75 rowsMeta.clear(); 76 cols.clear(); 77 } 79 80 81 87 public void query (Properties ctx, String whereClause, String orderClause) 88 { 89 RColumn rc = null; 90 StringBuffer sql = new StringBuffer ("SELECT "); 92 int size = cols.size(); 93 for (int i = 0; i < size; i++) 94 { 95 rc = (RColumn)cols.get(i); 96 if (i > 0) 97 sql.append(","); 98 sql.append(rc.getColSQL()); 99 } 100 sql.append(" FROM ").append(m_TableName).append(" ").append(RModel.TABLE_ALIAS); 101 if (whereClause != null && whereClause.length() > 0) 102 sql.append(" WHERE ").append(whereClause); 103 String finalSQL = MRole.getDefault(ctx, false).addAccessSQL( 104 sql.toString(), RModel.TABLE_ALIAS, MRole.SQL_FULLYQUALIFIED, MRole.SQL_RO); 105 if (orderClause != null && orderClause.length() > 0) 106 finalSQL += " ORDER BY " + orderClause; 107 Log.trace(Log.l6_Database, "RModelData.query SQL=" + finalSQL); 108 109 int index = 1; m_rows.clear(); 112 try 113 { 114 Statement stmt = DB.createStatement(); 115 ResultSet rs = stmt.executeQuery(finalSQL); 116 while (rs.next()) 117 { 118 ArrayList row = new ArrayList(size); 119 index = 1; 120 for (int i = 0; i < size; i++) 122 { 123 rc = (RColumn)cols.get(i); 124 if (rc.isIDcol()) 126 row.add(new KeyNamePair (rs.getInt(index++), rs.getString(index++))); 127 else if (rs.getString(index) == null) 129 { 130 index++; 131 row.add(null); 132 } 133 else if (rc.getColClass() == String .class) 134 row.add(rs.getString(index++)); 135 else if (rc.getColClass() == BigDecimal.class) 136 row.add(rs.getBigDecimal(index++)); 137 else if (rc.getColClass() == Double .class) 138 row.add(new Double (rs.getDouble(index++))); 139 else if (rc.getColClass() == Integer .class) 140 row.add(new Integer (rs.getInt(index++))); 141 else if (rc.getColClass() == Timestamp.class) 142 row.add(rs.getTimestamp(index++)); 143 else if (rc.getColClass() == Boolean .class) 144 row.add(new Boolean ("Y".equals(rs.getString(index++)))); 145 else { 147 row.add(rs.getString(index++)); 148 } 149 } 150 m_rows.add(row); 151 } 152 rs.close(); 153 stmt.close(); 154 } 155 catch (SQLException e) 156 { 157 Log.error("RModelData.query", e); 158 } 159 process(); 160 } 162 166 private void process() 167 { 168 Log.trace(Log.l5_DData, "RModelData.process - Start Rows=" + m_rows.size()); 169 170 173 int gSize = groups.size(); 175 int[] groupBys = new int[gSize]; 176 Object [] groupBysValue = new Object [gSize]; 177 Object INITVALUE = new Object (); 178 for (int i = 0; i < gSize; i++) 179 { 180 groupBys[i] = ((Integer )groups.get(i)).intValue(); 181 groupBysValue[i] = INITVALUE; 182 Log.trace(Log.l6_Database, "GroupBy level=" + i + " col=" + groupBys[i]); 183 } 184 if (gSize > 0) 186 { 187 ArrayList newRow = new ArrayList(); 188 for (int c = 0; c < cols.size(); c++) 189 newRow.add(""); 190 m_rows.add(newRow); 191 } 192 193 int fSize = functions.size(); 195 int[] funcCols = new int[fSize]; 196 String [] funcFuns = new String [fSize]; 197 int index = 0; 198 Iterator it = functions.keySet().iterator(); 199 while (it.hasNext()) 200 { 201 Object key = it.next(); 202 funcCols[index] = ((Integer )key).intValue(); 203 funcFuns[index] = functions.get(key).toString(); 204 Log.trace(Log.l6_Database, "Function " + funcFuns[index] + " col=" + funcCols[index]); 205 index++; 206 } 207 BigDecimal[][] funcVals = new BigDecimal [fSize][gSize+1]; 208 int totalIndex = gSize; Log.trace(Log.l6_Database, "FunctionValues = [ " + fSize + " * " + (gSize+1) + " ]"); 210 for (int f = 0; f < fSize; f++) 211 for (int g = 0; g < gSize+1; g++) 212 funcVals[f][g] = Env.ZERO; 213 214 rows.clear(); 215 for (int r = 0; r < m_rows.size(); r++) 217 { 218 ArrayList row = (ArrayList)m_rows.get(r); 219 boolean[] haveBreak = new boolean[groupBys.length]; 221 for (int level = 0; level < groupBys.length; level ++) 222 { 223 int idx = groupBys[level]; 224 if (groupBysValue[level] == INITVALUE) 225 haveBreak[level] = false; 226 else if (!groupBysValue[level].equals(row.get(idx))) 227 haveBreak[level] = true; 228 else 229 haveBreak[level] = false; 230 if (level > 0 && haveBreak[level-1]) 232 haveBreak[level] = true; 233 } 234 for (int level = groupBys.length-1; level >= 0; level--) 236 { 237 int idx = groupBys[level]; 238 if (groupBysValue[level] == INITVALUE) 239 groupBysValue[level] = row.get(idx); 240 else if (haveBreak[level]) 241 { 242 ArrayList newRow = new ArrayList(); 245 for (int c = 0; c < cols.size(); c++) 246 { 247 if (c == idx) { 249 if (groupBysValue[c] == null || groupBysValue[c].toString().length() == 0) 250 newRow.add("="); 251 else 252 newRow.add(groupBysValue[c]); 253 } 254 else 255 { 256 boolean found = false; 257 for (int fc = 0; fc < funcCols.length; fc++) 258 { 259 if (c == funcCols[fc]) 260 { 261 newRow.add(funcVals[fc][level]); 263 funcVals[fc][level] = Env.ZERO; 264 found = true; 265 } 266 } 267 if (!found) 268 newRow.add(null); 269 } 270 } m_groupRows.add(new Integer (rows.size())); rows.add(newRow); 274 groupBysValue[level] = row.get(idx); 275 } 276 } 278 for (int fc = 0; fc < funcCols.length; fc++) 280 { 281 int col = funcCols[fc]; 282 Object value = row.get(col); 284 BigDecimal bd = Env.ZERO; 285 if (value == null) 286 ; 287 else if (value instanceof BigDecimal) 288 bd = (BigDecimal)value; 289 else 290 { 291 try { 292 bd = new BigDecimal(value.toString()); 293 } catch (Exception e) { } 294 } 295 296 for (int level = 0; level < gSize+1; level++) 297 { 298 if (funcFuns[fc].equals(RModel.FUNCTION_SUM)) 299 funcVals[fc][level] = funcVals[fc][level].add(bd); 300 else if (funcFuns[fc].equals(RModel.FUNCTION_COUNT)) 301 funcVals[fc][level] = funcVals[fc][level].add(ONE); 302 } } 305 rows.add(row); 306 } 308 if (functions.size() > 0) 310 { 311 ArrayList newRow = new ArrayList(); 312 for (int c = 0; c < cols.size(); c++) 313 { 314 boolean found = false; 315 for (int fc = 0; fc < funcCols.length; fc++) 316 { 317 if (c == funcCols[fc]) 318 { 319 newRow.add(funcVals[fc][totalIndex]); 320 found = true; 321 } 322 } 323 if (!found) 324 newRow.add(null); 325 } if (gSize > 0) 328 rows.remove(rows.size()-1); 329 m_groupRows.add(new Integer (rows.size())); rows.add(newRow); 331 } 332 Log.trace(Log.l5_DData, "RModelData.process - End Rows=" + rows.size()); 333 m_rows.clear(); 334 } 336 337 338 343 public boolean isGroupRow (int row) 344 { 345 if (m_groupRowsIndicator == null) 347 { 348 m_groupRowsIndicator = new ArrayList(rows.size()); 349 for (int r = 0; r < rows.size(); r++) 350 m_groupRowsIndicator.add(new Boolean (m_groupRows.contains(new Integer (r)))); 351 } 352 if (row < 0 || row >= m_groupRowsIndicator.size()) 353 return false; 354 return ((Boolean )m_groupRowsIndicator.get(row)).booleanValue(); 355 } 357 363 public void moveRow (int from, int to) 364 { 365 if (from < 0 || to >= rows.size()) 366 throw new IllegalArgumentException ("Row from invalid"); 367 if (to < 0 || to >= rows.size()) 368 throw new IllegalArgumentException ("Row to invalid"); 369 Object temp = rows.get(from); 371 rows.remove(from); 372 rows.add(to, temp); 373 if (m_groupRowsIndicator != null) 375 { 376 temp = m_groupRowsIndicator.get(from); 377 m_groupRowsIndicator.remove(from); 378 m_groupRowsIndicator.add(to, temp); 379 } 380 } 382 } | Popular Tags |