/* * 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.ConnectionListener; import hermes.Hermes; import hermes.HermesConfigurationListener; import hermes.HermesException; import hermes.HermesRepository; import hermes.HermesRepositoryListener; import hermes.HermesRuntimeException; import hermes.JNDIConnectionFactory; import hermes.browser.HermesBrowser; import hermes.browser.model.tree.AbstractTreeNode; import hermes.browser.model.tree.DestinationConfigTreeNode; import hermes.browser.model.tree.DestinationFragmentTreeNode; import hermes.browser.model.tree.HermesTreeNode; import hermes.browser.model.tree.HermesTreeNodeComparator; import hermes.browser.model.tree.MessageStoreTreeNode; import hermes.browser.model.tree.MessageStoreURLTreeNode; import hermes.browser.model.tree.NamingConfigTreeNode; import hermes.browser.model.tree.RepositoryTreeNode; import hermes.browser.tasks.UpdateMessageStoresTask; import hermes.config.DestinationConfig; import hermes.config.JDBCStore; import hermes.config.NamingConfig; import hermes.config.WatchConfig; import hermes.impl.DestinationConfigKeyWrapper; import hermes.store.MessageStore; import hermes.store.StoreUtils; import hermes.swing.SwingRunner; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Timer; import java.util.TreeMap; import javax.jms.JMSException; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import org.apache.log4j.Category; /** * @author colincrist@hermesjms.com * @version $Id: BrowserTreeModel.java,v 1.26 2006/10/30 17:44:07 colincrist Exp $ */ public class BrowserTreeModel extends DefaultTreeModel implements HermesConfigurationListener, HermesRepositoryListener, ConnectionListener { /** * */ private static final long serialVersionUID = -6549632581191585022L; private static final Category cat = Category.getInstance(BrowserTreeModel.class); private static final Timer timer = new Timer(); private DefaultMutableTreeNode ctxRootNode = new DefaultMutableTreeNode("contexts"); private Map<DestinationConfigKeyWrapper, DestinationConfigTreeNode> destinationMap = new HashMap<DestinationConfigKeyWrapper, DestinationConfigTreeNode>(); // private Map<String, Map<DestinationConfigKeyWrapper, // DestinationConfigTreeNode>> topicMap = new HashMap<String, Map<String, // DestinationConfigKeyWrapper>>(); private Map<String, MessageStoreURLTreeNode> stores = new HashMap<String, MessageStoreURLTreeNode>(); private Map<String, HermesTreeNode> hermesMap = new TreeMap<String, HermesTreeNode>(); private DefaultMutableTreeNode jmsRootNode = new DefaultMutableTreeNode("sessions"); private Map<String, NamingConfigTreeNode> namingNodeById = new HashMap<String, NamingConfigTreeNode>(); private Map<HermesRepository, RepositoryTreeNode> rep2Node = new HashMap<HermesRepository, RepositoryTreeNode>(); private DefaultMutableTreeNode repositoryNode = new DefaultMutableTreeNode("files"); private DefaultMutableTreeNode storesNode = new DefaultMutableTreeNode("stores"); private DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("jms"); public BrowserTreeModel() throws HermesException { super(new DefaultMutableTreeNode()); setRoot(rootNode); rootNode.removeAllChildren(); jmsRootNode.removeAllChildren(); ctxRootNode.removeAllChildren(); rootNode.add(jmsRootNode); rootNode.add(ctxRootNode); rootNode.add(storesNode); if (!HermesBrowser.getBrowser().isRestricted()) { rootNode.add(repositoryNode); } // // Update any MessageStores.... if (!HermesBrowser.getBrowser().isMessageStoresDisabled()) { MessageStoreURLTreeNode localURLNode = new MessageStoreURLTreeNode("local", StoreUtils.getDefaultConnectionURL()); addMessageStoreURLTreeNode(localURLNode); } for (Iterator iter = HermesBrowser.getBrowser().getConfig().getJdbcStore().iterator(); iter.hasNext();) { JDBCStore storeConfig = (JDBCStore) iter.next(); try { addMessageStoreURLTreeNode(new MessageStoreURLTreeNode(storeConfig)); } catch (ClassNotFoundException ex) { HermesBrowser.getBrowser().showErrorDialog("Cannot load JDBC driver " + storeConfig.getDriver()); } } Hermes.events.addConnectionListener(this); } public NamingConfigTreeNode getNamingConfigTreeNode(String name) throws HermesException { if (namingNodeById.containsKey(name)) { return namingNodeById.get(name) ; } else { throw new HermesException("No such naming configuration " + name) ; } } public void addMessageStoreURLTreeNode(MessageStoreURLTreeNode node) { stores.put(node.getURL(), node); storesNode.add(node); nodesWereInserted(storesNode, new int[] { storesNode.getChildCount() - 1 }); HermesBrowser.getBrowser().getThreadPool().invokeLater(new UpdateMessageStoresTask(this, node)); } public void onConnectionClosed(Hermes hermes) { if (hermesMap.containsKey(hermes.getId())) { final HermesTreeNode node = hermesMap.get(hermes.getId()); node.setConnectionOpen(false); } else { cat.error("onConnectionClosed(), no such Hermes id=" + hermes.getId()); } } public void onConnectionOpen(Hermes hermes) { if (hermesMap.containsKey(hermes.getId())) { final HermesTreeNode node = hermesMap.get(hermes.getId()); node.setConnectionOpen(true); } else { cat.error("onConnectionOpen(), no such Hermes id=" + hermes.getId()); } } public Collection<MessageStore> getMessageStores() { final Collection<MessageStore> stores = new ArrayList<MessageStore>(); for (int i = 0; i < storesNode.getChildCount(); i++) { if (storesNode.getChildAt(i) instanceof MessageStoreURLTreeNode) { final MessageStoreURLTreeNode urlNode = (MessageStoreURLTreeNode) storesNode.getChildAt(i); for (int j = 0; j < urlNode.getChildCount(); j++) { final MessageStoreTreeNode node = (MessageStoreTreeNode) urlNode.getChildAt(j); stores.add(node.getMessageStore()); } } } return stores; } public HermesTreeNode getFirstHermesTreeNode() { final Iterator<Map.Entry<String, HermesTreeNode>> iter = hermesMap.entrySet().iterator(); return iter.hasNext() ? iter.next().getValue() : null; } public void onMessageStoreAdded(final MessageStore store) { SwingRunner.invokeLater(new Runnable() { public void run() { final MessageStoreURLTreeNode parent = stores.get(store.getURL()); if (parent != null) { parent.add(new MessageStoreTreeNode(BrowserTreeModel.this, store.getId(), store)); nodeStructureChanged(parent); } else { throw new HermesRuntimeException("Cannot find JDBC URL " + store.getURL()); } } }); } public void onMessageStoreRemoved(final MessageStore store) { SwingRunner.invokeLater(new Runnable() { public void run() { final MessageStoreURLTreeNode parent = stores.get(store.getURL()); if (parent != null) { for (int i = 0; i < parent.getChildCount(); i++) { if (parent.getChildAt(i) instanceof MessageStoreTreeNode) { final MessageStoreTreeNode node = (MessageStoreTreeNode) parent.getChildAt(i); if (node.getId().equals(store.getId())) { parent.remove(i); nodeStructureChanged(parent); break; } } } } } }); } public Collection<String> getAllHermesIds() { return hermesMap.keySet(); } /* * (non-Javadoc) * * @see org.metastuff.hermes.HermesConfigurationListener#onDestinationAdded(org.metastuff.hermes.Hermes, * org.metastuff.hermes.config.DestinationConfig) */ public void onDestinationAdded(final Hermes hermes, final DestinationConfig destinationConfig) { // cat.debug("onDestinationAdded, hermes=" + hermes.getId() + " " + // Domain.getDomain(destinationConfig.getDomain()).toString() + "=" + // destinationConfig.getName()); SwingRunner.invokeLater(new Runnable() { public void run() { if (hermesMap.containsKey(hermes.getId())) { final HermesTreeNode cfNode = (HermesTreeNode) hermesMap.get(hermes.getId()); final DestinationConfigTreeNode dNode = new DestinationConfigTreeNode(cfNode, destinationConfig, cfNode.isCascadeNamespace()); final DestinationConfigKeyWrapper key = new DestinationConfigKeyWrapper(hermes, destinationConfig); if (destinationMap.containsKey(key)) { cat.error("duplicate destination key=" + key); } else { destinationMap.put(key, dNode); if (cfNode.isCascadeNamespace()) { try { if (cfNode.getHermes().getConnectionFactory() instanceof JNDIConnectionFactory) { TreeUtils.add(BrowserTreeModel.this, cfNode.getHermes(), destinationConfig.getName(), "/", cfNode, dNode); } else { TreeUtils.add(BrowserTreeModel.this, cfNode.getHermes(), destinationConfig.getName(), ".", cfNode, dNode); } } catch (JMSException ex) { HermesBrowser.getBrowser().showErrorDialog(ex); } } else { cfNode.add(dNode); nodesWereInserted(cfNode, new int[] { cfNode.getIndex(dNode) }); } } } } }); } public void onDestinationRemoved(final Hermes hermes, final DestinationConfig destinationConfig) { SwingRunner.invokeLater(new Runnable() { public void run() { if (hermesMap.containsKey(hermes.getId())) { final HermesTreeNode cfNode = (HermesTreeNode) hermesMap.get(hermes.getId()); final DestinationConfigKeyWrapper key = new DestinationConfigKeyWrapper(hermes, destinationConfig); if (destinationMap.containsKey(key)) { final DestinationConfigTreeNode node = destinationMap.remove(key); if (node != null) { if (node.getParent() == cfNode) { int index = cfNode.getIndex(node); cfNode.remove(node); nodesWereRemoved(cfNode, new int[] { index }, new Object[] { node }); } else if (node.getParent() instanceof DestinationFragmentTreeNode) { AbstractTreeNode cleanup = node; do { AbstractTreeNode cleanupParent = (AbstractTreeNode) cleanup.getParent(); int index = cleanupParent.getIndex(cleanup); cleanupParent.remove(cleanup); nodesWereRemoved(cleanupParent, new int[] { index }, new Object[] { cleanup }); cleanup = cleanupParent; } while (cleanup.getChildCount() == 0 && cleanup instanceof DestinationFragmentTreeNode); } } } } } }); } public void onHermesAdded(Hermes hermes) { // cat.debug("onHermesAdded, hermes=" + hermes); try { if (hermesMap.containsKey(hermes.getId())) { onHermesRemoved(hermes); } HermesTreeNode cfNode = new HermesTreeNode(hermes.getId(), hermes, this); HermesTreeNodeComparator comparator = new HermesTreeNodeComparator(); hermesMap.put(hermes.getId(), cfNode); int i = 0; for (; i < jmsRootNode.getChildCount(); i++) { HermesTreeNode node = (HermesTreeNode) jmsRootNode.getChildAt(i); if (comparator.compare(cfNode, node) < 0) { break; } } jmsRootNode.insert(cfNode, i); nodesWereInserted(jmsRootNode, new int[] { i }); } catch (JMSException ex) { cat.error(ex.getMessage(), ex); } } public void onHermesRemoved(Hermes hermes) { // cat.debug("onHermesRemoved, hermes=" + hermes); if (hermesMap.containsKey(hermes.getId())) { HermesTreeNode cfNode = (HermesTreeNode) hermesMap.get(hermes.getId()); int index = jmsRootNode.getIndex(cfNode); if (jmsRootNode.isNodeChild(cfNode)) { jmsRootNode.remove(cfNode); nodesWereRemoved(jmsRootNode, new int[] { index }, new Object[] { cfNode }); } hermesMap.remove(hermes.getId()); for (Iterator<DestinationConfigKeyWrapper> iter = destinationMap.keySet().iterator(); iter.hasNext();) { DestinationConfigKeyWrapper key = iter.next(); if (key.getHermes().equals(hermes)) { iter.remove(); } } } } public void onNamingAdded(NamingConfig namingConfig) { final NamingConfigTreeNode node = new NamingConfigTreeNode(namingConfig); namingNodeById.put(namingConfig.getId(), node); ctxRootNode.add(node); SwingUtilities.invokeLater(new Runnable() { public void run() { if (ctxRootNode.getChildCount() == 0) { nodeStructureChanged(ctxRootNode); } else { nodesWereInserted(ctxRootNode, new int[] { ctxRootNode.getIndex(node) }); } } }); } public void onNamingRemoved(NamingConfig namingConfig) { final NamingConfigTreeNode node = (NamingConfigTreeNode) namingNodeById.get(namingConfig.getId()); if (node != null) { final int index = ctxRootNode.getIndex(node); if (node != null) { // HJMS-7 Check that the node is a child before removing it. if (ctxRootNode.isNodeChild(node)) { ctxRootNode.remove(node); SwingUtilities.invokeLater(new Runnable() { public void run() { nodesWereRemoved(ctxRootNode, new int[] { index }, new Object[] { node }); } }); } namingNodeById.remove(namingConfig.getId()); } } } /* * (non-Javadoc) * * @see hermes.HermesRepositoryListener#onRepositoryAdded(hermes.HermesRepository) */ public void onRepositoryAdded(HermesRepository repository) { final RepositoryTreeNode node = new RepositoryTreeNode(repository); rep2Node.put(repository, node); repositoryNode.add(node); SwingUtilities.invokeLater(new Runnable() { public void run() { nodesWereInserted(repositoryNode, new int[] { repositoryNode.getIndex(node) }); } }); } /* * (non-Javadoc) * * @see hermes.HermesRepositoryListener#onRepositoryRemoved(hermes.HermesRepository) */ public void onRepositoryRemoved(HermesRepository repository) { final RepositoryTreeNode node = (RepositoryTreeNode) rep2Node.remove(repository); final int index = repositoryNode.getIndex(node); rep2Node.remove(repository); repositoryNode.remove(node); SwingUtilities.invokeLater(new Runnable() { public void run() { nodeStructureChanged(repositoryNode); } }); } public void onWatchAdded(WatchConfig watchConfig) { // NOP } public void onWatchRemoved(WatchConfig watchConfig) { // NOP } }