EMMA Coverage Report (generated Mon Nov 29 14:43:38 PST 2010)
[all classes][com.jeantessier.metrics]

COVERAGE SUMMARY FOR SOURCE FILE [NbSubMetricsMeasurement.java]

nameclass, %method, %block, %line, %
NbSubMetricsMeasurement.java100% (1/1)100% (8/8)80%  (458/575)70%  (91.5/130)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class NbSubMetricsMeasurement100% (1/1)100% (8/8)80%  (458/575)70%  (91.5/130)
resolveOperand (String, Metrics): double 100% (1/1)42%  (80/191)27%  (14.1/52)
compute (): double 100% (1/1)93%  (65/70)95%  (12.4/13)
evaluateTerm (String, Metrics): boolean 100% (1/1)100% (218/219)100% (42/42)
NbSubMetricsMeasurement (MeasurementDescriptor, Metrics, String): void 100% (1/1)100% (56/56)100% (12/12)
accept (MeasurementVisitor): void 100% (1/1)100% (4/4)100% (2/2)
getSelectMetrics (Metrics): boolean 100% (1/1)100% (23/23)100% (5/5)
getTerms (): List 100% (1/1)100% (3/3)100% (1/1)
isEmpty (): boolean 100% (1/1)100% (9/9)100% (3/3)

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

[all classes][com.jeantessier.metrics]
EMMA 2.0.5312 (C) Vladimir Roubtsov