KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jeantessier > metrics > NbSubMetricsMeasurement


1 /*
2  * Copyright (c) 2001-2005, Jean Tessier
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of Jean Tessier nor the names of his contributors
17  * may be used to endorse or promote products derived from this software
18  * without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */

32
33 package com.jeantessier.metrics;
34
35 import java.io.*;
36 import java.util.*;
37
38 import org.apache.log4j.*;
39
40 /**
41  * Counts the number of submetrics according to selection
42  * criteria. If there are no criteria, it matches all
43  * submetrics. Each criterion is a boolean expression
44  * with measurement names, numbers, and boolean operators
45  * (<, <=, >, >=, ==, and !=). If a submetric matches
46  * any one of the expressions in the criteria, it is
47  * included in the count.
48  *
49  * <p>This is the syntax for initializing this type of
50  * measurement:</p>
51  *
52  * <pre>
53  * &lt;init&gt;
54  * (number | measurement name [DISPOSE_x]) [operator [(number | measurement name [DISPOSE_x])]]*
55  * ...
56  * &lt;/init&gt;
57  * </pre>
58  */

59 public class NbSubMetricsMeasurement extends MeasurementBase {
60     private static final String JavaDoc OPERATORS = "/(<=)|(<)|(>=)|(>)|(==)|(!=)/";
61
62     private static final String JavaDoc LESSER_THAN = "<";
63     private static final String JavaDoc LESSER_THAN_OR_EQUAL = "<=";
64     private static final String JavaDoc GREATER_THAN = ">";
65     private static final String JavaDoc GREATER_THAN_OR_EQUAL = ">=";
66     private static final String JavaDoc EQUALS = "==";
67     private static final String JavaDoc NOT_EQUALS = "!=";
68
69     private static final double DELTA = 0.1;
70
71     private List terms = new LinkedList();
72     private int value = 0;
73
74     public NbSubMetricsMeasurement(MeasurementDescriptor descriptor, Metrics context, String JavaDoc initText) {
75         super(descriptor, context, initText);
76
77         try {
78             BufferedReader in = new BufferedReader(new StringReader(initText));
79             String JavaDoc line;
80
81             while ((line = in.readLine()) != null) {
82                 terms.add(line.trim());
83             }
84
85             in.close();
86         } catch (Exception JavaDoc ex) {
87             Logger.getLogger(getClass()).debug("Cannot initialize with \"" + initText + "\"", ex);
88             terms.clear();
89         }
90     }
91
92     public List getTerms() {
93         return terms;
94     }
95     
96     public void accept(MeasurementVisitor visitor) {
97         visitor.visitNbSubMetricsMeasurement(this);
98     }
99
100     public boolean isEmpty() {
101         if (!isCached()) {
102             compute();
103         }
104
105         return super.isEmpty();
106     }
107     
108     protected double compute() {
109         if (!isCached()) {
110             synchronized (this) {
111                 if (!isCached()) {
112                     value = 0;
113                     
114                     if (getTerms().isEmpty()) {
115                         value = getContext().getSubMetrics().size();
116                     } else {
117                         Iterator i = getContext().getSubMetrics().iterator();
118                         while (i.hasNext()) {
119                             Metrics metrics = (Metrics) i.next();
120                             
121                             if (getSelectMetrics(metrics)) {
122                                 value++;
123                             }
124                         }
125                     }
126
127                     setEmpty(value == 0);
128
129                     setCached(true);
130                 }
131             }
132         }
133         
134         return value;
135     }
136
137     private boolean getSelectMetrics(Metrics metrics) {
138         boolean result = getTerms().isEmpty();
139         
140         Iterator i = getTerms().iterator();
141         while (!result && i.hasNext()) {
142             result = evaluateTerm((String JavaDoc) i.next(), metrics);
143         }
144
145         return result;
146     }
147
148     private boolean evaluateTerm(String JavaDoc term, Metrics metrics) {
149         boolean result;
150
151         Logger.getLogger(getClass()).debug("EvaluateTerm(\"" + term + "\", " + metrics + ")");
152         
153         List elements = new ArrayList();
154         perl().split(elements, OPERATORS, term);
155
156         result = (elements.size() > 0) && ((elements.size() % 2) == 1);
157         
158         if (elements.size() == 1) {
159             result = metrics.hasMeasurement((String JavaDoc) elements.remove(0));
160         } else {
161             while (result && (elements.size() > 2) && ((elements.size() % 2) == 1)) {
162                 String JavaDoc leftString = (String JavaDoc) elements.remove(0);
163                 String JavaDoc operator = (String JavaDoc) elements.remove(0);
164                 String JavaDoc rightString = (String JavaDoc) elements.get(0);
165
166                 double leftOperand = 0;
167                 try {
168                     leftOperand = Double.parseDouble(leftString);
169                 } catch (NumberFormatException JavaDoc ex) {
170                     try {
171                         leftOperand = resolveOperand(leftString, metrics);
172                     } catch (NullPointerException JavaDoc ex2) {
173                         result = false;
174                     }
175                 }
176
177                 double rightOperand = 0;
178                 try {
179                     rightOperand = Double.parseDouble(rightString);
180                 } catch (NumberFormatException JavaDoc ex) {
181                     try {
182                         rightOperand = resolveOperand(rightString, metrics);
183                     } catch (NullPointerException JavaDoc ex2) {
184                         result = false;
185                     }
186                 }
187
188                 if (result) {
189                     if (operator.equals(LESSER_THAN)) {
190                         result = leftOperand < rightOperand;
191                     } else if (operator.equals(LESSER_THAN_OR_EQUAL)) {
192                         result = leftOperand <= rightOperand;
193                     } else if (operator.equals(GREATER_THAN)) {
194                         result = leftOperand > rightOperand;
195                     } else if (operator.equals(GREATER_THAN_OR_EQUAL)) {
196                         result = leftOperand >= rightOperand;
197                     } else if (operator.equals(EQUALS)) {
198                         result = Math.abs(leftOperand - rightOperand) <= DELTA;
199                     } else if (operator.equals(NOT_EQUALS)) {
200                         result = Math.abs(leftOperand - rightOperand) > DELTA;
201                     }
202                 }
203             }
204         }
205
206         Logger.getLogger(getClass()).debug("EvaluateTerm(\"" + term + "\", " + metrics + "): " + result);
207
208         return result;
209     }
210
211     private double resolveOperand(String JavaDoc name, Metrics metrics) {
212         double result = 0;
213             
214         name = name.trim();
215
216         Logger.getLogger(getClass()).debug("ResolveOperand(\"" + name + "\", " + metrics + ")");
217
218         if (name.length() != 0) {
219             int dispose;
220
221             synchronized (perl()) {
222                 if (perl().match("/(.*)\\s+(dispose_\\w+)$/i", name)) {
223                     name = perl().group(1);
224                     
225                     String JavaDoc disposeText = perl().group(2);
226                     
227                     if (disposeText.equalsIgnoreCase("DISPOSE_IGNORE")) {
228                         dispose = StatisticalMeasurement.DISPOSE_IGNORE;
229                     } else if (disposeText.equalsIgnoreCase("DISPOSE_MINIMUM")) {
230                         dispose = StatisticalMeasurement.DISPOSE_MINIMUM;
231                     } else if (disposeText.equalsIgnoreCase("DISPOSE_MEDIAN")) {
232                         dispose = StatisticalMeasurement.DISPOSE_MEDIAN;
233                     } else if (disposeText.equalsIgnoreCase("DISPOSE_AVERAGE")) {
234                         dispose = StatisticalMeasurement.DISPOSE_AVERAGE;
235                     } else if (disposeText.equalsIgnoreCase("DISPOSE_STANDARD_DEVIATION")) {
236                         dispose = StatisticalMeasurement.DISPOSE_STANDARD_DEVIATION;
237                     } else if (disposeText.equalsIgnoreCase("DISPOSE_MAXIMUM")) {
238                         dispose = StatisticalMeasurement.DISPOSE_MAXIMUM;
239                     } else if (disposeText.equalsIgnoreCase("DISPOSE_SUM")) {
240                         dispose = StatisticalMeasurement.DISPOSE_SUM;
241                     } else if (disposeText.equalsIgnoreCase("DISPOSE_NB_DATA_POINTS")) {
242                         dispose = StatisticalMeasurement.DISPOSE_NB_DATA_POINTS;
243                     } else {
244                         dispose = StatisticalMeasurement.DISPOSE_IGNORE;
245                     }
246                 } else {
247                     dispose = StatisticalMeasurement.DISPOSE_IGNORE;
248                 }
249             }
250             
251             Measurement measurement = metrics.getMeasurement(name);
252             
253             if (measurement instanceof StatisticalMeasurement) {
254                 StatisticalMeasurement stats = (StatisticalMeasurement) measurement;
255                 
256                 switch (dispose) {
257                     case StatisticalMeasurement.DISPOSE_MINIMUM:
258                         result = stats.getMinimum();
259                         break;
260                     case StatisticalMeasurement.DISPOSE_MEDIAN:
261                         result = stats.getMedian();
262                         break;
263                     case StatisticalMeasurement.DISPOSE_AVERAGE:
264                         result = stats.getAverage();
265                         break;
266                     case StatisticalMeasurement.DISPOSE_STANDARD_DEVIATION:
267                         result = stats.getStandardDeviation();
268                         break;
269                     case StatisticalMeasurement.DISPOSE_MAXIMUM:
270                         result = stats.getMaximum();
271                         break;
272                     case StatisticalMeasurement.DISPOSE_SUM:
273                         result = stats.getSum();
274                         break;
275                     case StatisticalMeasurement.DISPOSE_NB_DATA_POINTS:
276                         result = stats.getNbDataPoints();
277                         break;
278                     case StatisticalMeasurement.DISPOSE_IGNORE:
279                     default:
280                         result = stats.doubleValue();
281                         break;
282                 }
283             } else if (measurement instanceof NullMeasurement) {
284                 throw new NullPointerException JavaDoc();
285             } else {
286                 result = measurement.doubleValue();
287             }
288         }
289
290         Logger.getLogger(getClass()).debug("ResolveOperand(\"" + name + "\", " + metrics + "): " + result);
291         
292         return result;
293     }
294 }
295
Popular Tags