View Javadoc

1   /***
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Exoffice Technologies.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Exoffice Technologies. Exolab is a registered
23   *    trademark of Exoffice Technologies.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 2000-2001,2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42   *
43   * $Id: OpenJMSContext.java,v 1.6 2003/08/17 01:32:23 tanderson Exp $
44   *
45   * Date         Author  Changes
46   * $Date	    jimm    Created
47   */
48  package org.exolab.jms.jndiadministration;
49  
50  import java.awt.Rectangle;
51  import java.awt.event.ActionEvent;
52  import java.awt.event.ActionListener;
53  import java.util.Enumeration;
54  
55  import javax.naming.Context;
56  import javax.naming.NameClassPair;
57  import javax.naming.NamingException;
58  import javax.swing.JMenuItem;
59  import javax.swing.JOptionPane;
60  import javax.swing.JPopupMenu;
61  import javax.swing.JTree;
62  import javax.swing.tree.DefaultMutableTreeNode;
63  import javax.swing.tree.DefaultTreeModel;
64  
65  
66  /***
67   * This class controls all dispay characteristics and menus related to a
68   * queue/topic object. Currently only add/delete, edit and purge is supported.
69   * Add is added from the OpenJMSServer node. Only one menu is created for
70   * all queue/topics since it is modal, it can be shared by all the nodes.
71   *
72   * @version     $Revision: 1.6 $ $Date: 2003/08/17 01:32:23 $
73   * @author      <a href="mailto:mourikis@exolab.org">Jim Mourikis</a>
74   * @see         AdminMgr
75   */
76  public class OpenJMSContext extends DefaultMutableTreeNode
77      implements OpenJMSNode {
78  
79      // The Context Name
80      private String contextName_;
81  
82      // The display name
83      private String displayName_;
84  
85      // Does this context have any nodes
86      private boolean isLeaf_;
87  
88      // Whether this node has been opened and explored already.
89      private boolean isExplored_ = false;
90  
91      //  A reference to the tree this node belongs to.
92      static private JTree tree_ = null;
93  
94      // A flag indicating if the menu has been created yet.
95      static private boolean commandsCreated_ = false;
96  
97      // The popup menu for all contexts
98      static private JPopupMenu commands_ = null;
99  
100 
101     /***
102      * The constructor gets its unique name for this context and a
103      * reference to its parent tree.
104      *
105      * <P>If this is the first context call, the menu for all contexts
106      * is created.
107      *
108      * @param contextName This context name.
109      * @param tree The parent tree this context belongs to.
110      *
111      */
112     public OpenJMSContext(String contextName, String parentName, JTree tree) {
113         if (parentName != null) {
114             contextName_ = parentName + "." + contextName;
115         } else {
116             contextName_ = contextName;
117         }
118         displayName_ = contextName;
119 
120         isLeaf_ = false;
121         if (!commandsCreated_) {
122             tree_ = tree;
123             createCommands();
124             commandsCreated_ = true;
125         }
126     }
127 
128     /***
129      * Create the menu for all contexts and set up the Action events for
130      * each menu item. Since menus are shared, the callbacks called are
131      * static. Once a menu is slected, the slected node can be determined
132      * from the parent object.
133      *
134      */
135     protected void createCommands() {
136         commands_ = new JPopupMenu();
137         JMenuItem m = new JMenuItem("Add Context");
138         m.addActionListener(new ActionListener() {
139 
140             public void actionPerformed(ActionEvent evt) {
141                 createContext();
142             }
143         });
144         commands_.add(m);
145 
146         m = new JMenuItem("Bind Object");
147         m.addActionListener(new ActionListener() {
148 
149             public void actionPerformed(ActionEvent evt) {
150                 bindObject();
151             }
152         });
153         commands_.add(m);
154 
155         m = new JMenuItem("Rename Context");
156         m.addActionListener(new ActionListener() {
157 
158             public void actionPerformed(ActionEvent evt) {
159                 renameContext();
160             }
161         });
162         commands_.add(m);
163 
164         m = new JMenuItem("Delete Context");
165         m.addActionListener(new ActionListener() {
166 
167             public void actionPerformed(ActionEvent evt) {
168                 deleteContext();
169             }
170         });
171         commands_.add(m);
172     }
173 
174     /***
175      * Children are allowed for all contexts
176      *
177      * @return boolean Always returns true.
178      *
179      */
180     public boolean getAllowsChildren() {
181         return true;
182     }
183 
184     /***
185      * Contexts are leaves iff they have no objects registered against
186      * them.
187      *
188      * @return boolean true if no objects are registered.
189      */
190     public boolean isLeaf() {
191         return isLeaf_;
192     }
193 
194     /***
195      * As a performance enhancement, no child is added to the context until
196      * after it is expanded.
197      */
198     public void update() {
199         if (!isExplored_) {
200             Object ob = AdminConnection.instance().lookup(contextName_);
201             if (ob != null) {
202                 if (ob instanceof Context) {
203                     Enumeration e = AdminConnection.instance().getAllContexts
204                         (contextName_);
205                     if (e != null) {
206                         while (e.hasMoreElements()) {
207                             NameClassPair pair =
208                                 (NameClassPair) e.nextElement();
209                             add(new OpenJMSContext
210                                 (pair.getName(), contextName_, tree_));
211                         }
212                     }
213                 } else {
214                     add(new OpenJMSObject(ob.getClass().getName(), tree_));
215                 }
216                 refresh();
217             }
218             isExplored_ = true;
219         }
220     }
221 
222     /***
223      * This node has been right clicked. The locations of this node is given
224      * by the loc object. Use this location to popup the context
225      * menu.
226      *
227      * @param The location of this node.
228      *
229      */
230     public void displayCommands(Rectangle loc) {
231         double x;
232         double y;
233 
234         x = loc.getX();
235         y = loc.getY();
236         y += loc.getHeight();
237 
238         commands_.show(tree_, (int) x, (int) y);
239     }
240 
241     /***
242      * The unique name of this Context
243      *
244      * @return String the context name
245      */
246     public String toString() {
247         return displayName_;
248     }
249 
250     /***
251      * This node has changed. Inform the parent tree that it needs to be
252      * re-drawn.
253      */
254     private void refresh() {
255         DefaultTreeModel model = (DefaultTreeModel) tree_.getModel();
256         model.nodeStructureChanged((DefaultMutableTreeNode) this);
257     }
258 
259     /***
260      * Get the particular instance of the context that has been selected.
261      *
262      * @return OpenJMSContext the instance selected.
263      */
264     static private OpenJMSContext getInstanceSelected() {
265         Object loc = tree_.getLastSelectedPathComponent();
266         return (OpenJMSContext) loc;
267     }
268 
269     /***
270      * Create a new context. Popup the dialog, and prompt the user for the
271      * context name. Attempt to create the context. If creation is successfull
272      * add the node to the tree.
273      */
274     static private void createContext() {
275         OpenJMSContext This = getInstanceSelected();
276         ObjectDialog.instance().display("Enter a unique context name",
277             "Context Creation");
278         if (ObjectDialog.instance().isConfirmed()) {
279             try {
280                 AdminConnection.instance().createContext
281                     (This.contextName_ + "." +
282                     ObjectDialog.instance().getName());
283                 This.add(new OpenJMSContext
284                     (ObjectDialog.instance().getName(), This.contextName_,
285                         tree_));
286                 This.refresh();
287             } catch (NamingException exception) {
288                 JOptionPane.showMessageDialog(
289                     tree_, exception.getMessage(), "Context Create Error",
290                     JOptionPane.ERROR_MESSAGE);
291             }
292         }
293     }
294 
295     /***
296      * Rename the selected context.
297      */
298     static private void renameContext() {
299         OpenJMSContext This = getInstanceSelected();
300         ObjectDialog.instance().display(
301             "Enter a new context name\n" +
302             "for context: " + This.displayName_, "Rename Context");
303         if (ObjectDialog.instance().isConfirmed()) {
304             try {
305                 String newName = This.contextName_.substring
306                     (0, This.contextName_.indexOf(This.displayName_));
307                 newName += ObjectDialog.instance().getName();
308                 AdminConnection.instance().renameContext(
309                     This.contextName_, newName);
310                 This.contextName_ = newName;
311                 This.displayName_ = ObjectDialog.instance().getName();
312                 This.refresh();
313             } catch (NamingException exception) {
314                 JOptionPane.showMessageDialog(
315                     tree_, exception.getMessage(),
316                     "Context Rename Error", JOptionPane.ERROR_MESSAGE);
317             }
318         }
319     }
320 
321     /***
322      * Create a new Object. The object must be given its fully qualified name
323      * and have a default constructor.
324      * For this release no paramaters are passed in.
325      */
326     static private void bindObject() {
327         String errorString = null;
328 
329         OpenJMSContext This = getInstanceSelected();
330         ObjectDialog.instance().display(
331             "Enter the objects fully qualified name", "Bind Object");
332         if (ObjectDialog.instance().isConfirmed()) {
333             try {
334                 Object ob = null;
335 
336                 if (ObjectDialog.instance().getName().equals(
337                     "org.exolab.jms.client.JmsTopic")) {
338                     ob = new org.exolab.jms.client.JmsTopic(This.contextName_);
339                 } else if (ObjectDialog.instance().getName().equals(
340                     "org.exolab.jms.client.JmsQueue")) {
341                     ob = new org.exolab.jms.client.JmsQueue(This.contextName_);
342                     ((org.exolab.jms.client.JmsDestination)
343                         ob).setPersistent(true);
344                 } else {
345                     ob = Class.forName(
346                         ObjectDialog.instance().getName()).newInstance();
347                 }
348 
349                 AdminConnection.instance().rebind(This.contextName_, ob);
350                 This.removeAllChildren();
351                 This.add(new OpenJMSObject(
352                     ObjectDialog.instance().getName(), tree_));
353                 This.refresh();
354             } catch (NamingException exception) {
355                 errorString = exception.getMessage();
356             } catch (IllegalAccessException exception) {
357                 errorString = "Illegal Access error for\n" + "Object: " +
358                     ObjectDialog.instance().getName();
359             } catch (InstantiationException exception) {
360                 errorString = "Object: " + ObjectDialog.instance().getName() +
361                     "\nCannot be instantaiated";
362             } catch (ClassNotFoundException exception) {
363                 errorString = "Object: " + ObjectDialog.instance().getName() +
364                     "\nCannot be found";
365             }
366 
367             if (errorString != null) {
368                 JOptionPane.showMessageDialog(
369                     tree_, errorString, "Object bind error",
370                     JOptionPane.ERROR_MESSAGE);
371             }
372         }
373     }
374 
375     /***
376      * Delete the selected context object. Display a confirmation dialog
377      * and wait for its return. If the user has confirmed the action, first
378      * delete it from the database and if that is successful remove the node
379      * from the tree.
380      *
381      * <P>Note: deleting a context also deletes all subcontexts and bound
382      * objects.
383      */
384     static private void deleteContext() {
385         OpenJMSContext This = getInstanceSelected();
386         QueryDialog.instance().display(
387             "Are you sure you want to delete \nselected Context: "
388             + This.displayName_);
389         if (QueryDialog.instance().isConfirmed()) {
390             try {
391                 AdminConnection.instance().destroyContext(This.contextName_);
392                 This.removeFromParent();
393                 This.refresh();
394             } catch (NamingException exception) {
395                 JOptionPane.showMessageDialog(
396                     tree_, exception.getMessage(), "Context Destroy Error",
397                     JOptionPane.ERROR_MESSAGE);
398             }
399         }
400     }
401 
402 } //-- OpenJMSContext