001package org.javasimon.callback; 002 003import org.javasimon.Counter; 004import org.javasimon.CounterSample; 005import org.javasimon.Manager; 006import org.javasimon.Simon; 007import org.javasimon.Split; 008import org.javasimon.Stopwatch; 009import org.javasimon.StopwatchSample; 010 011import java.util.HashMap; 012import java.util.Map; 013 014/** 015 * Callback processes various events of the Java Simon API and is used as an extension point of the API. 016 * Callbacks can be registered with the {@link org.javasimon.Manager} using its {@link CompositeCallback} 017 * that can be obtained by calling {@link org.javasimon.Manager#callback()}. After adding the callback 018 * into the main composite callback (or anywhere lower into the callback tree) by calling 019 * {@link CompositeCallback#addCallback(Callback)} all events are propagated to all Callbacks (unless filtered 020 * using {@link FilterCallback}). Methods called on various events are named {@code onEventXY} with type of the source 021 * clearly mentioned in the name (Manager, Simon, Stopwatch, Counter). 022 * <p/> 023 * Callbacks can be configured via Manager configuration facility. (Configuration part is still rather WIP.) 024 * <p/> 025 * Callback can have a lifecycle supported with methods {@link #initialize(Manager)} and {@link #cleanup()}. 026 * Callback is initialized when it is attached to the manager (anywhere in the callback tree) and 027 * deinitialized when the callback is removed from the callback tree. 028 * 029 * @author <a href="mailto:virgo47@gmail.com">Richard "Virgo" Richter</a> 030 */ 031public interface Callback { 032 033 /** Lifecycle method called when the callback is added to a manager. */ 034 void initialize(Manager manager); 035 036 /** 037 * Lifecycle method called when the callback is removed from the manager. It should implement 038 * any necessary cleanup or resources - e.g. release JDBC connection if one was used for Callback 039 * functionality. 040 * <p/> 041 * <b>It is important to realize that this method is not guaranteed to be called for all callbacks, only for 042 * callbacks removed from Manager's callback tree.</b> 043 */ 044 void cleanup(); 045 046 /** 047 * Stopwatch start event. <b>Duration of all callbacks is included into the split time!</b> 048 * {@link StopwatchSample} valid for the moment after the start is provided because the callback 049 * is executed out of synchronized block. 050 * It is guaranteed that {@link org.javasimon.Split#getStopwatch()} will not return {@code null}. 051 * 052 * @param split started Split 053 */ 054 void onStopwatchStart(Split split); 055 056 /** 057 * Stopwatch stop event. This action is executed after the split time is calculated and does not 058 * affect the measuring. {@link StopwatchSample} valid for the moment after the stop is provided 059 * because the callback is executed out of synchronized block. 060 * It is guaranteed that {@link org.javasimon.Split#getStopwatch()} will not return {@code null}. 061 * 062 * @param split stopped Split 063 * @param sample stopwatch sampled after the stop 064 */ 065 void onStopwatchStop(Split split, StopwatchSample sample); 066 067 /** 068 * Stopwatch add split event. {@link StopwatchSample} valid for the moment after the add is provided 069 * because the callback is executed out of synchronized block. 070 * It is guaranteed that {@link org.javasimon.Split#getStopwatch()} will not return {@code null}. 071 * 072 * @param stopwatch modified Stopwatch 073 * @param split added split object 074 * @param sample stopwatch sampled after the add 075 * @since 3.1 076 */ 077 void onStopwatchAdd(Stopwatch stopwatch, Split split, StopwatchSample sample); 078 079 /** 080 * Counter decrease event. {@link CounterSample} valid for the moment after the operation is provided 081 * because the callback is executed out of synchronized block. 082 * 083 * @param counter modified Counter 084 * @param dec decrement amount 085 * @param sample counter sampled after the operation 086 */ 087 void onCounterDecrease(Counter counter, long dec, CounterSample sample); 088 089 /** 090 * Counter increase event. {@link CounterSample} valid for the moment after the operation is provided 091 * because the callback is executed out of synchronized block. 092 * 093 * @param counter modified Counter 094 * @param inc increment amount 095 * @param sample counter sampled after the operation 096 */ 097 void onCounterIncrease(Counter counter, long inc, CounterSample sample); 098 099 /** 100 * Counter set event. {@link CounterSample} valid for the moment after the operation is provided 101 * because the callback is executed out of synchronized block. 102 * 103 * @param counter modified Counter 104 * @param val new value 105 * @param sample counter sampled after the operation 106 */ 107 void onCounterSet(Counter counter, long val, CounterSample sample); 108 109 /** 110 * Simon created event is called when Simon is successfully created by the Manager. 111 * <b>Runs within the block synchronized on the Manager</b> - this results in high consistency, but it also 112 * means that <b>implementations of this method should not take much time.</b> 113 * 114 * @param simon created Simon 115 */ 116 void onSimonCreated(Simon simon); 117 118 /** 119 * Simon destroyed event is called when Simon is successfully destroyed by the Manager. 120 * <b>Runs within the block synchronized on the Manager</b> - this results in high consistency, but it also 121 * means that <b>implementations of this method should not take much time.</b> 122 * 123 * @param simon destroyed Simon 124 */ 125 void onSimonDestroyed(Simon simon); 126 127 /** 128 * Event called when the manager is cleared. 129 * <b>Runs within the block synchronized on the Manager</b> - this results in high consistency, but it also 130 * means that <b>implementations of this method should not take much time.</b> 131 */ 132 void onManagerClear(); 133 134 /** 135 * Message event is used to propagate arbitrary messages from the manager, or it can 136 * be used by the other Callback methods internally. 137 * 138 * @param message message text 139 */ 140 void onManagerMessage(String message); 141 142 /** 143 * Warning event containing warning and/or cause. 144 * 145 * @param warning arbitrary warning message - can be {@code null}, unless concrete implementation states otherwise 146 * @param cause exception causing this warning - can be {@code null}, unless concrete implementation states otherwise 147 */ 148 void onManagerWarning(String warning, Exception cause); 149 150 /** 151 * Enumeration of all supported callback actions. {@link #ALL} is meta-action usable in 152 * configurations meaning that the configuration entry applies to all actions (any action). 153 * In callback configuration action names in lowercase and with _ replaced for - can be 154 * used (e.g. "counter-increase" instead for {@link #COUNTER_INCREASE}. 155 * <p/> 156 * Event codes are used for configuration purposes instead of enum literals. 157 */ 158 enum Event { 159 /** Meta-action designating all actions (or any action in rules). */ 160 ALL("all"), 161 162 /** Start of the stopwatch. */ 163 STOPWATCH_START("start"), 164 165 /** Stop of the stopwatch. */ 166 STOPWATCH_STOP("stop"), 167 168 /** Adding value to the stopwatch. */ 169 STOPWATCH_ADD("add"), 170 171 /** Counter increased. */ 172 COUNTER_INCREASE("increase"), 173 174 /** Counter decreased. */ 175 COUNTER_DECREASE("decrease"), 176 177 /** Counter set to arbitrary value. */ 178 COUNTER_SET("set"), 179 180 /** Creation of a Simon. */ 181 CREATED("created"), 182 183 /** Removing of a Simon. */ 184 DESTROYED("destroyed"), 185 186 /** Clearing of the manager. */ 187 MANAGER_CLEAR("clearManager"), 188 189 /** Event producing arbitrary message. */ 190 MESSAGE("message"), 191 192 /** Warning related to the manager. */ 193 WARNING("warning"); 194 195 private static Map<String, Event> codeValues = new HashMap<>(); 196 197 private String code; 198 199 static { 200 for (Event value : values()) { 201 codeValues.put(value.code.toLowerCase(), value); 202 } 203 } 204 205 /** 206 * Constructor of the event with its code. 207 * 208 * @param code code of the event 209 */ 210 Event(String code) { 211 this.code = code; 212 } 213 214 /** 215 * Returns event for String code used in XML configuration. 216 * 217 * @param code String code 218 * @return Event object 219 */ 220 public static Event forCode(String code) { 221 return codeValues.get(code.toLowerCase()); 222 } 223 } 224}