/* * Copyright 2003,2004 Colin Crist * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package hermes.browser.model; import hermes.HermesRuntimeException; import hermes.browser.components.FitScrollPane; import hermes.impl.DestinationConfigKeyWrapper; import java.awt.Component; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Collection; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.swing.JComponent; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; import org.apache.log4j.Logger; import com.jidesoft.grid.HierarchicalTable; import com.jidesoft.grid.HierarchicalTableComponentFactory; import com.jidesoft.grid.HierarchicalTableModel; import com.jidesoft.grid.SortableTable; import com.jidesoft.grid.TreeLikeHierarchicalPanel; /** * @author colincrist@hermesjms.com last changed by: $Author: colincrist $ * @version $Id: QueueWatchTableModel.java,v 1.2 2004/07/30 17:25:14 colincrist * Exp $ */ public class QueueWatchTableModel extends DefaultTableModel implements HierarchicalTableModel, PropertyChangeListener, HierarchicalTableComponentFactory { /** * */ private static final long serialVersionUID = -6942582606985280259L; private static final Logger log = Logger.getLogger(QueueWatchTableModel.class); public static final int HERMES_POS = 0; public static final int DESTINATION_POS = 1; public static final int DURABLE_POS = 2 ; public static final int DEPTH_POS = 3; public static final int OLDEST_POS = 4; private Map<DestinationConfigKeyWrapper, WatchInfo> watchInfoByKey = new HashMap<DestinationConfigKeyWrapper, WatchInfo>(); private Map childComponentByWatchInfo = new HashMap(); /* * (non-Javadoc) * * @see javax.swing.table.TableModel#getColumnCount() */ public int getColumnCount() { return 5; } public WatchInfo getRowByKey(DestinationConfigKeyWrapper key) { if (watchInfoByKey.containsKey(key)) { return (WatchInfo) watchInfoByKey.get(key); } else { throw new HermesRuntimeException("cannot find WatchInfo key=" + key + " in set " + watchInfoByKey.keySet()) ; } } public void removeAll() { dataVector.clear(); watchInfoByKey.clear(); fireTableDataChanged(); } public synchronized void addRow(WatchInfo info) { dataVector.add(info); watchInfoByKey.put(info.getKey(), info); fireTableRowsInserted(dataVector.size() - 1, dataVector.size()); info.addPropertyChangeListener(this); } public void removeRow(WatchInfo info) { int index = dataVector.indexOf(info); if ( index > 0) { dataVector.remove(info); fireTableRowsDeleted(index, index + 1); } watchInfoByKey.remove(info.getKey()); childComponentByWatchInfo.remove(info); info.removePropertyChangeListener(this); } public void fireRowChanged(WatchInfo info) { int index = dataVector.indexOf(info); log.debug("row " + index + " changed"); fireTableRowsUpdated(index, index); } public WatchInfo getRow(int row) { if ( row >= dataVector.size()) { return null; } else { return (WatchInfo) dataVector.elementAt(row); } } public Iterator iterator() { return dataVector.iterator(); } public Collection rows() { return dataVector; } public Collection getDestinationWatchConfigs() { ArrayList rval = new ArrayList() ; for (Iterator iter = dataVector.iterator(); iter.hasNext();) { WatchInfo info = (WatchInfo) iter.next(); rval.add(info.getConfig()) ; } return rval ; } public WatchInfo findWatchInfo(String hermesId, String destinationName) { for (Iterator iter = dataVector.iterator(); iter.hasNext();) { WatchInfo info = (WatchInfo) iter.next(); if ( info.getHermesId().equals(hermesId) && info.getConfig().getName().equals(destinationName)) { return info; } } return null; } /* * (non-Javadoc) * * @see javax.swing.table.TableModel#getValueAt(int, int) */ public Object getValueAt(int y, int x) { synchronized (this) { WatchInfo info = (WatchInfo) dataVector.elementAt(y); switch (x) { case HERMES_POS: return info.getHermesId(); case DESTINATION_POS: return info.getConfig().getName(); case DURABLE_POS: return info.getConfig().isDurable() ? info.getConfig().getClientID() : "N/A" ; case DEPTH_POS: return new Integer(info.getDepth()); case OLDEST_POS: if ( info.getOldest() == 0) { return null; } else { return new Date(info.getOldest()); } } return "Unknown"; } } /* * (non-Javadoc) * * @see javax.swing.table.TableModel#isCellEditable(int, int) */ public boolean isCellEditable(int y, int arxg1) { return false; } /* * (non-Javadoc) * * @see javax.swing.table.TableModel#getRowCount() */ public int getRowCount() { return dataVector.size(); } /* * (non-Javadoc) * * @see javax.swing.table.TableModel#getColumnClass(int) */ public Class getColumnClass(int column) { switch (column) { case HERMES_POS: return String.class; case DESTINATION_POS: return String.class; case DURABLE_POS: return String.class ; case DEPTH_POS: return Integer.class; case OLDEST_POS: return Date.class; } return Object.class; } private JTable createTable(WatchInfo info) { SortableTable table = new SortableTable() { /** * */ private static final long serialVersionUID = 1087047228958497075L; public boolean isCellEditable(int arg0, int arg1) { return false; } }; final Map statistics = info.getStatistics() ; final MapTableModel model = statistics.size() > 10 ? new KeyValueMapTableModel(statistics) : new OneRowMapTableModel(statistics); info.addPropertyChangeListener(WatchInfo.STATISTICS, new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if ( evt.getNewValue() != null && evt.getNewValue() instanceof Map) { model.setMap((Map) evt.getNewValue()); } } }); table.setModel(model); table.setSortable(true) ; return table; } /** * Gets the statistics table for the given row, its created lazily and * cachd. */ public synchronized Object getChildValueAt(int y) { return getRow(y); } public Component createChildComponent(HierarchicalTable arg0, Object object, int row) { WatchInfo info = (WatchInfo) object; JComponent rval; if ( !childComponentByWatchInfo.containsKey(info)) { rval = new TreeLikeHierarchicalPanel(new FitScrollPane(createTable(info))); childComponentByWatchInfo.put(info, rval); } else { rval = (JComponent) childComponentByWatchInfo.get(info); } return rval; } public void destroyChildComponent(HierarchicalTable arg0, Component arg1, int arg2) { // TODO Auto-generated method stub } public boolean hasChild(int y) { return true; } public boolean isExpandable(int row) { return isHierarchical(row) ; } public boolean isHierarchical(int y) { return true; } public boolean hasAlert() { /* * @@TODO this is terribly inefficient if ever anyone watches a large number of queues! */ for (Iterator iter = watchInfoByKey.entrySet().iterator() ; iter.hasNext() ;) { Map.Entry entry = (Map.Entry) iter.next() ; WatchInfo info = (WatchInfo) entry.getValue() ; if (info.isInAlert()) { return true ; } } return false ; } public void propertyChange(PropertyChangeEvent event) { final WatchInfo watchInfo = (WatchInfo) watchInfoByKey.get((DestinationConfigKeyWrapper) event.getSource()); if ( watchInfo != null) { if ( event.getPropertyName().equals(WatchInfo.STATISTICS)) { // NOP, listener registered in getChildComponent(). } else { log.debug("property=" + event.getPropertyName() + " old=" + event.getOldValue() + " new=" + event.getNewValue()); fireRowChanged(watchInfo); } } else { log.error("propertyChange: cannot find WatchInfo key= " + event.getSource()); } } }