001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027
028package org.opends.guitools.controlpanel.ui;
029
030import static org.opends.messages.AdminToolMessages.*;
031import static com.forgerock.opendj.util.OperatingSystem.isMacOS;
032
033import java.awt.event.ActionEvent;
034import java.awt.event.ActionListener;
035import java.awt.event.KeyEvent;
036import java.lang.reflect.InvocationHandler;
037import java.lang.reflect.Method;
038import java.lang.reflect.Proxy;
039import java.util.HashSet;
040import java.util.Set;
041
042import javax.swing.JMenu;
043import javax.swing.JMenuItem;
044
045import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
046import org.opends.guitools.controlpanel.task.Task;
047import org.opends.guitools.controlpanel.util.Utilities;
048import org.forgerock.i18n.LocalizableMessage;
049
050/**
051 * The menu bar that appears on the main panel.
052 *
053 */
054public class MainMenuBar extends GenericMenuBar
055{
056  private static final long serialVersionUID = 6441273044772077947L;
057
058  private GenericDialog dlg;
059  private RefreshOptionsPanel panel;
060
061  /**
062   * Constructor.
063   * @param info the control panel information.
064   */
065  public MainMenuBar(ControlPanelInfo info)
066  {
067    super(info);
068
069    addMenus();
070
071    if (isMacOS())
072    {
073      setMacOSQuitHandler();
074    }
075  }
076
077  /**
078   * Method that can be overwritten to set specific menus.
079   *
080   */
081  protected void addMenus()
082  {
083    add(createFileMenuBar());
084    add(createViewMenuBar());
085    add(createHelpMenuBar());
086  }
087
088  /**
089   * The method called when the user clicks on quick.  It will check that there
090   * are not ongoing tasks.  If there are tasks, it will ask the user for
091   * confirmation to quit.
092   *
093   */
094  public void quitClicked()
095  {
096    Set<String> runningTasks = new HashSet<>();
097    for (Task task : getInfo().getTasks())
098    {
099      if (task.getState() == Task.State.RUNNING)
100      {
101        runningTasks.add(task.getTaskDescription().toString());
102      }
103    }
104    boolean confirmed = true;
105    if (!runningTasks.isEmpty())
106    {
107      String allTasks = Utilities.getStringFromCollection(runningTasks, "<br>");
108      LocalizableMessage title = INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get();
109      LocalizableMessage msg =
110        INFO_CTRL_PANEL_RUNNING_TASKS_CONFIRMATION_DETAILS.get(allTasks);
111      confirmed = Utilities.displayConfirmationDialog(
112          Utilities.getParentDialog(this), title, msg);
113    }
114    if (confirmed)
115    {
116      System.exit(0);
117    }
118  }
119
120  /**
121   * Creates the File menu bar.
122   * @return the File menu bar.
123   */
124  protected JMenu createFileMenuBar()
125  {
126    JMenu menu = Utilities.createMenu(INFO_CTRL_PANEL_FILE_MENU.get(),
127        INFO_CTRL_PANEL_FILE_MENU_DESCRIPTION.get());
128    menu.setMnemonic(KeyEvent.VK_F);
129    JMenuItem menuItem = Utilities.createMenuItem(
130        INFO_CTRL_PANEL_CONNECT_TO_SERVER_MENU.get());
131    menuItem.addActionListener(new ActionListener()
132    {
133      public void actionPerformed(ActionEvent ev)
134      {
135        connectToServerClicked();
136      }
137    });
138    menu.add(menuItem);
139
140    if (!isMacOS())
141    {
142      menuItem = Utilities.createMenuItem(INFO_CTRL_PANEL_EXIT_MENU.get());
143      menuItem.addActionListener(new ActionListener()
144      {
145        /** {@inheritDoc} */
146        public void actionPerformed(ActionEvent ev)
147        {
148          quitClicked();
149        }
150      });
151      menu.add(menuItem);
152    }
153    return menu;
154  }
155
156  /**
157   * Creates the View menu bar.
158   * @return the View menu bar.
159   */
160  protected JMenu createViewMenuBar()
161  {
162    JMenu menu = Utilities.createMenu(INFO_CTRL_PANEL_VIEW_MENU.get(),
163        INFO_CTRL_PANEL_HELP_VIEW_DESCRIPTION.get());
164    menu.setMnemonic(KeyEvent.VK_V);
165    JMenuItem menuItem = Utilities.createMenuItem(
166        INFO_CTRL_PANEL_REFRESH_MENU.get());
167    menuItem.addActionListener(new ActionListener()
168    {
169      public void actionPerformed(ActionEvent ev)
170      {
171        refreshOptionsClicked();
172      }
173    });
174    menu.add(menuItem);
175    return menu;
176  }
177
178  /**
179   * Specific method to be able to handle the Quit events sent from the COCOA
180   * menu of Mac OS.
181   *
182   */
183  private void setMacOSQuitHandler()
184  {
185    try
186    {
187      Class<? extends Object> applicationClass =
188        Class.forName("com.apple.eawt.Application");
189      Class<? extends Object> applicationListenerClass =
190        Class.forName("com.apple.eawt.ApplicationListener");
191      final Object  macApplication = applicationClass.getConstructor(
192          (Class[])null).newInstance((Object[])null);
193      InvocationHandler adapter = new InvocationHandler()
194      {
195        public Object invoke (Object proxy, Method method, Object[] args)
196        throws Throwable
197        {
198          Object event = args[0];
199          if (method.getName().equals("handleQuit"))
200          {
201            quitClicked();
202
203            // quitClicked will exit if we must exit
204            Method setHandledMethod = event.getClass().getDeclaredMethod(
205                "setHandled", new Class[] { boolean.class });
206            setHandledMethod.invoke(event, new Object[] { Boolean.FALSE });
207          }
208          return null;
209        }
210      };
211      Method addListenerMethod =
212        applicationClass.getDeclaredMethod("addApplicationListener",
213            new Class[] { applicationListenerClass });
214      Object proxy = Proxy.newProxyInstance(MainMenuBar.class.getClassLoader(),
215          new Class[] { applicationListenerClass }, adapter);
216      addListenerMethod.invoke(macApplication, new Object[] { proxy });
217    } catch (Throwable t) {
218      t.printStackTrace();
219    }
220  }
221
222  /**
223   * The method called when the user clicks on 'Refresh Options'.
224   *
225   */
226  protected void refreshOptionsClicked()
227  {
228    if (panel == null)
229    {
230      panel = new RefreshOptionsPanel();
231      panel.setInfo(getInfo());
232      dlg = new GenericDialog(
233          Utilities.getFrame(MainMenuBar.this),
234          panel);
235      dlg.setModal(true);
236      Utilities.centerGoldenMean(dlg,
237          Utilities.getFrame(MainMenuBar.this));
238    }
239    dlg.setVisible(true);
240    if (!panel.isCanceled())
241    {
242      getInfo().setPoolingPeriod(panel.getPoolingPeriod());
243      getInfo().stopPooling();
244      getInfo().startPooling();
245    }
246  }
247
248  /**
249   * The method called when the user clicks on 'Connect to Server...'.
250   */
251  protected void connectToServerClicked()
252  {
253    Set<String> runningTasks = new HashSet<>();
254    for (Task task : getInfo().getTasks())
255    {
256      if (task.getState() == Task.State.RUNNING)
257      {
258        runningTasks.add(task.getTaskDescription().toString());
259      }
260    }
261    boolean confirmed = true;
262    if (!runningTasks.isEmpty())
263    {
264      String allTasks = Utilities.getStringFromCollection(runningTasks, "<br>");
265      LocalizableMessage title = INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get();
266      LocalizableMessage msg =
267        INFO_CTRL_PANEL_RUNNING_TASKS_CHANGE_SERVER_CONFIRMATION_DETAILS.get(
268            allTasks);
269      confirmed = Utilities.displayConfirmationDialog(
270          Utilities.getParentDialog(this), title, msg);
271    }
272    if (confirmed)
273    {
274      GenericDialog dlg =
275        ControlCenterMainPane.getLocalOrRemoteDialog(getInfo());
276      Utilities.centerGoldenMean(dlg,
277          Utilities.getFrame(MainMenuBar.this));
278      dlg.setVisible(true);
279    }
280  }
281}