1/**
2 * Copyright (c) 2004-2011 QOS.ch
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free  of charge, to any person obtaining
6 * a  copy  of this  software  and  associated  documentation files  (the
7 * "Software"), to  deal in  the Software without  restriction, including
8 * without limitation  the rights to  use, copy, modify,  merge, publish,
9 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
10 * permit persons to whom the Software  is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The  above  copyright  notice  and  this permission  notice  shall  be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
17 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
18 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 */
25package org.slf4j.profiler;
26
27/**
28 * A very basic @{link TimeInstrument} which can be started and stopped
29 * once and only once.
30 *
31 * @author Ceki Gülcü
32 *
33 */
34public class StopWatch implements TimeInstrument {
35
36    private String name;
37    private long startTime;
38    private long stopTime;
39    TimeInstrumentStatus status;
40
41    public StopWatch(String name) {
42        start(name);
43    }
44
45    StopWatch(StopWatch original) {
46        this.name = original.name;
47        this.startTime = original.startTime;
48        this.stopTime = original.stopTime;
49        this.status = original.status;
50    }
51
52    public void start(String name) {
53        this.name = name;
54        startTime = System.nanoTime();
55        status = TimeInstrumentStatus.STARTED;
56    }
57
58    public String getName() {
59        return name;
60    }
61
62    public TimeInstrument stop() {
63        if (status == TimeInstrumentStatus.STOPPED) {
64            return this;
65        }
66        return stop(System.nanoTime());
67    }
68
69    public StopWatch stop(long stopTime) {
70        this.status = TimeInstrumentStatus.STOPPED;
71        this.stopTime = stopTime;
72        return this;
73    }
74
75    @Override
76    public String toString() {
77        StringBuilder buf = new StringBuilder();
78        buf.append("StopWatch [");
79        buf.append(name);
80        buf.append("] ");
81
82        switch (status) {
83        case STARTED:
84            buf.append("STARTED");
85            break;
86        case STOPPED:
87            buf.append("elapsed time: ");
88            buf.append(Util.durationInDurationUnitsAsStr(elapsedTime(), DurationUnit.MICROSECOND));
89            break;
90        default:
91            throw new IllegalStateException("Status " + status + " is not expected");
92        }
93        return buf.toString();
94    }
95
96    public final long elapsedTime() {
97        if (status == TimeInstrumentStatus.STARTED) {
98            return 0;
99        } else {
100            return stopTime - startTime;
101        }
102    }
103
104    public TimeInstrumentStatus getStatus() {
105        return status;
106    }
107
108    public void print() {
109        System.out.println(toString());
110    }
111
112    public void log() {
113        throw new UnsupportedOperationException("A stopwatch instance does not know how to log");
114    }
115
116}
117