001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.metrics;
034:
035: import java.util.*;
036:
037: import org.apache.log4j.*;
038:
039: public class Metrics {
040: public static final String PACKAGES = "P";
041:
042: public static final String CLASSES = "C";
043: public static final String PUBLIC_CLASSES = "PuC";
044: public static final String FINAL_CLASSES = "FC";
045: public static final String ABSTRACT_CLASSES = "AC";
046: public static final String SYNTHETIC_CLASSES = "SynthC";
047: public static final String INTERFACES = "I";
048: public static final String DEPRECATED_CLASSES = "DC";
049: public static final String STATIC_CLASSES = "SC";
050:
051: public static final String PUBLIC_METHODS = "PuM";
052: public static final String PROTECTED_METHODS = "ProM";
053: public static final String PRIVATE_METHODS = "ProM";
054: public static final String PACKAGE_METHODS = "PaM";
055: public static final String FINAL_METHODS = "FM";
056: public static final String ABSTRACT_METHODS = "AM";
057: public static final String DEPRECATED_METHODS = "DM";
058: public static final String SYNTHETIC_METHODS = "SynthM";
059: public static final String STATIC_METHODS = "SM";
060: public static final String SYNCHRONIZED_METHODS = "SynchM";
061: public static final String NATIVE_METHODS = "NM";
062: public static final String TRIVIAL_METHODS = "TM";
063:
064: public static final String ATTRIBUTES = "A";
065: public static final String PUBLIC_ATTRIBUTES = "PuA";
066: public static final String PROTECTED_ATTRIBUTES = "ProA";
067: public static final String PRIVATE_ATTRIBUTES = "PriA";
068: public static final String PACKAGE_ATTRIBUTES = "PaA";
069: public static final String FINAL_ATTRIBUTES = "FA";
070: public static final String DEPRECATED_ATTRIBUTES = "DA";
071: public static final String SYNTHETIC_ATTRIBUTES = "SynthA";
072: public static final String STATIC_ATTRIBUTES = "SA";
073: public static final String TRANSIENT_ATTRIBUTES = "TA";
074: public static final String VOLATILE_ATTRIBUTES = "VA";
075:
076: public static final String INNER_CLASSES = "IC";
077: public static final String PUBLIC_INNER_CLASSES = "PuIC";
078: public static final String PROTECTED_INNER_CLASSES = "ProIC";
079: public static final String PRIVATE_INNER_CLASSES = "PriIC";
080: public static final String PACKAGE_INNER_CLASSES = "PaIC";
081: public static final String ABSTRACT_INNER_CLASSES = "AIC";
082: public static final String FINAL_INNER_CLASSES = "FIC";
083: public static final String STATIC_INNER_CLASSES = "SIC";
084:
085: public static final String DEPTH_OF_INHERITANCE = "DOI";
086: public static final String SUBCLASSES = "SUB";
087: public static final String CLASS_SLOC = "class SLOC";
088:
089: public static final String SLOC = "SLOC";
090: public static final String PARAMETERS = "PARAM";
091: public static final String LOCAL_VARIABLES = "LVAR";
092:
093: public static final String INBOUND_INTRA_PACKAGE_DEPENDENCIES = "IIP";
094: public static final String INBOUND_EXTRA_PACKAGE_DEPENDENCIES = "IEP";
095: public static final String OUTBOUND_INTRA_PACKAGE_DEPENDENCIES = "OIP";
096: public static final String OUTBOUND_EXTRA_PACKAGE_DEPENDENCIES = "OEP";
097:
098: public static final String INBOUND_INTRA_CLASS_METHOD_DEPENDENCIES = "IICM";
099: public static final String INBOUND_INTRA_PACKAGE_METHOD_DEPENDENCIES = "IIPM";
100: public static final String INBOUND_EXTRA_PACKAGE_METHOD_DEPENDENCIES = "IEPM";
101: public static final String OUTBOUND_INTRA_CLASS_FEATURE_DEPENDENCIES = "OICF";
102: public static final String OUTBOUND_INTRA_PACKAGE_FEATURE_DEPENDENCIES = "OIPF";
103: public static final String OUTBOUND_INTRA_PACKAGE_CLASS_DEPENDENCIES = "OIPC";
104: public static final String OUTBOUND_EXTRA_PACKAGE_FEATURE_DEPENDENCIES = "OEPF";
105: public static final String OUTBOUND_EXTRA_PACKAGE_CLASS_DEPENDENCIES = "OEPC";
106:
107: public static final String GROUP_NAME_CHARACTER_COUNT = "GNCC";
108: public static final String GROUP_NAME_WORD_COUNT = "GNWC";
109: public static final String CLASS_NAME_CHARACTER_COUNT = "CNCC";
110: public static final String CLASS_NAME_WORD_COUNT = "CNWC";
111: public static final String METHOD_NAME_CHARACTER_COUNT = "MNCC";
112: public static final String METHOD_NAME_WORD_COUNT = "MNWC";
113:
114: private static final Measurement NULL_MEASUREMENT = new NullMeasurement();
115:
116: private Metrics parent;
117: private String name;
118:
119: private Map<String, Measurement> measurements = new TreeMap<String, Measurement>();
120: private Map<String, Metrics> submetrics = new TreeMap<String, Metrics>();
121:
122: public Metrics(String name) {
123: this (null, name);
124: }
125:
126: /**
127: * @param parent The context for this metrics (e.g., methods's class, class'
128: * package). You may pass <code>null</code> to create
129: * top-level metrics.
130: * @param name The name of the element being measured
131: * (e.g., class name, method name).
132: */
133: public Metrics(Metrics parent, String name) {
134: this .parent = parent;
135: this .name = name;
136:
137: if (parent == null) {
138: Logger.getLogger(getClass()).debug(
139: "Created top-level metrics \"" + name + "\"");
140: } else {
141: Logger.getLogger(getClass()).debug(
142: "Created metrics \"" + name + "\" under \""
143: + parent.getName() + "\"");
144: }
145: }
146:
147: public Metrics getParent() {
148: return parent;
149: }
150:
151: /**
152: * @return The name of the element being measured
153: * (e.g., class name, method name).
154: */
155: public String getName() {
156: return name;
157: }
158:
159: void track(Measurement measurement) {
160: track(measurement.getShortName(), measurement);
161: }
162:
163: void track(String name, Measurement measurement) {
164: measurements.put(name, measurement);
165: }
166:
167: public void addToMeasurement(String name) {
168: addToMeasurement(name, 1);
169: }
170:
171: public void addToMeasurement(String name, int delta) {
172: getMeasurement(name).add(delta);
173: }
174:
175: public void addToMeasurement(String name, long delta) {
176: getMeasurement(name).add(delta);
177: }
178:
179: public void addToMeasurement(String name, float delta) {
180: getMeasurement(name).add(delta);
181: }
182:
183: public void addToMeasurement(String name, double delta) {
184: getMeasurement(name).add(delta);
185: }
186:
187: public void addToMeasurement(String name, Object delta) {
188: getMeasurement(name).add(delta);
189: }
190:
191: public Measurement getMeasurement(String name) {
192: Measurement result = measurements.get(name);
193:
194: if (result == null) {
195: result = NULL_MEASUREMENT;
196: Logger.getLogger(getClass()).info(
197: "Null measurement \"" + name + "\" on \""
198: + getName() + "\"");
199: }
200:
201: return result;
202: }
203:
204: public boolean hasMeasurement(String name) {
205: return measurements.get(name) != null;
206: }
207:
208: public Collection<String> getMeasurementNames() {
209: return Collections
210: .unmodifiableCollection(measurements.keySet());
211: }
212:
213: public Metrics addSubMetrics(Metrics metrics) {
214: return submetrics.put(metrics.getName(), metrics);
215: }
216:
217: public Collection<Metrics> getSubMetrics() {
218: return Collections.unmodifiableCollection(submetrics.values());
219: }
220:
221: public boolean isEmpty() {
222: boolean result = true;
223:
224: Iterator<Measurement> i = measurements.values().iterator();
225: while (result && i.hasNext()) {
226: Measurement measurement = i.next();
227: if (measurement.getDescriptor().isVisible()) {
228: result = measurement.isEmpty();
229: }
230: }
231:
232: Iterator<Metrics> j = submetrics.values().iterator();
233: while (result && j.hasNext()) {
234: result = j.next().isEmpty();
235: }
236:
237: return result;
238: }
239:
240: public boolean isInRange() {
241: boolean result = true;
242:
243: Iterator<Measurement> i = measurements.values().iterator();
244: while (result && i.hasNext()) {
245: result = i.next().isInRange();
246: }
247:
248: return result;
249: }
250:
251: public String toString() {
252: StringBuffer result = new StringBuffer();
253:
254: result.append(getClass().getName()).append(" ").append(
255: getName()).append(" with [");
256:
257: Iterator<String> i = getMeasurementNames().iterator();
258: while (i.hasNext()) {
259: String name = i.next();
260: Measurement measure = getMeasurement(name);
261:
262: result.append("\"").append(name).append("\"(").append(
263: measure.getClass().getName()).append(")");
264: if (i.hasNext()) {
265: result.append(", ");
266: }
267: }
268:
269: result.append("]");
270:
271: return result.toString();
272: }
273: }
|