package er.reporting;
import java.util.Enumeration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.webobjects.appserver.WOComponent;
import com.webobjects.appserver.WOContext;
import com.webobjects.appserver.WORequest;
import com.webobjects.appserver.WOResponse;
import com.webobjects.foundation.NSArray;
import com.webobjects.foundation.NSDictionary;
import com.webobjects.foundation.NSMutableDictionary;
import com.webobjects.foundation.NSNotification;
import com.webobjects.foundation.NSNotificationCenter;
import com.webobjects.foundation.NSSelector;
import er.extensions.eof.ERXConstant;
import er.extensions.foundation.ERXStringUtilities;
import er.extensions.foundation.ERXValueUtilities;
import er.grouping.DRAttribute;
import er.grouping.DRCriteria;
import er.grouping.DRGroup;
import er.grouping.DRMasterCriteria;
import er.grouping.DRRecordGroup;
import er.grouping.DRReportModel;
public class WRReport extends WOComponent {
private static final Logger log = LoggerFactory.getLogger(WRReport.class);
protected DRReportModel _model;
// iterators...
public DRGroup aGrp, hGroup, vGroup, zGroup;
public String areportStyle;
public int currentIndex, currentIndexV;
public int currentLevelV, currentLevel;
public int vheadingCount;
public int depth;
public String dispType;
public DRAttribute attrib;
protected DRCriteria _topCriteriaV, _topCriteria;
protected int _vheadingIndex;
protected NSMutableDictionary _indexDict;
protected NSMutableDictionary _currentZCriteria;
protected NSArray _recordGroupDisplayTypes;
protected NSArray _reportStyles;
protected String _selectedReportStyle;
protected String _selectedRecordGroupDisplayType;
protected String _recordGroupTotalToShow;
protected String _recordGroupTotalFormat;
protected Boolean _showRecordGroupAsTable;
protected Boolean _showRecordGroupHeadings;
protected Boolean _showPresentationControls;
protected Boolean _showEditing;
protected String _componentName;
protected Boolean _showNavigation;
protected NSArray _colorDict;
//String _baseColor, _maxColor;
//NSMutableDictionary _currCritDictCache;
protected Boolean _showCustomReportStyle;
protected boolean _initializedDimensionArrayFromBindings;
protected Boolean _showTopCriteriaLabel;
protected Boolean _shouldTotalCheck;
public WRReport(WOContext c) {
super(c);
_currentZCriteria = new NSMutableDictionary();
_indexDict = new NSMutableDictionary();
//_currCritDictCache = new NSMutableDictionary();
//_baseColor = "d0cfbd";
//_maxColor = "ffec00";
_colorDict = null;
_initializedDimensionArrayFromBindings = false;
_recordGroupDisplayTypes = new NSArray(new Object[]{"SINGLE_TOTAL" , "TABLE" , "TOTALS"});
_reportStyles = new NSArray(new Object[]{"VERTICAL_ROWS" , "NESTED_CELLS"});
NSSelector rebuildModelSelector = new NSSelector("rebuildModel", ERXConstant.NotificationClassArray);
NSNotificationCenter.defaultCenter().addObserver(this, rebuildModelSelector, DRReportModel.DRReportModelRebuildNotification, null);
}
public Object recordGroupTest() {
throw new IllegalStateException("There is a component bound to this variable and it doesn't exist. If you need this component to work, please look at what this is supposed to do and submit a patch.");
}
@Override
public void finalize() throws Throwable {
NSNotificationCenter.defaultCenter().removeObserver(this);
super.finalize();
}
public Boolean booleanValueForBinding(String name) {
boolean flag = ERXValueUtilities.booleanValue(valueForBinding(name));
return flag ? Boolean.TRUE : Boolean.FALSE;
}
public NSArray recordGroupDisplayTypes() {
return _recordGroupDisplayTypes;
}
public NSArray reportStyles() {
return _reportStyles;
}
@Override
public boolean synchronizesVariablesWithBindings() {
return false;
}
public void initializeDimensionArrayFromBindings() {
if(!_initializedDimensionArrayFromBindings) {
if(model() != null) {
_initializedDimensionArrayFromBindings = true;
initializeDimensionArrayFromBindings("H");
initializeDimensionArrayFromBindings("V");
initializeDimensionArrayFromBindings("Z");
log.debug("V :{}", model().vList());
log.debug("H :{}", model().hList());
log.debug("Z :{}", model().zList());
} else {
log.error("Model is null!");
}
}
}
@Override
public void awake() {
_model = null;
_vheadingIndex = 0;
_indexDict.removeAllObjects();
_colorDict = null;
_showPresentationControls = null;
_showRecordGroupHeadings = null;
_showTopCriteriaLabel = null;
_shouldTotalCheck = null;
_recordGroupTotalToShow = null;
_currentZCriteria.removeAllObjects();
//_initializedDimensionArrayFromBindings = false;
initializeDimensionArrayFromBindings();
}
@Override
public void takeValuesFromRequest(WORequest r, WOContext c) {
super.takeValuesFromRequest(r, c);
}
@Override
public void appendToResponse(WOResponse r, WOContext c) {
initializeDimensionArrayFromBindings();
super.appendToResponse(r, c);
}
public void rebuildModel(NSNotification notification) {
if(_model != null && _model == notification.object()) {
log.debug("rebuildModel: {}: {}", notification.object().hashCode(), _model.hashCode());
_currentZCriteria.removeAllObjects();
_initializedDimensionArrayFromBindings = false;
_model = null;
}
}
public boolean showPresentationControls() {
if (_showPresentationControls == null) {
_showPresentationControls = booleanValueForBinding("showPresentationControls");
}
return _showPresentationControls.booleanValue();
}
public void setShowPresentationControls(boolean v) {
_showPresentationControls = v ? Boolean.TRUE : Boolean.FALSE;
}
public void setShouldTotalCheck(boolean shouldTotalCheck) {
_shouldTotalCheck = Boolean.valueOf(shouldTotalCheck);
}
public boolean shouldTotalCheck() {
if (_shouldTotalCheck == null) {
_shouldTotalCheck = booleanValueForBinding("shouldTotalCheck");
}
return _shouldTotalCheck.booleanValue();
}
public NSDictionary currentZCriteria() {
return _currentZCriteria;
}
public String selectedRecordGroupDisplayType() {
if (_selectedRecordGroupDisplayType == null) {
_selectedRecordGroupDisplayType = (String)valueForBinding("selectedRecordGroupDisplayType");
if (_selectedRecordGroupDisplayType == null) {
_selectedRecordGroupDisplayType = "TOTALS";
}
}
return _selectedRecordGroupDisplayType;
}
public void setSelectedRecordGroupDisplayType(String v) {
_selectedRecordGroupDisplayType = v;
}
public String selectedReportStyle() {
if (_selectedReportStyle == null) {
_selectedReportStyle = (String)valueForBinding("selectedReportStyle");
if (_selectedReportStyle == null) {
_selectedReportStyle = "NESTED_CELLS";
}
}
return _selectedReportStyle;
}
public void setSelectedReportStyle(String v) {
_selectedReportStyle = v;
}
public boolean showVerticalRows() {
if (selectedReportStyle().equals("VERTICAL_ROWS")
&& !showRecordGroupAsTable()
&& selectedRecordGroupDisplayType().equals("TABLE")) {
return true;
}
return false;
}
public String recordGroupTotalToShow() {
if (_recordGroupTotalToShow == null) {
_recordGroupTotalToShow = (String)valueForBinding("recordGroupTotalToShow");
if (_recordGroupTotalToShow == null) {
_recordGroupTotalToShow = "description";
}
}
return _recordGroupTotalToShow;
}
public void setRecordGroupTotalToShow(String v) {
_recordGroupTotalToShow = v;
}
public String recordGroupTotalFormat() {
if (_recordGroupTotalFormat == null) {
_recordGroupTotalFormat = (String)valueForBinding("recordGroupTotalFormat");
if (_recordGroupTotalFormat == null) {
_recordGroupTotalFormat = "#,###0.00;;-#,###0.00";
}
}
return _recordGroupTotalFormat;
}
public void setRecordGroupTotalFormat(String v) {
_recordGroupTotalFormat = v;
}
public boolean showDefaultReportStyle() {
return showCustomReportStyle();
}
public boolean showCustomReportStyle() {
if (_showCustomReportStyle == null) {
_showCustomReportStyle = booleanValueForBinding("showCustomReportStyle");
}
return _showCustomReportStyle.booleanValue();
}
public void setShowCustomReportStyle(boolean v) {
_showCustomReportStyle = v ? Boolean.TRUE : Boolean.FALSE;
}
public boolean showRecordGroupHeadings() {
if (_showRecordGroupHeadings == null) {
if (!hasBinding("showRecordGroupHeadings")) {
_showRecordGroupHeadings = Boolean.TRUE;
} else {
_showRecordGroupHeadings = booleanValueForBinding("showRecordGroupHeadings");
}
}
return _showRecordGroupHeadings.booleanValue();
}
public void setShowRecordGroupHeadings(boolean v) {
_showRecordGroupHeadings = v ? Boolean.TRUE : Boolean.FALSE;
}
public boolean showRecordGroupAsTable() {
if (_showRecordGroupAsTable == null) {
if (!hasBinding("showRecordGroupAsTable")) {
_showRecordGroupAsTable = Boolean.FALSE;
} else {
_showRecordGroupAsTable = booleanValueForBinding("showRecordGroupAsTable");
}
}
return _showRecordGroupAsTable.booleanValue();
}
public void setShowRecordGroupAsTable(boolean v) {
_showRecordGroupAsTable = v ? Boolean.TRUE : Boolean.FALSE;
}
public boolean showTotalsOnlyAsCells() {
if (selectedRecordGroupDisplayType().equals("TOTALS")
&& !showRecordGroupAsTable()) {
return true;
}
return false;
}
public String componentName() {
if(_componentName == null) {
_componentName = (String)valueForBinding("recordGroupComponentName");
if(_componentName == null) {
_componentName = "WRRecordGroup";
}
}
return _componentName;
}
public boolean showAsCells() {
if (!showRecordGroupAsTable()
&& !selectedRecordGroupDisplayType().equals("SINGLE_TOTAL")
&& !selectedRecordGroupDisplayType().equals("TABLE")) {
return true;
}
return false;
}
public boolean showEditing() {
if(_showEditing == null){
_showEditing = booleanValueForBinding("showEditing");
}
return _showEditing.booleanValue();
}
public boolean showNavigation() {
if (_showNavigation ==null) {
_showNavigation = booleanValueForBinding("showNavigation");
}
return _showNavigation.booleanValue();
}
public void setShowNavigation(boolean v) {
_showNavigation = v ? Boolean.TRUE : Boolean.FALSE;
}
public DRReportModel model() {
if (_model == null) {
_model = (DRReportModel)valueForBinding("model");
}
return _model;
}
public boolean showSingleRow() {
if (model().vList().count() > 0) {
return false;
}
return true;
}
public boolean showSingleCol() {
if (model().hList().count() > 0) {
return false;
}
return true;
}
public boolean showNoColNoRow() {
if (showSingleRow() && showSingleCol()) {
return true;
}
return false;
}
public NSArray zDimensions() {
return model().zList();
}
public NSArray horzDimensions() {
return model().hList();
}
public NSArray vertDimensions() {
return model().vList();
}
public NSArray topHorzGroupCriteriaList() {
NSArray hList = model().hList();
if (hList.count() > 0) {
DRGroup group = (DRGroup)hList.objectAtIndex(0);
NSArray sortedCriteriaList = group.sortedCriteriaList();
return sortedCriteriaList;
}
return NSArray.EmptyArray;
}
public NSArray topVertGroupCriteriaList() {
NSArray arr = model().vList();
if (arr.count() > 0) {
DRGroup grp = (DRGroup)arr.objectAtIndex(0);
return grp.sortedCriteriaList();
}
return NSArray.EmptyArray;
}
public int colSpanForHorzList() {
return model().spanForVListIndexAsCellsShowHeadingShowTotals(false, currentLevel-1, showAsCells(), showRecordGroupHeadings(), selectedRecordGroupDisplayType().equals("TOTALS"));
}
public int horzColSpan() {
return colSpanForHorzList();
}
public boolean hasTitle() {
return title() != null;
}
public String title() {
return (String)valueForBinding("title");
}
public NSArray vertSubList() {
DRMasterCriteria masterCritForCrit = topCriteriaV().masterCriteria();
DRGroup drg = (DRGroup)model().vList().lastObject();
if(drg != null){
DRMasterCriteria bottomMasterCrit = drg.masterCriteria();
if (masterCritForCrit.equals(bottomMasterCrit)) {
return null;
}
}
DRGroup innerGroup = (DRGroup)model().vList().objectAtIndex(currentLevelV - 1);
return innerGroup.sortedCriteriaList();
}
public DRCriteria topCriteria() {
return _topCriteria;
}
public void setTopCriteria(DRCriteria c) {
//log.debug( "c:"+c);
if(c != null){
String ky = c.masterCriteria().label();
//log.debug( "ky:"+ky);
if (ky != null) {
_currentZCriteria.setObjectForKey(c, ky);
}
}
_topCriteria = c;
}
public NSArray horzSubList() {
// current DRGroup for row is: hGroup
// current DRCriteria for nesting is: topCriteria
// need list of sub criteria if any give the above
DRGroup innerGroup;
DRMasterCriteria masterCritForCrit = topCriteria().masterCriteria();
if (masterCritForCrit.equals(hGroup.masterCriteria())) {
return null;
}
innerGroup = (DRGroup)model().hList().objectAtIndex(currentLevel-1);
return innerGroup.sortedCriteriaList();
}
public NSArray horzSubList2() {
DRMasterCriteria masterCritForCrit = topCriteria().masterCriteria();
DRGroup grp = (DRGroup)model().hList().lastObject();
DRMasterCriteria bottomMasterCrit = grp.masterCriteria();
if (masterCritForCrit.equals(bottomMasterCrit)) {
return null;
}
DRGroup innerGroup = (DRGroup)model().hList().objectAtIndex(currentLevel-1);
return innerGroup.sortedCriteriaList();
}
public void initializeDimensionArrayFromBindings(String dimension) {
NSArray keypaths = ERXValueUtilities.arrayValue(valueForBinding("keysIn" + dimension));
if(keypaths != null && keypaths.count() > 0) {
for (Enumeration en = keypaths.objectEnumerator(); en.hasMoreElements(); ) {
String keypath = (String)en.nextElement();
DRMasterCriteria crit = model().masterCriteriaForKeyPath(keypath);
if(crit != null) {
DRGroup group = model().groupForMasterCriteria(crit);
if("Z".equals(dimension))
model().addToZList(group);
else if("H".equals(dimension))
model().addToHList(group);
else if("V".equals(dimension))
model().addToVList(group);
} else {
log.warn("Criteria not found: {}", keypath);
}
}
}
}
public NSDictionary addCoordsFrom(NSMutableDictionary currCritDict) {
NSMutableDictionary dict = new NSMutableDictionary();
Enumeration en = model().groups().objectEnumerator();
//log.debug( "currCritDict:"+currCritDict);
while (en.hasMoreElements()) {
DRGroup grp = (DRGroup)en.nextElement();
DRMasterCriteria dmc = grp.masterCriteria();
DRCriteria crt = (DRCriteria)currCritDict.objectForKey(dmc.label());
if(crt != null) {
dict.setObjectForKey(crt, dmc.keyDesc());
if (crt.isTotal()) {
NSMutableDictionary d = (NSMutableDictionary)dict.objectForKey("isTotal");
if (d == null) {
d = new NSMutableDictionary();
dict.setObjectForKey(d, "isTotal");
}
d.setObjectForKey("true", dmc.keyDesc());
}
}
}
return dict;
}
public NSDictionary currentCoordinates() {
NSDictionary dict = addCoordsFrom(_currentZCriteria);
return dict;
}
public DRRecordGroup recordGroup() {
NSDictionary crds = currentCoordinates();
DRRecordGroup drg = model().recordGroupForCoordinates(crds);
return drg;
}
public DRCriteria topCriteriaV() {
return _topCriteriaV;
}
public void setTopCriteriaV(DRCriteria c) {
if(c != null) {
String ky = c.masterCriteria().label();
if (ky != null) {
_currentZCriteria.setObjectForKey(c, ky);
}
}
_topCriteriaV = c;
}
public String topCriteriaVLabel() {
return topCriteriaV().label();
}
public int vheadingCount() {
return model().vList().count()-1;
}
public int vheadingIndex() {
return _vheadingIndex;
}
public void setVheadingIndex(int indx) {
_vheadingIndex = indx;
}
public int vertRowSpan() {
return model().spanForVListIndexAsCellsShowHeadingShowTotals(true, vheadingIndex(), !showRecordGroupAsTable(), showRecordGroupHeadings(), selectedRecordGroupDisplayType().equals("TOTALS"));
}
public boolean showIndentCell() {
int oldCnt;
Number oldCount = (Number)_indexDict.objectForKey(Integer.valueOf(vheadingIndex()));
if (oldCount == null) {
oldCnt = 0;
} else {
int span = model().spanForVListIndexAsCellsShowHeadingShowTotals(true, vheadingIndex(), !showRecordGroupAsTable(), showRecordGroupHeadings(), selectedRecordGroupDisplayType().equals("TOTALS"));
oldCnt = oldCount.intValue();
oldCnt++;
if (oldCnt > (span-1)) {
oldCnt = 0;
}
}
_indexDict.setObjectForKey(Integer.valueOf(oldCnt), Integer.valueOf(vheadingIndex()));
if (oldCnt == 0) {
return true;
}
return false;
}
public String vIndentCriteriaLabel() {
DRGroup grp = (DRGroup)model().vList().objectAtIndex(vheadingIndex());
String ky = grp.masterCriteria().label();
DRCriteria crt = (DRCriteria)_currentZCriteria.objectForKey(ky);
return crt.label();
}
public WOComponent regenReport() {
//_initializedDimensionArrayFromBindings = false;
return null;
}
public int numberOfCrits() {
int nm = 1;
Enumeration en = model().hList().objectEnumerator();
//log.debug( "this.model().hList():"+this.model().hList());
while (en.hasMoreElements()) {
DRGroup grp = (DRGroup)en.nextElement();
nm = nm*grp.sortedCriteriaList().count();
}
//log.debug( "nm:"+nm);
return nm;
}
public boolean showHeadersForAsCells() {
if (showRecordGroupHeadings() && showTotalsOnlyAsCells()) {
return true;
}
return false;
}
public NSDictionary attributeListDict() {
return model().flatAttributeListTotalDict();
}
public int depthCount() {
//log.debug( "this.attributeListDict().allKeys().count():"+this.attributeListDict().allKeys().count());
//log.debug( "this.attributeListDict().allKeys().count():"+this.attributeListDict());
return attributeListDict().allKeys().count();
}
public int colspanAddition() {
int count = model().vList().count();
return count - currentLevelV;
}
public int depthCountAllAttribs() {
return model().flatAttributeList().count()+model().vList().count() - vheadingIndex();
}
public int indentCellCount() {
return currentLevelV;
}
public boolean showVHeadings() {
if (vheadingIndex() == 0) {
return true;
}
return false;
}
public NSArray attributeListAtDepth() {
Number ky = Integer.valueOf(depth);
//log.debug( "ky:"+ky);
NSArray a = (NSArray)attributeListDict().objectForKey(ky);
//log.debug( "a:"+a);
return a;
}
public int colSpan() {
int cls = attrib.flatAttributesTotal().count();
if (attrib.showTotal()) {
cls = cls+1;
}
//log.debug( "cls:"+cls);
return cls == 0 ? 1 : cls;
}
public int rowSpan() {
//flatAttributes
int rs = 1;
if (!attrib.isGroup()) {
rs = depthCount()-depth;
}
//log.debug( "rs:"+rs);
return rs;
}
public String attribLabel() {
return attrib.label();
}
public String idAttributeTd() {
String id = attrib.keyPath();
id = ERXStringUtilities.escapeNonXMLChars(id);
return id;
}
public DRAttribute attrib() {
return attrib;
}
public void setAttrib(DRAttribute at) {
attrib = at;
}
public DRGroup aGrp() {
return aGrp;
}
public void setAGrp(DRGroup gp) {
aGrp = gp;
}
public NSDictionary totalDict() {
NSDictionary dict = currentCoordinates();
NSDictionary totalDict = (NSDictionary)dict.objectForKey("isTotal");
return totalDict;
}
public int totalCount() {
NSDictionary totalDict = totalDict();
if (totalDict == null) {
return 0;
}
int totalCount = totalDict.allKeys().count();
return totalCount;
}
public String colorForCoords() {
int totalCount = totalCount();
int maxColorsConfigured = colorDict().count();
if (totalCount == maxColorsConfigured) {
return "#eeeeee";
}
if (totalCount > maxColorsConfigured) {
return "#ffffff";
}
return (String)colorDict().objectAtIndex(totalCount);
}
public String bgcolorRowSpanTd() {
return colorForCoords();
}
public String bgcolorColSpanTd() {
return colorForCoords();
}
public String classAttributeTd() {
return "WRAttribute" + depth + "Total" + totalCount();
}
public String classColSpanTd() {
return "WRHTotal" + totalCount();
}
public String classRowSpanTd() {
return "WRVTotal" + totalCount();
}
/*
public int hexstringToInt(String str) {
String base = "0x";
String hexs = base.concat(str);
long n = this.strtoul(hexs.toCharArray(), (char)null, 16);
int i = (int)n;
return i;
}
*/
public NSArray colorDict() {
if (_colorDict == null) {
if (hasBinding("colors")) {
_colorDict = (NSArray)valueForBinding("colors");
}
if (_colorDict == null) {
_colorDict = new NSArray(new Object[]{"#c6c3af" , "#b7af4b" , "#d5ba27" , "#ffec00"});
}
/*
int i;
int numOfGroups = [[[self model] groups] count];
int maxColorAsNumber = [self hexstringToInt:_maxColor];
int minColorAsNumber = [self hexstringToInt:_baseColor];
int colorDelta = maxColorAsNumber - minColorAsNumber;
double colorInterval = (double)colorDelta/(double)numOfGroups;
NSMutableArray *arr = [NSMutableArray array];
for(i=0;i< numOfGroups; i++){
int colorAsDecimal = i* colorInterval + minColorAsNumber;
NSString * colorHexString = [NSString stringWithFormat:@"%x", colorAsDecimal];
[arr addObject:colorHexString];
}
//NSLog(@"buildColorDict: %@", arr);
colorDict = [[NSArray arrayWithArray:arr] retain];
*/
}
return _colorDict;
}
public int vheadingCount2() {
return model().vList().count();
}
public boolean showTopCriteriaLabel() {
if(_showTopCriteriaLabel == null) {
if(!hasBinding("showTopCriteriaLabel")) {
_showTopCriteriaLabel = Boolean.TRUE;
} else {
_showTopCriteriaLabel = booleanValueForBinding("showTopCriteriaLabel");
}
}
return _showTopCriteriaLabel.booleanValue();
}
}