1 /*
2 Bloof - visualize the evolution of your software project
3 Copyright ( C ) 2003 Lukasz Pekacki <lukasz@pekacki.de>
4 http://bloof.sf.net/
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along with
15 this program; if not, write to the Free Software Foundation, Inc.,
16 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 $RCSfile: SqlMetric.java,v $
19 Created on $Date: 2003/10/13 15:52:31 $
20 */
21 package net.sf.bloof.metrics;
22
23 import java.awt.BorderLayout;
24 import java.sql.ResultSet;
25 import java.sql.ResultSetMetaData;
26 import java.sql.SQLException;
27 import java.sql.Types;
28 import java.util.Vector;
29
30 import javax.swing.BoxLayout;
31 import javax.swing.JComponent;
32 import javax.swing.JLabel;
33 import javax.swing.JPanel;
34 import javax.swing.JTable;
35 import javax.swing.border.EmptyBorder;
36
37 import net.n3.nanoxml.XMLElement;
38 import net.sf.bloof.Bloof;
39 import net.sf.bloof.db.Database;
40 import net.sf.bloof.util.ProgressEvent;
41 import net.sf.bloof.util.intl.Messages;
42 import net.sf.bloof.util.intl.Text;
43
44
45 /***
46 * Metric wrapper for generic SQL queries provided by the user
47 * @author Lukasz Pekacki <pekacki@users.sourceforge.net>
48 * @version $Id: SqlMetric.java,v 1.4 2003/10/13 15:52:31 pekacki Exp $
49 */
50 public class SqlMetric implements Metric {
51 /***
52 * Default constructor
53 *
54 */
55 public SqlMetric() {
56 mName = "Sql metric";
57 }
58 /***
59 * Constructor containing parametes
60 * @param aParams parameters for the metric
61 */
62 public SqlMetric(MetricParameter aParams) {
63 setupMetric(aParams);
64 }
65 private JLabel createTopLabel(String aString) {
66 JLabel lab = new JLabel(aString);
67 EmptyBorder eBorder = new EmptyBorder(0, 5, 0, 5);
68 lab.setBorder(eBorder);
69 return lab;
70 }
71
72 /***
73 * @see net.sf.bloof.metrics.Metric#getDescription()
74 */
75 public String getDescription() {
76 return Messages.getString(Text.DESCRIBE_SQL_METRIC);
77 }
78
79 /***
80 * @see net.sf.bloof.metrics.Metric#getName()
81 */
82 public String getName() {
83 return mName;
84 }
85
86 /***
87 * Returns the index of the column that contains a type of number.
88 * If no such column exists, or more than one such columns exist,
89 * it returns -1
90 * @param metaData meta data element to process
91 * @return the index of the column that contains a type of number.
92 * If no such column exists, or more than one such columns exist,
93 * it returns -1
94 */
95 private int getNumberColumnIndex(ResultSetMetaData aMetaData) throws SQLException {
96 int index = -1;
97 for (int i = 1; i < aMetaData.getColumnCount() + 1; i++) {
98 if (aMetaData.getColumnType(i) == Types.INTEGER
99 || aMetaData.getColumnType(i) == Types.NUMERIC
100 || aMetaData.getColumnType(i) == Types.SMALLINT
101 || aMetaData.getColumnType(i) == Types.REAL
102 || aMetaData.getColumnType(i) == Types.BIGINT
103 || aMetaData.getColumnType(i) == Types.FLOAT
104 || aMetaData.getColumnType(i) == Types.DOUBLE) {
105 if (index > 0) {
106 index = -1;
107 break;
108 } else {
109 index = i;
110 }
111 }
112 }
113 return index;
114 }
115 /***
116 * @see net.sf.bloof.metrics.Metric#getParameter()
117 */
118 public MetricParameter getParameter() {
119 return null;
120 }
121
122 /***
123 * Returns a time line chart if there is one and only one time column,
124 * otherwise it returns a table
125 * @see net.sf.bloof.metrics.Metric#getResultComponent()
126 */
127 public JComponent getResultComponent() {
128 return getTableComponent();
129 }
130
131 /***
132 * Returns a time line element if there is one and only one time column,
133 * otherwise it returns a table element
134 * @see net.sf.bloof.metrics.Metric#getResultXml()
135 */
136 public XMLElement getResultXml() {
137 XMLElement xml = new XMLElement("result");
138 XMLElement params = new XMLElement("parameter");
139 XMLElement data = null;
140 params.setAttribute("sql", mMetricParam.getSqlQuery());
141 if (mResultTable != null) {
142 xml.setAttribute("type", "table");
143 data = mResultTable.getXML();
144 } else {
145 xml.setAttribute("type", "timeline");
146 data = mResultTimeline.getResultXml();
147 }
148 xml.addChild(params);
149 xml.addChild(data);
150 return xml;
151 }
152
153 /***
154 * @see net.sf.bloof.metrics.Metric#getSetup()
155 */
156 public MetricParameter getSetup() {
157 return mMetricParam;
158 }
159
160 private JComponent getTableComponent() {
161 JComponent title = getTitle();
162 JPanel innerTablePane = new JPanel();
163 innerTablePane.setLayout(new BoxLayout(innerTablePane, BoxLayout.Y_AXIS));
164 JTable table = new JTable(mResultTable.getTabelModel());
165 innerTablePane.add(table.getTableHeader());
166 innerTablePane.add(table);
167 JPanel compund = new JPanel(new BorderLayout());
168 compund.add(title, BorderLayout.NORTH);
169 compund.add(innerTablePane, BorderLayout.CENTER);
170 return compund;
171
172 }
173
174 /***
175 * Returns the index of the column that contains a type of time.
176 * If no such column exists, or more than one such columns exist,
177 * it returns -1
178 * @param metaData meta data element to process
179 * @return the index of the column that contains a type of time.
180 * If no such column exists, or more than one such columns exist,
181 * it returns -1
182 */
183 private int getTimeColumnIndex(ResultSetMetaData aMetaData) throws SQLException {
184 int index = -1;
185 for (int i = 1; i < aMetaData.getColumnCount() + 1; i++) {
186 if (aMetaData.getColumnType(i) == Types.TIME
187 || aMetaData.getColumnType(i) == Types.TIMESTAMP
188 || aMetaData.getColumnType(i) == Types.DATE) {
189 if (index > 0) {
190 index = -1;
191 break;
192 } else {
193 index = i;
194 }
195 }
196 }
197 return index;
198 }
199
200
201 /***
202 * Create a title component for this metric
203 * @return title component
204 */
205 public JComponent getTitle() {
206 JPanel title = new JPanel();
207 title.setLayout(new BoxLayout(title, BoxLayout.Y_AXIS));
208 JPanel top = new JPanel();
209 JPanel filters = new JPanel();
210 filters.add(createTopLabel("SQL query: " + mMetricParam.getSqlQuery()));
211 title.add(top);
212 title.add(filters);
213 return title;
214 }
215
216 private void processTableResult(ResultSet aRes, ResultSetMetaData aMetaData)
217 throws SQLException {
218 Object[] columnNames = new Object[aMetaData.getColumnCount()];
219 for (int i = 0; i < aMetaData.getColumnCount(); i++) {
220 columnNames[i] = aMetaData.getColumnName(i + 1);
221 }
222 mResultTable = new ResultTable(columnNames);
223 while (aRes.next()) {
224 Vector row = new Vector();
225 for (int i = 0; i < columnNames.length; i++) {
226 row.add(aRes.getObject(i + 1));
227 }
228 mResultTable.addRow(row);
229 }
230 }
231
232 private void processTimeLineResult(
233 ResultSet aRes,
234 ResultSetMetaData aMetaData,
235 int aTimeColumn,
236 int aNumberColumn)
237 throws SQLException {
238 if (aMetaData != null) {
239 // makes no difference
240 }
241 mResultTimeline = new ResultTimeLine();
242 while (aRes.next()) {
243 TimeValue tv =
244 new TimeValue(aRes.getDate(aTimeColumn), new Double(aRes.getDouble(aNumberColumn)));
245 mResultTimeline.addEntry(tv);
246 }
247 }
248
249 /***
250 * @see net.sf.bloof.metrics.Metric#runMetric()
251 */
252 public void runMetric(Database aDatabase) throws SQLException {
253 /* build SQL query */
254 Bloof.propagateProgressEvent(new ProgressEvent(Messages.getString(Text.EXECUTING_DB_QUERY), 20));
255 ResultSet res = aDatabase.executeQuery(mSqlQuery);
256 ResultSetMetaData metaData = res.getMetaData();
257 int timeColumnIndex = getTimeColumnIndex(metaData);
258 int numberColumnIndex = getNumberColumnIndex(metaData);
259 Bloof.propagateProgressEvent(new ProgressEvent(Messages.getString(Text.CONSTRUCTING_RESULT), 80));
260 if (timeColumnIndex > 0 && numberColumnIndex > 0) {
261 processTimeLineResult(res, metaData, timeColumnIndex, numberColumnIndex);
262 } else {
263 processTableResult(res, metaData);
264 }
265 Bloof.propagateProgressEvent(new ProgressEvent(Messages.getString(Text.FINISHED), 100));
266 }
267
268 /***
269 * @see net.sf.bloof.metrics.Metric#setName(java.lang.String)
270 */
271 public void setName(String aName) {
272 mName = aName;
273
274 }
275 /***
276 * @see net.sf.bloof.metrics.Metric#setupMetric(net.sf.bloof.metrics.MetricParameter)
277 */
278 public void setupMetric(MetricParameter aMetricParams) {
279 mMetricParam = aMetricParams;
280 mSqlQuery = mMetricParam.getSqlQuery();
281 }
282
283 /***
284 * @see java.lang.Object#toString()
285 */
286 public String toString() {
287 return mName;
288 }
289 private MetricParameter mMetricParam;
290 private String mName, mSqlQuery;
291 private ResultTable mResultTable;
292 private ResultTimeLine mResultTimeline;
293 }
This page was automatically generated by Maven