KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > scriptella > execution > ExecutionStatisticsBuilder


1 /*
2  * Copyright 2006-2007 The Scriptella Project Team.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package scriptella.execution;
17
18 import scriptella.configuration.Location;
19 import scriptella.spi.Connection;
20
21 import java.util.Date JavaDoc;
22 import java.util.Stack JavaDoc;
23
24
25 /**
26  * A builder for execution statistics.
27  * <p>This class collects runtime ETL execution statistics, the usage contract is the following:</p>
28  * <ul>
29  * <li>{@link #etlStarted()} invoked on ETL start.
30  * <li>Call {@link #elementStarted(Location, Connection)} before executing an element.
31  * <li>Call {@link #elementExecuted()} or {@link #elementFailed()} after executing an element.
32  * <li>{@link #etlComplete()} invoked when ETL completes.
33  * <li>{@link #getStatistics() Obtain statistics} after ETL completes.
34  * </ul>
35  * <em>Notes:</em>
36  * <ul>
37  * <li>Start/End element callbacks sequence must comply with executing elements position in a XML file.
38 * <li>This class is not thread safe.
39  * </ul>
40  *
41  * @author Fyodor Kupolov
42  * @version 1.0
43  */

44 public class ExecutionStatisticsBuilder {
45     private ExecutionStatistics executionStatistics;
46
47     //Execution stack for nested elements
48
protected Stack JavaDoc<ExecutionStatistics.ElementInfo> executionStack = new Stack JavaDoc<ExecutionStatistics.ElementInfo>();
49
50     /**
51      * Called when new element execution started.
52      *
53      * @param loc element location.
54      */

55     public void elementStarted(final Location loc, Connection connection) {
56         ExecutionStatistics.ElementInfo ei = getInfo(loc);
57         executionStack.push(ei);
58         ei.statementsOnStart = connection.getExecutedStatementsCount();
59         ei.connection = connection;
60         ei.started=System.nanoTime();
61     }
62
63     /**
64      * This method is called when element has been executed.
65      */

66     public void elementExecuted() {
67         setElementState(true);
68     }
69
70     /**
71      * Invoked on ETL start
72      */

73     public void etlStarted() {
74         executionStatistics = new ExecutionStatistics();
75         executionStatistics.setStarted(new Date JavaDoc());
76     }
77
78     /**
79      * Invoked on ETL completion.
80      */

81     public void etlComplete() {
82         if (executionStatistics==null) {
83             throw new IllegalStateException JavaDoc("etlStarted not called");
84         }
85
86         //assume that statistics is obtained immediately after the execution
87
executionStatistics.setFinished(new Date JavaDoc());
88     }
89
90
91     /**
92      * Calculates execution time and statements number for the completed element.
93      */

94     private void setElementState(boolean ok) {
95         ExecutionStatistics.ElementInfo ended = executionStack.pop();
96         long ti = System.nanoTime() - ended.started;
97         ended.workingTime += ti; //increase the total working time for element
98
if (ended.workingTime < 0) {
99             ended.workingTime = 0;
100         }
101         final Connection con = ended.connection;
102         ended.connection=null; //clear the connection to avoid leaks
103
long conStatements = con.getExecutedStatementsCount();
104         long elStatements = conStatements - ended.statementsOnStart;
105         if (ok) {
106             ended.okCount++;
107         } else {
108             ended.failedCount++;
109         }
110
111         if (elStatements > 0) {
112             ended.statements += elStatements;
113             executionStatistics.statements+=elStatements;
114         }
115
116
117         //Exclude this element time from parent elements
118
//Also find the parent elements with the same connection and decrement their number of statements
119
for (int i=executionStack.size()-1;i>=0;i--) {
120             final ExecutionStatistics.ElementInfo parent = executionStack.get(i);
121             parent.workingTime -= ti;
122             if (parent.connection==con) { //if the same objects
123
parent.statementsOnStart+=elStatements;
124             }
125         }
126
127     }
128
129     public void elementFailed() {
130         setElementState(false);
131     }
132
133     private ExecutionStatistics.ElementInfo getInfo(final Location loc) {
134         if (executionStatistics==null) {
135             throw new IllegalStateException JavaDoc("etlStarted must be invoked prior to calling this method");
136         }
137         ExecutionStatistics.ElementInfo ei = executionStatistics.elements.get(loc.getXPath());
138
139         if (ei == null) {
140             ei = new ExecutionStatistics.ElementInfo();
141             ei.id = loc.getXPath();
142             executionStatistics.elements.put(loc.getXPath(), ei);
143         }
144
145         return ei;
146     }
147
148     public ExecutionStatistics getStatistics() {
149         return executionStatistics;
150     }
151 }
152
Popular Tags