001: package com.jamonapi;
002:
003: import java.util.*;
004: import java.text.*;
005:
006: /**
007: * AccumulateMonitors represent Monitors that increase in value. AccumulateMonitors use the Gang of 4's decorator pattern to pass
008: * method invocations to the next Monitor in the chain. Note many of the public methods such as start(), stop() and reset() call the
009: * same method of next Monitor in the decorator chain. Any classes that inherit from AccumulateMonitor implement the protected methods
010: * startThis(), stopThis(), and resetThis() and leave the public methods as is. In general the various ...This() (startThis(), stopThis(),
011: * resetThis()) methods perform the action on that instance and the methods without ...This() (start(), stop(), reset()) take care of
012: * passing the command down the decorator chain.
013: **/
014:
015: public class AccumulateMonitor implements AccumulateMonitorInterface {
016: // Constants used in the various AccumulateMonitor classes
017: static protected final String TOTAL = "Total";
018: static protected final String MIN = "Min";
019: static protected final String MAX = "Max";
020: static protected final String HITS = "Hits";
021: static protected final String AVG = "Avg";
022: static protected final String STANDARD_DEVIATION = "Std Dev";
023: static protected final String ACTIVE = "Active";
024: static protected final String AVGACTIVE = "Avg Active";
025: static protected final String MAXACTIVE = "Max Active";
026:
027: protected long accrued; // holds the value of what we are monitoring.
028: private AccumulateMonitorInterface childMonitor; // pointer to next Monitor in the decorator chain.
029: private boolean primary = false;
030:
031: static protected final String MILLISECONDS = "ms.";
032: static protected final String NONE = "";
033:
034: /** Get the value of the monitor. What this value means depends on what the monitor does. In the case of a Timing monitor it would be
035: * the elapsed time since the monitor was started.
036: *
037: * Sample call:
038: * long accrued=monitor.getAccrued();
039: *
040: **/
041:
042: synchronized public long getAccrued() {
043: return accrued;
044: }
045:
046: /** Default constructor.
047: *
048: * Note Monitors use the Gang of 4 decorator pattern where each monitor points to and calls the next monitor in the chain. With
049: * the default constructor there is no need for a next Monitors in the chain, but to keep the logic identical to when there is
050: * a next Monitor in the chain a NullMonitor (that does nothing) is used as the next Monitor to call in the decorator pattern.
051: * Martin Fowler's Refactoring book discusses NullMonitor's.
052: */
053: public AccumulateMonitor() {
054: this (NullAccumulateMonitor.createInstance());
055: }
056:
057: /** Monitors use the Gang of 4 decorator pattern where each monitor points to and calls the next monitor in the chain.
058: * This constructor as its argument takes the next AccumulateMonitor in the chain.
059: *
060: * Sample Call:
061: * AccumulateMonitor mon=new AccumulateMonitor(new AccumulateMonitor(new AccumulateMonitor()));
062: */
063:
064: public AccumulateMonitor(AccumulateMonitorInterface childMonitor) {
065: this .childMonitor = childMonitor;
066: }
067:
068: /** Erase/wipe out any accrued statistics for this monitor **/
069: synchronized protected void resetThis() {
070: accrued = 0;
071: }
072:
073: /** Increase the monitors accrued value by the ammount specified in the parameter, and call increase on all monitors in the
074: * decorator chain.
075: *
076: * Sample Call:
077: * monitor.increase(100);
078: **/
079: public void increase(long increaseValue) {
080: increaseThis(increaseValue);
081: childMonitor.increase(increaseValue);
082: }
083:
084: /** Increase the monitors accrued value by 1 unit.
085: *
086: * Sample Call:
087: * monitor.increase();
088: **/
089: public void increase() {
090: increase(1);
091: }
092:
093: /** Erase/wipe out any accrued statistics for this monitor, and call reset on all monitors in the decorator chain
094: *
095: * Sample Call:
096: * monitor.reset();
097: *
098: **/
099: public void reset() {
100: resetThis();
101: childMonitor.reset();
102: }
103:
104: /** Display this Monitor as well as all Monitor's in the decorator chain as Strings **/
105: public String toString() {
106: return toStringThis() + toStringChild();
107: }
108:
109: /** Dispay the units appropriate for this monitor **/
110: public String getUnits() {
111: return NONE;
112: }
113:
114: /** Display this Monitors type **/
115: public String getType() {
116: return NONE;
117: }
118:
119: /** Populate the ArrayList with data from this Monitor as well as all other Monitors in the decorator chain **/
120: public void getData(ArrayList rowData) {
121: getDataThis(rowData);
122: childMonitor.getData(rowData);
123: }
124:
125: /** Start gathering statistics for this Monitor. The Monitor will run until the stop() method is called. start() will also
126: * call the start() method for all other Monitors in the decorator chain.
127: **/
128: public void start() {
129: startThis();
130: childMonitor.start();
131: }
132:
133: /** Contains any logic that this Monitor must perform when it is started **/
134: protected void startThis() {
135: }
136:
137: /** Stop gathering statistics for the Monitor. stop() is called after a Monitor has been started with the start() method.
138: * stop() will also call the stop() method for all Monitors in the decorator chain.
139: **/
140: public void stop() {
141: childMonitor.stop();
142: stopThis();
143: }
144:
145: /** Contains any logic that this Monitor must perform when it is stopped **/
146: protected void stopThis() {
147: }
148:
149: /** Return the accrued value in String format **/
150: public String getAccruedString() {
151: return convertToString(getAccrued());
152: }
153:
154: /** Add this Monitor's accrued value in string format to an ArrayList. **/
155: protected void getDataThis(ArrayList rowData) {
156: rowData.add(getAccruedString());
157: }
158:
159: /** Display this Monitor in String format **/
160: synchronized protected String toStringThis() {
161: return getDisplayString(getType(), getAccruedString(),
162: getUnits());
163:
164: }
165:
166: /** Display Monitor's in the Decorator chain in String format **/
167: protected String toStringChild() {
168: return childMonitor.toString();
169: }
170:
171: /** Convert a float value to a String
172: *
173: * Sample Call:
174: * String number=AccumulateMonitor.convertToString(1234.5); // returns 1,234.5
175: **/
176: protected static String convertToString(double value) {
177: DecimalFormat numberFormat = (DecimalFormat) NumberFormat
178: .getNumberInstance();
179: numberFormat.applyPattern("#,###.#");
180: return numberFormat.format(value);
181:
182: }
183:
184: protected String getDisplayString(String type, String value,
185: String units) {
186: return type + "=" + value + " " + units + " ";
187: }
188:
189: /** Add the value passed to this method to the Monitor's accrued value **/
190: synchronized protected void increaseThis(long increase) {
191: accrued += increase;
192:
193: }
194:
195: /** Add the display header that is associated with this Monitor to the header (as an ArrayList entry). Also give all Monitors in the
196: * decorator chain the opportunity to add their header entries.
197: **/
198: public void getHeader(ArrayList header) {
199: getHeaderThis(header);
200: childMonitor.getHeader(header);
201:
202: }
203:
204: protected void getHeaderThis(ArrayList header) {
205: header.add(getType() + " " + getUnits());
206: }
207:
208: /** Indicates whether or not this Monitor is primary. See www.jamonapi.com for an explanation of primary Monitors. **/
209: public boolean isPrimary() {
210: return primary;
211: }
212:
213: /** Specify whether or not this Monitor is primary. See www.jamonapi.com for an explanation of primary Monitors. Call setPrimary()
214: * for all Monitors in the decorator chain
215: **/
216: public void setPrimary(boolean primary) {
217: this .primary = primary;
218: childMonitor.setPrimary(primary);
219: }
220:
221: /** Method that calls test code for this class. **/
222: public static void main(String[] args) throws Exception {
223: // Note for any of the AccumulateMonitors don't need to be started first. i.e. when they
224: // are created you may call increase() without first having called start()
225: AccumulateMonitor m = new AccumulateMonitor();
226: System.out.println("0=" + m);
227:
228: m.increase(25);
229: System.out.println("25=" + m);
230: m.increase(50);
231: System.out.println("75=" + m);
232:
233: m.reset();
234: System.out.println("0=" + m);
235: m.increase(1000);
236: System.out.println("1000=" + m);
237:
238: }
239: }
|