Files
HRMS/hrmsEjb/net/sf/jasperreports/engine/fill/JRFillDataset.java
2025-07-28 13:56:49 +05:30

654 lines
24 KiB
Java

package net.sf.jasperreports.engine.fill;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.TimeZone;
import net.sf.jasperreports.engine.JRAbstractScriptlet;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRDataset;
import net.sf.jasperreports.engine.JRDefaultScriptlet;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRExpression;
import net.sf.jasperreports.engine.JRField;
import net.sf.jasperreports.engine.JRGroup;
import net.sf.jasperreports.engine.JRParameter;
import net.sf.jasperreports.engine.JRPropertiesHolder;
import net.sf.jasperreports.engine.JRPropertiesMap;
import net.sf.jasperreports.engine.JRQuery;
import net.sf.jasperreports.engine.JRRuntimeException;
import net.sf.jasperreports.engine.JRSortField;
import net.sf.jasperreports.engine.JRVariable;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRSortableDataSource;
import net.sf.jasperreports.engine.design.JRDesignVariable;
import net.sf.jasperreports.engine.query.JRQueryExecuter;
import net.sf.jasperreports.engine.query.JRQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRClassLoader;
import net.sf.jasperreports.engine.util.JRQueryExecuterUtils;
import net.sf.jasperreports.engine.util.JRResourcesUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class JRFillDataset implements JRDataset {
private static final Log log = LogFactory.getLog(JRFillDataset.class);
private final JRBaseFiller filler;
private final JRDataset parent;
private final boolean isMain;
protected JRQuery query = null;
private boolean useDatasourceParamValue = false;
private boolean useConnectionParamValue = false;
protected JRFillParameter[] parameters = null;
protected Map parametersMap = null;
protected JRFillField[] fields = null;
protected Map fieldsMap = null;
protected JRFillVariable[] variables = null;
protected Map variablesMap = null;
protected Set variableCalculationReqs;
protected JRFillElementDataset[] elementDatasets;
protected JRFillElementDataset[] origElementDatasets;
protected JRFillGroup[] groups = null;
protected String resourceBundleBaseName = null;
protected byte whenResourceMissingType;
protected String scriptletClassName = null;
protected JRDataSource dataSource = null;
protected Locale locale = null;
protected ResourceBundle resourceBundle = null;
protected TimeZone timeZone = null;
protected int reportCount = 0;
protected JRCalculator calculator = null;
protected JRAbstractScriptlet scriptlet = null;
protected Integer reportMaxCount = null;
private JRQueryExecuter queryExecuter;
protected JRFillDataset(JRBaseFiller filler, JRDataset dataset, JRFillObjectFactory factory) {
factory.put(dataset, this);
this.filler = filler;
this.parent = dataset;
this.isMain = dataset.isMainDataset();
this.scriptletClassName = dataset.getScriptletClass();
this.resourceBundleBaseName = dataset.getResourceBundle();
this.whenResourceMissingType = dataset.getWhenResourceMissingType();
this.query = dataset.getQuery();
setParameters(dataset, factory);
setFields(dataset, factory);
setVariables(dataset, factory);
setGroups(dataset, factory);
}
private void setParameters(JRDataset dataset, JRFillObjectFactory factory) {
JRParameter[] jrParameters = dataset.getParameters();
if (jrParameters != null && jrParameters.length > 0) {
this.parameters = new JRFillParameter[jrParameters.length];
this.parametersMap = new HashMap();
for (int i = 0; i < this.parameters.length; i++) {
this.parameters[i] = factory.getParameter(jrParameters[i]);
this.parametersMap.put(this.parameters[i].getName(), this.parameters[i]);
}
}
}
private void setGroups(JRDataset dataset, JRFillObjectFactory factory) {
JRGroup[] jrGroups = dataset.getGroups();
if (jrGroups != null && jrGroups.length > 0) {
this.groups = new JRFillGroup[jrGroups.length];
for (int i = 0; i < this.groups.length; i++)
this.groups[i] = factory.getGroup(jrGroups[i]);
}
}
private void setVariables(JRDataset dataset, JRFillObjectFactory factory) {
JRVariable[] jrVariables = dataset.getVariables();
if (jrVariables != null && jrVariables.length > 0) {
List variableList = new ArrayList(jrVariables.length * 3);
this.variablesMap = new HashMap();
for (int i = 0; i < jrVariables.length; i++)
addVariable(jrVariables[i], variableList, factory);
setVariables(variableList);
}
}
private JRFillVariable addVariable(JRVariable parentVariable, List variableList, JRFillObjectFactory factory) {
JRVariable jRVariable1, varianceVar, countVar;
JRFillVariable jRFillVariable1, fillVarianceVar, fillCountVar;
JRVariable sumVar;
JRFillVariable fillSumVar, variable = factory.getVariable(parentVariable);
byte calculation = variable.getCalculation();
switch (calculation) {
case 3:
case 7:
jRVariable1 = createHelperVariable(parentVariable, "_COUNT", (byte)1);
jRFillVariable1 = addVariable(jRVariable1, variableList, factory);
variable.setHelperVariable(jRFillVariable1, (byte)0);
sumVar = createHelperVariable(parentVariable, "_SUM", (byte)2);
fillSumVar = addVariable(sumVar, variableList, factory);
variable.setHelperVariable(fillSumVar, (byte)1);
break;
case 6:
varianceVar = createHelperVariable(parentVariable, "_VARIANCE", (byte)7);
fillVarianceVar = addVariable(varianceVar, variableList, factory);
variable.setHelperVariable(fillVarianceVar, (byte)2);
break;
case 10:
countVar = createDistinctCountHelperVariable(parentVariable);
fillCountVar = addVariable(countVar, variableList, factory);
variable.setHelperVariable(fillCountVar, (byte)0);
break;
}
variableList.add(variable);
return variable;
}
private JRVariable createHelperVariable(JRVariable variable, String nameSuffix, byte calculation) {
JRDesignVariable helper = new JRDesignVariable();
helper.setName(variable.getName() + nameSuffix);
helper.setValueClassName(variable.getValueClassName());
helper.setIncrementerFactoryClassName(variable.getIncrementerFactoryClassName());
helper.setResetType(variable.getResetType());
helper.setResetGroup(variable.getResetGroup());
helper.setIncrementType(variable.getIncrementType());
helper.setIncrementGroup(variable.getIncrementGroup());
helper.setCalculation(calculation);
helper.setSystemDefined(true);
helper.setExpression(variable.getExpression());
return (JRVariable)helper;
}
private JRVariable createDistinctCountHelperVariable(JRVariable variable) {
JRDesignVariable helper = new JRDesignVariable();
helper.setName(variable.getName() + "_DISTINCT_COUNT");
helper.setValueClassName(variable.getValueClassName());
helper.setIncrementerFactoryClassName(JRDistinctCountIncrementerFactory.class.getName());
helper.setResetType((byte)1);
if (variable.getIncrementType() != 5)
helper.setResetType(variable.getIncrementType());
helper.setResetGroup(variable.getIncrementGroup());
helper.setCalculation((byte)0);
helper.setSystemDefined(true);
helper.setExpression(variable.getExpression());
return (JRVariable)helper;
}
private void setVariables(List variableList) {
this.variables = new JRFillVariable[variableList.size()];
this.variables = (JRFillVariable[])variableList.toArray((Object[])this.variables);
for (int i = 0; i < this.variables.length; i++)
this.variablesMap.put(this.variables[i].getName(), this.variables[i]);
}
private void setFields(JRDataset dataset, JRFillObjectFactory factory) {
JRField[] jrFields = dataset.getFields();
if (jrFields != null && jrFields.length > 0) {
this.fields = new JRFillField[jrFields.length];
this.fieldsMap = new HashMap();
for (int i = 0; i < this.fields.length; i++) {
this.fields[i] = factory.getField(jrFields[i]);
this.fieldsMap.put(this.fields[i].getName(), this.fields[i]);
}
}
}
protected void createCalculator(JasperReport jasperReport) throws JRException {
setCalculator(createCalculator(jasperReport, this));
}
protected void setCalculator(JRCalculator calculator) {
this.calculator = calculator;
}
protected static JRCalculator createCalculator(JasperReport jasperReport, JRDataset dataset) throws JRException {
JREvaluator evaluator = JasperCompileManager.loadEvaluator(jasperReport, dataset);
return new JRCalculator(evaluator);
}
protected void initCalculator() throws JRException {
this.calculator.init(this);
}
protected void inheritFromMain() {
if (this.resourceBundleBaseName == null && !this.isMain) {
this.resourceBundleBaseName = this.filler.mainDataset.resourceBundleBaseName;
this.whenResourceMissingType = this.filler.mainDataset.whenResourceMissingType;
}
}
protected JRAbstractScriptlet createScriptlet() throws JRException {
JRDefaultScriptlet jRDefaultScriptlet;
JRAbstractScriptlet tmpScriptlet = null;
if (this.scriptletClassName != null) {
try {
Class scriptletClass = JRClassLoader.loadClassForName(this.scriptletClassName);
tmpScriptlet = scriptletClass.newInstance();
} catch (ClassNotFoundException e) {
throw new JRException("Error loading scriptlet class : " + this.scriptletClassName, e);
} catch (Exception e) {
throw new JRException("Error creating scriptlet class instance : " + this.scriptletClassName, e);
}
} else {
jRDefaultScriptlet = new JRDefaultScriptlet();
}
return (JRAbstractScriptlet)jRDefaultScriptlet;
}
protected void initElementDatasets(JRFillObjectFactory factory) {
this.elementDatasets = factory.getElementDatasets(this);
}
protected void filterElementDatasets(JRFillElementDataset elementDataset) {
this.origElementDatasets = this.elementDatasets;
this.elementDatasets = new JRFillElementDataset[] { elementDataset };
}
protected void restoreElementDatasets() {
if (this.origElementDatasets != null) {
this.elementDatasets = this.origElementDatasets;
this.origElementDatasets = null;
}
}
protected ResourceBundle loadResourceBundle() {
ResourceBundle loadedBundle;
if (this.resourceBundleBaseName == null) {
loadedBundle = null;
} else {
loadedBundle = JRResourcesUtil.loadResourceBundle(this.resourceBundleBaseName, this.locale);
}
return loadedBundle;
}
protected void setParameterValues(Map parameterValues) throws JRException {
parameterValues.put("REPORT_PARAMETERS_MAP", parameterValues);
this.reportMaxCount = (Integer)parameterValues.get("REPORT_MAX_COUNT");
this.locale = (Locale)parameterValues.get("REPORT_LOCALE");
if (this.locale == null) {
this.locale = Locale.getDefault();
parameterValues.put("REPORT_LOCALE", this.locale);
}
this.resourceBundle = (ResourceBundle)parameterValues.get("REPORT_RESOURCE_BUNDLE");
if (this.resourceBundle == null) {
this.resourceBundle = loadResourceBundle();
if (this.resourceBundle != null)
parameterValues.put("REPORT_RESOURCE_BUNDLE", this.resourceBundle);
}
this.timeZone = (TimeZone)parameterValues.get("REPORT_TIME_ZONE");
if (this.timeZone == null) {
this.timeZone = TimeZone.getDefault();
parameterValues.put("REPORT_TIME_ZONE", this.timeZone);
}
this.scriptlet = (JRAbstractScriptlet)parameterValues.get("REPORT_SCRIPTLET");
if (this.scriptlet == null) {
this.scriptlet = createScriptlet();
parameterValues.put("REPORT_SCRIPTLET", this.scriptlet);
}
this.scriptlet.setData(this.parametersMap, this.fieldsMap, this.variablesMap, this.groups);
setFillParameterValues(parameterValues);
}
protected void initDatasource() throws JRException {
this.queryExecuter = null;
this.dataSource = (JRDataSource)getParameterValue("REPORT_DATA_SOURCE");
if (!this.useDatasourceParamValue && (this.useConnectionParamValue || this.dataSource == null)) {
this.dataSource = createQueryDatasource();
setParameter("REPORT_DATA_SOURCE", this.dataSource);
}
JRSortField[] sortFields = getSortFields();
if (sortFields != null && sortFields.length > 0) {
this.dataSource = (JRDataSource)new JRSortableDataSource(this.dataSource, (JRField[])this.fields, sortFields, this.locale);
setParameter("REPORT_DATA_SOURCE", this.dataSource);
}
}
private void setFillParameterValues(Map parameterValues) throws JRException {
if (this.parameters != null && this.parameters.length > 0)
for (int i = 0; i < this.parameters.length; i++) {
Object value = null;
if (parameterValues.containsKey(this.parameters[i].getName())) {
value = parameterValues.get(this.parameters[i].getName());
} else if (!this.parameters[i].isSystemDefined()) {
value = this.calculator.evaluate(this.parameters[i].getDefaultValueExpression(), (byte)3);
if (value != null)
parameterValues.put(this.parameters[i].getName(), value);
}
setParameter(this.parameters[i], value);
}
}
private JRDataSource createQueryDatasource() throws JRException {
if (this.query == null)
return null;
try {
if (log.isDebugEnabled())
log.debug("Fill " + this.filler.fillerId + ": Creating " + this.query.getLanguage() + " query executer");
JRQueryExecuterFactory queryExecuterFactory = JRQueryExecuterUtils.getQueryExecuterFactory(this.query.getLanguage());
this.queryExecuter = queryExecuterFactory.createQueryExecuter(this.parent, this.parametersMap);
this.filler.fillContext.setRunningQueryExecuter(this.queryExecuter);
return this.queryExecuter.createDatasource();
} finally {
this.filler.fillContext.clearRunningQueryExecuter();
}
}
protected void reset() {
this.useDatasourceParamValue = false;
this.useConnectionParamValue = false;
}
protected void setDatasourceParameterValue(Map parameterValues, JRDataSource ds) {
this.useDatasourceParamValue = true;
if (ds != null)
parameterValues.put("REPORT_DATA_SOURCE", ds);
}
protected void setConnectionParameterValue(Map parameterValues, Connection conn) {
this.useConnectionParamValue = true;
if (conn != null)
parameterValues.put("REPORT_CONNECTION", conn);
}
protected void closeDatasource() {
if (this.queryExecuter != null) {
if (log.isDebugEnabled())
log.debug("Fill " + this.filler.fillerId + ": closing query executer");
this.queryExecuter.close();
this.queryExecuter = null;
}
reset();
}
protected void start() {
this.reportCount = 0;
}
protected boolean next() throws JRException {
boolean hasNext = false;
if (this.dataSource != null) {
boolean includeRow = true;
JRExpression filterExpression = getFilterExpression();
do {
hasNext = advanceDataSource();
if (!hasNext)
continue;
setOldValues();
this.calculator.estimateVariables();
if (filterExpression != null) {
Boolean filterExprResult = (Boolean)this.calculator.evaluate(filterExpression, (byte)2);
includeRow = (filterExprResult != null && filterExprResult.booleanValue());
}
if (includeRow)
continue;
revertToOldValues();
} while (hasNext && !includeRow);
if (hasNext)
this.reportCount++;
}
return hasNext;
}
protected void setOldValues() throws JRException {
if (this.fields != null && this.fields.length > 0)
for (int i = 0; i < this.fields.length; i++) {
JRFillField field = this.fields[i];
field.setPreviousOldValue(field.getOldValue());
field.setOldValue(field.getValue());
field.setValue(this.dataSource.getFieldValue(field));
}
if (this.variables != null && this.variables.length > 0)
for (int i = 0; i < this.variables.length; i++) {
JRFillVariable variable = this.variables[i];
variable.setPreviousOldValue(variable.getOldValue());
variable.setOldValue(variable.getValue());
}
}
protected void revertToOldValues() {
if (this.fields != null && this.fields.length > 0)
for (int i = 0; i < this.fields.length; i++) {
JRFillField field = this.fields[i];
field.setValue(field.getOldValue());
field.setOldValue(field.getPreviousOldValue());
}
if (this.variables != null && this.variables.length > 0)
for (int i = 0; i < this.variables.length; i++) {
JRFillVariable variable = this.variables[i];
variable.setValue(variable.getOldValue());
variable.setOldValue(variable.getPreviousOldValue());
}
}
protected boolean advanceDataSource() throws JRException {
boolean hasNext = ((this.reportMaxCount == null || this.reportMaxCount.intValue() > this.reportCount) && this.dataSource.next());
return hasNext;
}
protected void setParameter(String parameterName, Object value) throws JRException {
JRFillParameter parameter = (JRFillParameter)this.parametersMap.get(parameterName);
if (parameter != null)
setParameter(parameter, value);
}
protected void setParameter(JRFillParameter parameter, Object value) throws JRException {
if (value != null) {
if (parameter.getValueClass().isInstance(value)) {
parameter.setValue(value);
} else {
throw new JRException("Incompatible " + value.getClass().getName() + " value assigned to parameter " + parameter.getName() + " in the " + getName() + " dataset.");
}
} else {
parameter.setValue(value);
}
}
public Object getVariableValue(String variableName) {
JRFillVariable var = (JRFillVariable)this.variablesMap.get(variableName);
if (var == null)
throw new JRRuntimeException("No such variable " + variableName);
return var.getValue();
}
public Object getParameterValue(String parameterName) {
return getParameterValue(parameterName, false);
}
public Object getParameterValue(String parameterName, boolean ignoreMissing) {
Object value;
JRFillParameter param = (JRFillParameter)this.parametersMap.get(parameterName);
if (param == null) {
if (!ignoreMissing)
throw new JRRuntimeException("No such parameter " + parameterName);
value = null;
} else {
value = param.getValue();
}
return value;
}
public Object getFieldValue(String fieldName) {
JRFillField var = (JRFillField)this.fieldsMap.get(fieldName);
if (var == null)
throw new JRRuntimeException("No such field " + fieldName);
return var.getValue();
}
protected static class VariableCalculationReq {
String variableName;
byte calculation;
VariableCalculationReq(String variableName, byte calculation) {
this.variableName = variableName;
this.calculation = calculation;
}
public boolean equals(Object o) {
if (o == null || !(o instanceof VariableCalculationReq))
return false;
VariableCalculationReq r = (VariableCalculationReq)o;
return (this.variableName.equals(r.variableName) && this.calculation == r.calculation);
}
public int hashCode() {
return 31 * this.calculation + this.variableName.hashCode();
}
}
protected void addVariableCalculationReq(String variableName, byte calculation) {
if (this.variableCalculationReqs == null)
this.variableCalculationReqs = new HashSet();
this.variableCalculationReqs.add(new VariableCalculationReq(variableName, calculation));
}
protected void checkVariableCalculationReqs(JRFillObjectFactory factory) {
if (this.variableCalculationReqs != null && !this.variableCalculationReqs.isEmpty()) {
List variableList = new ArrayList(this.variables.length * 2);
for (int i = 0; i < this.variables.length; i++) {
JRFillVariable variable = this.variables[i];
checkVariableCalculationReq(variable, variableList, factory);
}
setVariables(variableList);
}
}
private void checkVariableCalculationReq(JRFillVariable variable, List variableList, JRFillObjectFactory factory) {
if (hasVariableCalculationReq(variable, (byte)3) || hasVariableCalculationReq(variable, (byte)7)) {
if (variable.getHelperVariable((byte)0) == null) {
JRVariable countVar = createHelperVariable(variable, "_COUNT", (byte)1);
JRFillVariable fillCountVar = factory.getVariable(countVar);
checkVariableCalculationReq(fillCountVar, variableList, factory);
variable.setHelperVariable(fillCountVar, (byte)0);
}
if (variable.getHelperVariable((byte)1) == null) {
JRVariable sumVar = createHelperVariable(variable, "_SUM", (byte)2);
JRFillVariable fillSumVar = factory.getVariable(sumVar);
checkVariableCalculationReq(fillSumVar, variableList, factory);
variable.setHelperVariable(fillSumVar, (byte)1);
}
}
if (hasVariableCalculationReq(variable, (byte)6))
if (variable.getHelperVariable((byte)2) == null) {
JRVariable varianceVar = createHelperVariable(variable, "_VARIANCE", (byte)7);
JRFillVariable fillVarianceVar = factory.getVariable(varianceVar);
checkVariableCalculationReq(fillVarianceVar, variableList, factory);
variable.setHelperVariable(fillVarianceVar, (byte)2);
}
if (hasVariableCalculationReq(variable, (byte)10))
if (variable.getHelperVariable((byte)0) == null) {
JRVariable countVar = createDistinctCountHelperVariable(variable);
JRFillVariable fillCountVar = factory.getVariable(countVar);
checkVariableCalculationReq(fillCountVar, variableList, factory);
variable.setHelperVariable(fillCountVar, (byte)0);
}
variableList.add(variable);
}
private boolean hasVariableCalculationReq(JRVariable var, byte calculation) {
return this.variableCalculationReqs.contains(new VariableCalculationReq(var.getName(), calculation));
}
public String getName() {
return this.parent.getName();
}
public String getScriptletClass() {
return this.parent.getScriptletClass();
}
public JRParameter[] getParameters() {
return (JRParameter[])this.parameters;
}
public Map getParametersMap() {
return this.parametersMap;
}
public JRQuery getQuery() {
return this.query;
}
public JRField[] getFields() {
return (JRField[])this.fields;
}
public JRSortField[] getSortFields() {
return this.parent.getSortFields();
}
public JRVariable[] getVariables() {
return (JRVariable[])this.variables;
}
public JRGroup[] getGroups() {
return (JRGroup[])this.groups;
}
public boolean isMainDataset() {
return this.isMain;
}
public String getResourceBundle() {
return this.parent.getResourceBundle();
}
public byte getWhenResourceMissingType() {
return this.whenResourceMissingType;
}
public void setWhenResourceMissingType(byte whenResourceMissingType) {
this.whenResourceMissingType = whenResourceMissingType;
}
public boolean hasProperties() {
return this.parent.hasProperties();
}
public JRPropertiesMap getPropertiesMap() {
return this.parent.getPropertiesMap();
}
public JRPropertiesHolder getParentProperties() {
return null;
}
public JRExpression getFilterExpression() {
return this.parent.getFilterExpression();
}
public Object clone() {
return null;
}
}