first commit
This commit is contained in:
37
hrmsEjb/net/sf/jasperreports/crosstabs/JRCellContents.java
Normal file
37
hrmsEjb/net/sf/jasperreports/crosstabs/JRCellContents.java
Normal file
@@ -0,0 +1,37 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.sf.jasperreports.engine.JRBox;
|
||||
import net.sf.jasperreports.engine.JRBoxContainer;
|
||||
import net.sf.jasperreports.engine.JRElementGroup;
|
||||
import net.sf.jasperreports.engine.JRStyleContainer;
|
||||
|
||||
public interface JRCellContents extends JRElementGroup, JRStyleContainer, JRBoxContainer {
|
||||
public static final byte POSITION_X_LEFT = 1;
|
||||
|
||||
public static final byte POSITION_X_CENTER = 2;
|
||||
|
||||
public static final byte POSITION_X_RIGHT = 3;
|
||||
|
||||
public static final byte POSITION_X_STRETCH = 4;
|
||||
|
||||
public static final byte POSITION_Y_TOP = 1;
|
||||
|
||||
public static final byte POSITION_Y_MIDDLE = 2;
|
||||
|
||||
public static final byte POSITION_Y_BOTTOM = 3;
|
||||
|
||||
public static final byte POSITION_Y_STRETCH = 4;
|
||||
|
||||
public static final int NOT_CALCULATED = -2147483648;
|
||||
|
||||
Color getBackcolor();
|
||||
|
||||
JRBox getBox();
|
||||
|
||||
int getWidth();
|
||||
|
||||
int getHeight();
|
||||
|
||||
Byte getMode();
|
||||
}
|
51
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstab.java
Normal file
51
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstab.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import net.sf.jasperreports.engine.JRElement;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
|
||||
public interface JRCrosstab extends JRElement {
|
||||
public static final int DEFAULT_COLUMN_BREAK_OFFSET = 10;
|
||||
|
||||
public static final String VARIABLE_ROW_COUNT = "ROW_COUNT";
|
||||
|
||||
public static final String VARIABLE_COLUMN_COUNT = "COLUMN_COUNT";
|
||||
|
||||
public static final byte RUN_DIRECTION_LTR = 0;
|
||||
|
||||
public static final byte RUN_DIRECTION_RTL = 1;
|
||||
|
||||
int getId();
|
||||
|
||||
JRCrosstabDataset getDataset();
|
||||
|
||||
JRCrosstabRowGroup[] getRowGroups();
|
||||
|
||||
JRCrosstabColumnGroup[] getColumnGroups();
|
||||
|
||||
JRCrosstabMeasure[] getMeasures();
|
||||
|
||||
int getColumnBreakOffset();
|
||||
|
||||
boolean isRepeatColumnHeaders();
|
||||
|
||||
boolean isRepeatRowHeaders();
|
||||
|
||||
JRCrosstabCell[][] getCells();
|
||||
|
||||
JRCrosstabParameter[] getParameters();
|
||||
|
||||
JRExpression getParametersMapExpression();
|
||||
|
||||
JRCellContents getWhenNoDataCell();
|
||||
|
||||
JRElement getElementByKey(String paramString);
|
||||
|
||||
JRCellContents getHeaderCell();
|
||||
|
||||
JRVariable[] getVariables();
|
||||
|
||||
byte getRunDirection();
|
||||
|
||||
void setRunDirection(byte paramByte);
|
||||
}
|
11
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstabBucket.java
Normal file
11
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstabBucket.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
|
||||
public interface JRCrosstabBucket {
|
||||
byte getOrder();
|
||||
|
||||
JRExpression getExpression();
|
||||
|
||||
JRExpression getComparatorExpression();
|
||||
}
|
15
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstabCell.java
Normal file
15
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstabCell.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import net.sf.jasperreports.engine.JRCloneable;
|
||||
|
||||
public interface JRCrosstabCell extends JRCloneable {
|
||||
Integer getWidth();
|
||||
|
||||
Integer getHeight();
|
||||
|
||||
String getRowTotalGroup();
|
||||
|
||||
String getColumnTotalGroup();
|
||||
|
||||
JRCellContents getContents();
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
public interface JRCrosstabColumnGroup extends JRCrosstabGroup {
|
||||
int getHeight();
|
||||
|
||||
byte getPosition();
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import net.sf.jasperreports.engine.JRElementDataset;
|
||||
|
||||
public interface JRCrosstabDataset extends JRElementDataset {
|
||||
boolean isDataPreSorted();
|
||||
}
|
20
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstabGroup.java
Normal file
20
hrmsEjb/net/sf/jasperreports/crosstabs/JRCrosstabGroup.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import net.sf.jasperreports.engine.JRCloneable;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
|
||||
public interface JRCrosstabGroup extends JRCloneable {
|
||||
String getName();
|
||||
|
||||
byte getTotalPosition();
|
||||
|
||||
JRCrosstabBucket getBucket();
|
||||
|
||||
JRCellContents getHeader();
|
||||
|
||||
JRCellContents getTotalHeader();
|
||||
|
||||
JRVariable getVariable();
|
||||
|
||||
boolean hasTotal();
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import net.sf.jasperreports.engine.JRCloneable;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
|
||||
public interface JRCrosstabMeasure extends JRCloneable {
|
||||
public static final byte PERCENTAGE_TYPE_NONE = 0;
|
||||
|
||||
public static final byte PERCENTAGE_TYPE_GRAND_TOTAL = 1;
|
||||
|
||||
String getName();
|
||||
|
||||
String getValueClassName();
|
||||
|
||||
Class getValueClass();
|
||||
|
||||
JRExpression getValueExpression();
|
||||
|
||||
byte getCalculation();
|
||||
|
||||
String getIncrementerFactoryClassName();
|
||||
|
||||
Class getIncrementerFactoryClass();
|
||||
|
||||
byte getPercentageOfType();
|
||||
|
||||
String getPercentageCalculatorClassName();
|
||||
|
||||
Class getPercentageCalculatorClass();
|
||||
|
||||
JRVariable getVariable();
|
||||
}
|
@@ -0,0 +1,6 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
import net.sf.jasperreports.engine.JRDatasetParameter;
|
||||
import net.sf.jasperreports.engine.JRParameter;
|
||||
|
||||
public interface JRCrosstabParameter extends JRParameter, JRDatasetParameter {}
|
@@ -0,0 +1,7 @@
|
||||
package net.sf.jasperreports.crosstabs;
|
||||
|
||||
public interface JRCrosstabRowGroup extends JRCrosstabGroup {
|
||||
int getWidth();
|
||||
|
||||
byte getPosition();
|
||||
}
|
@@ -0,0 +1,102 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.engine.JRBox;
|
||||
import net.sf.jasperreports.engine.JRBoxContainer;
|
||||
import net.sf.jasperreports.engine.JRDefaultStyleProvider;
|
||||
import net.sf.jasperreports.engine.JRElementGroup;
|
||||
import net.sf.jasperreports.engine.JRLineBox;
|
||||
import net.sf.jasperreports.engine.JRStyle;
|
||||
import net.sf.jasperreports.engine.base.JRBaseElementGroup;
|
||||
import net.sf.jasperreports.engine.base.JRBaseLineBox;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
import net.sf.jasperreports.engine.util.JRBoxUtil;
|
||||
import net.sf.jasperreports.engine.util.LineBoxWrapper;
|
||||
|
||||
public class JRBaseCellContents extends JRBaseElementGroup implements JRCellContents, Serializable {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected JRDefaultStyleProvider defaultStyleProvider;
|
||||
|
||||
protected JRStyle style;
|
||||
|
||||
protected String styleNameReference;
|
||||
|
||||
protected Byte mode;
|
||||
|
||||
protected Color backcolor;
|
||||
|
||||
protected JRLineBox lineBox;
|
||||
|
||||
protected int width;
|
||||
|
||||
protected int height;
|
||||
|
||||
private JRBox box;
|
||||
|
||||
public JRBaseCellContents(JRCellContents cell, JRBaseObjectFactory factory) {
|
||||
super((JRElementGroup)cell, factory);
|
||||
this.box = null;
|
||||
this.defaultStyleProvider = factory.getDefaultStyleProvider();
|
||||
this.style = factory.getStyle(cell.getStyle());
|
||||
this.styleNameReference = cell.getStyleNameReference();
|
||||
this.mode = cell.getMode();
|
||||
this.backcolor = cell.getBackcolor();
|
||||
this.lineBox = cell.getLineBox().clone((JRBoxContainer)this);
|
||||
this.width = cell.getWidth();
|
||||
this.height = cell.getHeight();
|
||||
}
|
||||
|
||||
public Color getBackcolor() {
|
||||
return this.backcolor;
|
||||
}
|
||||
|
||||
public JRBox getBox() {
|
||||
return (JRBox)new LineBoxWrapper(getLineBox());
|
||||
}
|
||||
|
||||
public JRLineBox getLineBox() {
|
||||
return this.lineBox;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public JRDefaultStyleProvider getDefaultStyleProvider() {
|
||||
return this.defaultStyleProvider;
|
||||
}
|
||||
|
||||
public JRStyle getStyle() {
|
||||
return this.style;
|
||||
}
|
||||
|
||||
public Byte getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public String getStyleNameReference() {
|
||||
return this.styleNameReference;
|
||||
}
|
||||
|
||||
public Color getDefaultLineColor() {
|
||||
return Color.black;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
if (this.lineBox == null) {
|
||||
this.lineBox = (JRLineBox)new JRBaseLineBox((JRBoxContainer)this);
|
||||
JRBoxUtil.setBoxToLineBox(this.box, this.lineBox);
|
||||
this.box = null;
|
||||
}
|
||||
}
|
||||
}
|
264
hrmsEjb/net/sf/jasperreports/crosstabs/base/JRBaseCrosstab.java
Normal file
264
hrmsEjb/net/sf/jasperreports/crosstabs/base/JRBaseCrosstab.java
Normal file
@@ -0,0 +1,264 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstab;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabCell;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabDataset;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabMeasure;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabParameter;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup;
|
||||
import net.sf.jasperreports.crosstabs.design.JRDesignCrosstab;
|
||||
import net.sf.jasperreports.engine.JRCommonElement;
|
||||
import net.sf.jasperreports.engine.JRElement;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRExpressionCollector;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.JRVisitor;
|
||||
import net.sf.jasperreports.engine.base.JRBaseElement;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
import net.sf.jasperreports.engine.util.JRStyleResolver;
|
||||
|
||||
public class JRBaseCrosstab extends JRBaseElement implements JRCrosstab {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_RUN_DIRECTION = "runDirection";
|
||||
|
||||
protected int id;
|
||||
|
||||
protected JRCrosstabParameter[] parameters;
|
||||
|
||||
protected JRVariable[] variables;
|
||||
|
||||
protected JRExpression parametersMapExpression;
|
||||
|
||||
protected JRCrosstabDataset dataset;
|
||||
|
||||
protected JRCrosstabRowGroup[] rowGroups;
|
||||
|
||||
protected JRCrosstabColumnGroup[] columnGroups;
|
||||
|
||||
protected JRCrosstabMeasure[] measures;
|
||||
|
||||
protected int columnBreakOffset;
|
||||
|
||||
protected boolean repeatColumnHeaders = true;
|
||||
|
||||
protected boolean repeatRowHeaders = true;
|
||||
|
||||
protected byte runDirection;
|
||||
|
||||
protected JRCrosstabCell[][] cells;
|
||||
|
||||
protected JRCellContents whenNoDataCell;
|
||||
|
||||
protected JRCellContents headerCell;
|
||||
|
||||
public JRBaseCrosstab(JRCrosstab crosstab, JRBaseObjectFactory factory, int id) {
|
||||
super((JRElement)crosstab, factory);
|
||||
this.id = id;
|
||||
this.columnBreakOffset = crosstab.getColumnBreakOffset();
|
||||
this.repeatColumnHeaders = crosstab.isRepeatColumnHeaders();
|
||||
this.repeatRowHeaders = crosstab.isRepeatRowHeaders();
|
||||
this.runDirection = crosstab.getRunDirection();
|
||||
this.dataset = factory.getCrosstabDataset(crosstab.getDataset());
|
||||
copyParameters(crosstab, factory);
|
||||
copyVariables(crosstab, factory);
|
||||
this.headerCell = factory.getCell(crosstab.getHeaderCell());
|
||||
copyRowGroups(crosstab, factory);
|
||||
copyColumnGroups(crosstab, factory);
|
||||
copyMeasures(crosstab, factory);
|
||||
copyCells(crosstab, factory);
|
||||
this.whenNoDataCell = factory.getCell(crosstab.getWhenNoDataCell());
|
||||
}
|
||||
|
||||
public byte getMode() {
|
||||
return JRStyleResolver.getMode((JRCommonElement)this, (byte)2);
|
||||
}
|
||||
|
||||
private void copyParameters(JRCrosstab crosstab, JRBaseObjectFactory factory) {
|
||||
JRCrosstabParameter[] crossParameters = crosstab.getParameters();
|
||||
if (crossParameters != null) {
|
||||
this.parameters = new JRCrosstabParameter[crossParameters.length];
|
||||
for (int i = 0; i < this.parameters.length; i++)
|
||||
this.parameters[i] = factory.getCrosstabParameter(crossParameters[i]);
|
||||
}
|
||||
this.parametersMapExpression = factory.getExpression(crosstab.getParametersMapExpression());
|
||||
}
|
||||
|
||||
private void copyVariables(JRCrosstab crosstab, JRBaseObjectFactory factory) {
|
||||
JRVariable[] vars = crosstab.getVariables();
|
||||
if (vars != null) {
|
||||
this.variables = new JRVariable[vars.length];
|
||||
for (int i = 0; i < vars.length; i++)
|
||||
this.variables[i] = (JRVariable)factory.getVariable(vars[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyRowGroups(JRCrosstab crosstab, JRBaseObjectFactory factory) {
|
||||
JRCrosstabRowGroup[] crossRowGroups = crosstab.getRowGroups();
|
||||
if (crossRowGroups != null) {
|
||||
this.rowGroups = new JRCrosstabRowGroup[crossRowGroups.length];
|
||||
for (int i = 0; i < crossRowGroups.length; i++)
|
||||
this.rowGroups[i] = factory.getCrosstabRowGroup(crossRowGroups[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyColumnGroups(JRCrosstab crosstab, JRBaseObjectFactory factory) {
|
||||
JRCrosstabColumnGroup[] crossColumnGroups = crosstab.getColumnGroups();
|
||||
if (crossColumnGroups != null) {
|
||||
this.columnGroups = new JRCrosstabColumnGroup[crossColumnGroups.length];
|
||||
for (int i = 0; i < crossColumnGroups.length; i++)
|
||||
this.columnGroups[i] = factory.getCrosstabColumnGroup(crossColumnGroups[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyMeasures(JRCrosstab crosstab, JRBaseObjectFactory factory) {
|
||||
JRCrosstabMeasure[] crossMeasures = crosstab.getMeasures();
|
||||
if (crossMeasures != null) {
|
||||
this.measures = new JRCrosstabMeasure[crossMeasures.length];
|
||||
for (int i = 0; i < crossMeasures.length; i++)
|
||||
this.measures[i] = factory.getCrosstabMeasure(crossMeasures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyCells(JRCrosstab crosstab, JRBaseObjectFactory factory) {
|
||||
JRCrosstabCell[][] crossCells = crosstab.getCells();
|
||||
if (crossCells != null) {
|
||||
this.cells = new JRCrosstabCell[this.rowGroups.length + 1][this.columnGroups.length + 1];
|
||||
for (int i = 0; i <= this.rowGroups.length; i++) {
|
||||
for (int j = 0; j <= this.columnGroups.length; j++)
|
||||
this.cells[i][j] = factory.getCrosstabCell(crossCells[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public JRCrosstabDataset getDataset() {
|
||||
return this.dataset;
|
||||
}
|
||||
|
||||
public JRCrosstabRowGroup[] getRowGroups() {
|
||||
return this.rowGroups;
|
||||
}
|
||||
|
||||
public JRCrosstabColumnGroup[] getColumnGroups() {
|
||||
return this.columnGroups;
|
||||
}
|
||||
|
||||
public JRCrosstabMeasure[] getMeasures() {
|
||||
return this.measures;
|
||||
}
|
||||
|
||||
public void collectExpressions(JRExpressionCollector collector) {
|
||||
collector.collect(this);
|
||||
}
|
||||
|
||||
public void visit(JRVisitor visitor) {
|
||||
visitor.visitCrosstab(this);
|
||||
}
|
||||
|
||||
public int getColumnBreakOffset() {
|
||||
return this.columnBreakOffset;
|
||||
}
|
||||
|
||||
public boolean isRepeatColumnHeaders() {
|
||||
return this.repeatColumnHeaders;
|
||||
}
|
||||
|
||||
public boolean isRepeatRowHeaders() {
|
||||
return this.repeatRowHeaders;
|
||||
}
|
||||
|
||||
public JRCrosstabCell[][] getCells() {
|
||||
return this.cells;
|
||||
}
|
||||
|
||||
public JRCrosstabParameter[] getParameters() {
|
||||
return this.parameters;
|
||||
}
|
||||
|
||||
public JRExpression getParametersMapExpression() {
|
||||
return this.parametersMapExpression;
|
||||
}
|
||||
|
||||
public JRCellContents getWhenNoDataCell() {
|
||||
return this.whenNoDataCell;
|
||||
}
|
||||
|
||||
public static JRElement getElementByKey(JRCrosstab crosstab, String key) {
|
||||
JRElement element = null;
|
||||
if (crosstab.getHeaderCell() != null)
|
||||
element = crosstab.getHeaderCell().getElementByKey(key);
|
||||
if (element == null)
|
||||
element = getHeadersElement((JRCrosstabGroup[])crosstab.getRowGroups(), key);
|
||||
if (element == null)
|
||||
element = getHeadersElement((JRCrosstabGroup[])crosstab.getColumnGroups(), key);
|
||||
if (element == null)
|
||||
if (crosstab instanceof JRDesignCrosstab) {
|
||||
List cellsList = ((JRDesignCrosstab)crosstab).getCellsList();
|
||||
for (Iterator it = cellsList.iterator(); element == null && it.hasNext(); ) {
|
||||
JRCrosstabCell cell = it.next();
|
||||
element = cell.getContents().getElementByKey(key);
|
||||
}
|
||||
} else {
|
||||
JRCrosstabCell[][] cells = crosstab.getCells();
|
||||
for (int i = cells.length - 1; element == null && i >= 0; i--) {
|
||||
for (int j = (cells[i]).length - 1; element == null && j >= 0; j--) {
|
||||
JRCrosstabCell cell = cells[i][j];
|
||||
if (cell != null)
|
||||
element = cell.getContents().getElementByKey(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (element == null && crosstab.getWhenNoDataCell() != null)
|
||||
element = crosstab.getWhenNoDataCell().getElementByKey(key);
|
||||
return element;
|
||||
}
|
||||
|
||||
private static JRElement getHeadersElement(JRCrosstabGroup[] groups, String key) {
|
||||
JRElement element = null;
|
||||
if (groups != null)
|
||||
for (int i = 0; element == null && i < groups.length; i++) {
|
||||
JRCellContents header = groups[i].getHeader();
|
||||
element = header.getElementByKey(key);
|
||||
if (element == null) {
|
||||
JRCellContents totalHeader = groups[i].getTotalHeader();
|
||||
element = totalHeader.getElementByKey(key);
|
||||
}
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
public JRElement getElementByKey(String elementKey) {
|
||||
return getElementByKey(this, elementKey);
|
||||
}
|
||||
|
||||
public JRCellContents getHeaderCell() {
|
||||
return this.headerCell;
|
||||
}
|
||||
|
||||
public JRVariable[] getVariables() {
|
||||
return this.variables;
|
||||
}
|
||||
|
||||
public byte getRunDirection() {
|
||||
return this.runDirection;
|
||||
}
|
||||
|
||||
public void setRunDirection(byte runDirection) {
|
||||
byte old = this.runDirection;
|
||||
this.runDirection = runDirection;
|
||||
getEventSupport().firePropertyChange("runDirection", old, this.runDirection);
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,37 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import java.io.Serializable;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabBucket;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
|
||||
public class JRBaseCrosstabBucket implements JRCrosstabBucket, Serializable {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected byte order = 1;
|
||||
|
||||
protected JRExpression expression;
|
||||
|
||||
protected JRExpression comparatorExpression;
|
||||
|
||||
protected JRBaseCrosstabBucket() {}
|
||||
|
||||
public JRBaseCrosstabBucket(JRCrosstabBucket bucket, JRBaseObjectFactory factory) {
|
||||
factory.put(bucket, this);
|
||||
this.order = bucket.getOrder();
|
||||
this.expression = factory.getExpression(bucket.getExpression());
|
||||
this.comparatorExpression = factory.getExpression(bucket.getComparatorExpression());
|
||||
}
|
||||
|
||||
public byte getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
public JRExpression getExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
public JRExpression getComparatorExpression() {
|
||||
return this.comparatorExpression;
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import java.io.Serializable;
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabCell;
|
||||
import net.sf.jasperreports.engine.JRRuntimeException;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
|
||||
public class JRBaseCrosstabCell implements JRCrosstabCell, Serializable {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected Integer width;
|
||||
|
||||
protected Integer height;
|
||||
|
||||
protected String rowTotalGroup;
|
||||
|
||||
protected String columnTotalGroup;
|
||||
|
||||
protected JRCellContents contents;
|
||||
|
||||
protected JRBaseCrosstabCell() {}
|
||||
|
||||
public JRBaseCrosstabCell(JRCrosstabCell crosstabCell, JRBaseObjectFactory factory) {
|
||||
factory.put(crosstabCell, this);
|
||||
this.width = crosstabCell.getWidth();
|
||||
this.height = crosstabCell.getHeight();
|
||||
this.rowTotalGroup = crosstabCell.getRowTotalGroup();
|
||||
this.columnTotalGroup = crosstabCell.getColumnTotalGroup();
|
||||
this.contents = factory.getCell(crosstabCell.getContents());
|
||||
}
|
||||
|
||||
public String getRowTotalGroup() {
|
||||
return this.rowTotalGroup;
|
||||
}
|
||||
|
||||
public String getColumnTotalGroup() {
|
||||
return this.columnTotalGroup;
|
||||
}
|
||||
|
||||
public JRCellContents getContents() {
|
||||
return this.contents;
|
||||
}
|
||||
|
||||
public Integer getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public Integer getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
JRBaseCrosstabCell clone = null;
|
||||
try {
|
||||
clone = (JRBaseCrosstabCell)super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
throw new JRRuntimeException(e);
|
||||
}
|
||||
if (this.contents != null)
|
||||
clone.contents = (JRCellContents)this.contents.clone();
|
||||
return clone;
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
|
||||
public class JRBaseCrosstabColumnGroup extends JRBaseCrosstabGroup implements JRCrosstabColumnGroup {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected int height;
|
||||
|
||||
protected byte position = 1;
|
||||
|
||||
public JRBaseCrosstabColumnGroup(JRCrosstabColumnGroup group, JRBaseObjectFactory factory) {
|
||||
super((JRCrosstabGroup)group, factory);
|
||||
this.height = group.getHeight();
|
||||
this.position = group.getPosition();
|
||||
}
|
||||
|
||||
public byte getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
}
|
@@ -0,0 +1,24 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabDataset;
|
||||
import net.sf.jasperreports.engine.JRElementDataset;
|
||||
import net.sf.jasperreports.engine.JRExpressionCollector;
|
||||
import net.sf.jasperreports.engine.base.JRBaseElementDataset;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
|
||||
public class JRBaseCrosstabDataset extends JRBaseElementDataset implements JRCrosstabDataset {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected boolean dataPreSorted = false;
|
||||
|
||||
public JRBaseCrosstabDataset(JRCrosstabDataset dataset, JRBaseObjectFactory factory) {
|
||||
super((JRElementDataset)dataset, factory);
|
||||
this.dataPreSorted = dataset.isDataPreSorted();
|
||||
}
|
||||
|
||||
public void collectExpressions(JRExpressionCollector collector) {}
|
||||
|
||||
public boolean isDataPreSorted() {
|
||||
return this.dataPreSorted;
|
||||
}
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import java.io.Serializable;
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabBucket;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
|
||||
public abstract class JRBaseCrosstabGroup implements JRCrosstabGroup, Serializable {
|
||||
protected String name;
|
||||
|
||||
protected byte totalPosition = 0;
|
||||
|
||||
protected JRCrosstabBucket bucket;
|
||||
|
||||
protected JRCellContents header;
|
||||
|
||||
protected JRCellContents totalHeader;
|
||||
|
||||
protected JRVariable variable;
|
||||
|
||||
protected JRBaseCrosstabGroup() {}
|
||||
|
||||
public JRBaseCrosstabGroup(JRCrosstabGroup group, JRBaseObjectFactory factory) {
|
||||
factory.put(group, this);
|
||||
this.name = group.getName();
|
||||
this.totalPosition = group.getTotalPosition();
|
||||
this.bucket = factory.getCrosstabBucket(group.getBucket());
|
||||
this.header = factory.getCell(group.getHeader());
|
||||
this.totalHeader = factory.getCell(group.getTotalHeader());
|
||||
this.variable = (JRVariable)factory.getVariable(group.getVariable());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public JRCrosstabBucket getBucket() {
|
||||
return this.bucket;
|
||||
}
|
||||
|
||||
public byte getTotalPosition() {
|
||||
return this.totalPosition;
|
||||
}
|
||||
|
||||
public boolean hasTotal() {
|
||||
return (this.totalPosition != 0);
|
||||
}
|
||||
|
||||
public JRCellContents getHeader() {
|
||||
return this.header;
|
||||
}
|
||||
|
||||
public JRCellContents getTotalHeader() {
|
||||
return this.totalHeader;
|
||||
}
|
||||
|
||||
public JRVariable getVariable() {
|
||||
return this.variable;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,148 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import java.io.Serializable;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabMeasure;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRRuntimeException;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
import net.sf.jasperreports.engine.util.JRClassLoader;
|
||||
|
||||
public class JRBaseCrosstabMeasure implements JRCrosstabMeasure, Serializable {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected String name;
|
||||
|
||||
protected String valueClassName;
|
||||
|
||||
protected String valueClassRealName = null;
|
||||
|
||||
protected Class valueClass;
|
||||
|
||||
protected JRExpression expression;
|
||||
|
||||
protected byte calculation = 1;
|
||||
|
||||
protected String incrementerFactoryClassName;
|
||||
|
||||
protected String incrementerFactoryClassRealName;
|
||||
|
||||
protected Class incrementerFactoryClass;
|
||||
|
||||
protected byte percentageOfType = 0;
|
||||
|
||||
protected String percentageCalculatorClassName;
|
||||
|
||||
protected String percentageCalculatorClassRealName;
|
||||
|
||||
protected Class percentageCalculatorClass;
|
||||
|
||||
protected JRVariable variable;
|
||||
|
||||
protected JRBaseCrosstabMeasure() {}
|
||||
|
||||
public JRBaseCrosstabMeasure(JRCrosstabMeasure measure, JRBaseObjectFactory factory) {
|
||||
factory.put(measure, this);
|
||||
this.name = measure.getName();
|
||||
this.valueClassName = measure.getValueClassName();
|
||||
this.expression = factory.getExpression(measure.getValueExpression());
|
||||
this.calculation = measure.getCalculation();
|
||||
this.incrementerFactoryClassName = measure.getIncrementerFactoryClassName();
|
||||
this.percentageOfType = measure.getPercentageOfType();
|
||||
this.percentageCalculatorClassName = measure.getPercentageCalculatorClassName();
|
||||
this.variable = (JRVariable)factory.getVariable(measure.getVariable());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public String getValueClassName() {
|
||||
return this.valueClassName;
|
||||
}
|
||||
|
||||
public JRExpression getValueExpression() {
|
||||
return this.expression;
|
||||
}
|
||||
|
||||
public byte getCalculation() {
|
||||
return this.calculation;
|
||||
}
|
||||
|
||||
public String getIncrementerFactoryClassName() {
|
||||
return this.incrementerFactoryClassName;
|
||||
}
|
||||
|
||||
public byte getPercentageOfType() {
|
||||
return this.percentageOfType;
|
||||
}
|
||||
|
||||
public Class getIncrementerFactoryClass() {
|
||||
if (this.incrementerFactoryClass == null) {
|
||||
String className = getIncrementerFactoryClassRealName();
|
||||
if (className != null)
|
||||
try {
|
||||
this.incrementerFactoryClass = JRClassLoader.loadClassForName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new JRRuntimeException("Could not load measure incrementer class", e);
|
||||
}
|
||||
}
|
||||
return this.incrementerFactoryClass;
|
||||
}
|
||||
|
||||
private String getIncrementerFactoryClassRealName() {
|
||||
if (this.incrementerFactoryClassRealName == null)
|
||||
this.incrementerFactoryClassRealName = JRClassLoader.getClassRealName(this.incrementerFactoryClassName);
|
||||
return this.incrementerFactoryClassRealName;
|
||||
}
|
||||
|
||||
public Class getValueClass() {
|
||||
if (this.valueClass == null) {
|
||||
String className = getValueClassRealName();
|
||||
if (className != null)
|
||||
try {
|
||||
this.valueClass = JRClassLoader.loadClassForName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new JRRuntimeException("Could not load bucket value class", e);
|
||||
}
|
||||
}
|
||||
return this.valueClass;
|
||||
}
|
||||
|
||||
private String getValueClassRealName() {
|
||||
if (this.valueClassRealName == null)
|
||||
this.valueClassRealName = JRClassLoader.getClassRealName(this.valueClassName);
|
||||
return this.valueClassRealName;
|
||||
}
|
||||
|
||||
public JRVariable getVariable() {
|
||||
return this.variable;
|
||||
}
|
||||
|
||||
public String getPercentageCalculatorClassName() {
|
||||
return this.percentageCalculatorClassName;
|
||||
}
|
||||
|
||||
public Class getPercentageCalculatorClass() {
|
||||
if (this.percentageCalculatorClass == null) {
|
||||
String className = getPercentageCalculatorClassRealName();
|
||||
if (className != null)
|
||||
try {
|
||||
this.percentageCalculatorClass = JRClassLoader.loadClassForName(className);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new JRRuntimeException("Could not load measure percentage calculator class", e);
|
||||
}
|
||||
}
|
||||
return this.percentageCalculatorClass;
|
||||
}
|
||||
|
||||
private String getPercentageCalculatorClassRealName() {
|
||||
if (this.percentageCalculatorClassRealName == null)
|
||||
this.percentageCalculatorClassRealName = JRClassLoader.getClassRealName(this.percentageCalculatorClassName);
|
||||
return this.percentageCalculatorClassRealName;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,31 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabParameter;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRParameter;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
import net.sf.jasperreports.engine.base.JRBaseParameter;
|
||||
|
||||
public class JRBaseCrosstabParameter extends JRBaseParameter implements JRCrosstabParameter {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected JRExpression valueExpression;
|
||||
|
||||
protected JRBaseCrosstabParameter() {}
|
||||
|
||||
public JRBaseCrosstabParameter(JRCrosstabParameter parameter, JRBaseObjectFactory factory) {
|
||||
super((JRParameter)parameter, factory);
|
||||
this.valueExpression = factory.getExpression(parameter.getExpression());
|
||||
}
|
||||
|
||||
public JRExpression getExpression() {
|
||||
return this.valueExpression;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
JRBaseCrosstabParameter clone = (JRBaseCrosstabParameter)super.clone();
|
||||
if (this.valueExpression != null)
|
||||
clone.valueExpression = (JRExpression)this.valueExpression.clone();
|
||||
return clone;
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
package net.sf.jasperreports.crosstabs.base;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup;
|
||||
import net.sf.jasperreports.engine.base.JRBaseObjectFactory;
|
||||
|
||||
public class JRBaseCrosstabRowGroup extends JRBaseCrosstabGroup implements JRCrosstabRowGroup {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
protected int width;
|
||||
|
||||
protected byte position = 1;
|
||||
|
||||
public JRBaseCrosstabRowGroup(JRCrosstabRowGroup group, JRBaseObjectFactory factory) {
|
||||
super((JRCrosstabGroup)group, factory);
|
||||
this.width = group.getWidth();
|
||||
this.position = group.getPosition();
|
||||
}
|
||||
|
||||
public byte getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JRCrosstabOrigin implements Serializable {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final byte TYPE_HEADER_CELL = 1;
|
||||
|
||||
public static final byte TYPE_WHEN_NO_DATA_CELL = 2;
|
||||
|
||||
public static final byte TYPE_ROW_GROUP_HEADER = 3;
|
||||
|
||||
public static final byte TYPE_ROW_GROUP_TOTAL_HEADER = 4;
|
||||
|
||||
public static final byte TYPE_COLUMN_GROUP_HEADER = 5;
|
||||
|
||||
public static final byte TYPE_COLUMN_GROUP_TOTAL_HEADER = 6;
|
||||
|
||||
public static final byte TYPE_DATA_CELL = 7;
|
||||
|
||||
private final JRDesignCrosstab crosstab;
|
||||
|
||||
private final byte type;
|
||||
|
||||
private final String rowGroupName;
|
||||
|
||||
private final String columnGroupName;
|
||||
|
||||
public JRCrosstabOrigin(JRDesignCrosstab crosstab, byte type) {
|
||||
this(crosstab, type, null, null);
|
||||
}
|
||||
|
||||
public JRCrosstabOrigin(JRDesignCrosstab crosstab, byte type, String rowGroupName, String columnGroupName) {
|
||||
this.crosstab = crosstab;
|
||||
this.type = type;
|
||||
this.rowGroupName = rowGroupName;
|
||||
this.columnGroupName = columnGroupName;
|
||||
}
|
||||
|
||||
public byte getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public String getRowGroupName() {
|
||||
return this.rowGroupName;
|
||||
}
|
||||
|
||||
public String getColumnGroupName() {
|
||||
return this.columnGroupName;
|
||||
}
|
||||
|
||||
public JRDesignCrosstab getCrosstab() {
|
||||
return this.crosstab;
|
||||
}
|
||||
}
|
@@ -0,0 +1,147 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.engine.JRBox;
|
||||
import net.sf.jasperreports.engine.JRBoxContainer;
|
||||
import net.sf.jasperreports.engine.JRDefaultStyleProvider;
|
||||
import net.sf.jasperreports.engine.JRLineBox;
|
||||
import net.sf.jasperreports.engine.JRStyle;
|
||||
import net.sf.jasperreports.engine.base.JRBaseLineBox;
|
||||
import net.sf.jasperreports.engine.design.JRDesignElementGroup;
|
||||
import net.sf.jasperreports.engine.util.JRBoxUtil;
|
||||
import net.sf.jasperreports.engine.util.LineBoxWrapper;
|
||||
|
||||
public class JRDesignCellContents extends JRDesignElementGroup implements JRCellContents {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_BOX = "box";
|
||||
|
||||
public static final String PROPERTY_STYLE = "style";
|
||||
|
||||
public static final String PROPERTY_STYLE_NAME_REFERENCE = "styleNameReference";
|
||||
|
||||
protected JRDefaultStyleProvider defaultStyleProvider;
|
||||
|
||||
protected JRStyle style;
|
||||
|
||||
protected String styleNameReference;
|
||||
|
||||
protected Byte mode;
|
||||
|
||||
private Color backcolor;
|
||||
|
||||
private JRLineBox lineBox;
|
||||
|
||||
private int width = Integer.MIN_VALUE;
|
||||
|
||||
private int height = Integer.MIN_VALUE;
|
||||
|
||||
private JRCrosstabOrigin origin;
|
||||
|
||||
private JRBox box;
|
||||
|
||||
public Color getBackcolor() {
|
||||
return this.backcolor;
|
||||
}
|
||||
|
||||
public void setBackcolor(Color color) {
|
||||
Object old = this.backcolor;
|
||||
this.backcolor = color;
|
||||
getEventSupport().firePropertyChange("backcolor", old, this.backcolor);
|
||||
}
|
||||
|
||||
public JRBox getBox() {
|
||||
return (JRBox)new LineBoxWrapper(getLineBox());
|
||||
}
|
||||
|
||||
public JRLineBox getLineBox() {
|
||||
return this.lineBox;
|
||||
}
|
||||
|
||||
public void setBox(JRBox box) {
|
||||
JRBoxUtil.setBoxToLineBox(box, this.lineBox);
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
protected void setHeight(int height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
protected void setWidth(int width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public JRDefaultStyleProvider getDefaultStyleProvider() {
|
||||
return this.defaultStyleProvider;
|
||||
}
|
||||
|
||||
public JRStyle getStyle() {
|
||||
return this.style;
|
||||
}
|
||||
|
||||
public void setStyle(JRStyle style) {
|
||||
Object old = this.style;
|
||||
this.style = style;
|
||||
getEventSupport().firePropertyChange("style", old, this.style);
|
||||
}
|
||||
|
||||
public Byte getMode() {
|
||||
return this.mode;
|
||||
}
|
||||
|
||||
public void setMode(Byte mode) {
|
||||
Object old = this.mode;
|
||||
this.mode = mode;
|
||||
getEventSupport().firePropertyChange("mode", old, this.mode);
|
||||
}
|
||||
|
||||
public String getStyleNameReference() {
|
||||
return this.styleNameReference;
|
||||
}
|
||||
|
||||
public void setStyleNameReference(String styleName) {
|
||||
Object old = this.styleNameReference;
|
||||
this.styleNameReference = styleName;
|
||||
getEventSupport().firePropertyChange("styleNameReference", old, this.styleNameReference);
|
||||
}
|
||||
|
||||
public JRCrosstabOrigin getOrigin() {
|
||||
return this.origin;
|
||||
}
|
||||
|
||||
public void setOrigin(JRCrosstabOrigin origin) {
|
||||
this.origin = origin;
|
||||
}
|
||||
|
||||
public Color getDefaultLineColor() {
|
||||
return Color.black;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public JRDesignCellContents() {
|
||||
this.box = null;
|
||||
this.lineBox = (JRLineBox)new JRBaseLineBox((JRBoxContainer)this);
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
|
||||
in.defaultReadObject();
|
||||
if (this.lineBox == null) {
|
||||
this.lineBox = (JRLineBox)new JRBaseLineBox((JRBoxContainer)this);
|
||||
JRBoxUtil.setBoxToLineBox(this.box, this.lineBox);
|
||||
this.box = null;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,946 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.Serializable;
|
||||
import java.net.URLStreamHandlerFactory;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.TimeZone;
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstab;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabBucket;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabCell;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabDataset;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabMeasure;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabParameter;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup;
|
||||
import net.sf.jasperreports.crosstabs.base.JRBaseCrosstab;
|
||||
import net.sf.jasperreports.engine.JRCommonElement;
|
||||
import net.sf.jasperreports.engine.JRDefaultStyleProvider;
|
||||
import net.sf.jasperreports.engine.JRElement;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRExpressionCollector;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.JRVisitor;
|
||||
import net.sf.jasperreports.engine.design.JRDesignElement;
|
||||
import net.sf.jasperreports.engine.design.JRDesignVariable;
|
||||
import net.sf.jasperreports.engine.util.FileResolver;
|
||||
import net.sf.jasperreports.engine.util.FormatFactory;
|
||||
import net.sf.jasperreports.engine.util.JRStyleResolver;
|
||||
import net.sf.jasperreports.engine.util.Pair;
|
||||
import org.apache.commons.collections.SequencedHashMap;
|
||||
|
||||
public class JRDesignCrosstab extends JRDesignElement implements JRCrosstab {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_COLUMN_BREAK_OFFSET = "columnBreakOffset";
|
||||
|
||||
public static final String PROPERTY_DATASET = "dataset";
|
||||
|
||||
public static final String PROPERTY_HEADER_CELL = "headerCell";
|
||||
|
||||
public static final String PROPERTY_PARAMETERS_MAP_EXPRESSION = "parametersMapExpression";
|
||||
|
||||
public static final String PROPERTY_REPEAT_COLUMN_HEADERS = "repeatColumnHeaders";
|
||||
|
||||
public static final String PROPERTY_REPEAT_ROW_HEADERS = "repeatRowHeaders";
|
||||
|
||||
public static final String PROPERTY_WHEN_NO_DATA_CELL = "whenNoDataCell";
|
||||
|
||||
public static final String PROPERTY_CELLS = "cells";
|
||||
|
||||
public static final String PROPERTY_ROW_GROUPS = "rowGroups";
|
||||
|
||||
public static final String PROPERTY_COLUMN_GROUPS = "columnGroups";
|
||||
|
||||
public static final String PROPERTY_MEASURES = "measures";
|
||||
|
||||
public static final String PROPERTY_PARAMETERS = "parameters";
|
||||
|
||||
protected List parametersList;
|
||||
|
||||
protected Map parametersMap;
|
||||
|
||||
protected SequencedHashMap variablesList;
|
||||
|
||||
protected JRExpression parametersMapExpression;
|
||||
|
||||
protected JRDesignCrosstabDataset dataset;
|
||||
|
||||
protected List rowGroups;
|
||||
|
||||
protected List columnGroups;
|
||||
|
||||
protected List measures;
|
||||
|
||||
protected Map rowGroupsMap;
|
||||
|
||||
protected Map columnGroupsMap;
|
||||
|
||||
protected Map measuresMap;
|
||||
|
||||
protected int columnBreakOffset = 10;
|
||||
|
||||
protected boolean repeatColumnHeaders = true;
|
||||
|
||||
protected boolean repeatRowHeaders = true;
|
||||
|
||||
protected byte runDirection;
|
||||
|
||||
protected List cellsList;
|
||||
|
||||
protected Map cellsMap;
|
||||
|
||||
protected JRDesignCrosstabCell[][] crossCells;
|
||||
|
||||
protected JRDesignCellContents whenNoDataCell;
|
||||
|
||||
protected JRDesignCellContents headerCell;
|
||||
|
||||
private class MeasureClassChangeListener implements PropertyChangeListener, Serializable {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
private final JRDesignCrosstab this$0;
|
||||
|
||||
private MeasureClassChangeListener() {}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
JRDesignCrosstab.this.measureClassChanged((JRDesignCrosstabMeasure)evt.getSource(), (String)evt.getNewValue());
|
||||
}
|
||||
}
|
||||
|
||||
private PropertyChangeListener measureClassChangeListener = new MeasureClassChangeListener();
|
||||
|
||||
private static final Object[] BUILT_IN_PARAMETERS = new Object[] {
|
||||
"REPORT_PARAMETERS_MAP", Map.class, "REPORT_LOCALE", Locale.class, "REPORT_RESOURCE_BUNDLE", ResourceBundle.class, "REPORT_TIME_ZONE", TimeZone.class, "REPORT_FORMAT_FACTORY", FormatFactory.class,
|
||||
"REPORT_CLASS_LOADER", ClassLoader.class, "REPORT_URL_HANDLER_FACTORY", URLStreamHandlerFactory.class, "REPORT_FILE_RESOLVER", FileResolver.class };
|
||||
|
||||
private static final Object[] BUILT_IN_VARIABLES = new Object[] { "ROW_COUNT", Integer.class, "COLUMN_COUNT", Integer.class };
|
||||
|
||||
public JRDesignCrosstab(JRDefaultStyleProvider defaultStyleProvider) {
|
||||
super(defaultStyleProvider);
|
||||
this.parametersList = new ArrayList();
|
||||
this.parametersMap = new HashMap();
|
||||
this.rowGroupsMap = new HashMap();
|
||||
this.rowGroups = new ArrayList();
|
||||
this.columnGroupsMap = new HashMap();
|
||||
this.columnGroups = new ArrayList();
|
||||
this.measuresMap = new HashMap();
|
||||
this.measures = new ArrayList();
|
||||
this.cellsMap = new HashMap();
|
||||
this.cellsList = new ArrayList();
|
||||
addBuiltinParameters();
|
||||
this.variablesList = new SequencedHashMap();
|
||||
addBuiltinVariables();
|
||||
this.dataset = new JRDesignCrosstabDataset();
|
||||
}
|
||||
|
||||
private void addBuiltinParameters() {
|
||||
for (int i = 0; i < BUILT_IN_PARAMETERS.length; i++) {
|
||||
JRDesignCrosstabParameter parameter = new JRDesignCrosstabParameter();
|
||||
parameter.setName((String)BUILT_IN_PARAMETERS[i++]);
|
||||
parameter.setValueClass((Class)BUILT_IN_PARAMETERS[i]);
|
||||
parameter.setSystemDefined(true);
|
||||
try {
|
||||
addParameter(parameter);
|
||||
} catch (JRException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void addBuiltinVariables() {
|
||||
for (int i = 0; i < BUILT_IN_VARIABLES.length; i++) {
|
||||
JRDesignVariable variable = new JRDesignVariable();
|
||||
variable.setName((String)BUILT_IN_VARIABLES[i]);
|
||||
variable.setValueClass((Class)BUILT_IN_VARIABLES[++i]);
|
||||
variable.setCalculation((byte)8);
|
||||
variable.setSystemDefined(true);
|
||||
addVariable((JRVariable)variable);
|
||||
}
|
||||
}
|
||||
|
||||
public JRDesignCrosstab() {
|
||||
this((JRDefaultStyleProvider)null);
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public JRCrosstabDataset getDataset() {
|
||||
return this.dataset;
|
||||
}
|
||||
|
||||
public JRDesignCrosstabDataset getDesignDataset() {
|
||||
return this.dataset;
|
||||
}
|
||||
|
||||
public JRCrosstabRowGroup[] getRowGroups() {
|
||||
JRCrosstabRowGroup[] groups = new JRCrosstabRowGroup[this.rowGroups.size()];
|
||||
this.rowGroups.toArray((Object[])groups);
|
||||
return groups;
|
||||
}
|
||||
|
||||
public JRCrosstabColumnGroup[] getColumnGroups() {
|
||||
JRCrosstabColumnGroup[] groups = new JRCrosstabColumnGroup[this.columnGroups.size()];
|
||||
this.columnGroups.toArray((Object[])groups);
|
||||
return groups;
|
||||
}
|
||||
|
||||
public JRCrosstabMeasure[] getMeasures() {
|
||||
JRCrosstabMeasure[] measureArray = new JRCrosstabMeasure[this.measures.size()];
|
||||
this.measures.toArray((Object[])measureArray);
|
||||
return measureArray;
|
||||
}
|
||||
|
||||
public void collectExpressions(JRExpressionCollector collector) {
|
||||
collector.collect(this);
|
||||
}
|
||||
|
||||
public void visit(JRVisitor visitor) {
|
||||
visitor.visitCrosstab(this);
|
||||
}
|
||||
|
||||
public void setDataset(JRDesignCrosstabDataset dataset) {
|
||||
Object old = this.dataset;
|
||||
this.dataset = dataset;
|
||||
getEventSupport().firePropertyChange("dataset", old, this.dataset);
|
||||
}
|
||||
|
||||
public void addRowGroup(JRDesignCrosstabRowGroup group) throws JRException {
|
||||
String groupName = group.getName();
|
||||
if (this.rowGroupsMap.containsKey(groupName) || this.columnGroupsMap.containsKey(groupName) || this.measuresMap.containsKey(groupName))
|
||||
throw new JRException("A group or measure having the same name already exists in the crosstab.");
|
||||
this.rowGroupsMap.put(groupName, new Integer(this.rowGroups.size()));
|
||||
this.rowGroups.add(group);
|
||||
addRowGroupVars(group);
|
||||
setParent(group);
|
||||
getEventSupport().fireCollectionElementAddedEvent("rowGroups", group, this.rowGroups.size() - 1);
|
||||
}
|
||||
|
||||
protected void addRowGroupVars(JRDesignCrosstabRowGroup rowGroup) {
|
||||
addVariable(rowGroup.getVariable());
|
||||
for (Iterator measureIt = this.measures.iterator(); measureIt.hasNext(); ) {
|
||||
JRCrosstabMeasure measure = measureIt.next();
|
||||
addTotalVar(measure, rowGroup, (JRCrosstabColumnGroup)null);
|
||||
for (Iterator colIt = this.columnGroups.iterator(); colIt.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = colIt.next();
|
||||
addTotalVar(measure, rowGroup, colGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addColumnGroup(JRDesignCrosstabColumnGroup group) throws JRException {
|
||||
String groupName = group.getName();
|
||||
if (this.rowGroupsMap.containsKey(groupName) || this.columnGroupsMap.containsKey(groupName) || this.measuresMap.containsKey(groupName))
|
||||
throw new JRException("A group or measure having the same name already exists in the crosstab.");
|
||||
this.columnGroupsMap.put(groupName, new Integer(this.columnGroups.size()));
|
||||
this.columnGroups.add(group);
|
||||
addColGroupVars(group);
|
||||
setParent(group);
|
||||
getEventSupport().fireCollectionElementAddedEvent("columnGroups", group, this.columnGroups.size() - 1);
|
||||
}
|
||||
|
||||
protected void addColGroupVars(JRDesignCrosstabColumnGroup colGroup) {
|
||||
addVariable(colGroup.getVariable());
|
||||
for (Iterator measureIt = this.measures.iterator(); measureIt.hasNext(); ) {
|
||||
JRCrosstabMeasure measure = measureIt.next();
|
||||
addTotalVar(measure, (JRCrosstabRowGroup)null, colGroup);
|
||||
for (Iterator rowIt = this.rowGroups.iterator(); rowIt.hasNext(); ) {
|
||||
JRCrosstabRowGroup rowGroup = rowIt.next();
|
||||
addTotalVar(measure, rowGroup, colGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void addMeasure(JRDesignCrosstabMeasure measure) throws JRException {
|
||||
String measureName = measure.getName();
|
||||
if (this.rowGroupsMap.containsKey(measureName) || this.columnGroupsMap.containsKey(measureName) || this.measuresMap.containsKey(measureName))
|
||||
throw new JRException("A group or measure having the same name already exists in the crosstab.");
|
||||
measure.addPropertyChangeListener("valueClassName", this.measureClassChangeListener);
|
||||
this.measuresMap.put(measureName, new Integer(this.measures.size()));
|
||||
this.measures.add(measure);
|
||||
addMeasureVars(measure);
|
||||
getEventSupport().fireCollectionElementAddedEvent("measures", measure, this.measures.size() - 1);
|
||||
}
|
||||
|
||||
protected void addMeasureVars(JRDesignCrosstabMeasure measure) {
|
||||
addVariable(measure.getVariable());
|
||||
for (Iterator colIt = this.columnGroups.iterator(); colIt.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = colIt.next();
|
||||
addTotalVar((JRCrosstabMeasure)measure, (JRCrosstabRowGroup)null, colGroup);
|
||||
}
|
||||
for (Iterator rowIt = this.rowGroups.iterator(); rowIt.hasNext(); ) {
|
||||
JRCrosstabRowGroup rowGroup = rowIt.next();
|
||||
addTotalVar((JRCrosstabMeasure)measure, rowGroup, (JRCrosstabColumnGroup)null);
|
||||
for (Iterator iterator = this.columnGroups.iterator(); iterator.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = iterator.next();
|
||||
addTotalVar((JRCrosstabMeasure)measure, rowGroup, colGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void addTotalVar(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup) {
|
||||
JRDesignVariable var = new JRDesignVariable();
|
||||
var.setCalculation((byte)8);
|
||||
var.setSystemDefined(true);
|
||||
var.setName(getTotalVariableName(measure, rowGroup, colGroup));
|
||||
var.setValueClassName(measure.getValueClassName());
|
||||
addVariable((JRVariable)var);
|
||||
}
|
||||
|
||||
protected void removeTotalVar(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup) {
|
||||
String varName = getTotalVariableName(measure, rowGroup, colGroup);
|
||||
removeVariable(varName);
|
||||
}
|
||||
|
||||
public static String getTotalVariableName(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup) {
|
||||
StringBuffer name = new StringBuffer();
|
||||
name.append(measure.getName());
|
||||
if (rowGroup != null) {
|
||||
name.append('_');
|
||||
name.append(rowGroup.getName());
|
||||
}
|
||||
if (colGroup != null) {
|
||||
name.append('_');
|
||||
name.append(colGroup.getName());
|
||||
}
|
||||
name.append("_ALL");
|
||||
return name.toString();
|
||||
}
|
||||
|
||||
public JRCrosstabRowGroup removeRowGroup(String groupName) {
|
||||
JRCrosstabRowGroup removed = null;
|
||||
Integer idx = (Integer)this.rowGroupsMap.remove(groupName);
|
||||
if (idx != null) {
|
||||
removed = this.rowGroups.remove(idx.intValue());
|
||||
for (ListIterator listIterator = this.rowGroups.listIterator(idx.intValue()); listIterator.hasNext(); ) {
|
||||
JRCrosstabRowGroup group = listIterator.next();
|
||||
this.rowGroupsMap.put(group.getName(), new Integer(listIterator.previousIndex()));
|
||||
}
|
||||
for (Iterator it = this.cellsList.iterator(); it.hasNext(); ) {
|
||||
JRCrosstabCell cell = it.next();
|
||||
String rowTotalGroup = cell.getRowTotalGroup();
|
||||
if (rowTotalGroup != null && rowTotalGroup.equals(groupName)) {
|
||||
it.remove();
|
||||
this.cellsMap.remove(new Pair(rowTotalGroup, cell.getColumnTotalGroup()));
|
||||
getEventSupport().fireCollectionElementRemovedEvent("cells", cell, -1);
|
||||
}
|
||||
}
|
||||
removeRowGroupVars(removed);
|
||||
getEventSupport().fireCollectionElementRemovedEvent("rowGroups", removed, idx.intValue());
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected void removeRowGroupVars(JRCrosstabRowGroup rowGroup) {
|
||||
removeVariable(rowGroup.getVariable());
|
||||
for (Iterator measureIt = this.measures.iterator(); measureIt.hasNext(); ) {
|
||||
JRCrosstabMeasure measure = measureIt.next();
|
||||
removeTotalVar(measure, rowGroup, (JRCrosstabColumnGroup)null);
|
||||
for (Iterator colIt = this.columnGroups.iterator(); colIt.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = colIt.next();
|
||||
removeTotalVar(measure, rowGroup, colGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JRCrosstabRowGroup removeRowGroup(JRCrosstabRowGroup group) {
|
||||
return removeRowGroup(group.getName());
|
||||
}
|
||||
|
||||
public JRCrosstabColumnGroup removeColumnGroup(String groupName) {
|
||||
JRCrosstabColumnGroup removed = null;
|
||||
Integer idx = (Integer)this.columnGroupsMap.remove(groupName);
|
||||
if (idx != null) {
|
||||
removed = this.columnGroups.remove(idx.intValue());
|
||||
for (ListIterator listIterator = this.columnGroups.listIterator(idx.intValue()); listIterator.hasNext(); ) {
|
||||
JRCrosstabColumnGroup group = listIterator.next();
|
||||
this.columnGroupsMap.put(group.getName(), new Integer(listIterator.previousIndex()));
|
||||
}
|
||||
for (Iterator it = this.cellsList.iterator(); it.hasNext(); ) {
|
||||
JRCrosstabCell cell = it.next();
|
||||
String columnTotalGroup = cell.getColumnTotalGroup();
|
||||
if (columnTotalGroup != null && columnTotalGroup.equals(groupName)) {
|
||||
it.remove();
|
||||
this.cellsMap.remove(new Pair(cell.getRowTotalGroup(), columnTotalGroup));
|
||||
getEventSupport().fireCollectionElementRemovedEvent("cells", cell, -1);
|
||||
}
|
||||
}
|
||||
removeColGroupVars(removed);
|
||||
getEventSupport().fireCollectionElementRemovedEvent("columnGroups", removed, idx.intValue());
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected void removeColGroupVars(JRCrosstabColumnGroup colGroup) {
|
||||
removeVariable(colGroup.getVariable());
|
||||
for (Iterator measureIt = this.measures.iterator(); measureIt.hasNext(); ) {
|
||||
JRCrosstabMeasure measure = measureIt.next();
|
||||
removeTotalVar(measure, (JRCrosstabRowGroup)null, colGroup);
|
||||
for (Iterator rowIt = this.rowGroups.iterator(); rowIt.hasNext(); ) {
|
||||
JRCrosstabRowGroup rowGroup = rowIt.next();
|
||||
removeTotalVar(measure, rowGroup, colGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JRCrosstabColumnGroup removeColumnGroup(JRCrosstabColumnGroup group) {
|
||||
return removeColumnGroup(group.getName());
|
||||
}
|
||||
|
||||
public JRCrosstabMeasure removeMeasure(String measureName) {
|
||||
JRDesignCrosstabMeasure removed = null;
|
||||
Integer idx = (Integer)this.measuresMap.remove(measureName);
|
||||
if (idx != null) {
|
||||
removed = this.measures.remove(idx.intValue());
|
||||
for (ListIterator it = this.measures.listIterator(idx.intValue()); it.hasNext(); ) {
|
||||
JRCrosstabMeasure group = it.next();
|
||||
this.measuresMap.put(group.getName(), new Integer(it.previousIndex()));
|
||||
}
|
||||
removeMeasureVars(removed);
|
||||
removed.removePropertyChangeListener("valueClassName", this.measureClassChangeListener);
|
||||
getEventSupport().fireCollectionElementRemovedEvent("measures", removed, idx.intValue());
|
||||
}
|
||||
return (JRCrosstabMeasure)removed;
|
||||
}
|
||||
|
||||
protected void removeMeasureVars(JRDesignCrosstabMeasure measure) {
|
||||
removeVariable(measure.getVariable());
|
||||
for (Iterator colIt = this.columnGroups.iterator(); colIt.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = colIt.next();
|
||||
removeTotalVar((JRCrosstabMeasure)measure, (JRCrosstabRowGroup)null, colGroup);
|
||||
}
|
||||
for (Iterator rowIt = this.rowGroups.iterator(); rowIt.hasNext(); ) {
|
||||
JRCrosstabRowGroup rowGroup = rowIt.next();
|
||||
removeTotalVar((JRCrosstabMeasure)measure, rowGroup, (JRCrosstabColumnGroup)null);
|
||||
for (Iterator iterator = this.columnGroups.iterator(); iterator.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = iterator.next();
|
||||
removeTotalVar((JRCrosstabMeasure)measure, rowGroup, colGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JRCrosstabMeasure removeMeasure(JRCrosstabMeasure measure) {
|
||||
return removeMeasure(measure.getName());
|
||||
}
|
||||
|
||||
public boolean isRepeatColumnHeaders() {
|
||||
return this.repeatColumnHeaders;
|
||||
}
|
||||
|
||||
public void setRepeatColumnHeaders(boolean repeatColumnHeaders) {
|
||||
boolean old = this.repeatColumnHeaders;
|
||||
this.repeatColumnHeaders = repeatColumnHeaders;
|
||||
getEventSupport().firePropertyChange("repeatColumnHeaders", old, this.repeatColumnHeaders);
|
||||
}
|
||||
|
||||
public boolean isRepeatRowHeaders() {
|
||||
return this.repeatRowHeaders;
|
||||
}
|
||||
|
||||
public void setRepeatRowHeaders(boolean repeatRowHeaders) {
|
||||
boolean old = this.repeatRowHeaders;
|
||||
this.repeatRowHeaders = repeatRowHeaders;
|
||||
getEventSupport().firePropertyChange("repeatRowHeaders", old, this.repeatRowHeaders);
|
||||
}
|
||||
|
||||
public JRCrosstabCell[][] getCells() {
|
||||
return (JRCrosstabCell[][])this.crossCells;
|
||||
}
|
||||
|
||||
public List getCellsList() {
|
||||
return this.cellsList;
|
||||
}
|
||||
|
||||
public Map getCellsMap() {
|
||||
return this.cellsMap;
|
||||
}
|
||||
|
||||
public void addCell(JRDesignCrosstabCell cell) throws JRException {
|
||||
String rowTotalGroup = cell.getRowTotalGroup();
|
||||
if (rowTotalGroup != null && !this.rowGroupsMap.containsKey(rowTotalGroup))
|
||||
throw new JRException("Row group " + rowTotalGroup + " does not exist.");
|
||||
String columnTotalGroup = cell.getColumnTotalGroup();
|
||||
if (columnTotalGroup != null && !this.columnGroupsMap.containsKey(columnTotalGroup))
|
||||
throw new JRException("Row group " + columnTotalGroup + " does not exist.");
|
||||
Object cellKey = new Pair(rowTotalGroup, columnTotalGroup);
|
||||
if (this.cellsMap.containsKey(cellKey))
|
||||
throw new JRException("Duplicate cell in crosstab.");
|
||||
this.cellsMap.put(cellKey, cell);
|
||||
this.cellsList.add(cell);
|
||||
setCellOrigin(cell.getContents(), new JRCrosstabOrigin(this, (byte)7, rowTotalGroup, columnTotalGroup));
|
||||
getEventSupport().fireCollectionElementAddedEvent("cells", cell, this.cellsList.size() - 1);
|
||||
}
|
||||
|
||||
public JRCrosstabCell removeCell(String rowTotalGroup, String columnTotalGroup) {
|
||||
Object cellKey = new Pair(rowTotalGroup, columnTotalGroup);
|
||||
JRCrosstabCell cell = (JRCrosstabCell)this.cellsMap.remove(cellKey);
|
||||
if (cell != null) {
|
||||
this.cellsList.remove(cell);
|
||||
getEventSupport().fireCollectionElementRemovedEvent("cells", cell, -1);
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
|
||||
public JRCrosstabCell removeCell(JRCrosstabCell cell) {
|
||||
return removeCell(cell.getRowTotalGroup(), cell.getColumnTotalGroup());
|
||||
}
|
||||
|
||||
public JRCrosstabParameter[] getParameters() {
|
||||
JRCrosstabParameter[] parameters = new JRCrosstabParameter[this.parametersList.size()];
|
||||
this.parametersList.toArray((Object[])parameters);
|
||||
return parameters;
|
||||
}
|
||||
|
||||
public List getParametersList() {
|
||||
return this.parametersList;
|
||||
}
|
||||
|
||||
public Map getParametersMap() {
|
||||
return this.parametersMap;
|
||||
}
|
||||
|
||||
public JRExpression getParametersMapExpression() {
|
||||
return this.parametersMapExpression;
|
||||
}
|
||||
|
||||
public void addParameter(JRCrosstabParameter parameter) throws JRException {
|
||||
if (this.parametersMap.containsKey(parameter.getName()))
|
||||
if (this.parametersMap.containsKey(parameter.getName()))
|
||||
throw new JRException("Duplicate declaration of parameter : " + parameter.getName());
|
||||
this.parametersMap.put(parameter.getName(), parameter);
|
||||
this.parametersList.add(parameter);
|
||||
getEventSupport().fireCollectionElementAddedEvent("parameters", parameter, this.parametersList.size() - 1);
|
||||
}
|
||||
|
||||
public JRCrosstabParameter removeParameter(String parameterName) {
|
||||
JRCrosstabParameter param = (JRCrosstabParameter)this.parametersMap.remove(parameterName);
|
||||
if (param != null) {
|
||||
int idx = this.parametersList.indexOf(param);
|
||||
if (idx >= 0)
|
||||
this.parametersList.remove(idx);
|
||||
getEventSupport().fireCollectionElementRemovedEvent("parameters", param, idx);
|
||||
}
|
||||
return param;
|
||||
}
|
||||
|
||||
public JRCrosstabParameter removeParameter(JRCrosstabParameter parameter) {
|
||||
return removeParameter(parameter.getName());
|
||||
}
|
||||
|
||||
public void setParametersMapExpression(JRExpression expression) {
|
||||
Object old = this.parametersMapExpression;
|
||||
this.parametersMapExpression = expression;
|
||||
getEventSupport().firePropertyChange("parametersMapExpression", old, this.parametersMapExpression);
|
||||
}
|
||||
|
||||
public Map getVariablesMap() {
|
||||
JRVariable[] variables = getVariables();
|
||||
Map variablesMap = new HashMap();
|
||||
for (int i = 0; i < variables.length; i++)
|
||||
variablesMap.put(variables[i].getName(), variables[i]);
|
||||
return variablesMap;
|
||||
}
|
||||
|
||||
public JRVariable[] getVariables() {
|
||||
JRVariable[] variables = new JRVariable[this.variablesList.size()];
|
||||
this.variablesList.values().toArray((Object[])variables);
|
||||
return variables;
|
||||
}
|
||||
|
||||
public int getColumnBreakOffset() {
|
||||
return this.columnBreakOffset;
|
||||
}
|
||||
|
||||
public void setColumnBreakOffset(int columnBreakOffset) {
|
||||
int old = this.columnBreakOffset;
|
||||
this.columnBreakOffset = columnBreakOffset;
|
||||
getEventSupport().firePropertyChange("columnBreakOffset", old, this.columnBreakOffset);
|
||||
}
|
||||
|
||||
public void preprocess() {
|
||||
setGroupVariablesClass(this.rowGroups);
|
||||
setGroupVariablesClass(this.columnGroups);
|
||||
calculateSizes();
|
||||
}
|
||||
|
||||
protected void setGroupVariablesClass(List groups) {
|
||||
for (Iterator it = groups.iterator(); it.hasNext(); ) {
|
||||
JRDesignCrosstabGroup group = it.next();
|
||||
JRCrosstabBucket bucket = group.getBucket();
|
||||
if (bucket != null) {
|
||||
JRExpression expression = bucket.getExpression();
|
||||
if (expression != null)
|
||||
group.designVariable.setValueClassName(expression.getValueClassName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void calculateSizes() {
|
||||
setWhenNoDataCellSize();
|
||||
createCellMatrix();
|
||||
int rowHeadersWidth = calculateRowHeadersSizes();
|
||||
int colHeadersHeight = calculateColumnHeadersSizes();
|
||||
if (this.headerCell != null) {
|
||||
this.headerCell.setWidth(rowHeadersWidth);
|
||||
this.headerCell.setHeight(colHeadersHeight);
|
||||
}
|
||||
}
|
||||
|
||||
protected void setWhenNoDataCellSize() {
|
||||
if (this.whenNoDataCell != null) {
|
||||
this.whenNoDataCell.setWidth(getWidth());
|
||||
this.whenNoDataCell.setHeight(getHeight());
|
||||
}
|
||||
}
|
||||
|
||||
protected void createCellMatrix() {
|
||||
this.crossCells = new JRDesignCrosstabCell[this.rowGroups.size() + 1][this.columnGroups.size() + 1];
|
||||
for (Iterator it = this.cellsList.iterator(); it.hasNext(); ) {
|
||||
JRDesignCrosstabCell crosstabCell = it.next();
|
||||
JRDesignCellContents contents = (JRDesignCellContents)crosstabCell.getContents();
|
||||
String rowTotalGroup = crosstabCell.getRowTotalGroup();
|
||||
int rowGroupIndex = (rowTotalGroup == null) ? (rowGroupIndex = this.rowGroups.size()) : ((Integer)this.rowGroupsMap.get(rowTotalGroup)).intValue();
|
||||
Integer cellWidth = crosstabCell.getWidth();
|
||||
if (cellWidth != null)
|
||||
contents.setWidth(cellWidth.intValue());
|
||||
String columnTotalGroup = crosstabCell.getColumnTotalGroup();
|
||||
int columnGroupIndex = (columnTotalGroup == null) ? (columnGroupIndex = this.columnGroups.size()) : ((Integer)this.columnGroupsMap.get(columnTotalGroup)).intValue();
|
||||
Integer cellHeight = crosstabCell.getHeight();
|
||||
if (cellHeight != null)
|
||||
contents.setHeight(cellHeight.intValue());
|
||||
this.crossCells[rowGroupIndex][columnGroupIndex] = crosstabCell;
|
||||
}
|
||||
inheritCells();
|
||||
}
|
||||
|
||||
protected JRDesignCrosstabRowGroup getRowGroup(int rowGroupIndex) {
|
||||
return this.rowGroups.get(rowGroupIndex);
|
||||
}
|
||||
|
||||
protected JRDesignCrosstabColumnGroup getColumnGroup(int columnGroupIndex) {
|
||||
return this.columnGroups.get(columnGroupIndex);
|
||||
}
|
||||
|
||||
protected void inheritCells() {
|
||||
for (int i = this.rowGroups.size(); i >= 0; i--) {
|
||||
for (int j = this.columnGroups.size(); j >= 0; j--) {
|
||||
boolean used = ((i == this.rowGroups.size() || getRowGroup(i).hasTotal()) && (j == this.columnGroups.size() || getColumnGroup(j).hasTotal()));
|
||||
if (used) {
|
||||
if (this.crossCells[i][j] == null) {
|
||||
inheritCell(i, j);
|
||||
if (this.crossCells[i][j] == null) {
|
||||
this.crossCells[i][j] = emptyCell(i, j);
|
||||
inheritCellSize(i, j);
|
||||
}
|
||||
} else {
|
||||
inheritCellSize(i, j);
|
||||
}
|
||||
} else {
|
||||
this.crossCells[i][j] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private JRDesignCrosstabCell emptyCell(int i, int j) {
|
||||
JRDesignCrosstabCell emptyCell = new JRDesignCrosstabCell();
|
||||
if (i < this.rowGroups.size())
|
||||
emptyCell.setRowTotalGroup(((JRCrosstabRowGroup)this.rowGroups.get(i)).getName());
|
||||
if (j < this.columnGroups.size())
|
||||
emptyCell.setColumnTotalGroup(((JRCrosstabColumnGroup)this.columnGroups.get(j)).getName());
|
||||
return emptyCell;
|
||||
}
|
||||
|
||||
protected void inheritCellSize(int i, int j) {
|
||||
JRDesignCrosstabCell cell = this.crossCells[i][j];
|
||||
JRDesignCellContents contents = (JRDesignCellContents)cell.getContents();
|
||||
if (contents.getWidth() == Integer.MIN_VALUE)
|
||||
if (i < this.rowGroups.size()) {
|
||||
JRDesignCrosstabCell rowCell = this.crossCells[this.rowGroups.size()][j];
|
||||
if (rowCell != null)
|
||||
contents.setWidth(rowCell.getContents().getWidth());
|
||||
} else {
|
||||
for (int k = j + 1; k <= this.columnGroups.size(); k++) {
|
||||
if (this.crossCells[i][k] != null) {
|
||||
contents.setWidth(this.crossCells[i][k].getContents().getWidth());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (contents.getHeight() == Integer.MIN_VALUE)
|
||||
if (j < this.columnGroups.size()) {
|
||||
JRDesignCrosstabCell colCell = this.crossCells[i][this.columnGroups.size()];
|
||||
if (colCell != null)
|
||||
contents.setHeight(colCell.getContents().getHeight());
|
||||
} else {
|
||||
for (int k = i + 1; k <= this.rowGroups.size(); k++) {
|
||||
if (this.crossCells[k][j] != null)
|
||||
contents.setHeight(this.crossCells[k][j].getContents().getHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void inheritCell(int i, int j) {
|
||||
JRDesignCrosstabCell inheritedCell = null;
|
||||
if (j < this.columnGroups.size()) {
|
||||
JRDesignCrosstabCell colCell = this.crossCells[this.rowGroups.size()][j];
|
||||
JRDesignCellContents colContents = (colCell == null) ? null : (JRDesignCellContents)colCell.getContents();
|
||||
for (int k = j + 1; inheritedCell == null && k <= this.columnGroups.size(); k++) {
|
||||
JRDesignCrosstabCell cell = this.crossCells[i][k];
|
||||
if (cell != null) {
|
||||
JRDesignCellContents contents = (JRDesignCellContents)cell.getContents();
|
||||
if (colContents == null || contents.getWidth() == colContents.getWidth())
|
||||
inheritedCell = cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (inheritedCell == null && i < this.rowGroups.size()) {
|
||||
JRDesignCrosstabCell rowCell = this.crossCells[i][this.columnGroups.size()];
|
||||
JRDesignCellContents rowContents = (rowCell == null) ? null : (JRDesignCellContents)rowCell.getContents();
|
||||
for (int k = i + 1; inheritedCell == null && k <= this.rowGroups.size(); k++) {
|
||||
JRDesignCrosstabCell cell = this.crossCells[k][j];
|
||||
if (cell != null) {
|
||||
JRDesignCellContents contents = (JRDesignCellContents)cell.getContents();
|
||||
if (rowContents == null || contents.getHeight() == rowContents.getHeight())
|
||||
inheritedCell = cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.crossCells[i][j] = inheritedCell;
|
||||
}
|
||||
|
||||
protected int calculateRowHeadersSizes() {
|
||||
int widthSum = 0;
|
||||
for (int i = this.rowGroups.size() - 1, heightSum = 0; i >= 0; i--) {
|
||||
JRDesignCrosstabRowGroup group = this.rowGroups.get(i);
|
||||
widthSum += group.getWidth();
|
||||
JRDesignCrosstabCell cell = this.crossCells[i + 1][this.columnGroups.size()];
|
||||
if (cell != null)
|
||||
heightSum += cell.getContents().getHeight();
|
||||
JRDesignCellContents header = (JRDesignCellContents)group.getHeader();
|
||||
header.setHeight(heightSum);
|
||||
header.setWidth(group.getWidth());
|
||||
if (group.hasTotal()) {
|
||||
JRDesignCellContents totalHeader = (JRDesignCellContents)group.getTotalHeader();
|
||||
totalHeader.setWidth(widthSum);
|
||||
JRDesignCrosstabCell totalCell = this.crossCells[i][this.columnGroups.size()];
|
||||
if (totalCell != null)
|
||||
totalHeader.setHeight(totalCell.getContents().getHeight());
|
||||
}
|
||||
}
|
||||
return widthSum;
|
||||
}
|
||||
|
||||
protected int calculateColumnHeadersSizes() {
|
||||
int heightSum = 0;
|
||||
for (int i = this.columnGroups.size() - 1, widthSum = 0; i >= 0; i--) {
|
||||
JRDesignCrosstabColumnGroup group = this.columnGroups.get(i);
|
||||
heightSum += group.getHeight();
|
||||
JRDesignCrosstabCell cell = this.crossCells[this.rowGroups.size()][i + 1];
|
||||
if (cell != null)
|
||||
widthSum += cell.getContents().getWidth();
|
||||
JRDesignCellContents header = (JRDesignCellContents)group.getHeader();
|
||||
header.setHeight(group.getHeight());
|
||||
header.setWidth(widthSum);
|
||||
if (group.hasTotal()) {
|
||||
JRDesignCellContents totalHeader = (JRDesignCellContents)group.getTotalHeader();
|
||||
totalHeader.setHeight(heightSum);
|
||||
JRDesignCrosstabCell totalCell = this.crossCells[this.rowGroups.size()][i];
|
||||
if (totalCell != null)
|
||||
totalHeader.setWidth(totalCell.getContents().getWidth());
|
||||
}
|
||||
}
|
||||
return heightSum;
|
||||
}
|
||||
|
||||
public JRCellContents getWhenNoDataCell() {
|
||||
return this.whenNoDataCell;
|
||||
}
|
||||
|
||||
public void setWhenNoDataCell(JRDesignCellContents whenNoDataCell) {
|
||||
Object old = this.whenNoDataCell;
|
||||
this.whenNoDataCell = whenNoDataCell;
|
||||
setCellOrigin(this.whenNoDataCell, new JRCrosstabOrigin(this, (byte)2));
|
||||
getEventSupport().firePropertyChange("whenNoDataCell", old, this.whenNoDataCell);
|
||||
}
|
||||
|
||||
public JRElement getElementByKey(String elementKey) {
|
||||
return JRBaseCrosstab.getElementByKey(this, elementKey);
|
||||
}
|
||||
|
||||
public byte getMode() {
|
||||
return JRStyleResolver.getMode((JRCommonElement)this, (byte)2);
|
||||
}
|
||||
|
||||
public JRCellContents getHeaderCell() {
|
||||
return this.headerCell;
|
||||
}
|
||||
|
||||
public void setHeaderCell(JRDesignCellContents headerCell) {
|
||||
Object old = this.headerCell;
|
||||
this.headerCell = headerCell;
|
||||
setCellOrigin(this.headerCell, new JRCrosstabOrigin(this, (byte)1));
|
||||
getEventSupport().firePropertyChange("headerCell", old, this.headerCell);
|
||||
}
|
||||
|
||||
protected void measureClassChanged(JRDesignCrosstabMeasure measure, String valueClassName) {
|
||||
for (Iterator colIt = this.columnGroups.iterator(); colIt.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = colIt.next();
|
||||
setTotalVarClass((JRCrosstabMeasure)measure, (JRCrosstabRowGroup)null, colGroup, valueClassName);
|
||||
}
|
||||
for (Iterator rowIt = this.rowGroups.iterator(); rowIt.hasNext(); ) {
|
||||
JRCrosstabRowGroup rowGroup = rowIt.next();
|
||||
setTotalVarClass((JRCrosstabMeasure)measure, rowGroup, (JRCrosstabColumnGroup)null, valueClassName);
|
||||
for (Iterator iterator = this.columnGroups.iterator(); iterator.hasNext(); ) {
|
||||
JRCrosstabColumnGroup colGroup = iterator.next();
|
||||
setTotalVarClass((JRCrosstabMeasure)measure, rowGroup, colGroup, valueClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void setTotalVarClass(JRCrosstabMeasure measure, JRCrosstabRowGroup rowGroup, JRCrosstabColumnGroup colGroup, String valueClassName) {
|
||||
JRDesignVariable variable = getVariable(getTotalVariableName(measure, rowGroup, colGroup));
|
||||
variable.setValueClassName(valueClassName);
|
||||
}
|
||||
|
||||
private void addVariable(JRVariable variable) {
|
||||
this.variablesList.put(variable.getName(), variable);
|
||||
}
|
||||
|
||||
private void removeVariable(JRVariable variable) {
|
||||
removeVariable(variable.getName());
|
||||
}
|
||||
|
||||
private void removeVariable(String varName) {
|
||||
this.variablesList.remove(varName);
|
||||
}
|
||||
|
||||
private JRDesignVariable getVariable(String varName) {
|
||||
return (JRDesignVariable)this.variablesList.get(varName);
|
||||
}
|
||||
|
||||
public byte getRunDirection() {
|
||||
return this.runDirection;
|
||||
}
|
||||
|
||||
public void setRunDirection(byte runDirection) {
|
||||
byte old = this.runDirection;
|
||||
this.runDirection = runDirection;
|
||||
getEventSupport().firePropertyChange("runDirection", old, this.runDirection);
|
||||
}
|
||||
|
||||
protected void setCellOrigin(JRCellContents cell, JRCrosstabOrigin origin) {
|
||||
if (cell instanceof JRDesignCellContents)
|
||||
setCellOrigin((JRDesignCellContents)cell, origin);
|
||||
}
|
||||
|
||||
protected void setCellOrigin(JRDesignCellContents cell, JRCrosstabOrigin origin) {
|
||||
if (cell != null)
|
||||
cell.setOrigin(origin);
|
||||
}
|
||||
|
||||
protected void setParent(JRDesignCrosstabGroup group) {
|
||||
if (group != null)
|
||||
group.setParent(this);
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
JRDesignCrosstab clone = (JRDesignCrosstab)super.clone();
|
||||
if (this.parametersList != null) {
|
||||
clone.parametersList = new ArrayList(this.parametersList.size());
|
||||
clone.parametersMap = new HashMap(this.parametersList.size());
|
||||
for (int i = 0; i < this.parametersList.size(); i++) {
|
||||
JRCrosstabParameter parameter = (JRCrosstabParameter)((JRCrosstabParameter)this.parametersList.get(i)).clone();
|
||||
clone.parametersList.add(parameter);
|
||||
clone.parametersMap.put(parameter.getName(), parameter);
|
||||
}
|
||||
}
|
||||
if (this.variablesList != null) {
|
||||
clone.variablesList = new SequencedHashMap(this.variablesList.size());
|
||||
for (Iterator it = this.variablesList.sequence().iterator(); it.hasNext(); ) {
|
||||
Object key = it.next();
|
||||
JRVariable variable = (JRVariable)this.variablesList.get(key);
|
||||
clone.variablesList.put(variable.getName(), variable);
|
||||
}
|
||||
}
|
||||
if (this.parametersMapExpression != null)
|
||||
clone.parametersMapExpression = (JRExpression)this.parametersMapExpression.clone();
|
||||
if (this.dataset != null)
|
||||
clone.dataset = (JRDesignCrosstabDataset)this.dataset.clone();
|
||||
if (this.rowGroups != null) {
|
||||
clone.rowGroups = new ArrayList(this.rowGroups.size());
|
||||
clone.rowGroupsMap = new HashMap(this.rowGroups.size());
|
||||
for (int i = 0; i < this.rowGroups.size(); i++) {
|
||||
JRCrosstabRowGroup group = (JRCrosstabRowGroup)((JRCrosstabRowGroup)this.rowGroups.get(i)).clone();
|
||||
clone.rowGroups.add(group);
|
||||
clone.rowGroupsMap.put(group.getName(), new Integer(i));
|
||||
}
|
||||
}
|
||||
if (this.columnGroups != null) {
|
||||
clone.columnGroups = new ArrayList(this.columnGroups.size());
|
||||
clone.columnGroupsMap = new HashMap(this.columnGroups.size());
|
||||
for (int i = 0; i < this.columnGroups.size(); i++) {
|
||||
JRCrosstabColumnGroup group = (JRCrosstabColumnGroup)((JRCrosstabColumnGroup)this.columnGroups.get(i)).clone();
|
||||
clone.columnGroups.add(group);
|
||||
clone.columnGroupsMap.put(group.getName(), new Integer(i));
|
||||
}
|
||||
}
|
||||
if (this.measures != null) {
|
||||
clone.measures = new ArrayList(this.measures.size());
|
||||
clone.measuresMap = new HashMap(this.measures.size());
|
||||
for (int i = 0; i < this.measures.size(); i++) {
|
||||
JRCrosstabMeasure measure = (JRCrosstabMeasure)((JRCrosstabMeasure)this.measures.get(i)).clone();
|
||||
clone.measures.add(measure);
|
||||
clone.measuresMap.put(measure.getName(), new Integer(i));
|
||||
}
|
||||
}
|
||||
if (this.cellsList != null) {
|
||||
clone.cellsList = new ArrayList(this.cellsList.size());
|
||||
clone.cellsMap = new HashMap(this.cellsList.size());
|
||||
for (int i = 0; i < this.cellsList.size(); i++) {
|
||||
JRDesignCrosstabCell cell = (JRDesignCrosstabCell)((JRDesignCrosstabCell)this.cellsList.get(i)).clone();
|
||||
clone.cellsList.add(cell);
|
||||
clone.cellsMap.put(new Pair(cell.getRowTotalGroup(), cell.getColumnTotalGroup()), cell);
|
||||
}
|
||||
}
|
||||
if (this.whenNoDataCell != null)
|
||||
clone.whenNoDataCell = (JRDesignCellContents)this.whenNoDataCell.clone();
|
||||
if (this.headerCell != null)
|
||||
clone.headerCell = (JRDesignCellContents)this.headerCell.clone();
|
||||
return clone;
|
||||
}
|
||||
|
||||
public List getRowGroupsList() {
|
||||
return this.rowGroups;
|
||||
}
|
||||
|
||||
public Map getRowGroupIndicesMap() {
|
||||
return this.rowGroupsMap;
|
||||
}
|
||||
|
||||
public List getColumnGroupsList() {
|
||||
return this.columnGroups;
|
||||
}
|
||||
|
||||
public Map getColumnGroupIndicesMap() {
|
||||
return this.columnGroupsMap;
|
||||
}
|
||||
|
||||
public List getMesuresList() {
|
||||
return this.measures;
|
||||
}
|
||||
|
||||
public Map getMeasureIndicesMap() {
|
||||
return this.measuresMap;
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.base.JRBaseCrosstabBucket;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.design.JRDesignExpression;
|
||||
import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
|
||||
import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
|
||||
|
||||
public class JRDesignCrosstabBucket extends JRBaseCrosstabBucket implements JRChangeEventsSupport {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_COMPARATOR_EXPRESSION = "comparatorExpression";
|
||||
|
||||
public static final String PROPERTY_EXPRESSION = "expression";
|
||||
|
||||
public static final String PROPERTY_ORDER = "order";
|
||||
|
||||
private transient JRPropertyChangeSupport eventSupport;
|
||||
|
||||
public void setComparatorExpression(JRExpression comparatorExpression) {
|
||||
Object old = this.comparatorExpression;
|
||||
this.comparatorExpression = comparatorExpression;
|
||||
getEventSupport().firePropertyChange("comparatorExpression", old, this.comparatorExpression);
|
||||
}
|
||||
|
||||
public void setExpression(JRDesignExpression expression) {
|
||||
Object old = this.expression;
|
||||
this.expression = (JRExpression)expression;
|
||||
getEventSupport().firePropertyChange("expression", old, this.expression);
|
||||
}
|
||||
|
||||
public void setOrder(byte order) {
|
||||
byte old = this.order;
|
||||
this.order = order;
|
||||
getEventSupport().firePropertyChange("order", old, this.order);
|
||||
}
|
||||
|
||||
public JRPropertyChangeSupport getEventSupport() {
|
||||
synchronized (this) {
|
||||
if (this.eventSupport == null)
|
||||
this.eventSupport = new JRPropertyChangeSupport(this);
|
||||
}
|
||||
return this.eventSupport;
|
||||
}
|
||||
}
|
@@ -0,0 +1,61 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.base.JRBaseCrosstabCell;
|
||||
import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
|
||||
import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
|
||||
|
||||
public class JRDesignCrosstabCell extends JRBaseCrosstabCell implements JRChangeEventsSupport {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_COLUMN_TOTAL_GROUP = "columnTotalGroup";
|
||||
|
||||
public static final String PROPERTY_CONTENTS = "contents";
|
||||
|
||||
public static final String PROPERTY_HEIGHT = "height";
|
||||
|
||||
public static final String PROPERTY_ROW_TOTAL_GROUP = "rowTotalGroup";
|
||||
|
||||
public static final String PROPERTY_WIDTH = "width";
|
||||
|
||||
private transient JRPropertyChangeSupport eventSupport;
|
||||
|
||||
public void setColumnTotalGroup(String columnTotalGroup) {
|
||||
Object old = this.columnTotalGroup;
|
||||
this.columnTotalGroup = columnTotalGroup;
|
||||
getEventSupport().firePropertyChange("columnTotalGroup", old, this.columnTotalGroup);
|
||||
}
|
||||
|
||||
public void setContents(JRDesignCellContents contents) {
|
||||
Object old = this.contents;
|
||||
if (contents == null)
|
||||
contents = new JRDesignCellContents();
|
||||
this.contents = contents;
|
||||
getEventSupport().firePropertyChange("contents", old, this.contents);
|
||||
}
|
||||
|
||||
public void setRowTotalGroup(String rowTotalGroup) {
|
||||
Object old = this.rowTotalGroup;
|
||||
this.rowTotalGroup = rowTotalGroup;
|
||||
getEventSupport().firePropertyChange("rowTotalGroup", old, this.rowTotalGroup);
|
||||
}
|
||||
|
||||
public void setWidth(Integer width) {
|
||||
Object old = this.width;
|
||||
this.width = width;
|
||||
getEventSupport().firePropertyChange("width", old, this.width);
|
||||
}
|
||||
|
||||
public void setHeight(Integer height) {
|
||||
Object old = this.height;
|
||||
this.height = height;
|
||||
getEventSupport().firePropertyChange("height", old, this.height);
|
||||
}
|
||||
|
||||
public JRPropertyChangeSupport getEventSupport() {
|
||||
synchronized (this) {
|
||||
if (this.eventSupport == null)
|
||||
this.eventSupport = new JRPropertyChangeSupport(this);
|
||||
}
|
||||
return this.eventSupport;
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup;
|
||||
|
||||
public class JRDesignCrosstabColumnGroup extends JRDesignCrosstabGroup implements JRCrosstabColumnGroup {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_HEIGHT = "height";
|
||||
|
||||
public static final String PROPERTY_POSITION = "position";
|
||||
|
||||
protected int height;
|
||||
|
||||
protected byte position = 1;
|
||||
|
||||
public byte getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public void setPosition(byte position) {
|
||||
byte old = this.position;
|
||||
this.position = position;
|
||||
getEventSupport().firePropertyChange("position", old, this.position);
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return this.height;
|
||||
}
|
||||
|
||||
public void setHeight(int height) {
|
||||
int old = this.height;
|
||||
this.height = height;
|
||||
getEventSupport().firePropertyChange("height", old, this.height);
|
||||
}
|
||||
|
||||
public void setHeader(JRDesignCellContents header) {
|
||||
super.setHeader(header);
|
||||
setCellOrigin(this.header, new JRCrosstabOrigin(getParent(), (byte)5, null, getName()));
|
||||
}
|
||||
|
||||
public void setTotalHeader(JRDesignCellContents totalHeader) {
|
||||
super.setTotalHeader(totalHeader);
|
||||
setCellOrigin(this.totalHeader, new JRCrosstabOrigin(getParent(), (byte)6, null, getName()));
|
||||
}
|
||||
|
||||
void setParent(JRDesignCrosstab parent) {
|
||||
super.setParent(parent);
|
||||
setCellOrigin(this.header, new JRCrosstabOrigin(getParent(), (byte)5, null, getName()));
|
||||
setCellOrigin(this.totalHeader, new JRCrosstabOrigin(getParent(), (byte)6, null, getName()));
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabDataset;
|
||||
import net.sf.jasperreports.engine.JRExpressionCollector;
|
||||
import net.sf.jasperreports.engine.design.JRDesignElementDataset;
|
||||
|
||||
public class JRDesignCrosstabDataset extends JRDesignElementDataset implements JRCrosstabDataset {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_DATA_PRE_SORTED = "dataPreSorted";
|
||||
|
||||
protected boolean dataPreSorted = false;
|
||||
|
||||
public void collectExpressions(JRExpressionCollector collector) {}
|
||||
|
||||
public boolean isDataPreSorted() {
|
||||
return this.dataPreSorted;
|
||||
}
|
||||
|
||||
public void setDataPreSorted(boolean dataPreSorted) {
|
||||
boolean old = this.dataPreSorted;
|
||||
this.dataPreSorted = dataPreSorted;
|
||||
getEventSupport().firePropertyChange("dataPreSorted", old, this.dataPreSorted);
|
||||
}
|
||||
}
|
@@ -0,0 +1,95 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabBucket;
|
||||
import net.sf.jasperreports.crosstabs.base.JRBaseCrosstabGroup;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.design.JRDesignVariable;
|
||||
import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
|
||||
import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
|
||||
|
||||
public abstract class JRDesignCrosstabGroup extends JRBaseCrosstabGroup implements JRChangeEventsSupport {
|
||||
public static final String PROPERTY_BUCKET = "bucket";
|
||||
|
||||
public static final String PROPERTY_HEADER = "header";
|
||||
|
||||
public static final String PROPERTY_NAME = "name";
|
||||
|
||||
public static final String PROPERTY_TOTAL_HEADER = "totalHeader";
|
||||
|
||||
public static final String PROPERTY_TOTAL_POSITION = "totalPosition";
|
||||
|
||||
protected JRDesignVariable designVariable;
|
||||
|
||||
protected JRDesignCrosstab parent;
|
||||
|
||||
private transient JRPropertyChangeSupport eventSupport;
|
||||
|
||||
protected JRDesignCrosstabGroup() {
|
||||
this.variable = (JRVariable)(this.designVariable = new JRDesignVariable());
|
||||
this.designVariable.setCalculation((byte)8);
|
||||
this.designVariable.setSystemDefined(true);
|
||||
this.header = new JRDesignCellContents();
|
||||
this.totalHeader = new JRDesignCellContents();
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
Object old = this.name;
|
||||
this.name = name;
|
||||
this.designVariable.setName(name);
|
||||
getEventSupport().firePropertyChange("name", old, this.name);
|
||||
}
|
||||
|
||||
public void setTotalPosition(byte totalPosition) {
|
||||
byte old = this.totalPosition;
|
||||
this.totalPosition = totalPosition;
|
||||
getEventSupport().firePropertyChange("totalPosition", old, this.totalPosition);
|
||||
}
|
||||
|
||||
public void setBucket(JRDesignCrosstabBucket bucket) {
|
||||
Object old = this.bucket;
|
||||
this.bucket = (JRCrosstabBucket)bucket;
|
||||
getEventSupport().firePropertyChange("bucket", old, this.bucket);
|
||||
}
|
||||
|
||||
public void setHeader(JRDesignCellContents header) {
|
||||
Object old = this.header;
|
||||
if (header == null)
|
||||
header = new JRDesignCellContents();
|
||||
this.header = header;
|
||||
getEventSupport().firePropertyChange("header", old, this.header);
|
||||
}
|
||||
|
||||
public void setTotalHeader(JRDesignCellContents totalHeader) {
|
||||
Object old = this.totalHeader;
|
||||
if (totalHeader == null)
|
||||
totalHeader = new JRDesignCellContents();
|
||||
this.totalHeader = totalHeader;
|
||||
getEventSupport().firePropertyChange("totalHeader", old, this.totalHeader);
|
||||
}
|
||||
|
||||
public JRDesignCrosstab getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
void setParent(JRDesignCrosstab parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
protected void setCellOrigin(JRCellContents cell, JRCrosstabOrigin origin) {
|
||||
if (cell instanceof JRDesignCellContents)
|
||||
((JRDesignCellContents)cell).setOrigin(origin);
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public JRPropertyChangeSupport getEventSupport() {
|
||||
synchronized (this) {
|
||||
if (this.eventSupport == null)
|
||||
this.eventSupport = new JRPropertyChangeSupport(this);
|
||||
}
|
||||
return this.eventSupport;
|
||||
}
|
||||
}
|
@@ -0,0 +1,120 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import net.sf.jasperreports.crosstabs.base.JRBaseCrosstabMeasure;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.design.JRDesignVariable;
|
||||
import net.sf.jasperreports.engine.design.events.JRChangeEventsSupport;
|
||||
import net.sf.jasperreports.engine.design.events.JRPropertyChangeSupport;
|
||||
|
||||
public class JRDesignCrosstabMeasure extends JRBaseCrosstabMeasure implements JRChangeEventsSupport {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_CALCULATION = "calculation";
|
||||
|
||||
public static final String PROPERTY_INCREMENTER_FACTORY_CLASS_NAME = "incrementerFactoryClassName";
|
||||
|
||||
public static final String PROPERTY_NAME = "name";
|
||||
|
||||
public static final String PROPERTY_PERCENTAGE_CALCULATION_CLASS_NAME = "percentageCalculatorClassName";
|
||||
|
||||
public static final String PROPERTY_PERCENTAGE_OF_TYPE = "percentageOfType";
|
||||
|
||||
public static final String PROPERTY_VALUE_CLASS = "valueClassName";
|
||||
|
||||
public static final String PROPERTY_VALUE_EXPRESSION = "expression";
|
||||
|
||||
private JRDesignVariable designVariable;
|
||||
|
||||
private transient JRPropertyChangeSupport eventSupport;
|
||||
|
||||
public JRDesignCrosstabMeasure() {
|
||||
this.variable = (JRVariable)(this.designVariable = new JRDesignVariable());
|
||||
this.designVariable.setCalculation((byte)8);
|
||||
this.designVariable.setSystemDefined(true);
|
||||
}
|
||||
|
||||
public void setCalculation(byte calculation) {
|
||||
byte old = this.calculation;
|
||||
this.calculation = calculation;
|
||||
getEventSupport().firePropertyChange("calculation", old, this.calculation);
|
||||
}
|
||||
|
||||
public void setValueExpression(JRExpression expression) {
|
||||
Object old = this.expression;
|
||||
this.expression = expression;
|
||||
getEventSupport().firePropertyChange("expression", old, this.expression);
|
||||
}
|
||||
|
||||
public void setIncrementerFactoryClassName(String incrementerFactoryClassName) {
|
||||
Object old = this.incrementerFactoryClassName;
|
||||
this.incrementerFactoryClassName = incrementerFactoryClassName;
|
||||
this.incrementerFactoryClass = null;
|
||||
this.incrementerFactoryClassRealName = null;
|
||||
getEventSupport().firePropertyChange("incrementerFactoryClassName", old, this.incrementerFactoryClassName);
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
Object old = this.name;
|
||||
this.name = name;
|
||||
this.designVariable.setName(name);
|
||||
getEventSupport().firePropertyChange("name", old, this.name);
|
||||
}
|
||||
|
||||
public void setPercentageOfType(byte percentageOfType) {
|
||||
byte old = this.percentageOfType;
|
||||
this.percentageOfType = percentageOfType;
|
||||
getEventSupport().firePropertyChange("percentageOfType", old, this.percentageOfType);
|
||||
}
|
||||
|
||||
public void setPercentageCalculatorClassName(String percentageCalculatorClassName) {
|
||||
Object old = this.percentageCalculatorClassName;
|
||||
this.percentageCalculatorClassName = percentageCalculatorClassName;
|
||||
this.percentageCalculatorClass = null;
|
||||
this.percentageCalculatorClassRealName = null;
|
||||
getEventSupport().firePropertyChange("percentageCalculatorClassName", old, this.percentageCalculatorClassName);
|
||||
}
|
||||
|
||||
public void setValueClassName(String valueClassName) {
|
||||
String old = this.valueClassName;
|
||||
this.valueClassName = valueClassName;
|
||||
this.valueClass = null;
|
||||
this.valueClassRealName = null;
|
||||
this.designVariable.setValueClassName(valueClassName);
|
||||
getEventSupport().firePropertyChange("valueClassName", old, this.valueClassName);
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener l) {
|
||||
getPropertyChangeSupport().addPropertyChangeListener(l);
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(String propName, PropertyChangeListener l) {
|
||||
getPropertyChangeSupport().addPropertyChangeListener(propName, l);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(PropertyChangeListener l) {
|
||||
getPropertyChangeSupport().removePropertyChangeListener(l);
|
||||
}
|
||||
|
||||
public void removePropertyChangeListener(String propName, PropertyChangeListener l) {
|
||||
getPropertyChangeSupport().removePropertyChangeListener(propName, l);
|
||||
}
|
||||
|
||||
protected PropertyChangeSupport getPropertyChangeSupport() {
|
||||
return (PropertyChangeSupport)getEventSupport();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public JRPropertyChangeSupport getEventSupport() {
|
||||
synchronized (this) {
|
||||
if (this.eventSupport == null)
|
||||
this.eventSupport = new JRPropertyChangeSupport(this);
|
||||
}
|
||||
return this.eventSupport;
|
||||
}
|
||||
}
|
@@ -0,0 +1,30 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabParameter;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.design.JRDesignParameter;
|
||||
|
||||
public class JRDesignCrosstabParameter extends JRDesignParameter implements JRCrosstabParameter {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_VALUE_EXPRESSION = "valueExpression";
|
||||
|
||||
protected JRExpression valueExpression;
|
||||
|
||||
public JRExpression getExpression() {
|
||||
return this.valueExpression;
|
||||
}
|
||||
|
||||
public void setExpression(JRExpression expression) {
|
||||
Object old = this.valueExpression;
|
||||
this.valueExpression = expression;
|
||||
getEventSupport().firePropertyChange("valueExpression", old, this.valueExpression);
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
JRDesignCrosstabParameter clone = (JRDesignCrosstabParameter)super.clone();
|
||||
if (this.valueExpression != null)
|
||||
clone.valueExpression = (JRExpression)this.valueExpression.clone();
|
||||
return clone;
|
||||
}
|
||||
}
|
@@ -0,0 +1,51 @@
|
||||
package net.sf.jasperreports.crosstabs.design;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup;
|
||||
|
||||
public class JRDesignCrosstabRowGroup extends JRDesignCrosstabGroup implements JRCrosstabRowGroup {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
public static final String PROPERTY_POSITION = "position";
|
||||
|
||||
public static final String PROPERTY_WIDTH = "width";
|
||||
|
||||
protected int width;
|
||||
|
||||
protected byte position = 1;
|
||||
|
||||
public byte getPosition() {
|
||||
return this.position;
|
||||
}
|
||||
|
||||
public void setPosition(byte position) {
|
||||
byte old = this.position;
|
||||
this.position = position;
|
||||
getEventSupport().firePropertyChange("position", old, this.position);
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return this.width;
|
||||
}
|
||||
|
||||
public void setWidth(int width) {
|
||||
int old = this.width;
|
||||
this.width = width;
|
||||
getEventSupport().firePropertyChange("width", old, this.width);
|
||||
}
|
||||
|
||||
public void setHeader(JRDesignCellContents header) {
|
||||
super.setHeader(header);
|
||||
setCellOrigin(this.header, new JRCrosstabOrigin(getParent(), (byte)3, getName(), null));
|
||||
}
|
||||
|
||||
public void setTotalHeader(JRDesignCellContents totalHeader) {
|
||||
super.setTotalHeader(totalHeader);
|
||||
setCellOrigin(this.totalHeader, new JRCrosstabOrigin(getParent(), (byte)4, getName(), null));
|
||||
}
|
||||
|
||||
void setParent(JRDesignCrosstab parent) {
|
||||
super.setParent(parent);
|
||||
setCellOrigin(this.header, new JRCrosstabOrigin(getParent(), (byte)3, getName(), null));
|
||||
setCellOrigin(this.totalHeader, new JRCrosstabOrigin(getParent(), (byte)4, getName(), null));
|
||||
}
|
||||
}
|
@@ -0,0 +1,25 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import java.util.Map;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.fill.JREvaluator;
|
||||
import net.sf.jasperreports.engine.fill.JRFillExpressionEvaluator;
|
||||
|
||||
public class JRCrosstabExpressionEvaluator implements JRFillExpressionEvaluator {
|
||||
private final JREvaluator evaluator;
|
||||
|
||||
public JRCrosstabExpressionEvaluator(JREvaluator evaluator) {
|
||||
this.evaluator = evaluator;
|
||||
}
|
||||
|
||||
public Object evaluate(JRExpression expression, byte evaluationType) throws JRException {
|
||||
if (evaluationType != 3)
|
||||
throw new JRException("The crosstab evaluator doesn't support old or estimated expression evaluation.");
|
||||
return this.evaluator.evaluate(expression);
|
||||
}
|
||||
|
||||
public void init(Map parametersMap, Map variablesMap, byte whenResourceMissingType) throws JRException {
|
||||
this.evaluator.init(parametersMap, null, variablesMap, whenResourceMissingType);
|
||||
}
|
||||
}
|
@@ -0,0 +1,46 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabCell;
|
||||
import net.sf.jasperreports.engine.fill.JRFillCellContents;
|
||||
import net.sf.jasperreports.engine.fill.JRFillObjectFactory;
|
||||
|
||||
public class JRFillCrosstabCell implements JRCrosstabCell {
|
||||
private JRCrosstabCell parentCell;
|
||||
|
||||
protected JRFillCellContents contents;
|
||||
|
||||
public JRFillCrosstabCell(JRCrosstabCell cell, JRFillObjectFactory factory) {
|
||||
factory.put(cell, this);
|
||||
this.parentCell = cell;
|
||||
this.contents = factory.getCell(cell.getContents());
|
||||
}
|
||||
|
||||
public String getRowTotalGroup() {
|
||||
return this.parentCell.getRowTotalGroup();
|
||||
}
|
||||
|
||||
public String getColumnTotalGroup() {
|
||||
return this.parentCell.getColumnTotalGroup();
|
||||
}
|
||||
|
||||
public JRCellContents getContents() {
|
||||
return (JRCellContents)this.contents;
|
||||
}
|
||||
|
||||
public JRFillCellContents getFillContents() {
|
||||
return this.contents;
|
||||
}
|
||||
|
||||
public Integer getWidth() {
|
||||
return this.parentCell.getWidth();
|
||||
}
|
||||
|
||||
public Integer getHeight() {
|
||||
return this.parentCell.getHeight();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabColumnGroup;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
|
||||
import net.sf.jasperreports.engine.fill.JRFillObjectFactory;
|
||||
|
||||
public class JRFillCrosstabColumnGroup extends JRFillCrosstabGroup implements JRCrosstabColumnGroup {
|
||||
public JRFillCrosstabColumnGroup(JRCrosstabColumnGroup group, JRFillObjectFactory factory) {
|
||||
super((JRCrosstabGroup)group, factory);
|
||||
}
|
||||
|
||||
public byte getPosition() {
|
||||
return ((JRCrosstabColumnGroup)this.parentGroup).getPosition();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return ((JRCrosstabColumnGroup)this.parentGroup).getHeight();
|
||||
}
|
||||
}
|
@@ -0,0 +1,71 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCellContents;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabBucket;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.fill.JRFillCellContents;
|
||||
import net.sf.jasperreports.engine.fill.JRFillObjectFactory;
|
||||
import net.sf.jasperreports.engine.fill.JRFillVariable;
|
||||
|
||||
public abstract class JRFillCrosstabGroup implements JRCrosstabGroup {
|
||||
protected JRCrosstabGroup parentGroup;
|
||||
|
||||
protected JRFillCellContents header;
|
||||
|
||||
protected JRFillCellContents totalHeader;
|
||||
|
||||
protected JRFillVariable variable;
|
||||
|
||||
public JRFillCrosstabGroup(JRCrosstabGroup group, JRFillObjectFactory factory) {
|
||||
factory.put(group, this);
|
||||
this.parentGroup = group;
|
||||
this.header = factory.getCell(group.getHeader());
|
||||
this.totalHeader = factory.getCell(group.getTotalHeader());
|
||||
this.variable = factory.getVariable(group.getVariable());
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.parentGroup.getName();
|
||||
}
|
||||
|
||||
public byte getTotalPosition() {
|
||||
return this.parentGroup.getTotalPosition();
|
||||
}
|
||||
|
||||
public boolean hasTotal() {
|
||||
return this.parentGroup.hasTotal();
|
||||
}
|
||||
|
||||
public JRCrosstabBucket getBucket() {
|
||||
return this.parentGroup.getBucket();
|
||||
}
|
||||
|
||||
public JRCellContents getHeader() {
|
||||
return (JRCellContents)this.header;
|
||||
}
|
||||
|
||||
public JRCellContents getTotalHeader() {
|
||||
return (JRCellContents)this.totalHeader;
|
||||
}
|
||||
|
||||
public JRFillCellContents getFillHeader() {
|
||||
return this.header;
|
||||
}
|
||||
|
||||
public JRFillCellContents getFillTotalHeader() {
|
||||
return this.totalHeader;
|
||||
}
|
||||
|
||||
public JRVariable getVariable() {
|
||||
return (JRVariable)this.variable;
|
||||
}
|
||||
|
||||
public JRFillVariable getFillVariable() {
|
||||
return this.variable;
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,109 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabMeasure;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRVariable;
|
||||
import net.sf.jasperreports.engine.fill.JRDefaultIncrementerFactory;
|
||||
import net.sf.jasperreports.engine.fill.JRExtendedIncrementerFactory;
|
||||
import net.sf.jasperreports.engine.fill.JRFillObjectFactory;
|
||||
import net.sf.jasperreports.engine.fill.JRFillVariable;
|
||||
import net.sf.jasperreports.engine.fill.JRIncrementerFactoryCache;
|
||||
|
||||
public class JRFillCrosstabMeasure implements JRCrosstabMeasure {
|
||||
protected JRCrosstabMeasure parentMeasure;
|
||||
|
||||
protected JRFillVariable variable;
|
||||
|
||||
protected JRExtendedIncrementerFactory incrementerFactory;
|
||||
|
||||
protected JRPercentageCalculator percentageCalculator;
|
||||
|
||||
public JRFillCrosstabMeasure(JRCrosstabMeasure measure, JRFillObjectFactory factory) {
|
||||
factory.put(measure, this);
|
||||
this.parentMeasure = measure;
|
||||
this.variable = factory.getVariable(measure.getVariable());
|
||||
this.incrementerFactory = createIncrementerFactory();
|
||||
this.percentageCalculator = createPercentageCalculator();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.parentMeasure.getName();
|
||||
}
|
||||
|
||||
public String getValueClassName() {
|
||||
return this.parentMeasure.getValueClassName();
|
||||
}
|
||||
|
||||
public Class getValueClass() {
|
||||
return this.parentMeasure.getValueClass();
|
||||
}
|
||||
|
||||
public JRExpression getValueExpression() {
|
||||
return this.parentMeasure.getValueExpression();
|
||||
}
|
||||
|
||||
public byte getCalculation() {
|
||||
return this.parentMeasure.getCalculation();
|
||||
}
|
||||
|
||||
public String getIncrementerFactoryClassName() {
|
||||
return this.parentMeasure.getIncrementerFactoryClassName();
|
||||
}
|
||||
|
||||
public Class getIncrementerFactoryClass() {
|
||||
return this.parentMeasure.getIncrementerFactoryClass();
|
||||
}
|
||||
|
||||
public byte getPercentageOfType() {
|
||||
return this.parentMeasure.getPercentageOfType();
|
||||
}
|
||||
|
||||
public JRVariable getVariable() {
|
||||
return (JRVariable)this.variable;
|
||||
}
|
||||
|
||||
public JRFillVariable getFillVariable() {
|
||||
return this.variable;
|
||||
}
|
||||
|
||||
public JRExtendedIncrementerFactory getIncrementerFactory() {
|
||||
return this.incrementerFactory;
|
||||
}
|
||||
|
||||
public JRPercentageCalculator getPercentageCalculator() {
|
||||
return this.percentageCalculator;
|
||||
}
|
||||
|
||||
private JRExtendedIncrementerFactory createIncrementerFactory() {
|
||||
JRExtendedIncrementerFactory incrFactory;
|
||||
String incrementerFactoryClassName = getIncrementerFactoryClassName();
|
||||
if (incrementerFactoryClassName == null) {
|
||||
incrFactory = JRDefaultIncrementerFactory.getFactory(getValueClass());
|
||||
} else {
|
||||
incrFactory = (JRExtendedIncrementerFactory)JRIncrementerFactoryCache.getInstance(getIncrementerFactoryClass());
|
||||
}
|
||||
return incrFactory;
|
||||
}
|
||||
|
||||
public JRPercentageCalculator createPercentageCalculator() {
|
||||
JRPercentageCalculator percentageCalc;
|
||||
if (getPercentageOfType() == 1) {
|
||||
percentageCalc = JRPercentageCalculatorFactory.getPercentageCalculator(getPercentageCalculatorClass(), getValueClass());
|
||||
} else {
|
||||
percentageCalc = null;
|
||||
}
|
||||
return percentageCalc;
|
||||
}
|
||||
|
||||
public String getPercentageCalculatorClassName() {
|
||||
return this.parentMeasure.getPercentageCalculatorClassName();
|
||||
}
|
||||
|
||||
public Class getPercentageCalculatorClass() {
|
||||
return this.parentMeasure.getPercentageCalculatorClass();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
return null;
|
||||
}
|
||||
}
|
@@ -0,0 +1,20 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabParameter;
|
||||
import net.sf.jasperreports.engine.JRExpression;
|
||||
import net.sf.jasperreports.engine.JRParameter;
|
||||
import net.sf.jasperreports.engine.fill.JRFillObjectFactory;
|
||||
import net.sf.jasperreports.engine.fill.JRFillParameter;
|
||||
|
||||
public class JRFillCrosstabParameter extends JRFillParameter implements JRCrosstabParameter {
|
||||
private JRCrosstabParameter parentParameter;
|
||||
|
||||
public JRFillCrosstabParameter(JRCrosstabParameter parameter, JRFillObjectFactory factory) {
|
||||
super((JRParameter)parameter, factory);
|
||||
this.parentParameter = parameter;
|
||||
}
|
||||
|
||||
public JRExpression getExpression() {
|
||||
return this.parentParameter.getExpression();
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabGroup;
|
||||
import net.sf.jasperreports.crosstabs.JRCrosstabRowGroup;
|
||||
import net.sf.jasperreports.engine.fill.JRFillObjectFactory;
|
||||
|
||||
public class JRFillCrosstabRowGroup extends JRFillCrosstabGroup implements JRCrosstabRowGroup {
|
||||
public JRFillCrosstabRowGroup(JRCrosstabRowGroup group, JRFillObjectFactory factory) {
|
||||
super((JRCrosstabGroup)group, factory);
|
||||
}
|
||||
|
||||
public byte getPosition() {
|
||||
return ((JRCrosstabRowGroup)this.parentGroup).getPosition();
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return ((JRCrosstabRowGroup)this.parentGroup).getWidth();
|
||||
}
|
||||
}
|
@@ -0,0 +1,7 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import net.sf.jasperreports.engine.fill.JRCalculable;
|
||||
|
||||
public interface JRPercentageCalculator {
|
||||
Object calculatePercentage(JRCalculable paramJRCalculable1, JRCalculable paramJRCalculable2);
|
||||
}
|
@@ -0,0 +1,142 @@
|
||||
package net.sf.jasperreports.crosstabs.fill;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.sf.jasperreports.engine.JRRuntimeException;
|
||||
import net.sf.jasperreports.engine.fill.JRCalculable;
|
||||
|
||||
public class JRPercentageCalculatorFactory {
|
||||
private static final Map builtInCalculators = new HashMap();
|
||||
|
||||
static {
|
||||
builtInCalculators.put(Float.class.getName(), new FloatPercentageCalculator());
|
||||
builtInCalculators.put(Double.class.getName(), new DoublePercentageCalculator());
|
||||
builtInCalculators.put(Integer.class.getName(), new IntegerPercentageCalculator());
|
||||
builtInCalculators.put(Long.class.getName(), new LongPercentageCalculator());
|
||||
builtInCalculators.put(Short.class.getName(), new ShortPercentageCalculator());
|
||||
builtInCalculators.put(Byte.class.getName(), new BytePercentageCalculator());
|
||||
builtInCalculators.put(BigDecimal.class.getName(), new BigDecimalPercentageCalculator());
|
||||
builtInCalculators.put(BigInteger.class.getName(), new BigIntegerPercentageCalculator());
|
||||
}
|
||||
|
||||
private static final Map cachedCalculators = new HashMap();
|
||||
|
||||
public static boolean hasBuiltInCalculator(Class valueClass) {
|
||||
return builtInCalculators.containsKey(valueClass.getName());
|
||||
}
|
||||
|
||||
public static JRPercentageCalculator getPercentageCalculator(Class percentageCalculatorClass, Class valueClass) {
|
||||
JRPercentageCalculator calculator;
|
||||
if (percentageCalculatorClass == null) {
|
||||
calculator = (JRPercentageCalculator)builtInCalculators.get(valueClass.getName());
|
||||
if (calculator == null)
|
||||
throw new JRRuntimeException("Measure with type " + valueClass.getName() + " should specify a percentage calculator class.");
|
||||
} else {
|
||||
calculator = (JRPercentageCalculator)cachedCalculators.get(percentageCalculatorClass.getName());
|
||||
if (calculator == null)
|
||||
try {
|
||||
calculator = percentageCalculatorClass.newInstance();
|
||||
cachedCalculators.put(percentageCalculatorClass.getName(), calculator);
|
||||
} catch (InstantiationException e) {
|
||||
throw new JRRuntimeException("Error while creating percentage calculator instance of " + percentageCalculatorClass + ".", e);
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new JRRuntimeException("Error while creating percentage calculator instance of " + percentageCalculatorClass + ".", e);
|
||||
}
|
||||
}
|
||||
return calculator;
|
||||
}
|
||||
|
||||
public static class BytePercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
Byte totalVal = (Byte)total.getValue();
|
||||
Byte val = (Byte)value.getValue();
|
||||
byte percentage = 0;
|
||||
if (totalVal != null && totalVal.byteValue() != 0)
|
||||
percentage = (byte)(100 * val.byteValue() / totalVal.byteValue());
|
||||
return new Byte(percentage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ShortPercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
Short totalVal = (Short)total.getValue();
|
||||
Short val = (Short)value.getValue();
|
||||
short percentage = 0;
|
||||
if (totalVal != null && totalVal.shortValue() != 0)
|
||||
percentage = (short)(100 * val.shortValue() / totalVal.shortValue());
|
||||
return new Short(percentage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class IntegerPercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
Integer totalVal = (Integer)total.getValue();
|
||||
Integer val = (Integer)value.getValue();
|
||||
int percentage = 0;
|
||||
if (totalVal != null && totalVal.intValue() != 0)
|
||||
percentage = 100 * val.intValue() / totalVal.intValue();
|
||||
return new Integer(percentage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class LongPercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
Long totalVal = (Long)total.getValue();
|
||||
Long val = (Long)value.getValue();
|
||||
long percentage = 0L;
|
||||
if (totalVal != null && totalVal.longValue() != 0L)
|
||||
percentage = 100L * val.longValue() / totalVal.longValue();
|
||||
return new Long(percentage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class FloatPercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
Float totalVal = (Float)total.getValue();
|
||||
Float val = (Float)value.getValue();
|
||||
float percentage = 0.0F;
|
||||
if (totalVal != null && totalVal.floatValue() != 0.0F)
|
||||
percentage = 100.0F * val.floatValue() / totalVal.floatValue();
|
||||
return new Float(percentage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DoublePercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
Double totalVal = (Double)total.getValue();
|
||||
Double val = (Double)value.getValue();
|
||||
double percentage = 0.0D;
|
||||
if (totalVal != null && totalVal.doubleValue() != 0.0D)
|
||||
percentage = 100.0D * val.doubleValue() / totalVal.doubleValue();
|
||||
return new Double(percentage);
|
||||
}
|
||||
}
|
||||
|
||||
public static class BigDecimalPercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
BigDecimal percentage, totalVal = (BigDecimal)total.getValue();
|
||||
BigDecimal val = (BigDecimal)value.getValue();
|
||||
if (totalVal != null && totalVal.doubleValue() != 0.0D) {
|
||||
percentage = val.multiply(BigDecimal.valueOf(100L)).divide(totalVal, 4);
|
||||
} else {
|
||||
percentage = BigDecimal.valueOf(0L);
|
||||
}
|
||||
return percentage;
|
||||
}
|
||||
}
|
||||
|
||||
public static class BigIntegerPercentageCalculator implements JRPercentageCalculator {
|
||||
public Object calculatePercentage(JRCalculable value, JRCalculable total) {
|
||||
BigInteger percentage, totalVal = (BigInteger)total.getValue();
|
||||
BigInteger val = (BigInteger)value.getValue();
|
||||
if (totalVal != null && totalVal.doubleValue() != 0.0D) {
|
||||
percentage = val.multiply(BigInteger.valueOf(100L)).divide(totalVal);
|
||||
} else {
|
||||
percentage = BigInteger.valueOf(0L);
|
||||
}
|
||||
return percentage;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
package net.sf.jasperreports.crosstabs.fill.calculation;
|
||||
|
||||
import java.util.Comparator;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import org.apache.commons.collections.comparators.ReverseComparator;
|
||||
|
||||
public class BucketDefinition {
|
||||
public static final byte ORDER_ASCENDING = 1;
|
||||
|
||||
public static final byte ORDER_DESCENDING = 2;
|
||||
|
||||
public static final byte TOTAL_POSITION_NONE = 0;
|
||||
|
||||
public static final byte TOTAL_POSITION_START = 1;
|
||||
|
||||
public static final byte TOTAL_POSITION_END = 2;
|
||||
|
||||
protected static final byte VALUE_TYPE_VALUE = 0;
|
||||
|
||||
protected static final byte VALUE_TYPE_NULL = 1;
|
||||
|
||||
protected static final byte VALUE_TYPE_TOTAL = 2;
|
||||
|
||||
protected final Bucket VALUE_TOTAL = new Bucket((byte)2);
|
||||
|
||||
protected final Bucket VALUE_NULL = new Bucket((byte)1);
|
||||
|
||||
protected final Comparator comparator;
|
||||
|
||||
private final byte totalPosition;
|
||||
|
||||
private boolean computeTotal;
|
||||
|
||||
public BucketDefinition(Class valueClass, Comparator comparator, byte order, byte totalPosition) throws JRException {
|
||||
if (comparator == null && !Comparable.class.isAssignableFrom(valueClass))
|
||||
throw new JRException("The bucket expression values are not comparable and no comparator specified.");
|
||||
switch (order) {
|
||||
case 2:
|
||||
if (comparator == null) {
|
||||
this.comparator = (Comparator)new ReverseComparator();
|
||||
break;
|
||||
}
|
||||
this.comparator = (Comparator)new ReverseComparator(comparator);
|
||||
break;
|
||||
default:
|
||||
this.comparator = comparator;
|
||||
break;
|
||||
}
|
||||
this.totalPosition = totalPosition;
|
||||
this.computeTotal = (totalPosition != 0);
|
||||
}
|
||||
|
||||
public boolean computeTotal() {
|
||||
return this.computeTotal;
|
||||
}
|
||||
|
||||
public void setComputeTotal() {
|
||||
this.computeTotal = true;
|
||||
}
|
||||
|
||||
public byte getTotalPosition() {
|
||||
return this.totalPosition;
|
||||
}
|
||||
|
||||
public Comparator getComparator() {
|
||||
return this.comparator;
|
||||
}
|
||||
|
||||
public Bucket create(Object value) {
|
||||
if (value == null)
|
||||
return this.VALUE_NULL;
|
||||
return new Bucket(value);
|
||||
}
|
||||
|
||||
public class Bucket implements Comparable {
|
||||
private final Object value;
|
||||
|
||||
private final byte type;
|
||||
|
||||
private final BucketDefinition this$0;
|
||||
|
||||
protected Bucket(byte type) {
|
||||
this.value = null;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
protected Bucket(Object value) {
|
||||
this.value = value;
|
||||
this.type = 0;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == null || !(o instanceof Bucket))
|
||||
return false;
|
||||
if (o == this)
|
||||
return true;
|
||||
Bucket v = (Bucket)o;
|
||||
if (this.type != 0)
|
||||
return (this.type == v.type);
|
||||
return (v.type == 0 && this.value.equals(v.value));
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
int hash = this.type;
|
||||
if (this.type == 0)
|
||||
hash = 37 * hash + this.value.hashCode();
|
||||
return hash;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
switch (this.type) {
|
||||
case 1:
|
||||
return "NULL";
|
||||
case 2:
|
||||
return "TOTAL";
|
||||
}
|
||||
return String.valueOf(this.value);
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
Bucket val = (Bucket)o;
|
||||
if (this.type != val.type)
|
||||
return this.type - val.type;
|
||||
if (this.type != 0)
|
||||
return 0;
|
||||
if (BucketDefinition.this.comparator != null)
|
||||
return BucketDefinition.this.comparator.compare(this.value, val.value);
|
||||
return ((Comparable)this.value).compareTo(val.value);
|
||||
}
|
||||
|
||||
public boolean isTotal() {
|
||||
return (this.type == 2);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,843 @@
|
||||
package net.sf.jasperreports.crosstabs.fill.calculation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.JRRuntimeException;
|
||||
import net.sf.jasperreports.engine.util.JRProperties;
|
||||
|
||||
public class BucketingService {
|
||||
public static final String PROPERTY_BUCKET_MEASURE_LIMIT = "net.sf.jasperreports.crosstab.bucket.measure.limit";
|
||||
|
||||
protected static final byte DIMENSION_ROW = 0;
|
||||
|
||||
protected static final byte DIMENSION_COLUMN = 1;
|
||||
|
||||
protected static final int DIMENSIONS = 2;
|
||||
|
||||
protected final BucketDefinition[] allBuckets;
|
||||
|
||||
protected final BucketDefinition[][] buckets;
|
||||
|
||||
protected final int rowBucketCount;
|
||||
|
||||
protected final int colBucketCount;
|
||||
|
||||
protected final boolean[][] retrieveTotal;
|
||||
|
||||
private boolean[] rowRetrTotals;
|
||||
|
||||
private int rowRetrTotalMin;
|
||||
|
||||
private int rowRetrTotalMax;
|
||||
|
||||
private int[] rowRetrColMax;
|
||||
|
||||
protected final MeasureDefinition[] measures;
|
||||
|
||||
protected final int origMeasureCount;
|
||||
|
||||
protected final int[] measureIndexes;
|
||||
|
||||
protected final boolean sorted;
|
||||
|
||||
protected final BucketMap bucketValueMap;
|
||||
|
||||
protected long dataCount;
|
||||
|
||||
protected boolean processed;
|
||||
|
||||
protected HeaderCell[][] colHeaders;
|
||||
|
||||
protected HeaderCell[][] rowHeaders;
|
||||
|
||||
protected CrosstabCell[][] cells;
|
||||
|
||||
private final MeasureDefinition.MeasureValue[] zeroUserMeasureValues;
|
||||
|
||||
private final int bucketMeasureLimit;
|
||||
|
||||
private int runningBucketMeasureCount = 0;
|
||||
|
||||
public BucketingService(List rowBuckets, List columnBuckets, List measures, boolean sorted, boolean[][] retrieveTotal) {
|
||||
this.sorted = sorted;
|
||||
this.buckets = new BucketDefinition[2][];
|
||||
this.rowBucketCount = rowBuckets.size();
|
||||
this.buckets[0] = new BucketDefinition[this.rowBucketCount];
|
||||
rowBuckets.toArray((Object[])this.buckets[0]);
|
||||
this.colBucketCount = columnBuckets.size();
|
||||
this.buckets[1] = new BucketDefinition[this.colBucketCount];
|
||||
columnBuckets.toArray((Object[])this.buckets[1]);
|
||||
this.allBuckets = new BucketDefinition[this.rowBucketCount + this.colBucketCount];
|
||||
System.arraycopy(this.buckets[0], 0, this.allBuckets, 0, this.rowBucketCount);
|
||||
System.arraycopy(this.buckets[1], 0, this.allBuckets, this.rowBucketCount, this.colBucketCount);
|
||||
this.origMeasureCount = measures.size();
|
||||
List measuresList = new ArrayList(measures.size() * 2);
|
||||
List measureIndexList = new ArrayList(measures.size() * 2);
|
||||
int i;
|
||||
for (i = 0; i < measures.size(); i++) {
|
||||
MeasureDefinition measure = measures.get(i);
|
||||
addMeasure(measure, i, measuresList, measureIndexList);
|
||||
}
|
||||
this.measures = new MeasureDefinition[measuresList.size()];
|
||||
measuresList.toArray((Object[])this.measures);
|
||||
this.measureIndexes = new int[measureIndexList.size()];
|
||||
for (i = 0; i < this.measureIndexes.length; i++)
|
||||
this.measureIndexes[i] = ((Integer)measureIndexList.get(i)).intValue();
|
||||
this.retrieveTotal = retrieveTotal;
|
||||
checkTotals();
|
||||
this.bucketValueMap = createBucketMap(0);
|
||||
this.zeroUserMeasureValues = initUserMeasureValues();
|
||||
this.bucketMeasureLimit = JRProperties.getIntegerProperty("net.sf.jasperreports.crosstab.bucket.measure.limit", 0);
|
||||
}
|
||||
|
||||
protected void checkTotals() {
|
||||
this.rowRetrTotalMin = this.rowBucketCount + 1;
|
||||
this.rowRetrTotalMax = -1;
|
||||
this.rowRetrTotals = new boolean[this.rowBucketCount + 1];
|
||||
this.rowRetrColMax = new int[this.rowBucketCount + 1];
|
||||
for (int row = 0; row <= this.rowBucketCount; row++) {
|
||||
this.rowRetrColMax[row] = -1;
|
||||
boolean total = false;
|
||||
for (int i = 0; i <= this.colBucketCount; i++) {
|
||||
if (this.retrieveTotal[row][i]) {
|
||||
total = true;
|
||||
this.rowRetrColMax[row] = i;
|
||||
}
|
||||
}
|
||||
this.rowRetrTotals[row] = total;
|
||||
if (total) {
|
||||
if (row < this.rowRetrTotalMin)
|
||||
this.rowRetrTotalMin = row;
|
||||
this.rowRetrTotalMax = row;
|
||||
if (row < this.rowBucketCount)
|
||||
this.allBuckets[row].setComputeTotal();
|
||||
}
|
||||
}
|
||||
for (int col = 0; col < this.colBucketCount; col++) {
|
||||
BucketDefinition colBucket = this.allBuckets[this.rowBucketCount + col];
|
||||
if (!colBucket.computeTotal()) {
|
||||
boolean total = false;
|
||||
for (int i = 0; !total && i <= this.rowBucketCount; i++)
|
||||
total = this.retrieveTotal[i][col];
|
||||
if (total)
|
||||
colBucket.setComputeTotal();
|
||||
}
|
||||
}
|
||||
for (int d = 0; d < 2; d++) {
|
||||
boolean dTotal = false;
|
||||
for (int i = 0; i < (this.buckets[d]).length; i++) {
|
||||
if (dTotal) {
|
||||
this.buckets[d][i].setComputeTotal();
|
||||
} else {
|
||||
dTotal = this.buckets[d][i].computeTotal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.bucketValueMap.clear();
|
||||
this.processed = false;
|
||||
this.dataCount = 0L;
|
||||
this.runningBucketMeasureCount = 0;
|
||||
}
|
||||
|
||||
protected BucketMap createBucketMap(int level) {
|
||||
BucketMap map;
|
||||
if (this.sorted) {
|
||||
map = new BucketListMap(level, false);
|
||||
} else {
|
||||
map = new BucketTreeMap(level);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
protected BucketListMap createCollectBucketMap(int level) {
|
||||
return new BucketListMap(level, true);
|
||||
}
|
||||
|
||||
protected void addMeasure(MeasureDefinition measure, int index, List measuresList, List measureIndexList) {
|
||||
MeasureDefinition sumMeasure, varianceMeasure, countMeasure, measureDefinition1;
|
||||
switch (measure.getCalculation()) {
|
||||
case 3:
|
||||
case 7:
|
||||
sumMeasure = MeasureDefinition.createHelperMeasure(measure, (byte)2);
|
||||
addMeasure(sumMeasure, index, measuresList, measureIndexList);
|
||||
measureDefinition1 = MeasureDefinition.createHelperMeasure(measure, (byte)1);
|
||||
addMeasure(measureDefinition1, index, measuresList, measureIndexList);
|
||||
break;
|
||||
case 6:
|
||||
varianceMeasure = MeasureDefinition.createHelperMeasure(measure, (byte)7);
|
||||
addMeasure(varianceMeasure, index, measuresList, measureIndexList);
|
||||
break;
|
||||
case 10:
|
||||
countMeasure = MeasureDefinition.createDistinctCountHelperMeasure(measure);
|
||||
addMeasure(countMeasure, index, measuresList, measureIndexList);
|
||||
break;
|
||||
}
|
||||
measuresList.add(measure);
|
||||
measureIndexList.add(new Integer(index));
|
||||
}
|
||||
|
||||
public void addData(Object[] bucketValues, Object[] measureValues) throws JRException {
|
||||
if (this.processed)
|
||||
throw new JRException("Crosstab data has already been processed.");
|
||||
this.dataCount++;
|
||||
BucketDefinition.Bucket[] bucketVals = getBucketValues(bucketValues);
|
||||
MeasureDefinition.MeasureValue[] values = this.bucketValueMap.insertMeasureValues(bucketVals);
|
||||
for (int i = 0; i < this.measures.length; i++)
|
||||
values[i].addValue(measureValues[this.measureIndexes[i]]);
|
||||
}
|
||||
|
||||
protected void bucketMeasuresCreated() {
|
||||
this.runningBucketMeasureCount += this.origMeasureCount;
|
||||
checkBucketMeasureCount(this.runningBucketMeasureCount);
|
||||
}
|
||||
|
||||
protected BucketDefinition.Bucket[] getBucketValues(Object[] bucketValues) {
|
||||
BucketDefinition.Bucket[] bucketVals = new BucketDefinition.Bucket[this.allBuckets.length];
|
||||
for (int i = 0; i < this.allBuckets.length; i++) {
|
||||
BucketDefinition bucket = this.allBuckets[i];
|
||||
Object value = bucketValues[i];
|
||||
bucketVals[i] = bucket.create(value);
|
||||
}
|
||||
return bucketVals;
|
||||
}
|
||||
|
||||
protected MeasureDefinition.MeasureValue[] initMeasureValues() {
|
||||
MeasureDefinition.MeasureValue[] values = new MeasureDefinition.MeasureValue[this.measures.length];
|
||||
for (int i = 0; i < this.measures.length; i++) {
|
||||
MeasureDefinition measure = this.measures[i];
|
||||
measure.getClass();
|
||||
values[i] = new MeasureDefinition.MeasureValue(measure);
|
||||
switch (measure.getCalculation()) {
|
||||
case 3:
|
||||
case 7:
|
||||
values[i].setHelper(values[i - 2], (byte)1);
|
||||
values[i].setHelper(values[i - 1], (byte)0);
|
||||
break;
|
||||
case 6:
|
||||
values[i].setHelper(values[i - 1], (byte)2);
|
||||
case 10:
|
||||
values[i].setHelper(values[i - 1], (byte)0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
protected MeasureDefinition.MeasureValue[] initUserMeasureValues() {
|
||||
MeasureDefinition.MeasureValue[] vals = new MeasureDefinition.MeasureValue[this.origMeasureCount];
|
||||
for (int c = 0, i = 0; i < this.measures.length; i++) {
|
||||
if (!this.measures[i].isSystemDefined()) {
|
||||
this.measures[i].getClass();
|
||||
vals[c] = new MeasureDefinition.MeasureValue(this.measures[i]);
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
|
||||
public void processData() throws JRException {
|
||||
if (!this.processed) {
|
||||
if (this.dataCount > 0L) {
|
||||
if (this.allBuckets[this.rowBucketCount - 1].computeTotal() || this.allBuckets[this.allBuckets.length - 1].computeTotal())
|
||||
computeTotals(this.bucketValueMap);
|
||||
createCrosstab();
|
||||
}
|
||||
this.processed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasData() {
|
||||
return (this.dataCount > 0L);
|
||||
}
|
||||
|
||||
public HeaderCell[][] getColumnHeaders() {
|
||||
return this.colHeaders;
|
||||
}
|
||||
|
||||
public HeaderCell[][] getRowHeaders() {
|
||||
return this.rowHeaders;
|
||||
}
|
||||
|
||||
public CrosstabCell[][] getCrosstabCells() {
|
||||
return this.cells;
|
||||
}
|
||||
|
||||
public MeasureDefinition.MeasureValue[] getMeasureValues(BucketDefinition.Bucket[] bucketValues) {
|
||||
BucketMap map = this.bucketValueMap;
|
||||
for (int i = 0; map != null && i < this.allBuckets.length - 1; i++)
|
||||
map = (BucketMap)map.get(bucketValues[i]);
|
||||
return (map == null) ? null : (MeasureDefinition.MeasureValue[])map.get(bucketValues[this.allBuckets.length - 1]);
|
||||
}
|
||||
|
||||
protected MeasureDefinition.MeasureValue[] getUserMeasureValues(MeasureDefinition.MeasureValue[] values) {
|
||||
MeasureDefinition.MeasureValue[] vals = new MeasureDefinition.MeasureValue[this.origMeasureCount];
|
||||
for (int c = 0, i = 0; i < this.measures.length; i++) {
|
||||
if (!this.measures[i].isSystemDefined()) {
|
||||
vals[c] = values[i];
|
||||
c++;
|
||||
}
|
||||
}
|
||||
return vals;
|
||||
}
|
||||
|
||||
public MeasureDefinition.MeasureValue[] getGrandTotals() {
|
||||
BucketMap map = this.bucketValueMap;
|
||||
for (int i = 0; map != null && i < this.allBuckets.length - 1; i++)
|
||||
map = (BucketMap)map.getTotalEntry().getValue();
|
||||
return (map == null) ? null : (MeasureDefinition.MeasureValue[])map.getTotalEntry().getValue();
|
||||
}
|
||||
|
||||
protected void computeTotals(BucketMap bucketMap) throws JRException {
|
||||
byte dimension = (bucketMap.level < this.rowBucketCount) ? 0 : 1;
|
||||
if (dimension == 1 && !this.allBuckets[this.allBuckets.length - 1].computeTotal())
|
||||
return;
|
||||
if (!bucketMap.last)
|
||||
for (Iterator it = bucketMap.entryIterator(); it.hasNext(); ) {
|
||||
Map.Entry entry = it.next();
|
||||
computeTotals((BucketMap)entry.getValue());
|
||||
}
|
||||
if (this.allBuckets[bucketMap.level].computeTotal())
|
||||
if (dimension == 1) {
|
||||
computeColumnTotal(bucketMap);
|
||||
} else {
|
||||
computeRowTotals(bucketMap);
|
||||
}
|
||||
}
|
||||
|
||||
protected void sumVals(MeasureDefinition.MeasureValue[] totals, MeasureDefinition.MeasureValue[] vals) throws JRException {
|
||||
for (int i = 0; i < this.measures.length; i++)
|
||||
totals[i].addValue(vals[i]);
|
||||
}
|
||||
|
||||
protected void computeColumnTotal(BucketMap bucketMap) throws JRException {
|
||||
MeasureDefinition.MeasureValue[] totals = initMeasureValues();
|
||||
for (Iterator it = bucketMap.entryIterator(); it.hasNext(); ) {
|
||||
Map.Entry entry = it.next();
|
||||
for (int j = bucketMap.level + 1; j < this.allBuckets.length; j++)
|
||||
entry = ((BucketMap)entry.getValue()).getTotalEntry();
|
||||
sumVals(totals, (MeasureDefinition.MeasureValue[])entry.getValue());
|
||||
}
|
||||
for (int i = bucketMap.level + 1; i < this.allBuckets.length; i++)
|
||||
bucketMap = bucketMap.addTotalNextMap();
|
||||
bucketMap.addTotalEntry(totals);
|
||||
}
|
||||
|
||||
protected void computeRowTotals(BucketMap bucketMap) throws JRException {
|
||||
BucketListMap totals = createCollectBucketMap(this.rowBucketCount);
|
||||
for (Iterator it = bucketMap.entryIterator(); it.hasNext(); ) {
|
||||
Map.Entry entry = it.next();
|
||||
for (int j = bucketMap.level + 1; j < this.rowBucketCount; j++)
|
||||
entry = ((BucketMap)entry.getValue()).getTotalEntry();
|
||||
totals.collectVals((BucketMap)entry.getValue(), true);
|
||||
}
|
||||
BucketMap totalBucketMap = bucketMap;
|
||||
for (int i = bucketMap.level + 1; i < this.rowBucketCount; i++)
|
||||
totalBucketMap = totalBucketMap.addTotalNextMap();
|
||||
totalBucketMap.addTotalEntry(totals);
|
||||
}
|
||||
|
||||
protected static class MapEntry implements Map.Entry, Comparable {
|
||||
final BucketDefinition.Bucket key;
|
||||
|
||||
final Object value;
|
||||
|
||||
MapEntry(BucketDefinition.Bucket key, Object value) {
|
||||
this.key = key;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public Object setValue(Object value) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public int compareTo(Object o) {
|
||||
return this.key.compareTo(((MapEntry)o).key);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.key + ":" + this.value;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract class BucketMap {
|
||||
final int level;
|
||||
|
||||
final boolean last;
|
||||
|
||||
final BucketDefinition.Bucket totalKey;
|
||||
|
||||
private final BucketingService this$0;
|
||||
|
||||
BucketMap(int level) {
|
||||
this.level = level;
|
||||
this.last = (level == BucketingService.this.allBuckets.length - 1);
|
||||
this.totalKey = (BucketingService.this.allBuckets[level]).VALUE_TOTAL;
|
||||
}
|
||||
|
||||
BucketMap addTotalNextMap() {
|
||||
BucketMap nextMap = BucketingService.this.createBucketMap(this.level + 1);
|
||||
addTotalEntry(nextMap);
|
||||
return nextMap;
|
||||
}
|
||||
|
||||
abstract void set(BucketDefinition.Bucket param1Bucket, Object param1Object);
|
||||
|
||||
abstract void clear();
|
||||
|
||||
abstract Iterator entryIterator();
|
||||
|
||||
abstract Object get(BucketDefinition.Bucket param1Bucket);
|
||||
|
||||
abstract MeasureDefinition.MeasureValue[] insertMeasureValues(BucketDefinition.Bucket[] param1ArrayOfBucket);
|
||||
|
||||
abstract void addTotalEntry(Object param1Object);
|
||||
|
||||
abstract int size();
|
||||
|
||||
abstract Map.Entry getTotalEntry();
|
||||
}
|
||||
|
||||
protected class BucketTreeMap extends BucketMap {
|
||||
TreeMap map;
|
||||
|
||||
private final BucketingService this$0;
|
||||
|
||||
BucketTreeMap(int level) {
|
||||
super(level);
|
||||
this.map = new TreeMap();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this.map.clear();
|
||||
}
|
||||
|
||||
Iterator entryIterator() {
|
||||
return this.map.entrySet().iterator();
|
||||
}
|
||||
|
||||
Object get(BucketDefinition.Bucket key) {
|
||||
return this.map.get(key);
|
||||
}
|
||||
|
||||
MeasureDefinition.MeasureValue[] insertMeasureValues(BucketDefinition.Bucket[] bucketValues) {
|
||||
BucketTreeMap levelMap = (BucketTreeMap)BucketingService.this.bucketValueMap;
|
||||
for (int i = 0; i < bucketValues.length - 1; i++) {
|
||||
BucketTreeMap nextMap = (BucketTreeMap)levelMap.get(bucketValues[i]);
|
||||
if (nextMap == null) {
|
||||
nextMap = new BucketTreeMap(i + 1);
|
||||
levelMap.map.put(bucketValues[i], nextMap);
|
||||
}
|
||||
levelMap = nextMap;
|
||||
}
|
||||
MeasureDefinition.MeasureValue[] values = (MeasureDefinition.MeasureValue[])levelMap.get(bucketValues[bucketValues.length - 1]);
|
||||
if (values == null) {
|
||||
values = BucketingService.this.initMeasureValues();
|
||||
levelMap.map.put(bucketValues[bucketValues.length - 1], values);
|
||||
BucketingService.this.bucketMeasuresCreated();
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
int size() {
|
||||
return this.map.size();
|
||||
}
|
||||
|
||||
void addTotalEntry(Object value) {
|
||||
this.map.put(this.totalKey, value);
|
||||
}
|
||||
|
||||
Map.Entry getTotalEntry() {
|
||||
Object value = get(this.totalKey);
|
||||
return (value == null) ? null : new BucketingService.MapEntry(this.totalKey, value);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.map.toString();
|
||||
}
|
||||
|
||||
void set(BucketDefinition.Bucket key, Object value) {
|
||||
this.map.put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected class BucketListMap extends BucketMap {
|
||||
List entries;
|
||||
|
||||
private final BucketingService this$0;
|
||||
|
||||
BucketListMap(int level, boolean linked) {
|
||||
super(level);
|
||||
if (linked) {
|
||||
this.entries = new LinkedList();
|
||||
} else {
|
||||
this.entries = new ArrayList();
|
||||
}
|
||||
}
|
||||
|
||||
void clear() {
|
||||
this.entries.clear();
|
||||
}
|
||||
|
||||
Iterator entryIterator() {
|
||||
return this.entries.iterator();
|
||||
}
|
||||
|
||||
private void add(BucketDefinition.Bucket key, Object value) {
|
||||
this.entries.add(new BucketingService.MapEntry(key, value));
|
||||
}
|
||||
|
||||
Object get(BucketDefinition.Bucket key) {
|
||||
int idx = Collections.binarySearch(this.entries, new BucketingService.MapEntry(key, null));
|
||||
return (idx >= 0) ? ((BucketingService.MapEntry)this.entries.get(idx)).value : null;
|
||||
}
|
||||
|
||||
MeasureDefinition.MeasureValue[] insertMeasureValues(BucketDefinition.Bucket[] bucketValues) {
|
||||
int i = 0;
|
||||
Object levelObj = this;
|
||||
BucketListMap map = null;
|
||||
while (i < BucketingService.this.allBuckets.length) {
|
||||
map = (BucketListMap)levelObj;
|
||||
int size = map.entries.size();
|
||||
if (size == 0)
|
||||
break;
|
||||
BucketingService.MapEntry lastEntry = map.entries.get(size - 1);
|
||||
if (!lastEntry.key.equals(bucketValues[i]))
|
||||
break;
|
||||
i++;
|
||||
levelObj = lastEntry.value;
|
||||
}
|
||||
if (i == BucketingService.this.allBuckets.length)
|
||||
return (MeasureDefinition.MeasureValue[])levelObj;
|
||||
while (i < BucketingService.this.allBuckets.length - 1) {
|
||||
BucketListMap nextMap = new BucketListMap(i + 1, false);
|
||||
map.add(bucketValues[i], nextMap);
|
||||
map = nextMap;
|
||||
i++;
|
||||
}
|
||||
MeasureDefinition.MeasureValue[] values = BucketingService.this.initMeasureValues();
|
||||
map.add(bucketValues[i], values);
|
||||
BucketingService.this.bucketMeasuresCreated();
|
||||
return values;
|
||||
}
|
||||
|
||||
int size() {
|
||||
return this.entries.size();
|
||||
}
|
||||
|
||||
void addTotalEntry(Object value) {
|
||||
add(this.totalKey, value);
|
||||
}
|
||||
|
||||
Map.Entry getTotalEntry() {
|
||||
BucketingService.MapEntry lastEntry = this.entries.get(this.entries.size() - 1);
|
||||
if (lastEntry.key.isTotal())
|
||||
return lastEntry;
|
||||
return null;
|
||||
}
|
||||
|
||||
void set(BucketDefinition.Bucket key, Object value) {
|
||||
BucketingService.MapEntry mapEntry = new BucketingService.MapEntry(key, value);
|
||||
int idx = Collections.binarySearch(this.entries, mapEntry);
|
||||
int ins = -idx - 1;
|
||||
this.entries.add(ins, mapEntry);
|
||||
}
|
||||
|
||||
void collectVals(BucketingService.BucketMap map, boolean sum) throws JRException {
|
||||
ListIterator totalIt = this.entries.listIterator();
|
||||
BucketingService.MapEntry totalItEntry = totalIt.hasNext() ? totalIt.next() : null;
|
||||
Iterator it = map.entryIterator();
|
||||
Map.Entry entry = it.hasNext() ? it.next() : null;
|
||||
while (entry != null) {
|
||||
BucketDefinition.Bucket key = (BucketDefinition.Bucket)entry.getKey();
|
||||
int compare = (totalItEntry == null) ? -1 : key.compareTo(totalItEntry.key);
|
||||
if (compare <= 0) {
|
||||
Object addVal = null;
|
||||
if (this.last) {
|
||||
if (sum) {
|
||||
MeasureDefinition.MeasureValue[] totalVals = (compare == 0) ? (MeasureDefinition.MeasureValue[])totalItEntry.value : null;
|
||||
if (totalVals == null) {
|
||||
totalVals = BucketingService.this.initMeasureValues();
|
||||
addVal = totalVals;
|
||||
}
|
||||
BucketingService.this.sumVals(totalVals, (MeasureDefinition.MeasureValue[])entry.getValue());
|
||||
}
|
||||
} else {
|
||||
BucketListMap nextTotals = (compare == 0) ? (BucketListMap)totalItEntry.value : null;
|
||||
if (nextTotals == null) {
|
||||
nextTotals = BucketingService.this.createCollectBucketMap(this.level + 1);
|
||||
addVal = nextTotals;
|
||||
}
|
||||
nextTotals.collectVals((BucketingService.BucketMap)entry.getValue(), sum);
|
||||
}
|
||||
if (compare < 0) {
|
||||
if (totalItEntry != null)
|
||||
totalIt.previous();
|
||||
totalIt.add(new BucketingService.MapEntry(key, addVal));
|
||||
if (totalItEntry != null)
|
||||
totalIt.next();
|
||||
}
|
||||
entry = it.hasNext() ? it.next() : null;
|
||||
}
|
||||
if (compare >= 0)
|
||||
totalItEntry = totalIt.hasNext() ? totalIt.next() : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void createCrosstab() throws JRException {
|
||||
BucketListMap collectedCols;
|
||||
CollectedList[] collectedHeaders = new CollectedList[2];
|
||||
collectedHeaders[0] = createHeadersList((byte)0, this.bucketValueMap, 0, false);
|
||||
if (this.allBuckets[0].computeTotal()) {
|
||||
BucketMap map = this.bucketValueMap;
|
||||
for (int i = 0; i < this.rowBucketCount; i++)
|
||||
map = (BucketMap)map.getTotalEntry().getValue();
|
||||
collectedCols = (BucketListMap)map;
|
||||
} else {
|
||||
collectedCols = createCollectBucketMap(this.rowBucketCount);
|
||||
collectCols(collectedCols, this.bucketValueMap);
|
||||
}
|
||||
collectedHeaders[1] = createHeadersList((byte)1, collectedCols, 0, false);
|
||||
int rowBuckets = (collectedHeaders[0]).span;
|
||||
int colBuckets = (collectedHeaders[1]).span;
|
||||
int bucketMeasureCount = rowBuckets * colBuckets * this.origMeasureCount;
|
||||
checkBucketMeasureCount(bucketMeasureCount);
|
||||
this.colHeaders = createHeaders((byte)1, collectedHeaders);
|
||||
this.rowHeaders = createHeaders((byte)0, collectedHeaders);
|
||||
this.cells = new CrosstabCell[rowBuckets][colBuckets];
|
||||
fillCells(collectedHeaders, this.bucketValueMap, 0, new int[] { 0, 0 }, new ArrayList(), new ArrayList());
|
||||
}
|
||||
|
||||
protected void checkBucketMeasureCount(int bucketMeasureCount) {
|
||||
if (this.bucketMeasureLimit > 0 && bucketMeasureCount > this.bucketMeasureLimit)
|
||||
throw new JRRuntimeException("Crosstab bucket/measure limit (" + this.bucketMeasureLimit + ") exceeded.");
|
||||
}
|
||||
|
||||
protected void collectCols(BucketListMap collectedCols, BucketMap bucketMap) throws JRException {
|
||||
if (this.allBuckets[bucketMap.level].computeTotal()) {
|
||||
BucketMap map = bucketMap;
|
||||
for (int i = bucketMap.level; i < this.rowBucketCount; i++)
|
||||
map = (BucketMap)map.getTotalEntry().getValue();
|
||||
collectedCols.collectVals(map, false);
|
||||
return;
|
||||
}
|
||||
for (Iterator it = bucketMap.entryIterator(); it.hasNext(); ) {
|
||||
Map.Entry entry = it.next();
|
||||
BucketMap nextMap = (BucketMap)entry.getValue();
|
||||
if (bucketMap.level == this.rowBucketCount - 1) {
|
||||
collectedCols.collectVals(nextMap, false);
|
||||
continue;
|
||||
}
|
||||
collectCols(collectedCols, nextMap);
|
||||
}
|
||||
}
|
||||
|
||||
protected CollectedList createHeadersList(byte dimension, BucketMap bucketMap, int level, boolean total) {
|
||||
CollectedList headers = new CollectedList();
|
||||
for (Iterator it = bucketMap.entryIterator(); it.hasNext(); ) {
|
||||
Map.Entry entry = it.next();
|
||||
BucketDefinition.Bucket bucketValue = (BucketDefinition.Bucket)entry.getKey();
|
||||
boolean totalBucket = bucketValue.isTotal();
|
||||
byte totalPosition = this.allBuckets[bucketMap.level].getTotalPosition();
|
||||
boolean createHeader = (!totalBucket || total || totalPosition != 0);
|
||||
if (createHeader) {
|
||||
CollectedList nextHeaders;
|
||||
if (level + 1 < (this.buckets[dimension]).length) {
|
||||
BucketMap nextMap = (BucketMap)entry.getValue();
|
||||
nextHeaders = createHeadersList(dimension, nextMap, level + 1, (total || totalBucket));
|
||||
} else {
|
||||
nextHeaders = new CollectedList();
|
||||
nextHeaders.span = 1;
|
||||
}
|
||||
nextHeaders.key = bucketValue;
|
||||
if (totalBucket) {
|
||||
if (totalPosition == 1) {
|
||||
headers.addFirst(nextHeaders);
|
||||
continue;
|
||||
}
|
||||
headers.add(nextHeaders);
|
||||
continue;
|
||||
}
|
||||
headers.add(nextHeaders);
|
||||
}
|
||||
}
|
||||
if (headers.span == 0)
|
||||
headers.span = 1;
|
||||
return headers;
|
||||
}
|
||||
|
||||
protected HeaderCell[][] createHeaders(byte dimension, CollectedList[] headersLists) {
|
||||
HeaderCell[][] headers = new HeaderCell[(this.buckets[dimension]).length][(headersLists[dimension]).span];
|
||||
List vals = new ArrayList();
|
||||
fillHeaders(dimension, headers, 0, 0, headersLists[dimension], vals);
|
||||
return headers;
|
||||
}
|
||||
|
||||
protected void fillHeaders(byte dimension, HeaderCell[][] headers, int level, int col, CollectedList list, List vals) {
|
||||
if (level == (this.buckets[dimension]).length)
|
||||
return;
|
||||
for (Iterator it = list.iterator(); it.hasNext(); ) {
|
||||
CollectedList subList = (CollectedList)it.next();
|
||||
vals.add(subList.key);
|
||||
int depthSpan = subList.key.isTotal() ? ((this.buckets[dimension]).length - level) : 1;
|
||||
BucketDefinition.Bucket[] values = new BucketDefinition.Bucket[(this.buckets[dimension]).length];
|
||||
vals.toArray(values);
|
||||
headers[level][col] = new HeaderCell(values, subList.span, depthSpan);
|
||||
if (!subList.key.isTotal())
|
||||
fillHeaders(dimension, headers, level + 1, col, subList, vals);
|
||||
col += subList.span;
|
||||
vals.remove(vals.size() - 1);
|
||||
}
|
||||
}
|
||||
|
||||
protected void fillCells(CollectedList[] collectedHeaders, BucketMap bucketMap, int level, int[] pos, List vals, List bucketMaps) {
|
||||
bucketMaps.add(bucketMap);
|
||||
byte dimension = (level < this.rowBucketCount) ? 0 : 1;
|
||||
boolean last = (level == this.allBuckets.length - 1);
|
||||
CollectedList[] nextCollected = null;
|
||||
if (!last) {
|
||||
nextCollected = new CollectedList[2];
|
||||
for (int d = 0; d < 2; d++) {
|
||||
if (d != dimension)
|
||||
nextCollected[d] = collectedHeaders[d];
|
||||
}
|
||||
}
|
||||
boolean incrementRow = (level == (this.buckets[0]).length - 1);
|
||||
CollectedList collectedList = collectedHeaders[dimension];
|
||||
Iterator bucketIt = (bucketMap == null) ? null : bucketMap.entryIterator();
|
||||
Map.Entry bucketItEntry = (bucketIt != null && bucketIt.hasNext()) ? bucketIt.next() : null;
|
||||
for (Iterator it = collectedList.iterator(); it.hasNext(); ) {
|
||||
CollectedList list = (CollectedList)it.next();
|
||||
Map.Entry bucketEntry = null;
|
||||
if (list.key.isTotal()) {
|
||||
if (bucketMap != null)
|
||||
bucketEntry = bucketMap.getTotalEntry();
|
||||
} else if (bucketItEntry != null && bucketItEntry.getKey().equals(list.key)) {
|
||||
bucketEntry = bucketItEntry;
|
||||
bucketItEntry = bucketIt.hasNext() ? bucketIt.next() : null;
|
||||
}
|
||||
vals.add(list.key);
|
||||
if (last) {
|
||||
fillCell(pos, vals, bucketMaps, bucketEntry);
|
||||
} else {
|
||||
nextCollected[dimension] = list;
|
||||
BucketMap nextMap = (bucketEntry == null) ? null : (BucketMap)bucketEntry.getValue();
|
||||
fillCells(nextCollected, nextMap, level + 1, pos, vals, bucketMaps);
|
||||
}
|
||||
vals.remove(vals.size() - 1);
|
||||
if (incrementRow) {
|
||||
pos[0] = pos[0] + 1;
|
||||
pos[1] = 0;
|
||||
}
|
||||
}
|
||||
bucketMaps.remove(bucketMaps.size() - 1);
|
||||
}
|
||||
|
||||
protected void fillCell(int[] pos, List vals, List bucketMaps, Map.Entry bucketEntry) {
|
||||
Iterator valsIt = vals.iterator();
|
||||
BucketDefinition.Bucket[] rowValues = new BucketDefinition.Bucket[(this.buckets[0]).length];
|
||||
for (int i = 0; i < rowValues.length; i++)
|
||||
rowValues[i] = valsIt.next();
|
||||
BucketDefinition.Bucket[] columnValues = new BucketDefinition.Bucket[(this.buckets[1]).length];
|
||||
for (int j = 0; j < columnValues.length; j++)
|
||||
columnValues[j] = valsIt.next();
|
||||
MeasureDefinition.MeasureValue[] measureVals = (bucketEntry == null) ? this.zeroUserMeasureValues : getUserMeasureValues((MeasureDefinition.MeasureValue[])bucketEntry.getValue());
|
||||
MeasureDefinition.MeasureValue[][][] totals = retrieveTotals(vals, bucketMaps);
|
||||
this.cells[pos[0]][pos[1]] = new CrosstabCell(rowValues, columnValues, measureVals, totals);
|
||||
pos[1] = pos[1] + 1;
|
||||
}
|
||||
|
||||
protected MeasureDefinition.MeasureValue[][][] retrieveTotals(List vals, List bucketMaps) {
|
||||
MeasureDefinition.MeasureValue[][][] totals = new MeasureDefinition.MeasureValue[this.rowBucketCount + 1][this.colBucketCount + 1][];
|
||||
for (int row = this.rowRetrTotalMax; row >= this.rowRetrTotalMin; row--) {
|
||||
if (this.rowRetrTotals[row]) {
|
||||
BucketMap rowMap = bucketMaps.get(row);
|
||||
for (int i = row; rowMap != null && i < this.rowBucketCount; i++) {
|
||||
Map.Entry totalEntry = rowMap.getTotalEntry();
|
||||
rowMap = (totalEntry == null) ? null : (BucketMap)totalEntry.getValue();
|
||||
}
|
||||
for (int col = 0; col <= this.rowRetrColMax[row]; col++) {
|
||||
BucketMap colMap = rowMap;
|
||||
if (col < this.colBucketCount - 1)
|
||||
if (row == this.rowBucketCount) {
|
||||
rowMap = bucketMaps.get(this.rowBucketCount + col + 1);
|
||||
} else if (rowMap != null) {
|
||||
rowMap = (BucketMap)rowMap.get(vals.get(this.rowBucketCount + col));
|
||||
}
|
||||
if (this.retrieveTotal[row][col]) {
|
||||
for (int j = col + 1; colMap != null && j < this.colBucketCount; j++)
|
||||
colMap = (BucketMap)colMap.getTotalEntry().getValue();
|
||||
if (colMap != null)
|
||||
if (col == this.colBucketCount) {
|
||||
MeasureDefinition.MeasureValue[] measureValues = (MeasureDefinition.MeasureValue[])colMap.get(vals.get(this.rowBucketCount + this.colBucketCount - 1));
|
||||
totals[row][col] = getUserMeasureValues(measureValues);
|
||||
} else {
|
||||
Map.Entry totalEntry = colMap.getTotalEntry();
|
||||
if (totalEntry != null) {
|
||||
MeasureDefinition.MeasureValue[] totalValues = (MeasureDefinition.MeasureValue[])totalEntry.getValue();
|
||||
totals[row][col] = getUserMeasureValues(totalValues);
|
||||
}
|
||||
}
|
||||
if (totals[row][col] == null)
|
||||
totals[row][col] = this.zeroUserMeasureValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return totals;
|
||||
}
|
||||
|
||||
protected static class CollectedList extends LinkedList {
|
||||
private static final long serialVersionUID = 10200L;
|
||||
|
||||
int span = 0;
|
||||
|
||||
BucketDefinition.Bucket key;
|
||||
|
||||
public boolean add(Object o) {
|
||||
boolean added = super.add(o);
|
||||
incrementSpan(o);
|
||||
return added;
|
||||
}
|
||||
|
||||
public void addFirst(Object o) {
|
||||
super.addFirst(o);
|
||||
incrementSpan(o);
|
||||
}
|
||||
|
||||
public void addLast(Object o) {
|
||||
super.add(o);
|
||||
incrementSpan(o);
|
||||
}
|
||||
|
||||
private void incrementSpan(Object o) {
|
||||
if (o != null && o instanceof CollectedList) {
|
||||
this.span += ((CollectedList)o).span;
|
||||
} else {
|
||||
this.span++;
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.key + "/" + this.span + ": " + super.toString();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,55 @@
|
||||
package net.sf.jasperreports.crosstabs.fill.calculation;
|
||||
|
||||
public class CrosstabCell {
|
||||
private final BucketDefinition.Bucket[] rowBucketValues;
|
||||
|
||||
private final int rowTotalGroupIndex;
|
||||
|
||||
private final BucketDefinition.Bucket[] columnBucketValues;
|
||||
|
||||
private final int columnTotalGroupIndex;
|
||||
|
||||
private final MeasureDefinition.MeasureValue[] mesureValues;
|
||||
|
||||
private final MeasureDefinition.MeasureValue[][][] totals;
|
||||
|
||||
public CrosstabCell(BucketDefinition.Bucket[] rowBucketValues, BucketDefinition.Bucket[] columnBucketValues, MeasureDefinition.MeasureValue[] mesureValues, MeasureDefinition.MeasureValue[][][] totals) {
|
||||
this.rowBucketValues = rowBucketValues;
|
||||
this.rowTotalGroupIndex = getTotalIndex(rowBucketValues);
|
||||
this.columnBucketValues = columnBucketValues;
|
||||
this.columnTotalGroupIndex = getTotalIndex(columnBucketValues);
|
||||
this.mesureValues = mesureValues;
|
||||
this.totals = totals;
|
||||
}
|
||||
|
||||
private static int getTotalIndex(BucketDefinition.Bucket[] values) {
|
||||
int i = 0;
|
||||
while (i < values.length && !values[i].isTotal())
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
public MeasureDefinition.MeasureValue[] getMesureValues() {
|
||||
return this.mesureValues;
|
||||
}
|
||||
|
||||
public BucketDefinition.Bucket[] getColumnBucketValues() {
|
||||
return this.columnBucketValues;
|
||||
}
|
||||
|
||||
public BucketDefinition.Bucket[] getRowBucketValues() {
|
||||
return this.rowBucketValues;
|
||||
}
|
||||
|
||||
public int getColumnTotalGroupIndex() {
|
||||
return this.columnTotalGroupIndex;
|
||||
}
|
||||
|
||||
public int getRowTotalGroupIndex() {
|
||||
return this.rowTotalGroupIndex;
|
||||
}
|
||||
|
||||
public MeasureDefinition.MeasureValue[][][] getTotals() {
|
||||
return this.totals;
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
package net.sf.jasperreports.crosstabs.fill.calculation;
|
||||
|
||||
public class HeaderCell {
|
||||
private final BucketDefinition.Bucket[] bucketValues;
|
||||
|
||||
private final int levelSpan;
|
||||
|
||||
private final int depthSpan;
|
||||
|
||||
private final boolean isTotal;
|
||||
|
||||
public HeaderCell(BucketDefinition.Bucket[] bucketValues, int levelSpan, int depthSpan) {
|
||||
this.bucketValues = bucketValues;
|
||||
this.levelSpan = levelSpan;
|
||||
this.depthSpan = depthSpan;
|
||||
boolean foundTotal = false;
|
||||
for (int i = 0; i < bucketValues.length; i++) {
|
||||
if (bucketValues[i] != null && bucketValues[i].isTotal()) {
|
||||
foundTotal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.isTotal = foundTotal;
|
||||
}
|
||||
|
||||
public BucketDefinition.Bucket[] getBucketValues() {
|
||||
return this.bucketValues;
|
||||
}
|
||||
|
||||
public int getLevelSpan() {
|
||||
return this.levelSpan;
|
||||
}
|
||||
|
||||
public int getDepthSpan() {
|
||||
return this.depthSpan;
|
||||
}
|
||||
|
||||
public boolean isTotal() {
|
||||
return this.isTotal;
|
||||
}
|
||||
|
||||
public static HeaderCell createLevelSpanCopy(HeaderCell cell, int newLevelSpan) {
|
||||
return new HeaderCell(cell.bucketValues, newLevelSpan, cell.getDepthSpan());
|
||||
}
|
||||
}
|
@@ -0,0 +1,129 @@
|
||||
package net.sf.jasperreports.crosstabs.fill.calculation;
|
||||
|
||||
import net.sf.jasperreports.engine.JRException;
|
||||
import net.sf.jasperreports.engine.fill.AbstractValueProvider;
|
||||
import net.sf.jasperreports.engine.fill.JRCalculable;
|
||||
import net.sf.jasperreports.engine.fill.JRDistinctCountExtendedIncrementerFactory;
|
||||
import net.sf.jasperreports.engine.fill.JRExtendedIncrementer;
|
||||
import net.sf.jasperreports.engine.fill.JRExtendedIncrementerFactory;
|
||||
|
||||
public class MeasureDefinition {
|
||||
protected final byte calculation;
|
||||
|
||||
protected final JRExtendedIncrementerFactory incrementerFactory;
|
||||
|
||||
protected final Class valueClass;
|
||||
|
||||
protected final boolean isSystemDefined;
|
||||
|
||||
public MeasureDefinition(Class valueClass, byte calculation, JRExtendedIncrementerFactory incrementerFactory) {
|
||||
this(valueClass, calculation, incrementerFactory, false);
|
||||
}
|
||||
|
||||
protected MeasureDefinition(Class valueClass, byte calculation, JRExtendedIncrementerFactory incrementerFactory, boolean isSystemDefined) {
|
||||
this.valueClass = valueClass;
|
||||
this.calculation = calculation;
|
||||
this.incrementerFactory = incrementerFactory;
|
||||
this.isSystemDefined = isSystemDefined;
|
||||
}
|
||||
|
||||
public static MeasureDefinition createHelperMeasure(MeasureDefinition measure, byte helperCalculation) {
|
||||
return new MeasureDefinition(measure.valueClass, helperCalculation, measure.incrementerFactory, true);
|
||||
}
|
||||
|
||||
public static MeasureDefinition createDistinctCountHelperMeasure(MeasureDefinition measure) {
|
||||
return new MeasureDefinition(measure.valueClass, (byte)0, (JRExtendedIncrementerFactory)JRDistinctCountExtendedIncrementerFactory.getInstance(), true);
|
||||
}
|
||||
|
||||
public byte getCalculation() {
|
||||
return this.calculation;
|
||||
}
|
||||
|
||||
public JRExtendedIncrementerFactory getIncrementerFactory() {
|
||||
return this.incrementerFactory;
|
||||
}
|
||||
|
||||
public JRExtendedIncrementer getIncrementer() {
|
||||
return this.incrementerFactory.getExtendedIncrementer(this.calculation);
|
||||
}
|
||||
|
||||
protected boolean isSystemDefined() {
|
||||
return this.isSystemDefined;
|
||||
}
|
||||
|
||||
public Class getValueClass() {
|
||||
return this.valueClass;
|
||||
}
|
||||
|
||||
protected static final AbstractValueProvider VALUE_PROVIDER = new AbstractValueProvider() {
|
||||
public Object getValue(JRCalculable calculable) {
|
||||
return calculable.getValue();
|
||||
}
|
||||
};
|
||||
|
||||
public class MeasureValue implements JRCalculable {
|
||||
private Object value;
|
||||
|
||||
private MeasureValue[] helpers;
|
||||
|
||||
private boolean initialized;
|
||||
|
||||
private JRExtendedIncrementer incrementer;
|
||||
|
||||
private final MeasureDefinition this$0;
|
||||
|
||||
public MeasureValue() {
|
||||
this.value = null;
|
||||
this.helpers = new MeasureValue[3];
|
||||
this.incrementer = MeasureDefinition.this.getIncrementer();
|
||||
init();
|
||||
}
|
||||
|
||||
protected void init() {
|
||||
this.value = this.incrementer.initialValue();
|
||||
setInitialized(true);
|
||||
}
|
||||
|
||||
public void addValue(Object addValue) throws JRException {
|
||||
this.value = this.incrementer.increment(this, addValue, MeasureDefinition.VALUE_PROVIDER);
|
||||
setInitialized(false);
|
||||
}
|
||||
|
||||
public void addValue(MeasureValue measureValue) throws JRException {
|
||||
if (!measureValue.isInitialized()) {
|
||||
this.value = this.incrementer.combine(this, measureValue, MeasureDefinition.VALUE_PROVIDER);
|
||||
setInitialized(false);
|
||||
}
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return String.valueOf(getValue());
|
||||
}
|
||||
|
||||
public MeasureValue setHelper(MeasureValue helperVariable, byte type) {
|
||||
MeasureValue old = this.helpers[type];
|
||||
this.helpers[type] = helperVariable;
|
||||
return old;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return this.initialized;
|
||||
}
|
||||
|
||||
public Object getIncrementedValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
public JRCalculable getHelperVariable(byte helperType) {
|
||||
return this.helpers[helperType];
|
||||
}
|
||||
|
||||
public void setInitialized(boolean isInitialized) {
|
||||
this.initialized = isInitialized;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user