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