Inspector | Message | Severity | Location |
---|---|---|---|
Java Inspector 048 | Copyrights information should be present in each file. | 1 | |
Java Inspector 015 | Do not change parameter value. For comprehensibility, formal parameters should be final | 2 | 163:41 |
Java Inspector 081 | Avoid static collections, they can grow in size over time. | 2 | 55:9 |
Java Inspector 081 | Avoid static collections, they can grow in size over time. | 2 | 56:9 |
Java Inspector 081 | Avoid static collections, they can grow in size over time. | 2 | 61:9 |
Java Inspector 089 | Undocumented method | 2 | 116:41 |
Java Inspector 089 | Undocumented parameter categoryName | 2 | 149:9 |
Java Inspector 089 | Javadoc contains tag for non-existent parameter category | 2 | 149:9 |
Java Inspector 089 | Undocumented method | 2 | 160:17 |
Java Inspector 089 | Method is not properly documented | 2 | 191:17 |
Java Inspector 089 | Parameter consumers is not documented | 2 | 191:17 |
Java Inspector 089 | Undocumented method | 2 | 198:17 |
Java Inspector 089 | Undocumented method | 2 | 204:17 |
Java Inspector 089 | Method is not properly documented | 2 | 214:9 |
Java Inspector 089 | Parameter klass is not documented | 2 | 214:9 |
Java Inspector 089 | Method is not properly documented | 2 | 222:9 |
Java Inspector 089 | Undocumented method | 2 | 227:25 |
Java Inspector 089 | Undocumented method | 2 | 231:25 |
Java Inspector 089 | Method is not properly documented | 2 | 246:9 |
Java Inspector 089 | Parameter klass is not documented | 2 | 246:9 |
Java Inspector 089 | Method is not properly documented | 2 | 254:9 |
Java Inspector 089 | Parameter category is not documented | 2 | 254:9 |
Java Inspector 089 | Parameter factory is not documented | 2 | 296:9 |
Java Inspector 089 | Parameter consumer is not documented | 2 | 325:9 |
Java Inspector 089 | Undocumented method | 2 | 337:41 |
Java Inspector 089 | Undocumented method | 2 | 341:41 |
Java Inspector 089 | Undocumented method | 2 | 345:41 |
Java Inspector 089 | Undocumented method | 2 | 349:41 |
Java Inspector 089 | Undocumented method | 2 | 356:33 |
Java Inspector 089 | Parameter consumer is not documented | 2 | 376:9 |
Java Inspector 089 | Undocumented method | 2 | 384:41 |
Java Inspector 089 | Undocumented method | 2 | 388:41 |
Java Inspector 089 | Undocumented method | 2 | 392:41 |
Java Inspector 089 | Undocumented method | 2 | 396:41 |
Java Inspector 089 | Undocumented method | 2 | 403:33 |
Java Inspector 089 | Parameter consumer is not documented | 2 | 415:9 |
Java Inspector 089 | Undocumented method | 2 | 427:33 |
Java Inspector 089 | Undocumented method | 2 | 436:33 |
Java Inspector 089 | Undocumented method | 2 | 440:33 |
Java Inspector 089 | Undocumented method | 2 | 444:33 |
Java Inspector 089 | Undocumented method | 2 | 451:33 |
Java Inspector 089 | Parameter consumer is not documented | 2 | 467:9 |
Java Inspector 089 | Parameter factory is not documented | 2 | 496:9 |
Java Inspector 005 | Classes, interfaces, methods, and variables should be named according to Sun's naming conventions. | 3 | 53:9 |
Java Inspector 016 | Sun coding standards - class modifiers should be in order (public protected private abstract static final strictfp) | 3 | 368:9 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 65:101 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 76:64 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 78:62 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 80:77 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 82:75 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 84:75 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 86:62 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 88:98 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 90:75 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 93:56 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 110:56 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 122:50 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 327:60 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 331:60 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 378:60 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 417:60 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 421:60 |
Java Inspector 026 | Avoid hardwired string literals. Allowed literals: [] | 3 | 533:48 |
Java Inspector 040 | Parameter name categories clashes with field name in MeasurementCategoryFactory | 3 | 415:37 |
Java Inspector 051 | It is good practice to call in any case super() in a constructor. | 3 | 155:17 |
1/*
2 * hgcommons 9
3 * Hammurapi Group Common Library
4 * Copyright (C) 2003 Hammurapi Group
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 * URL: http://www.hammurapi.biz/hammurapi-biz/ef/xmenu/hammurapi-group/products/products/hgcommons/index.html
21 * e-Mail: support@hammurapi.biz
22 */
23package biz.hammurapi.metrics;
24
25import java.io.File;
26import java.io.FileInputStream;
27import java.io.FileNotFoundException;
28import java.io.IOException;
29import java.io.InputStream;
30import java.net.MalformedURLException;
31import java.net.URL;
32import java.util.ArrayList;
33import java.util.Collection;
34import java.util.HashMap;
35import java.util.Iterator;
36import java.util.Map;
37import java.util.logging.Level;
38import java.util.logging.Logger;
39
40import biz.hammurapi.config.Component;
41import biz.hammurapi.config.ConfigurationException;
42import biz.hammurapi.config.DomConfigFactory;
43import biz.hammurapi.config.RuntimeConfigurationException;
44
45/**
46 * Utility class which is a connection point between clients and
47 * concrete MeasurementConsumer implementations.
48 * @author Pavel Vlasov
49 *
50 * @version $Revision: 1.6 $
51 */
52public abstract class MeasurementCategoryFactory {
53 private static final Logger logger = Logger.getLogger(MeasurementCategoryFactory.class.getName());
54
55 private static Map categories=new HashMap();
56 private static Collection factories=new ArrayList();
57
58 /**
59 * Consumers and factories loaded on startup.
60 */
61 private static Collection bootConsumers = new ArrayList();
62
63 static {
64 try {
65 String config=System.getProperty(MeasurementCategoryFactory.class.getName()+":config");
66 if (config==null) {
67 Iterator mit = DomConfigFactory.loadProviders(MeasurementCategoryFactory.class, MeasurementCategoryFactory.class.getClassLoader());
68 while (mit.hasNext()) {
69 loadConsumers(mit.next());
70 }
71 } else {
72 InputStream is = null;
73 if (config.startsWith(biz.hammurapi.config.DomConfigFactory.RESOURCE_PREFIX)) {
74 is=MeasurementCategoryFactory.class.getClassLoader().getResourceAsStream(config.substring(biz.hammurapi.config.DomConfigFactory.RESOURCE_PREFIX.length()));
75 if (is==null) {
76 logger.warning("Could not configure measurement subsystem - resource not found '"+config.substring(biz.hammurapi.config.DomConfigFactory.RESOURCE_PREFIX.length()));
77 }
78 } else if (config.startsWith("url:")) {
79 try {
80 is=new URL(config.substring("url:".length())).openStream();
81 } catch (MalformedURLException e) {
82 logger.log(Level.WARNING, "Could not configure measurement subsystem from URL: "+e, e);
83 } catch (IOException e) {
84 logger.log(Level.WARNING, "Could not configure measurement subsystem from URL: "+e, e);
85 }
86 } else if (config.startsWith("file:")) {
87 try {
88 is=new FileInputStream(new File(config.substring("file:".length())));
89 } catch (FileNotFoundException e) {
90 logger.log(Level.WARNING, "Could not configure measurement subsystem from file: "+e, e);
91 }
92 } else {
93 logger.warning("Invalid measurement configuration string: "+config);
94 }
95
96 if (is!=null) {
97 DomConfigFactory factory = new DomConfigFactory(MeasurementCategoryFactory.class.getClassLoader());
98 bootConsumers.addAll((Collection) factory.create(is, null));
99 }
100 }
101
102 Iterator it=bootConsumers.iterator();
103 while (it.hasNext()) {
104 Object o=it.next();
105 if (o instanceof MeasurementConsumer) {
106 register((MeasurementConsumer) o);
107 } else if (o instanceof MeasurementCategoryFactory) {
108 register((MeasurementCategoryFactory) o);
109 } else if (o!=null) {
110 logger.warning("Not measurement sink or factory: "+o.getClass().getName());
111 }
112 }
113
114 if (!bootConsumers.isEmpty()) {
115 Runtime.getRuntime().addShutdownHook(new Thread() {
116 public void run() {
117 shutdownBootConsumers();
118 }
119 });
120 }
121 } catch (Exception e) {
122 logger.log(Level.SEVERE, "Could not configure metrics sybsystem: "+e, e);
123 }
124 }
125
126 /**
127 * Cannot be instantiated (abstract anyway)
128 */
129 protected MeasurementCategoryFactory() {
130 super();
131 }
132
133 private static void loadConsumers(Object provider) {
134 if (provider instanceof Collection) {
135 Iterator it = ((Collection) provider).iterator();
136 while (it.hasNext()) {
137 loadConsumers(it.next());
138 }
139 } else {
140 bootConsumers.add(provider);
141 }
142 }
143
144 /**
145 * Subclasses shall implement this method to bind sinks to category
146 * @param category
147 * @return sink for the category, can be null.
148 */
149 public abstract MeasurementConsumer getMeasurementConsumer(String categoryName);
150
151 private static class MeasurementCategoryProxy implements MeasurementCategory {
152
153 private Collection consumerList;
154
155 MeasurementCategoryProxy(Collection consumerList) {
156 this.consumerList=consumerList;
157 isActive=!consumerList.isEmpty();
158 }
159
160 public void addMeasurement(String name, double value, long time) {
161 if (isActive) {
162 if (time==0) {
163 time=System.currentTimeMillis();
164 }
165 synchronized (consumerList) {
166 Iterator it=consumerList.iterator();
167 while (it.hasNext()) {
168 ((MeasurementConsumer) it.next()).addMeasurement(name, value, time);
169 }
170 }
171 }
172 }
173
174 void addConsumer(MeasurementConsumer consumer) {
175 synchronized (consumerList) {
176 consumerList.add(consumer);
177 isActive=!consumerList.isEmpty();
178 }
179 }
180
181 void removeConsumer(MeasurementConsumer consumer) {
182 synchronized (consumerList) {
183 consumerList.remove(consumer);
184 isActive=!consumerList.isEmpty();
185 }
186 }
187
188 /**
189 * @param consumers
190 */
191 public void removeConsumers(Collection consumers) {
192 synchronized (consumerList) {
193 consumerList.removeAll(consumers);
194 isActive=!consumerList.isEmpty();
195 }
196 }
197
198 public boolean isActive() {
199 return isActive;
200 }
201
202 private boolean isActive;
203
204 public void shutdown() {
205 // Nothing
206
207 }
208 }
209
210 /**
211 * @param klass
212 * @return Time interval measurement category instance for a class
213 */
214 public static TimeIntervalCategory getTimeIntervalCategory(Class klass) {
215 return getTimeIntervalCategory(klass.getName());
216 }
217
218 /**
219 * @param categoryName category name
220 * @return Time interval measurement category instance
221 */
222 public static TimeIntervalCategory getTimeIntervalCategory(String categoryName) {
223 final MeasurementCategory cat=getCategory(categoryName);
224
225 return new TimeIntervalCategory() {
226
227 public long getTime() {
228 return cat.isActive() ? System.currentTimeMillis() : 0;
229 }
230
231 public void addInterval(String name, long start) {
232 if (cat.isActive()) {
233 long now=System.currentTimeMillis();
234 cat.addMeasurement(name, now-start, now);
235 }
236 }
237
238 };
239 }
240
241
242 /**
243 * @param klass
244 * @return Measurement sink instance for a class
245 */
246 public static MeasurementCategory getCategory(Class klass) {
247 return getCategory(klass.getName());
248 }
249
250 /**
251 * @param category
252 * @return Measurement sink instance for a category
253 */
254 public static MeasurementCategory getCategory(String category) {
255 synchronized (categories) {
256 MeasurementCategory ret=(MeasurementCategory) categories.get(category);
257 if (ret==null) {
258 final Collection consumerList=new ArrayList();
259 Iterator it=factories.iterator();
260 while (it.hasNext()) {
261 FactoryEntry entry=(FactoryEntry) it.next();
262 MeasurementConsumer consumer = entry.getCategory(category);
263 if (consumer!=null) {
264 consumerList.add(consumer);
265 }
266 }
267 ret=new MeasurementCategoryProxy(consumerList);
268 categories.put(category, ret);
269 }
270
271 return ret;
272 }
273 }
274
275 private static class FactoryEntry {
276 MeasurementCategoryFactory factory;
277
278 /**
279 * Consumers produced by the factory.
280 */
281 Collection consumers=new ArrayList();
282
283 MeasurementConsumer getCategory(String category) {
284 MeasurementConsumer ret = factory.getMeasurementConsumer(category);
285 if (ret!=null) {
286 consumers.add(ret);
287 }
288 return ret;
289 }
290 }
291
292 /**
293 * Registers sink factory.
294 * @param factory
295 */
296 public static void register(MeasurementCategoryFactory factory) {
297 if (factory instanceof Component) {
298 try {
299 ((Component) factory).start();
300 } catch (ConfigurationException e) {
301 throw new RuntimeConfigurationException(e);
302 }
303 }
304
305 synchronized (categories) {
306 FactoryEntry entry=new FactoryEntry();
307 entry.factory=factory;
308 factories.add(entry);
309 Iterator it=categories.entrySet().iterator();
310 while (it.hasNext()) {
311 Map.Entry me=(Map.Entry) it.next();
312 MeasurementConsumer consumer = entry.getCategory((String) me.getKey());
313 if (consumer!=null) {
314 ((MeasurementCategoryProxy) me.getValue()).addConsumer(consumer);
315 }
316 }
317 }
318 }
319
320 /**
321 * Register sink for a single category.
322 * @param category Category, cannot be null.
323 * @param consumer
324 */
325 public static void register(final String category, final MeasurementConsumer consumer) {
326 if (category==null) {
327 throw new IllegalArgumentException("Category is null");
328 }
329
330 if (consumer==null) {
331 throw new IllegalArgumentException("Consumer is null");
332 }
333
334 if (consumer instanceof Component) {
335 register(new MeasurementCategoryFactoryComponent() {
336
337 public MeasurementConsumer getMeasurementConsumer(String cat) {
338 return category.equals(cat) ? consumer : null;
339 }
340
341 public void start() throws ConfigurationException {
342 ((Component) consumer).start();
343 }
344
345 public void stop() throws ConfigurationException {
346 ((Component) consumer).stop();
347 }
348
349 public void setOwner(Object owner) {
350 // Ignore
351 }
352 });
353 } else {
354 register(new MeasurementCategoryFactory() {
355
356 public MeasurementConsumer getMeasurementConsumer(String cat) {
357 return category.equals(cat) ? consumer : null;
358 }
359 });
360 }
361 }
362
363 /**
364 * Mixture of factory and component to be implemented anonymously.
365 * @author Pavel Vlasov
366 * @revision $Revision: 1.6 $
367 */
368 private static abstract class MeasurementCategoryFactoryComponent extends MeasurementCategoryFactory implements Component{
369
370 }
371
372 /**
373 * Register sink for all categories.
374 * @param consumer
375 */
376 public static void register(final MeasurementConsumer consumer) {
377 if (consumer==null) {
378 throw new IllegalArgumentException("Consumer is null");
379 }
380
381 if (consumer instanceof Component) {
382 register(new MeasurementCategoryFactoryComponent() {
383
384 public MeasurementConsumer getMeasurementConsumer(String cat) {
385 return consumer;
386 }
387
388 public void start() throws ConfigurationException {
389 ((Component) consumer).start();
390 }
391
392 public void stop() throws ConfigurationException {
393 ((Component) consumer).stop();
394 }
395
396 public void setOwner(Object owner) {
397 // Ignore
398 }
399 });
400 } else {
401 register(new MeasurementCategoryFactory() {
402
403 public MeasurementConsumer getMeasurementConsumer(String cat) {
404 return consumer;
405 }
406 });
407 }
408 }
409
410 /**
411 * Register sink for several categories.
412 * @param categories Categories, cannot be null and array elements cannot be null.
413 * @param consumer
414 */
415 public static void register(final String[] categories, final MeasurementConsumer consumer) {
416 if (categories==null) {
417 throw new IllegalArgumentException("Categories is null");
418 }
419
420 if (consumer==null) {
421 throw new IllegalArgumentException("Consumer is null");
422 }
423
424 if (consumer instanceof Component) {
425 register(new MeasurementCategoryFactoryComponent() {
426
427 public MeasurementConsumer getMeasurementConsumer(String cat) {
428 for (int i=0; i<categories.length; i++) {
429 if (categories[i].equals(cat)) {
430 return consumer;
431 }
432 }
433 return null;
434 }
435
436 public void start() throws ConfigurationException {
437 ((Component) consumer).start();
438 }
439
440 public void stop() throws ConfigurationException {
441 ((Component) consumer).stop();
442 }
443
444 public void setOwner(Object owner) {
445 // Ignore
446 }
447 });
448 } else {
449 register(new MeasurementCategoryFactory() {
450
451 public MeasurementConsumer getMeasurementConsumer(String cat) {
452 for (int i=0; i<categories.length; i++) {
453 if (categories[i].equals(cat)) {
454 return consumer;
455 }
456 }
457 return null;
458 }
459 });
460 }
461 }
462
463 /**
464 * Unregisters consumer and its factory.
465 * @param consumer
466 */
467 public static void unregister(MeasurementConsumer consumer) {
468 synchronized (categories) {
469 Iterator asit=factories.iterator();
470 while (asit.hasNext()) {
471 FactoryEntry entry=(FactoryEntry) asit.next();
472 if (entry.consumers.contains(consumer)) {
473 asit.remove();
474 }
475 }
476
477 Iterator it=categories.values().iterator();
478 while (it.hasNext()) {
479 ((MeasurementCategoryProxy) it.next()).removeConsumer(consumer);
480 }
481 }
482
483 if (consumer instanceof Component) {
484 try {
485 ((Component) consumer).stop();
486 } catch (ConfigurationException e) {
487 throw new RuntimeConfigurationException(e);
488 }
489 }
490 }
491
492 /**
493 * Unregisters factory and its consumers.
494 * @param factory
495 */
496 public static void unregister(MeasurementCategoryFactory factory) {
497 synchronized (categories) {
498 Iterator asit=factories.iterator();
499 while (asit.hasNext()) {
500 FactoryEntry entry=(FactoryEntry) asit.next();
501 if (factory.equals(entry.factory)) {
502 asit.remove();
503 }
504
505 Iterator it=categories.values().iterator();
506 while (it.hasNext()) {
507 ((MeasurementCategoryProxy) it.next()).removeConsumers(entry.consumers);
508 }
509 }
510 }
511
512 if (factory instanceof Component) {
513 try {
514 ((Component) factory).stop();
515 } catch (ConfigurationException e) {
516 throw new RuntimeConfigurationException(e);
517 }
518 }
519 }
520
521 /**
522 *
523 */
524 private static void shutdownBootConsumers() {
525 Iterator it=bootConsumers.iterator();
526 while (it.hasNext()) {
527 Object o=it.next();
528 if (o instanceof MeasurementConsumer) {
529 unregister((MeasurementConsumer) o);
530 } else if (o instanceof MeasurementCategoryFactory) {
531 unregister((MeasurementCategoryFactory) o);
532 } else if (o!=null) {
533 logger.warning("Not measurement consumer or factory: "+o.getClass().getName());
534 }
535 it.remove();
536 }
537 }
538
539}
540