1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.monitoring.reporting;
19
20 import java.util.ArrayList;
21 import java.util.Collection;
22 import java.util.Collections;
23 import java.util.Comparator;
24 import java.util.HashSet;
25 import java.util.Iterator;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.Set;
29
30 import org.apache.commons.monitoring.Counter;
31 import org.apache.commons.monitoring.Monitor;
32 import org.apache.commons.monitoring.Role;
33 import org.apache.commons.monitoring.StatValue;
34 import org.apache.commons.monitoring.Unit;
35 import org.apache.commons.monitoring.Monitor.Key;
36 import org.apache.commons.monitoring.listeners.Detachable;
37
38
39
40
41
42
43 public abstract class AbstractRenderer
44 implements Renderer
45 {
46 private String contentType;
47
48
49 protected static final String MONITORS = "monitors";
50
51 protected static final String ROLES = "roles";
52
53 public AbstractRenderer( String contentType )
54 {
55 super();
56 this.contentType = contentType;
57 }
58
59 public void render( Context ctx, Collection<Monitor> monitors, Options options )
60 {
61 int count = 0;
62 prepareRendering( ctx, monitors, options );
63 for ( Monitor monitor : monitors )
64 {
65 if ( options.render( monitor ) )
66 {
67 if ( count > 0 )
68 {
69 hasNext( ctx, Monitor.class );
70 }
71 render( ctx, monitor, options );
72 count++;
73 }
74 }
75 }
76
77 protected void prepareRendering( Context ctx, Collection<Monitor> monitors, Options options )
78 {
79 ctx.put( ROLES, getRoles( monitors, options ) );
80 ctx.put( MONITORS, monitors );
81 }
82
83 protected void hasNext( Context ctx, Class<?> type )
84 {
85
86 }
87
88 protected void render( Context ctx, Monitor monitor, Options options, List<String> roles )
89 {
90 render( ctx, monitor, options );
91 }
92
93 protected void render( Context ctx, Monitor monitor, Options options )
94 {
95 if ( isDetatched( monitor ) )
96 {
97 renderDetached( ctx, (Detachable) monitor, options );
98 }
99 render( ctx, monitor.getKey() );
100 renderStatValues( ctx, monitor, options );
101 }
102
103 protected boolean isDetatched( Monitor monitor )
104 {
105 return monitor instanceof Detachable && ( (Detachable) monitor ).isDetached();
106 }
107
108 protected abstract void renderDetached( Context ctx, Detachable detached, Options options );
109
110 @SuppressWarnings( "unchecked" )
111 protected void renderStatValues( Context ctx, Monitor monitor, Options options )
112 {
113 List<Role> roles = (List<Role>) ctx.get( ROLES );
114 renderStatValues( ctx, monitor, options, roles );
115 }
116
117 @SuppressWarnings("unchecked")
118 protected void renderStatValues( Context ctx, Monitor monitor, Options options, List<Role> roles )
119 {
120 for ( Iterator<Role> iterator = roles.iterator(); iterator.hasNext(); )
121 {
122 Role role = iterator.next();
123 StatValue value = monitor.getValue( role );
124 if ( value != null )
125 {
126 render( ctx, value, options );
127 }
128 else
129 {
130 renderMissingValue( ctx, role );
131 }
132 if ( iterator.hasNext() )
133 {
134 hasNext( ctx, StatValue.class );
135 }
136 }
137 }
138
139
140
141
142
143
144
145 @SuppressWarnings("unchecked")
146 protected void renderMissingValue( Context ctx, Role role )
147 {
148
149 }
150
151 protected List<StatValue> getOrderedStatValues( Monitor monitor, Options options )
152 {
153 List<StatValue> values = new LinkedList<StatValue>( monitor.getValues() );
154 for ( Iterator<StatValue> iterator = values.iterator(); iterator.hasNext(); )
155 {
156 StatValue value = (StatValue) iterator.next();
157 if ( !options.renderRole( value.getRole() ) )
158 {
159 iterator.remove();
160 }
161 }
162 Collections.sort( values, new Comparator<StatValue>()
163 {
164 public int compare( StatValue value1, StatValue value2 )
165 {
166 return value1.getRole().compareTo( value2.getRole() );
167 }
168 } );
169 return values;
170 }
171
172 @SuppressWarnings("unchecked")
173 protected void render( Context ctx, StatValue value, Options options )
174 {
175 Role role = value.getRole();
176 if ( value instanceof Counter )
177 {
178 Counter counter = (Counter) value;
179 if ( options.render( role, "hits" ) )
180 {
181 render( ctx, value, "hits", counter.getHits(), options, 0 );
182 }
183 if ( options.render( role, "sum" ) )
184 {
185 render( ctx, value, "sum", counter.getSum(), options );
186 }
187 }
188 if ( options.render( role, "min" ) )
189 {
190 render( ctx, value, "min", value.getMin(), options );
191 }
192 if ( options.render( role, "max" ) )
193 {
194 render( ctx, value, "max", value.getMax(), options );
195 }
196 if ( options.render( role, "mean" ) )
197 {
198 render( ctx, value, "mean", value.getMean(), options );
199 }
200 if ( options.render( role, "deviation" ) )
201 {
202 render( ctx, value, "deviation", value.getStandardDeviation(), options, 1 );
203 }
204 if ( options.render( role, "value" ) )
205 {
206 render( ctx, value, "value", value.get(), options, 1 );
207 }
208 }
209
210 protected abstract void render( Context ctx, Key key );
211
212 protected void render( Context ctx, StatValue value, String attribute, Number number, Options options )
213 {
214 render( ctx, value, attribute, number, options, 1 );
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228 protected void render( Context ctx, StatValue value, String attribute, Number number, Options options, int ratio )
229 {
230 if ( number instanceof Double )
231 {
232 renderInternal( ctx, value, attribute, number.doubleValue(), options, ratio );
233 }
234 else
235 {
236 renderInternal( ctx, value, attribute, number.longValue(), options, ratio );
237 }
238 }
239
240 private void renderInternal( Context ctx, StatValue value, String attribute, long l, Options options, int ratio )
241 {
242 Unit unit = options.unitFor( value.getRole() );
243 if ( unit != null )
244 {
245 while ( ratio-- > 0 )
246 {
247 l = l / unit.getScale();
248 }
249 }
250
251 ctx.print( options.getNumberFormat().format( l ) );
252 }
253
254 private void renderInternal( Context ctx, StatValue value, String attribute, double d, Options options, int ratio )
255 {
256 if ( Double.isNaN( d ) )
257 {
258 renderNaN( ctx );
259 return;
260 }
261 Unit unit = options.unitFor( value.getRole() );
262 if ( unit != null )
263 {
264 while ( ratio-- > 0 )
265 {
266 d = d / unit.getScale();
267 }
268 }
269
270 ctx.print( options.getDecimalFormat().format( d ) );
271 }
272
273 protected void renderNaN( Context ctx )
274 {
275 ctx.print( "-" );
276 }
277
278
279
280
281
282 @SuppressWarnings("unchecked")
283 protected List<Role> getRoles( Collection<Monitor> monitors, Options options )
284 {
285 Set<Role> roles = new HashSet<Role>();
286 for ( Monitor monitor : monitors )
287 {
288 if ( options.render( monitor ) )
289 {
290 for ( Role role : monitor.getRoles() )
291 {
292 if ( options.renderRole( role ) )
293 {
294 roles.add( role );
295 }
296 }
297 }
298 }
299 List<Role> sorted = new ArrayList<Role>( roles );
300 Collections.<Role>sort( sorted );
301 return sorted;
302 }
303
304 public String getContentType()
305 {
306 return contentType;
307 }
308 }