package er.grouping; import java.util.Enumeration; import com.webobjects.eocontrol.EOSortOrdering; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSMutableArray; import com.webobjects.foundation.NSMutableDictionary; /* DRRecordGroup.h created by Administrator on Sun 01-Nov-1998 */ //#import <WebObjects/WebObjects.h> public class DRRecordGroup { protected DRCriteria _criteria; protected DRGroup _group; protected NSMutableDictionary _totals; protected NSMutableDictionary _totalsByKey; protected NSMutableArray _recordList; protected NSMutableDictionary _recordGroupDict; protected DRRecordGroup _parent; protected boolean _staleTotal; protected boolean _pregroupedListFound; // not used protected NSMutableDictionary _lookUpCoordinates; protected NSArray _totalList; protected NSArray _sortedRecordList; protected NSArray _rawRecordList; static public DRRecordGroup withCriteriaGroupParent(DRCriteria c, DRGroup grp, DRRecordGroup recGrp) { DRRecordGroup aVal = new DRRecordGroup(); aVal.initWithCriteria(c, grp, recGrp); return aVal; } private void coordsFromRecGroupDictionary(DRRecordGroup prnt, NSMutableDictionary dict) { DRRecordGroup nextParent = prnt.parent(); DRCriteria crit = prnt.criteria(); dict.setObjectForKey(crit, crit.masterCriteria().keyDesc()); if (nextParent != null) { coordsFromRecGroupDictionary(nextParent, dict); } } private NSMutableDictionary buildLookUpCoordinates() { NSMutableDictionary dict = new NSMutableDictionary(); if (_criteria == null) { return dict; } if (_parent != null) { coordsFromRecGroupDictionary(_parent, dict); } dict.setObjectForKey(_criteria, _criteria.masterCriteria().keyDesc()); return dict; } public DRRecordGroup initWithCriteria(DRCriteria c, DRGroup grp, DRRecordGroup recGrp) { _criteria = c; _group = grp; _parent = recGrp; _lookUpCoordinates = buildLookUpCoordinates(); DRRecordGroup preexistrg = null; if(_group != null){ preexistrg = _group.reportModel().recordGroupForCoordinates(_lookUpCoordinates); if (preexistrg != null) { _recordList = preexistrg.recordList(); _pregroupedListFound = true; } else { _group.reportModel().registerRecordGroupWithCoordinates(this, _lookUpCoordinates); } } return this; } public DRRecordGroup() { super(); _totals = new NSMutableDictionary(); _recordList = new NSMutableArray(); _recordGroupDict = new NSMutableDictionary(); _totalsByKey = new NSMutableDictionary(); _staleTotal = true; _pregroupedListFound = false; _sortedRecordList = null; } public NSMutableDictionary recordGroupDict() { return _recordGroupDict; } public DRCriteria criteria() { return _criteria; } public DRGroup group() { return _group; } public DRValue totalForKey(String totalKey) { DRValue value = (DRValue)_totalsByKey.objectForKey(totalKey); return value; } public NSDictionary totals() { // Loop over all DRRecords and ask each 'total-able' key for its value // and sum up into a dictionary of totals. keys in dict are keys into records // values are NSNumbers. Once computed, cache. //AK: there are two types of totals, the one is the simple sum we had earlier, // it gets stored in the _totals under (index number of the current record*index number of if (_staleTotal) { for(Enumeration en = recordList().objectEnumerator(); en.hasMoreElements(); ) { int i = 0; DRRecord rec = (DRRecord)en.nextElement(); NSArray flatlist = rec.flatValueList(); for(Enumeration en2 = flatlist.objectEnumerator(); en2.hasMoreElements(); ) { DRValue val = (DRValue)en2.nextElement(); boolean isComputed = val.attribute().isComputed(); double subTot, lastTot, newTot; Number indexNum = Integer.valueOf(i); DRValue totalValue = (DRValue)_totals.objectForKey(indexNum); if (totalValue == null) { if (val.shouldTotal()) { if(!isComputed) { totalValue = DRValue.withTotalAttribute(0, val.attribute()); } else { final NSArray rawRecords = rawRecordList(); totalValue = new DRValue(0, val.attribute()) { private Double total; @Override public double total() { if(total == null) { total = Double.valueOf(attribute().computeFromRawRecords(rawRecords)); } return total.doubleValue(); } }; } _totalsByKey.setObjectForKey(totalValue, totalValue.key()); } else { totalValue = DRValue.nullTotal(); } _totals.setObjectForKey(totalValue, indexNum); } if(!isComputed) { lastTot = totalValue.total(); subTot = val.total(); newTot = lastTot+subTot; totalValue.setTotal(newTot); } i++; } } _staleTotal = false; } return _totals; } public NSArray totalList() { if (_totalList == null) { int cnt = totals().allKeys().count(); int i; NSMutableArray totList = new NSMutableArray(); for (i = 0; i < cnt; i++) { totList.addObject(totals().objectForKey(Integer.valueOf(i))); } _totalList = new NSArray(totList); } return _totalList; } public NSArray sortedRecordList() { if (_sortedRecordList == null) { NSArray ords = null; if(_group != null){ ords = _group.reportModel().orderings(); } _sortedRecordList = EOSortOrdering.sortedArrayUsingKeyOrderArray(_recordList, ords); } return _sortedRecordList; } public NSArray rawRecordList() { if (_rawRecordList == null) { NSMutableArray rawRecs = new NSMutableArray(); NSArray recs = sortedRecordList(); Enumeration en = recs.objectEnumerator(); while (en.hasMoreElements()) { DRRecord rec = (DRRecord)en.nextElement(); Object rawRec = rec.rawRecord(); rawRecs.addObject(rawRec); } _rawRecordList = new NSArray(rawRecs); } return _rawRecordList; } public NSMutableArray recordList() { // might sort this based on settings in DRAttributes return _recordList; } public boolean pregroupedListFound() { return _pregroupedListFound; } public NSDictionary lookUpCoordinates() { return _lookUpCoordinates; } public NSArray children() { return _recordGroupDict.allValues(); } public DRRecordGroup parent() { return _parent; } public boolean childrenFromGroupCriteriaList(DRGroup grp) { //was sorted boolean listFound = false; NSArray crits = grp.criteriaList(); Enumeration anEnum = crits.objectEnumerator(); while (anEnum.hasMoreElements()) { DRCriteria crit = (DRCriteria)anEnum.nextElement(); DRRecordGroup recGrp = DRRecordGroup.withCriteriaGroupParent(crit, grp, this); listFound = recGrp.pregroupedListFound(); _recordGroupDict.setObjectForKey(recGrp, crit.keyDesc()); } return listFound; } public void groupSubRecordGroupGroupLookUpDict(NSArray groupList, NSDictionary groupLookUpDict) { int cnt = groupList.count(); if (cnt > 0) { DRMasterCriteria mc = (DRMasterCriteria)groupList.objectAtIndex(0); DRGroup grp = (DRGroup)groupLookUpDict.objectForKey(mc.keyDesc()); if (!childrenFromGroupCriteriaList(grp)) { groupByInto(recordList(), grp.masterCriteria(), recordGroupDict()); } // loop over each RecordGroup and send groupSubRecordGroup:(NSArray *)groupList // but only count is > 1 Enumeration anEnum = children().objectEnumerator(); while (anEnum.hasMoreElements()) { DRRecordGroup rg = (DRRecordGroup)anEnum.nextElement(); NSMutableArray arr = new NSMutableArray(groupList); arr.removeObjectAtIndex(0); rg.groupSubRecordGroupGroupLookUpDict(arr, groupLookUpDict); } } } public void groupByInto(NSMutableArray recs, DRMasterCriteria amc, NSMutableDictionary recGrpDict) { Enumeration anEnum = recs.objectEnumerator(); while (anEnum.hasMoreElements()) { DRRecord rec = (DRRecord)anEnum.nextElement(); amc.groupRecordRecordGroupsDictGroupParent(rec, recGrpDict, group(), this); } } @Override public String toString() { return ""+(super.toString())+"-lc:"+(_lookUpCoordinates)+"-"+(recordList().count())+"-"+(_recordGroupDict.toString()); } public boolean staleTotal() { return _staleTotal; } public void makeStale() { _staleTotal = true; _totals.removeAllObjects(); _totalList = null; } }