/*
*
* Copyright (c) void.fm
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice, this
* list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
*
* Neither the name void.fm nor the names of its contributors may be
* used to endorse or promote products derived from this software without specific
* prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package etm.core.monitor;
import java.util.HashMap;
import java.util.Map;
/**
* The MeasurementPoint represents one measurement.
* <p/>
* <p/>
* Usage example:
* </p>
* <pre>
* EtmMonitor monitor = ...;
* MeasurementPoint point = new MeasurementPoint(monitor, "name");
* try {
* <p/>
* // execute business code
* <p/>
* } finally {
* point.collect();
* }
* </pre>
*
* @author void.fm
* @version $Revision$
* @see EtmMonitor
*/
public class MeasurementPoint implements EtmPoint {
private static final long SECOND_MULTIPLIER = 1000L;
private final EtmMonitorSupport monitor;
private MeasurementPoint parent = null;
private String name;
private Long startTime;
private Long endTime;
private long ticks = 0;
private long startTimeMillis = 0;
private Map context;
/**
* Creates a new measurement point using the given
* monitor and name.
*
* @param aMonitor The monitor to be associated with.
* @param aName The name of this measurement point, may be null at construction time.
* In this case you may need to set the name using {@link #alterName(String)}
* before calling {@link #collect()}.
* @deprecated Please use {@link etm.core.monitor.EtmMonitor#createPoint(String)} instead. Will be made
* package visible with JETM 2.0.0.
*/
public MeasurementPoint(EtmMonitor aMonitor, String aName) {
// will be made package visible with JETM 2.0.0
monitor = (EtmMonitorSupport) aMonitor;
name = aName;
startTimeMillis = System.currentTimeMillis();
monitor.visitPreMeasurement(this);
}
public void collect() {
if (name == null) {
throw new IllegalStateException("A measurement point may not be collected without a proper name.");
}
monitor.visitPostCollect(this);
}
public void alterName(String newName) {
name = newName;
}
public String getName() {
return name;
}
public long getStartTime() {
return startTime.longValue();
}
public long getEndTime() {
return endTime != null ? endTime.longValue() : 0L;
}
public long getTicks() {
return ticks;
}
/**
* Sets a parent measurement point.
*
* @param aParent The parent.
*/
protected void setParent(MeasurementPoint aParent) {
parent = aParent;
}
public EtmPoint getParent() {
return parent;
}
public boolean isCollectable() {
// We always assume that parent is master.
// if the root parent is collectable, everything else should be collectable too.
if (parent != null) {
return parent.isCollectable();
}
return endTime != null;
}
/**
* Sets the start time of the measurement.
*
* @param aStartTime The start time.
*/
protected void setStartTime(long aStartTime) {
startTime = new Long(aStartTime);
}
/**
* Sets the end time of the measurement.
*
* @param aEndTime The end time.
*/
protected void setEndTime(long aEndTime) {
endTime = new Long(aEndTime);
}
/**
* Sets the number of ticks per millisecond.
*
* @param aTicks The number of ticks.
*/
protected void setTicks(long aTicks) {
ticks = aTicks;
}
public double getTransactionTime() {
if (isCollected()) {
return ((double) ((endTime.longValue() - startTime.longValue()) * SECOND_MULTIPLIER)) / (double) ticks;
} else {
throw new IllegalStateException("EtmPoint not collected yet.");
}
}
public boolean isCollected() {
return endTime != null;
}
public long getStartTimeMillis() {
return startTimeMillis;
}
public void addContextDetail(String key, Object value) {
if (context == null) {
context = new HashMap();
}
context.put(key, value);
}
public Map getContext() {
return context;
}
public String toString() {
return "MeasurementPoint{" +
"monitor=" + monitor +
", parent=" + parent +
", name='" + name + "'" +
", startTime=" + startTime +
", endTime=" + endTime +
", ticks=" + ticks +
", contextSize=" + ( context != null? context.size() : 0) +
"}";
}
}