001: package jimm.datavision.field;
002:
003: import jimm.datavision.*;
004: import jimm.datavision.gui.FieldWidget;
005: import jimm.datavision.gui.FormulaWidget;
006: import jimm.datavision.gui.SectionWidget;
007: import java.util.Collection;
008: import java.util.Observer;
009: import java.util.Observable;
010:
011: /**
012: * A formula field represents a formula calculated on-the-fly. The value of a
013: * formula field holds a {@link Formula} object. (In the XML, the formula
014: * field's value is the id of the formula.)
015: *
016: * @author Jim Menard, <a href="mailto:jimm@io.com">jimm@io.com</a>
017: */
018: public class FormulaField extends Field implements Observer {
019:
020: protected Formula formula;
021:
022: /**
023: * Constructs a formula field with the specified id in the specified report
024: * section whose {@link Formula}'s id is <var>value</var>.
025: *
026: * @param id the new field's id
027: * @param report the report containing this element
028: * @param section the report section in which the field resides
029: * @param value the id of a formula
030: * @param visible show/hide flag
031: */
032: public FormulaField(Long id, Report report, Section section,
033: Object value, boolean visible) {
034: super (id, report, section, value, visible);
035: formula = report.findFormula(value);
036: formula.addObserver(this );
037: }
038:
039: protected void finalize() throws Throwable {
040: formula.deleteObserver(this );
041: super .finalize();
042: }
043:
044: public void update(Observable o, Object arg) {
045: setChanged();
046: notifyObservers(arg);
047: }
048:
049: public FieldWidget makeWidget(SectionWidget sw) {
050: return new FormulaWidget(sw, this );
051: }
052:
053: /**
054: * Not really used; we drag formulas, not formula fields.
055: */
056: public String dragString() {
057: return typeString() + ":" + formula.getId();
058: }
059:
060: /**
061: * Returns the formula.
062: *
063: * @return the formula
064: */
065: public Formula getFormula() {
066: return formula;
067: }
068:
069: /**
070: * Sets the formula.
071: *
072: * @param newFormula the new formula
073: */
074: public void setFormula(Formula newFormula) {
075: if (formula != newFormula) {
076: formula.deleteObserver(this );
077: formula = newFormula;
078: formula.addObserver(this );
079: setChanged();
080: notifyObservers();
081: }
082: }
083:
084: public String typeString() {
085: return "formula";
086: }
087:
088: public String designLabel() {
089: return formula.designLabel();
090: }
091:
092: public String formulaString() {
093: return formula.formulaString();
094: }
095:
096: public boolean refersTo(Field f) {
097: return formula.refersTo(f);
098: }
099:
100: public boolean refersTo(Formula f) {
101: return f == formula || formula.refersTo(f);
102: }
103:
104: public boolean refersTo(UserColumn uc) {
105: return formula.refersTo(uc);
106: }
107:
108: public boolean refersTo(Parameter p) {
109: return formula.refersTo(p);
110: }
111:
112: /**
113: * This override returns <code>true</code> if this formula is in a detail
114: * section. We don't really know that this formula returns a number, so
115: * we'll err on the side of allowing aggregation.
116: *
117: * @return <code>true</code> if this field can be aggregated
118: */
119: public boolean canBeAggregated() {
120: // Section can be null during dragging.
121: return section != null && section.isDetail();
122: }
123:
124: /**
125: * Returns the value of this field. For formula fields, this is the
126: * value generated by evaluating the {@link Formula}.
127: *
128: * @return the result of evaluating the formula
129: */
130: public Object getValue() {
131: return formula.eval(this );
132: }
133:
134: /**
135: * Returns a collection of the columns used in the formula. This is used
136: * by the report's query when it is figuring out what columns and tables
137: * are used by the report. Calls {@link Formula#columnsUsed}.
138: *
139: * @return a possibly empty collection of database columns
140: * @see jimm.datavision.source.Query#findSelectablesUsed
141: */
142: public Collection columnsUsed() {
143: return formula.columnsUsed();
144: }
145:
146: /**
147: * Returns a collection of the user columns used in the formula. This is
148: * used by the report's query when it is figuring out what columns, tables,
149: * and user columns are used by the report. Calls
150: * {@link Formula#userColumnsUsed}.
151: *
152: * @return a possibly empty collection of user columns
153: * @see jimm.datavision.source.Query#findSelectablesUsed
154: */
155: public Collection userColumnsUsed() {
156: return formula.userColumnsUsed();
157: }
158:
159: }
|