📄 rmodeldata.java
字号:
/******************************************************************************
* The contents of this file are subject to the Compiere License Version 1.1
* ("License"); You may not use this file except in compliance with the License
* You may obtain a copy of the License at http://www.compiere.org/license.html
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
* the specific language governing rights and limitations under the License.
* The Original Code is Compiere ERP & CRM Business Solution
* The Initial Developer of the Original Code is Jorg Janke and ComPiere, Inc.
* Portions created by Jorg Janke are Copyright (C) 1999-2001 Jorg Janke, parts
* created by ComPiere are Copyright (C) ComPiere, Inc.; All Rights Reserved.
* Contributor(s): ______________________________________.
*****************************************************************************/
package org.compiere.report.core;
import java.util.*;
import java.math.*;
import java.sql.*;
import org.compiere.util.*;
/**
* Report Model Data - ValueObject.
* - Build SQL from RColumn info and Retrieve Data
* - owned by RModel
*
* @author Jorg Janke
* @version $Id: RModelData.java,v 1.7 2002/08/12 01:55:12 danb Exp $
*/
class RModelData
{
/**
* Constructor. Use query method to populate data
* @param TableName
*/
public RModelData (String TableName)
{
m_TableName = TableName;
} // RModelData
/** The Rows */
public ArrayList rows = new ArrayList();
/** The temporary Rows */
private ArrayList m_rows = new ArrayList();
/** The Row MetaData */
public ArrayList rowsMeta = new ArrayList();
/** The Column Definitions */
public ArrayList cols = new ArrayList();
/** Table Name */
private String m_TableName;
/** Functions (Integer - String) */
public HashMap functions = new HashMap();
/** Groups (Integer) */
public ArrayList groups = new ArrayList();
/** Array with row numbers that are groups */
private ArrayList m_groupRows = new ArrayList();
private ArrayList m_groupRowsIndicator = null;
/** Constant 1 */
private static final BigDecimal ONE = new BigDecimal(1.0);
/**
* Dispose
*/
public void dispose()
{
rows.clear();
m_rows.clear();
rowsMeta.clear();
cols.clear();
} // dispose
/*************************************************************************/
/**
* Query
* @param ctx
* @param whereClause the SQL where clause (w/o the WHERE)
* @param orderClause
*/
public void query (Properties ctx, String whereClause, String orderClause)
{
RColumn rc = null;
// Create SQL
StringBuffer sql = new StringBuffer ("SELECT ");
int size = cols.size();
for (int i = 0; i < size; i++)
{
rc = (RColumn)cols.get(i);
if (i > 0)
sql.append(",");
sql.append(rc.getColSQL());
}
sql.append(" FROM ").append(m_TableName).append(" ").append(RModel.TABLE_ALIAS);
if (whereClause != null && whereClause.length() > 0)
sql.append(" WHERE ").append(whereClause);
String finalSQL = Access.addROAccessSQL(ctx, sql.toString(), RModel.TABLE_ALIAS, true);
if (orderClause != null && orderClause.length() > 0)
finalSQL += " ORDER BY " + orderClause;
Log.trace(Log.l6_Database, "RModelData.query SQL=" + finalSQL);
// FillData
int index = 1; // rowset index
m_rows.clear();
try
{
Statement stmt = DB.createStatement();
ResultSet rs = stmt.executeQuery(finalSQL);
while (rs.next())
{
ArrayList row = new ArrayList(size);
index = 1;
// Columns
for (int i = 0; i < size; i++)
{
rc = (RColumn)cols.get(i);
// Get ID
if (rc.isIDcol())
row.add(new KeyNamePair (rs.getInt(index++), rs.getString(index++)));
// Null check
else if (rs.getString(index) == null)
{
index++;
row.add(null);
}
else if (rc.getColClass() == String.class)
row.add(rs.getString(index++));
else if (rc.getColClass() == BigDecimal.class)
row.add(rs.getBigDecimal(index++));
else if (rc.getColClass() == Double.class)
row.add(new Double(rs.getDouble(index++)));
else if (rc.getColClass() == Integer.class)
row.add(new Integer(rs.getInt(index++)));
else if (rc.getColClass() == Timestamp.class)
row.add(rs.getTimestamp(index++));
else if (rc.getColClass() == Boolean.class)
row.add(new Boolean("Y".equals(rs.getString(index++))));
else // should not happen
{
row.add(rs.getString(index++));
}
}
m_rows.add(row);
}
rs.close();
stmt.close();
}
catch (SQLException e)
{
Log.error("RModelData.query", e);
}
process();
} // query
/**
* Process Data
* Copy data in m_rows to rows and perform functions
*/
private void process()
{
Log.trace(Log.l5_DData, "RModelData.process - Start Rows=" + m_rows.size());
// Row level Funcions
// would come here
// Group by Values
int gSize = groups.size();
int[] groupBys = new int[gSize];
Object[] groupBysValue = new Object[gSize];
Object INITVALUE = new Object();
for (int i = 0; i < gSize; i++)
{
groupBys[i] = ((Integer)groups.get(i)).intValue();
groupBysValue[i] = INITVALUE;
Log.trace(Log.l6_Database, "GroupBy level=" + i + " col=" + groupBys[i]);
}
// Add additional row to force group change
if (gSize > 0)
{
ArrayList newRow = new ArrayList();
for (int c = 0; c < cols.size(); c++)
newRow.add("");
m_rows.add(newRow);
}
// Function Values - Function - GroupValue
int fSize = functions.size();
int[] funcCols = new int[fSize];
String[] funcFuns = new String[fSize];
int index = 0;
Iterator it = functions.keySet().iterator();
while (it.hasNext())
{
Object key = it.next();
funcCols[index] = ((Integer)key).intValue();
funcFuns[index] = functions.get(key).toString();
Log.trace(Log.l6_Database, "Function " + funcFuns[index] + " col=" + funcCols[index]);
index++;
}
BigDecimal[][] funcVals = new BigDecimal [fSize][gSize+1];
int totalIndex = gSize; // place for overall total
Log.trace(Log.l6_Database, "FunctionValues = [ " + fSize + " * " + (gSize+1) + " ]");
for (int f = 0; f < fSize; f++)
for (int g = 0; g < gSize+1; g++)
funcVals[f][g] = Env.ZERO;
rows.clear();
// Copy m_rows into rows
for (int r = 0; r < m_rows.size(); r++)
{
ArrayList row = (ArrayList)m_rows.get(r);
// do we have a group break
boolean[] haveBreak = new boolean[groupBys.length];
for (int level = 0; level < groupBys.length; level ++)
{
int idx = groupBys[level];
if (groupBysValue[level] == INITVALUE)
haveBreak[level] = false;
else if (!groupBysValue[level].equals(row.get(idx)))
haveBreak[level] = true;
else
haveBreak[level] = false;
// previous level had a break
if (level > 0 && haveBreak[level-1])
haveBreak[level] = true;
}
// create group levels - reverse order
for (int level = groupBys.length-1; level >= 0; level--)
{
int idx = groupBys[level];
if (groupBysValue[level] == INITVALUE)
groupBysValue[level] = row.get(idx);
else if (haveBreak[level])
{
// Log.trace(Log.l6_Database, "GroupBy Change level=" + level + " col=" + idx + " - " + groupBysValue[level]);
// create new row
ArrayList newRow = new ArrayList();
for (int c = 0; c < cols.size(); c++)
{
if (c == idx) // the group column
{
if (groupBysValue[c] == null || groupBysValue[c].toString().length() == 0)
newRow.add("=");
else
newRow.add(groupBysValue[c]);
}
else
{
boolean found = false;
for (int fc = 0; fc < funcCols.length; fc++)
{
if (c == funcCols[fc])
{
// newRow.add("fc= " + fc + " gl=" + level + " " + funcFuns[fc]);
newRow.add(funcVals[fc][level]);
funcVals[fc][level] = Env.ZERO;
found = true;
}
}
if (!found)
newRow.add(null);
}
} // for all columns
//
m_groupRows.add(new Integer(rows.size())); // group row indicator
rows.add(newRow);
groupBysValue[level] = row.get(idx);
}
} // for all groups
// functions
for (int fc = 0; fc < funcCols.length; fc++)
{
int col = funcCols[fc];
// convert value to big decimal
Object value = row.get(col);
BigDecimal bd = Env.ZERO;
if (value == null)
;
else if (value instanceof BigDecimal)
bd = (BigDecimal)value;
else
{
try {
bd = new BigDecimal(value.toString());
} catch (Exception e) { }
}
for (int level = 0; level < gSize+1; level++)
{
if (funcFuns[fc].equals(RModel.FUNCTION_SUM))
funcVals[fc][level] = funcVals[fc][level].add(bd);
else if (funcFuns[fc].equals(RModel.FUNCTION_COUNT))
funcVals[fc][level] = funcVals[fc][level].add(ONE);
} // for all group levels
} // for all functions
rows.add(row);
} // for all m_rows
// total row
if (functions.size() > 0)
{
ArrayList newRow = new ArrayList();
for (int c = 0; c < cols.size(); c++)
{
boolean found = false;
for (int fc = 0; fc < funcCols.length; fc++)
{
if (c == funcCols[fc])
{
newRow.add(funcVals[fc][totalIndex]);
found = true;
}
}
if (!found)
newRow.add(null);
} // for all columns
// remove empty row added earlier to force group change
if (gSize > 0)
rows.remove(rows.size()-1);
m_groupRows.add(new Integer(rows.size())); // group row indicator
rows.add(newRow);
}
Log.trace(Log.l5_DData, "RModelData.process - End Rows=" + rows.size());
m_rows.clear();
} // process
/*************************************************************************/
/**
* Is Row a Group Row
* @param row row index
* @return true, if group row
*/
public boolean isGroupRow (int row)
{
// build boolean Array
if (m_groupRowsIndicator == null)
{
m_groupRowsIndicator = new ArrayList(rows.size());
for (int r = 0; r < rows.size(); r++)
m_groupRowsIndicator.add(new Boolean(m_groupRows.contains(new Integer(r))));
}
if (row < 0 || row >= m_groupRowsIndicator.size())
return false;
return ((Boolean)m_groupRowsIndicator.get(row)).booleanValue();
} // isGroupRow
/**
* Move Row
* @param from index
* @param to index
* @throws IllegalArgumentException if row index is invalid
*/
public void moveRow (int from, int to)
{
if (from < 0 || to >= rows.size())
throw new IllegalArgumentException("Row from invalid");
if (to < 0 || to >= rows.size())
throw new IllegalArgumentException("Row to invalid");
// Move Data
Object temp = rows.get(from);
rows.remove(from);
rows.add(to, temp);
// Move Description indicator >>> m_groupRows is not in sync after row move !!
if (m_groupRowsIndicator != null)
{
temp = m_groupRowsIndicator.get(from);
m_groupRowsIndicator.remove(from);
m_groupRowsIndicator.add(to, temp);
}
} // moveRow
} // RModelData
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -