001: /*
002: * The contents of this file are subject to the Mozilla Public License
003: * Version 1.1 (the "License"); you may not use this file except in
004: * compliance with the License. You may obtain a copy of the License at
005: * http://www.mozilla.org/MPL/
006: *
007: * Software distributed under the License is distributed on an "AS IS"
008: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
009: * License for the specific language governing rights and limitations
010: * under the License.
011: *
012: * The Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
013: *
014: * The Initial Developer of the Original Code is iSQL-Viewer, A Mutli-Platform Database Tool.
015: * Portions created by Mark A. Kobold are Copyright (C) 2000-2007. All Rights Reserved.
016: *
017: * Contributor(s):
018: * Mark A. Kobold [mkobold <at> isqlviewer <dot> com].
019: *
020: * If you didn't download this code from the following link, you should check
021: * if you aren't using an obsolete version: http://www.isqlviewer.com
022: */
023: package org.isqlviewer.model;
024:
025: import java.sql.SQLException;
026: import java.util.Calendar;
027: import java.util.Date;
028: import java.util.List;
029: import java.util.TreeMap;
030: import java.util.Vector;
031:
032: import javax.swing.event.TreeModelEvent;
033: import javax.swing.tree.TreePath;
034:
035: import org.isqlviewer.JdbcCommandLogger;
036: import org.isqlviewer.history.HistoricalCommand;
037: import org.isqlviewer.sql.embedded.EmbeddedDatabase;
038: import org.isqlviewer.swing.outline.AbstractTreeTableModel;
039: import org.isqlviewer.swing.outline.OutlineModel;
040:
041: /**
042: * Model for displaying the historical events in a tree fashion.
043: * <p>
044: * This model is a two tier tree such that there are date nodes refere to an internal collection historical reference
045: * nodes.
046: *
047: * @author Mark A. Kobold <mkobold at isqlviewer dot com>
048: * @see org.isqlviewer.history.HistoryReference
049: * @version 1.0
050: */
051: public final class HistoryTreeModel extends AbstractTreeTableModel
052: implements JdbcCommandLogger {
053:
054: private static final Class[] columnTypes = { OutlineModel.class,
055: Date.class };
056:
057: private final TreeMap<Date, List<HistoricalCommand>> rootNode = new TreeMap<Date, List<HistoricalCommand>>();
058: private final List<Date> rootKeySet = new Vector<Date>();
059:
060: public HistoryTreeModel() {
061:
062: }
063:
064: public void addReference(HistoricalCommand reference) {
065:
066: Date normalizedDate = normalizeTimestamp(reference
067: .getQueryTime());
068: List<HistoricalCommand> set = null;
069: synchronized (rootNode) {
070: set = rootNode.get(normalizedDate);
071: if (set == null) {
072: set = new Vector<HistoricalCommand>();
073: rootNode.put(normalizedDate, set);
074: rootKeySet.add(normalizedDate);
075: reload();
076: }
077: set.add(reference);
078: }
079: Object[] objectPath = new Object[] { rootNode, normalizedDate };
080: Object[] children = new Object[] { reference };
081: int[] indicies = new int[] { set.size() - 1 };
082: fireTreeNodesInserted(new TreeModelEvent(this , objectPath,
083: indicies, children));
084: }
085:
086: /**
087: * Empties this tree model of all internal references to other objects.
088: * <p>
089: * fairly run of the mill clearing function.
090: */
091: public synchronized void clear() {
092:
093: rootNode.clear();
094: rootKeySet.clear();
095: reload();
096: }
097:
098: public Object getRoot() {
099:
100: return rootNode;
101: }
102:
103: public Object getChild(Object parent, int index) {
104:
105: if (parent == rootNode) {
106: return rootKeySet.get(index);
107: } else if (parent instanceof Date) {
108: List<?> list = rootNode.get(parent);
109: return list == null ? null : list.get(index);
110: } else if (parent instanceof HistoricalCommand) {
111: HistoricalCommand reference = (HistoricalCommand) parent;
112: return reference.getChildCommand(index);
113: }
114: return null;
115: }
116:
117: public int getChildCount(Object parent) {
118:
119: if (parent == rootNode) {
120: return rootKeySet.size();
121: } else if (parent instanceof Date) {
122: List<?> list = rootNode.get(parent);
123: return list == null ? 0 : list.size();
124: } else if (parent instanceof HistoricalCommand) {
125: HistoricalCommand reference = (HistoricalCommand) parent;
126: return reference.getChildCount();
127: }
128: return 0;
129: }
130:
131: public boolean isLeaf(Object node) {
132:
133: if (node instanceof HistoricalCommand) {
134: HistoricalCommand reference = (HistoricalCommand) node;
135: return !reference.hasChildCommands();
136: }
137: return false;
138: }
139:
140: public void valueForPathChanged(TreePath path, Object newValue) {
141:
142: }
143:
144: public int getIndexOfChild(Object parent, Object child) {
145:
146: if (parent == rootNode) {
147: return rootKeySet.indexOf(child);
148: } else if (parent instanceof Date) {
149: List<?> list = rootNode.get(parent);
150: return list == null ? -1 : list.indexOf(child);
151: } else if (parent instanceof HistoricalCommand) {
152: HistoricalCommand reference = (HistoricalCommand) parent;
153: HistoricalCommand subCommand = (HistoricalCommand) child;
154: return reference.indexOf(subCommand);
155: }
156: return -1;
157: }
158:
159: public Class getColumnClass(int column) {
160:
161: return columnTypes[column];
162: }
163:
164: public int getColumnCount() {
165:
166: return 2;
167: }
168:
169: public String getColumnName(int column) {
170:
171: switch (column) {
172: case 0:
173: return "Command";
174: case 1:
175: return "Time";
176: default:
177: return null;
178: }
179: }
180:
181: public Object getValueAt(Object node, int column) {
182:
183: if (node == rootNode) {
184: return rootNode;
185: } else if (column == 0 && node instanceof Date) {
186: return node;
187: }
188: return node;
189: }
190:
191: public synchronized void logCommand(HistoricalCommand command) {
192:
193: EmbeddedDatabase edb = EmbeddedDatabase.getSharedInstance();
194: try {
195: HistoricalCommand reference = edb
196: .addHistoricalCommand(command);
197: addReference(reference);
198: } catch (SQLException e) {
199: }
200: }
201:
202: @Override
203: public void setValueAt(Object aValue, Object node, int column) {
204:
205: }
206:
207: // Normalizes the timestamp to the zero hour minute and seconds of the day//
208: private Date normalizeTimestamp(Date timestamp) {
209:
210: Calendar calendar = Calendar.getInstance();
211: calendar.setTime(timestamp);
212: calendar.set(Calendar.HOUR_OF_DAY, 0);
213: calendar.set(Calendar.MINUTE, 0);
214: calendar.set(Calendar.SECOND, 0);
215: calendar.set(Calendar.MILLISECOND, 0);
216: Date branchDate = calendar.getTime();
217: return branchDate;
218: }
219: }
|