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-2003 (C) Exoffice Technologies Inc. All Rights Reserved.
42 *
43 * $Id: AdminMgr.java,v 1.4 2003/08/24 07:09:29 tanderson Exp $
44 *
45 * Date Author Changes
46 */
47
48
49 package org.exolab.jms.tools.admin;
50
51 import java.awt.BorderLayout;
52 import java.awt.Dimension;
53 import java.awt.Toolkit;
54 import java.awt.event.ActionEvent;
55 import java.awt.event.ActionListener;
56 import java.awt.event.MouseAdapter;
57 import java.awt.event.MouseEvent;
58 import java.awt.event.WindowAdapter;
59 import java.awt.event.WindowEvent;
60 import java.io.BufferedReader;
61 import java.io.IOException;
62 import java.io.InputStream;
63 import java.io.InputStreamReader;
64 import java.io.PrintStream;
65 import java.util.ArrayList;
66
67 import javax.swing.JComboBox;
68 import javax.swing.JFrame;
69 import javax.swing.JMenu;
70 import javax.swing.JMenuBar;
71 import javax.swing.JMenuItem;
72 import javax.swing.JOptionPane;
73 import javax.swing.JScrollPane;
74 import javax.swing.JSeparator;
75 import javax.swing.JTextField;
76 import javax.swing.JTree;
77 import javax.swing.SwingConstants;
78 import javax.swing.SwingUtilities;
79 import javax.swing.event.TreeExpansionEvent;
80 import javax.swing.event.TreeExpansionListener;
81 import javax.swing.tree.DefaultMutableTreeNode;
82 import javax.swing.tree.DefaultTreeModel;
83 import javax.swing.tree.TreePath;
84
85 import org.apache.log4j.xml.DOMConfigurator;
86 import org.apache.oro.text.regex.*;
87
88 import org.exolab.jms.config.AdminConfiguration;
89 import org.exolab.jms.config.Configuration;
90 import org.exolab.jms.config.ConfigurationManager;
91 import org.exolab.jms.util.CommandLine;
92
93
94 /***
95 * This class is the Gui controller for the JMS administration. It
96 * displays data as a hierarchical set of tree nodes.
97 *
98 * <P>The Root is all the contactable JMS servers, idealy there can be several
99 * of these all on different ports, with one common admin port they all listen
100 * to. A user selects a JMSServer then connects via the menu item. This
101 * allows the admin GUI to connect to the server via the main port and begin
102 * displaying all its Queue/Topics and registered consumers.
103 *
104 * If there are no queue/topics for a consumer the node will be empty.
105 * Selecting a consumer allows a user to see what its details are, i.e
106 * last message received and acked, whether the consumer is currently
107 * active/deactive paused etc.
108 *
109 * <P>The Gui can also be used to add/remove queue/topics and consumer
110 * registrations.
111 *
112 * Reliable Topics are read only, since they cannot be persisted, they simply
113 * display a snapshot at the time of connection.
114 *
115 * <P>For the moment this is not truly dynamic, that is a refresh needs to be
116 * activated on the Gui to cause an update (other than changes made
117 * through the Gui istelf).
118 *
119 * @version $Revision: 1.4 $ $Date: 2003/08/24 07:09:29 $
120 * @author <a href="mailto:mourikis@exolab.org">Jim Mourikis</a>
121 */
122 public class AdminMgr extends JFrame {
123
124 // Gui Declarations
125 private JMenuBar _menuBar;
126 private JMenu _file;
127 private JMenuItem _exit;
128 private JMenu _actions;
129 private JMenu _connections;
130 private JMenuItem _refresh;
131 private JMenuItem _online;
132 private JMenuItem _offline;
133 private JMenuItem _disconnect;
134 private JSeparator _separator;
135 private JMenuItem _startup;
136 private JMenuItem _shutdown;
137 private JScrollPane _jmsServers;
138 private JTree _serverProperties;
139 private JTextField _messageArea;
140 private JComboBox _jmsCombo;
141
142 // If this Admin object is connected to any OpenJMS
143 private boolean _connected = false;
144
145 /***
146 * The server start command
147 */
148 private static String _serverStart = null;
149
150 /***
151 * The server configuration file path
152 */
153 private static String _serverConfig = null;
154
155 // redirect stream to local console.
156 private StreamRedirect _output = null;
157
158 /***
159 * The default constructor performs all gui creations.
160 *
161 */
162 public AdminMgr() {
163 this("");
164 }
165
166 public AdminMgr(String title) {
167 initComponents(title);
168 pack();
169 }
170
171 /*** This method is called from within the constructor to
172 * initialize the form. All the GUI objects are created, and callbacks
173 * registered.
174 */
175 private void initComponents(String title) {
176 _menuBar = new JMenuBar();
177 _file = new JMenu();
178 _exit = new JMenuItem();
179 _actions = new JMenu();
180 _connections = new JMenu();
181 _refresh = new JMenuItem();
182 _online = new JMenuItem();
183 _offline = new JMenuItem();
184 _disconnect = new JMenuItem();
185 _separator = new JSeparator();
186 _startup = new JMenuItem();
187 _shutdown = new JMenuItem();
188 _jmsServers = new JScrollPane();
189 _jmsCombo = new JComboBox();
190 _serverProperties = new JTree();
191 setTitle("OpenJMS Administrator: " + title);
192 DefaultTreeModel serverModel =
193 OpenJMSServer.createServerList(_serverProperties);
194 _serverProperties.setModel(serverModel);
195 AdminInfo info = new AdminInfo();
196 _serverProperties.setCellRenderer(info);
197
198 _messageArea = new JTextField();
199 _file.setText("File");
200 _exit.setToolTipText("Exit administration");
201 _exit.setText("Exit");
202 _exit.setMnemonic('x');
203
204 _serverProperties.setRootVisible(false);
205 _serverProperties.setShowsRootHandles(true);
206 _serverProperties.putClientProperty("JTree.lineStyle", "Angled");
207 _serverProperties.setCellEditor(new OpenJMSEditor(_serverProperties,
208 _jmsCombo));
209 _serverProperties.setEditable(false);
210 setupCallbacks();
211 _file.add(_exit);
212 _file.setMnemonic('F');
213 _menuBar.add(_file);
214 _actions.setText("Actions");
215 _actions.setMnemonic('A');
216 _connections.setText("Connections");
217 _connections.setMnemonic('C');
218 _refresh.setToolTipText("Refresh the display");
219 _online.setToolTipText("Connect to a running OpenJMS Server");
220 _offline.setToolTipText("Connect directly to an OpenJMS database");
221 _refresh.setText("Refresh");
222 _refresh.setMnemonic('R');
223 _actions.add(_refresh);
224
225 _online.setText("Online");
226 _online.setMnemonic('O');
227 _offline.setText("Offline");
228 _offline.setMnemonic('f');
229 _connections.add(_online);
230 _connections.add(_offline);
231 _actions.add(_connections);
232 _disconnect.setToolTipText
233 ("Disconnect from any connected OpenJMS Servers");
234 _disconnect.setText("Disconnect");
235 _disconnect.setMnemonic('D');
236 _actions.add(_disconnect);
237
238 _actions.add(_separator);
239 _startup.setToolTipText("Start the OpenJMS server");
240 _startup.setText("Start OpenJMS");
241 _startup.setMnemonic('S');
242 _shutdown.setToolTipText("Shutdown the connected OpenJMS server");
243 _shutdown.setText("Shutdown OpenJMS");
244 _shutdown.setMnemonic('h');
245 _actions.add(_startup);
246 _actions.add(_shutdown);
247 _menuBar.add(_actions);
248
249 _jmsServers.setViewportView(_serverProperties);
250
251
252 getContentPane().add(_jmsServers, BorderLayout.CENTER);
253
254 _messageArea.setToolTipText("Message Area");
255 _messageArea.setEditable(false);
256 _messageArea.setForeground(java.awt.Color.red);
257 _messageArea.setText("Not Connected");
258 _messageArea.setHorizontalAlignment(SwingConstants.CENTER);
259
260
261 getContentPane().add(_messageArea, BorderLayout.SOUTH);
262 setJMenuBar(_menuBar);
263 _startup.setEnabled(true);
264 _shutdown.setEnabled(false);
265 _refresh.setEnabled(false);
266 _disconnect.setEnabled(false);
267 }
268
269 /***
270 * The exit method for the application, when the user shutdowns the form.
271 *
272 * @param evt The event that triggered this action.
273 *
274 */
275 private void exitAdmin(ActionEvent evt) {
276 System.exit(0);
277 }
278
279 /***
280 * Exit the Application when a user selects File->Exit from the menu
281 *
282 * @param evt The window event that triggered this call.
283 *
284 */
285 private void exitForm(WindowEvent evt) {
286 System.exit(0);
287 }
288
289 /***
290 * Refresh the display, and repaint all items.
291 *
292 * @param evt The event that triggered this operation.
293 *
294 */
295 private void refresh(ActionEvent evt) {
296 if (AbstractAdminConnection.instance() instanceof OnlineConnection) {
297 setConnected(false, null);
298 setConnected(true, "Connected - Online Mode");
299 _startup.setEnabled(false);
300 _shutdown.setEnabled(true);
301
302 } else {
303 ((OpenJMSServer) (_serverProperties.getModel().getRoot()
304 )).refresh();
305 }
306 }
307
308 /***
309 * Start the OpenJMSServer.
310 *
311 */
312 private void startup(ActionEvent evt) {
313
314 try {
315 String args[] = getStartCommand();
316
317 System.out.print("running ");
318 for (int i = 0, j = args.length; i < j; i++) {
319 System.out.print(args[i] + " ");
320 }
321 System.out.println();
322
323 if (_output != null) {
324 // Stop the old redirect if any.
325 _output.interrupt();
326 }
327 Process proc = Runtime.getRuntime().exec(args);
328 // Redirect output
329 _output = new StreamRedirect(proc.getInputStream());
330 // kick it off
331 _output.start();
332 } catch (Exception err) {
333 JOptionPane.showMessageDialog
334 (this, "Failed to Startup OpenJMSServer:\n" + err
335 + "\nCheck config file",
336 "OpenJMSServer Startup", JOptionPane.ERROR_MESSAGE);
337 }
338 }
339
340 /***
341 * When a user wishes to connect to all known OpenJMSServers.
342 * Attempt to create an RMI connection to the OpenJMSServer. If the server
343 * is not running, this will fail. The user can start the server through
344 * the start server command, and attempt to re-connect, or use the offline
345 * method below.
346 *
347 * @param evt The event that triggered this operation.
348 *
349 */
350 private void onlineConnect(ActionEvent evt) {
351 try {
352 // if online.
353 new OnlineConnection(this);
354 _startup.setEnabled(false);
355 _shutdown.setEnabled(true);
356 setConnected(true, "Connected - Online Mode");
357 } catch (Exception err) {
358 JOptionPane.showMessageDialog
359 (this, err.getMessage(), "Online Connection Error",
360 JOptionPane.ERROR_MESSAGE);
361 }
362 }
363
364
365 /***
366 * Connect to the database in offline mode. This action causes
367 * the file chooser to be displayed, and the user must select an existing
368 * database, or enter a new name to create a new database.
369 *
370 * All databases are suffixed with a ".db".
371 *
372 * @param evt The event that triggered this operation.
373 *
374 */
375 private void offlineConnect(ActionEvent evt) {
376 try {
377 // if online.
378 new OfflineConnection(this);
379 _startup.setEnabled(false);
380 _shutdown.setEnabled(false);
381 setConnected(true, "Connected - OFFLine Mode");
382 } catch (Exception err) {
383 JOptionPane.showMessageDialog
384 (this, err.getMessage(), "Database Error",
385 JOptionPane.ERROR_MESSAGE);
386 }
387 }
388
389 /***
390 * Disconnect from a connected OpenJMSServer. Close the database, set the
391 * connected flag to false, stop displaying the OpenJMS folder.
392 *
393 * @param evt The event that triggered this operation.
394 *
395 */
396 private void disconnect(ActionEvent evt) {
397 try {
398 AbstractAdminConnection.instance().close();
399 setConnected(false, null);
400 } catch (Exception e) {
401 JOptionPane.showMessageDialog
402 (this, e.getMessage(), "Database Close Error",
403 JOptionPane.ERROR_MESSAGE);
404 }
405 }
406
407 /***
408 * A conveniance routine to open/close all database connections,
409 * and fix up the display.
410 *
411 * <P>When connecting, show the root object, get any persistent queue/topic
412 * names currently in the db, and display them.
413 * Turn off the connection menu, enable the disconnection and shutdown
414 * and the context menus. Set the message area text to connected.
415 *
416 * <P>When disconnecting, turn off the root, destroy all Gui objects
417 * close the db connection, turn off all context sensitive menus,
418 * disable disconnection menu and enable connection. Set the message
419 * text to disconnected.
420 *
421 * @param c a flag inidication if this is a connection or disconnection.
422 *
423 */
424 private void setConnected(boolean c, String st) {
425 if (c) {
426 _serverProperties.setRootVisible(true);
427 ((OpenJMSServer)
428 (_serverProperties.getModel().getRoot())).displayConnections();
429 _connections.setEnabled(false);
430 _refresh.setEnabled(true);
431 // _shutdown.setEnabled(true);
432 _disconnect.setEnabled(true);
433 // _startup.setEnabled(false);
434 _messageArea.setForeground(java.awt.Color.green.darker().darker());
435 _messageArea.setText(st);
436 _connected = true;
437 } else {
438 _serverProperties.setRootVisible(false);
439 OpenJMSServer root =
440 (OpenJMSServer) _serverProperties.getModel().getRoot();
441 root.removeAllChildren();
442 DefaultTreeModel model =
443 (DefaultTreeModel) _serverProperties.getModel();
444 model.nodeStructureChanged((DefaultMutableTreeNode) root);
445 _connections.setEnabled(true);
446 _startup.setEnabled(true);
447 _shutdown.setEnabled(false);
448 _refresh.setEnabled(false);
449 _disconnect.setEnabled(false);
450 _messageArea.setForeground(java.awt.Color.red);
451 _messageArea.setText("Not Connected");
452 _connected = false;
453 }
454 }
455
456 /***
457 * Set up all Action menu callbacks, and mouse events for the tree and its
458 * nodes. Check all mose 2 key presses on a node, select the node,
459 * then call the nodes appropriate display methos to display its
460 * specific popup menus.
461 *
462 * <P>When first connected, all queue/topics displayed are not expaned.
463 * This is just a performance saver, since their could potentially
464 * be hundreds of objects. A callback is set up, so that when a queue/topic
465 * is expanded, it is lokked up only then to determine what consumers
466 * are registered with it.
467 */
468 private void setupCallbacks() {
469
470 addWindowListener(new WindowAdapter() {
471
472 public void windowClosing(WindowEvent evt) {
473 exitForm(evt);
474 }
475 }
476 );
477
478
479 _serverProperties.addMouseListener(new MouseAdapter() {
480
481 public void mousePressed(MouseEvent e) {
482 if (!_connected) {
483 return;
484 }
485
486 if (SwingUtilities.isRightMouseButton(e)) {
487 int selRow = _serverProperties.getRowForLocation
488 (e.getX(), e.getY());
489
490 _serverProperties.setSelectionRow(selRow);
491 Object loc =
492 _serverProperties.getLastSelectedPathComponent();
493 if (loc instanceof OpenJMSNode) {
494 OpenJMSNode node = (OpenJMSNode) loc;
495 node.displayCommands
496 (_serverProperties.getRowBounds(selRow));
497 } else if (loc instanceof OpenJMSServer) {
498 ((OpenJMSServer) loc).displayCommands
499 (_serverProperties.getRowBounds(selRow));
500 }
501 }
502 }
503 }
504 );
505
506 _serverProperties.addTreeExpansionListener(new TreeExpansionListener() {
507
508 public void treeCollapsed(TreeExpansionEvent e) {
509 // todo Anything.....
510 }
511
512 public void treeExpanded(TreeExpansionEvent e) {
513 TreePath path = e.getPath();
514 Object loc = path.getLastPathComponent();
515 if (loc instanceof OpenJMSNode) {
516 OpenJMSNode node = (OpenJMSNode) loc;
517 node.update();
518 }
519 }
520 }
521 );
522
523 /***
524 _serverProperties.addTreeSelectionListener(new TreeSelectionListener()
525 {
526 public void valueChanged(TreeSelectionEvent e)
527 {
528 TreePath path = e.getPath();
529 Object loc = path.getLastPathComponent();
530 if (loc instanceof OpenJMSNode)
531 {
532 OpenJMSNode node = (OpenJMSNode)loc;
533 System.out.println(node);
534 }
535 }
536 }
537 );
538
539 **/
540 _exit.addActionListener(new ActionListener() {
541
542 public void actionPerformed(ActionEvent evt) {
543 exitAdmin(evt);
544 }
545 }
546 );
547
548
549 _refresh.addActionListener(new ActionListener() {
550
551 public void actionPerformed(ActionEvent evt) {
552 refresh(evt);
553 }
554 }
555 );
556
557
558 _online.addActionListener(new ActionListener() {
559
560 public void actionPerformed(ActionEvent evt) {
561 onlineConnect(evt);
562 }
563 }
564 );
565
566 _offline.addActionListener(new ActionListener() {
567
568 public void actionPerformed(ActionEvent evt) {
569 offlineConnect(evt);
570 }
571 }
572 );
573
574 _disconnect.addActionListener(new ActionListener() {
575
576 public void actionPerformed(ActionEvent evt) {
577 disconnect(evt);
578 }
579 }
580 );
581
582 _startup.addActionListener(new ActionListener() {
583
584 public void actionPerformed(ActionEvent evt) {
585 startup(evt);
586 }
587 }
588 );
589
590 _shutdown.addActionListener(new ActionListener() {
591
592 public void actionPerformed(ActionEvent evt) {
593 try {
594 AbstractAdminConnection.instance().stopServer();
595 setConnected(false, null);
596 } catch (NullPointerException err) {
597 JOptionPane.showMessageDialog
598 (_file, "Must connect with online mode \nto "
599 + "shutdown server", "Shutdown Error",
600 JOptionPane.ERROR_MESSAGE);
601 }
602 }
603 }
604 );
605 }
606
607 /***
608 * The main entry point for this admin gui.
609 * The main form and any support dialogs are created.
610 * An initial size is given, and the gui placed in the middle of the screen
611 *
612 * @param args the command line arguments
613 *
614 */
615 public static void main(String args[]) {
616 try {
617 CommandLine cmdline = new CommandLine(args);
618
619 boolean helpSet = cmdline.exists("help");
620 boolean configSet = cmdline.exists("config");
621 boolean stopServer = cmdline.exists("stopServer");
622 String username = cmdline.value("u");
623 String password = cmdline.value("p");
624
625 if (helpSet) {
626 usage();
627 } else if (!configSet && !stopServer && args.length != 0) {
628 // invalid argument specified
629 usage();
630 } else {
631 String configFile = cmdline.value("config");
632 if (configFile == null) {
633 String home = getOpenJMSHome();
634 configFile = home + "/config/openjms.xml";
635 }
636 ConfigurationManager.setConfig(configFile);
637 Configuration config = ConfigurationManager.getConfig();
638 String path = config.getLoggerConfiguration().getFile();
639 if (path != null) {
640 DOMConfigurator.configure(path);
641 }
642 AdminConfiguration adminConfig = null;
643
644 adminConfig = config.getAdminConfiguration();
645 _serverStart = adminConfig.getScript();
646 _serverConfig = adminConfig.getConfig();
647 if (_serverConfig == null) {
648 _serverConfig = configFile;
649 }
650
651 if (stopServer) {
652 // this is a special mode that will just attempt
653 // a connection to the server and stop it. No GUI
654
655 new OnlineConnection(username, password);
656 AbstractAdminConnection.instance().stopServer();
657 } else {
658 AdminMgr admin = new AdminMgr(configFile);
659 QueryDialog.create(admin);
660 CreateQueueDialog.create(admin);
661 CreateTopicDialog.create(admin);
662 CreateLogonDialog.create(admin);
663 CreateUserDialog.create(admin);
664 ChangePasswordDialog.create(admin);
665 Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
666 // About center of screen
667 admin.setLocation(screen.width / 2 - 150, screen.height / 2 - 150);
668 admin.setSize(300, 300);
669 admin.invalidate();
670 admin.show();
671 }
672 }
673 } catch (Exception err) {
674 err.printStackTrace();
675 System.err.println("Failed to initialize AdminMgr.\nExiting....");
676 }
677 }
678
679 /***
680 * Print out information on running this sevice
681 */
682 static protected void usage() {
683 PrintStream out = System.out;
684
685 out.println("\n\n");
686 out.println("=====================================================");
687 out.println("Usage information for " + AdminMgr.class.getName());
688 out.println("=====================================================");
689 out.println("\n" + AdminMgr.class.getName());
690 out.println(" [-help | -config <xml config file>]\n");
691 out.println("\t-help displays this screen\n");
692 out.println("\t-config file name of xml-based config file\n");
693 }
694
695 /***
696 * A simple class to re-direct the output stream from JMS to the local
697 * console
698 */
699 class StreamRedirect extends Thread {
700
701 InputStream is_;
702
703 StreamRedirect(InputStream is) {
704 is_ = is;
705 }
706
707 public void run() {
708 try {
709 InputStreamReader isr = new InputStreamReader(is_);
710 BufferedReader br = new BufferedReader(isr);
711 String line = null;
712 while ((line = br.readLine()) != null) {
713 System.out.println(line);
714 }
715 } catch (IOException ioe) {
716 ioe.printStackTrace();
717 }
718 }
719 }
720
721 private String[] getStartCommand() throws Exception {
722 ArrayList args = new ArrayList();
723
724 if (_serverStart != null) {
725 Perl5Compiler compiler = new Perl5Compiler();
726 Pattern pattern = compiler.compile("'.*'|[^//s]*");
727 Perl5Matcher matcher = new Perl5Matcher();
728 PatternMatcherInput input = new PatternMatcherInput(_serverStart);
729
730 while (matcher.contains(input, pattern)) {
731 String arg = matcher.getMatch().toString();
732 if (arg.startsWith("'") && arg.endsWith("'")) {
733 arg = arg.substring(1, arg.length() - 1);
734 }
735 args.add(arg);
736 }
737 }
738
739 args.add("-config");
740 args.add(_serverConfig);
741
742 return (String[]) args.toArray(new String[0]);
743 }
744
745 /***
746 * Returns the value of the openjms.home environment variable
747 */
748 private static String getOpenJMSHome() {
749 return System.getProperty("openjms.home",
750 System.getProperty("user.dir"));
751 }
752
753 } //-- AdminMgr
754
This page was automatically generated by Maven