package er.grouping; import java.text.Format; import com.webobjects.foundation.NSArray; import com.webobjects.foundation.NSDictionary; import com.webobjects.foundation.NSMutableDictionary; import com.webobjects.foundation.NSTimestamp; import com.webobjects.foundation.NSTimestampFormatter; /** * The "value" for the {@link DRMasterCriteria}. For example, given * a <code>category</code> key, it would contain "Drama", "Sci-Fi" and "Comedy". * It also assigns a {@link #score()} to objects to support header sorting. * Some DRCriteria have very high scores and so always end up on the bottom; * for example: "OTHER" and "TOTAL". * <p> * For numeric DRCriteria, the value is a really huge number and * 1 + a really huge number ({@link #MAXNUMBER}), respectively. * For alpha DRCriteria. the value is a long word filled with z's ({@link #MAXSTRING}) * and the same with one z concatenated, respectively. */ public class DRCriteria { protected NSDictionary _valueDict; // The keys in the dict are DRSubMasterCriteria in the masterCriteria protected DRMasterCriteria _masterCriteria; protected String _label; public static final double MAXNUMBER = 99999999999.0; public static final String MAXSTRING = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"; public static String _defaultCalendarFormatString = "%m/%d/%Y"; protected boolean _isTotal; protected boolean _isOther; protected Object _score; public boolean isTotal() { return _isTotal; } public void setIsTotal(boolean v) { _isTotal = v; } public boolean isOther() { return _isOther; } public void setIsOther(boolean v) { _isOther = v; } static public DRCriteria asOtherWithMasterCriteria(DRMasterCriteria mc) { NSArray subMcs; DRSubMasterCriteria smc; DRCriteria aVal = new DRCriteria(); String lb = (String)mc.userInfo().objectForKey("OTHER_LABEL"); aVal.setMasterCriteria(mc); subMcs = aVal.masterCriteria().subCriteriaList(); smc = (DRSubMasterCriteria)subMcs.objectAtIndex(0); aVal.setValueDict(new NSDictionary( new Object[]{"*", "|Other|" , "OTHER"}, new Object[]{ "OTHER" , "lookupKey" , smc.keyDesc()}) ); if (lb != null) { aVal.setLabel(lb); } else { aVal.setLabel("Other"); } aVal.setIsTotal(false); aVal.setIsOther(true); return aVal; } static public DRCriteria asTotalWithMasterCriteria(DRMasterCriteria mc) { NSArray subMcs; DRSubMasterCriteria smc; DRCriteria aVal = new DRCriteria(); String lb = (String)mc.userInfo().objectForKey("TOTAL_LABEL"); aVal.setMasterCriteria(mc); subMcs = aVal.masterCriteria().subCriteriaList(); smc = (DRSubMasterCriteria)subMcs.objectAtIndex(0); aVal.setValueDict(new NSDictionary( new Object[]{"*", "|Total|" , "TOTAL"}, new Object[]{ "TOTAL" , "lookupKey" , smc.keyDesc()}) ); if (lb != null) { aVal.setLabel(lb); } else { aVal.setLabel("Total"); } aVal.setIsTotal(true); return aVal; } static public DRCriteria withMasterCriteriaValueDict(DRMasterCriteria mc, NSDictionary valD) { DRCriteria aVal = new DRCriteria(); aVal.setMasterCriteria(mc); aVal.setValueDict(valD); return aVal; } public DRCriteria() { super(); _label = null; _isTotal = false; _isOther = false; _score = null; } public void setMasterCriteria(DRMasterCriteria val) { _masterCriteria = val; } public DRMasterCriteria masterCriteria() { return _masterCriteria; } public void setValueDict(NSDictionary val) { _valueDict = val; } public NSDictionary valueDict() { return _valueDict; } @Override public String toString() { return "<DRCriteria valueDict: " + _valueDict + "; >"; } private String _keyDesc = null; public String keyDesc() { if(_keyDesc == null) { _keyDesc = super.toString(); } return _keyDesc; } public String calendarFormatForDates() { NSDictionary info = _masterCriteria.userInfo(); String v = (String)info.objectForKey("calendarFormat"); if (v != null) { return v; } return _defaultCalendarFormatString; } public String rangeSeparator() { NSDictionary info = _masterCriteria.userInfo(); String v = (String)info.objectForKey("rangeSeparator"); if (v != null) { return v; } return " to "; } public String compoundSeparator() { NSDictionary info = _masterCriteria.userInfo(); String calFrmt = (String)info.objectForKey("compoundSeparator"); if (calFrmt != null) { return calFrmt; } return "|"; } static private NSMutableDictionary _calFormatDict = new NSMutableDictionary(); static public Format formatterForFormat(String calFormat) { synchronized(_calFormatDict) { if(calFormat == null) calFormat = _defaultCalendarFormatString; NSTimestampFormatter v = (NSTimestampFormatter)_calFormatDict.objectForKey(calFormat); if(v == null) { v = new NSTimestampFormatter(calFormat); setFormatterForFormat(v, calFormat); } return v; } } static public void setFormatterForFormat(Format formatter, String calFormat) { synchronized(_calFormatDict) { _calFormatDict.setObjectForKey(formatter, calFormat); } } public String labelForDict(NSDictionary dict) { String highString, lowString; String lbl = ""; Object high = dict.objectForKey("H"); Object low = dict.objectForKey("L"); String calFormat = calendarFormatForDates(); Format formatter = DRCriteria.formatterForFormat(calFormat); if (high instanceof NSTimestamp) { highString = formatter.format(high); } else { highString = high.toString(); } if (low instanceof NSTimestamp) { lowString = formatter.format(low); } else { lowString = low.toString(); } lbl = lbl + lowString + rangeSeparator() + highString; return lbl; } public String label() { if (_label == null) { NSArray subMcs = _masterCriteria.subCriteriaList(); int cnt = subMcs.count(); String lbl = ""; int i; for (i = 0; i < cnt; i++) { DRSubMasterCriteria smc = (DRSubMasterCriteria)subMcs.objectAtIndex(i); Object rawVal = _valueDict.objectForKey(smc.keyDesc()); if (rawVal instanceof NSDictionary) { lbl = lbl.concat(labelForDict((NSDictionary)rawVal)); } else { lbl = lbl.concat(smc.lookUpKeyForValue(rawVal)); } if (!(i == (cnt-1))) { lbl = lbl.concat(compoundSeparator()); } } _label = lbl; } return _label; } public void setLabel(String lbl) { _label = lbl; } public Object score() { if (_score == null) { synchronized(this){ Object scr = null; NSArray subMcs = _masterCriteria.subCriteriaList(); DRSubMasterCriteria smc = (DRSubMasterCriteria)subMcs.objectAtIndex(0); Object rawVal = _valueDict.objectForKey(smc.keyDesc()); if (_valueDict.objectForKey("OTHER") != null) { if (subMcs.count() > 1 || _masterCriteria.isString()) { scr = MAXSTRING; } else { scr = Double.valueOf(MAXNUMBER+1); } } else if (_valueDict.objectForKey("TOTAL") != null) { if (subMcs.count() > 1 || _masterCriteria.isString()) { scr = MAXSTRING.concat("z"); } else { scr = Double.valueOf(MAXNUMBER+2); } } else if (subMcs.count() > 1) { scr = label().toLowerCase(); } else if (rawVal instanceof NSDictionary) { Object v = ((NSDictionary)rawVal).objectForKey("L"); //OWDebug.println(1, "v:"+v); try{ if (v instanceof String) scr = Double.valueOf((String)v); else scr = DRValueConverter.converter().numberForValue(v); } catch(NumberFormatException e) { scr = Double.valueOf(-1.0*MAXNUMBER); } } else if(rawVal instanceof String){ scr = ((String)rawVal).toLowerCase(); } else { scr = DRValueConverter.converter().numberForValue(rawVal); } _score = scr; } } return _score; } }