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-2015 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.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
036import org.opends.guitools.controlpanel.task.Task;
037import org.opends.guitools.controlpanel.util.Utilities;
038import org.forgerock.i18n.LocalizableMessage;
039
040/**
041 * The menu bar that appears on the main panel.
042 *
043 */
044public class MainMenuBar extends GenericMenuBar
045{
046  private static final long serialVersionUID = 6441273044772077947L;
047
048  private GenericDialog dlg;
049  private RefreshOptionsPanel panel;
050
051  /**
052   * Constructor.
053   * @param info the control panel information.
054   */
055  public MainMenuBar(ControlPanelInfo info)
056  {
057    super(info);
058
059    addMenus();
060
061    if (isMacOS())
062    {
063      setMacOSQuitHandler();
064    }
065  }
066
067  /**
068   * Method that can be overwritten to set specific menus.
069   *
070   */
071  protected void addMenus()
072  {
073    add(createFileMenuBar());
074    add(createViewMenuBar());
075    add(createHelpMenuBar());
076  }
077
078  /**
079   * The method called when the user clicks on quick.  It will check that there
080   * are not ongoing tasks.  If there are tasks, it will ask the user for
081   * confirmation to quit.
082   *
083   */
084  public void quitClicked()
085  {
086    Set<String> runningTasks = new HashSet<>();
087    for (Task task : getInfo().getTasks())
088    {
089      if (task.getState() == Task.State.RUNNING)
090      {
091        runningTasks.add(task.getTaskDescription().toString());
092      }
093    }
094    boolean confirmed = true;
095    if (!runningTasks.isEmpty())
096    {
097      String allTasks = Utilities.getStringFromCollection(runningTasks, "<br>");
098      LocalizableMessage title = INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get();
099      LocalizableMessage msg =
100        INFO_CTRL_PANEL_RUNNING_TASKS_CONFIRMATION_DETAILS.get(allTasks);
101      confirmed = Utilities.displayConfirmationDialog(
102          Utilities.getParentDialog(this), title, msg);
103    }
104    if (confirmed)
105    {
106      System.exit(0);
107    }
108  }
109
110  /**
111   * Creates the File menu bar.
112   * @return the File menu bar.
113   */
114  protected JMenu createFileMenuBar()
115  {
116    JMenu menu = Utilities.createMenu(INFO_CTRL_PANEL_FILE_MENU.get(),
117        INFO_CTRL_PANEL_FILE_MENU_DESCRIPTION.get());
118    menu.setMnemonic(KeyEvent.VK_F);
119    JMenuItem menuItem = Utilities.createMenuItem(
120        INFO_CTRL_PANEL_CONNECT_TO_SERVER_MENU.get());
121    menuItem.addActionListener(new ActionListener()
122    {
123      public void actionPerformed(ActionEvent ev)
124      {
125        connectToServerClicked();
126      }
127    });
128    menu.add(menuItem);
129
130    if (!isMacOS())
131    {
132      menuItem = Utilities.createMenuItem(INFO_CTRL_PANEL_EXIT_MENU.get());
133      menuItem.addActionListener(new ActionListener()
134      {
135        /** {@inheritDoc} */
136        public void actionPerformed(ActionEvent ev)
137        {
138          quitClicked();
139        }
140      });
141      menu.add(menuItem);
142    }
143    return menu;
144  }
145
146  /**
147   * Creates the View menu bar.
148   * @return the View menu bar.
149   */
150  protected JMenu createViewMenuBar()
151  {
152    JMenu menu = Utilities.createMenu(INFO_CTRL_PANEL_VIEW_MENU.get(),
153        INFO_CTRL_PANEL_HELP_VIEW_DESCRIPTION.get());
154    menu.setMnemonic(KeyEvent.VK_V);
155    JMenuItem menuItem = Utilities.createMenuItem(
156        INFO_CTRL_PANEL_REFRESH_MENU.get());
157    menuItem.addActionListener(new ActionListener()
158    {
159      public void actionPerformed(ActionEvent ev)
160      {
161        refreshOptionsClicked();
162      }
163    });
164    menu.add(menuItem);
165    return menu;
166  }
167
168  /**
169   * Specific method to be able to handle the Quit events sent from the COCOA
170   * menu of Mac OS.
171   *
172   */
173  private void setMacOSQuitHandler()
174  {
175    try
176    {
177      Class<? extends Object> applicationClass =
178        Class.forName("com.apple.eawt.Application");
179      Class<? extends Object> applicationListenerClass =
180        Class.forName("com.apple.eawt.ApplicationListener");
181      final Object  macApplication = applicationClass.getConstructor(
182          (Class[])null).newInstance((Object[])null);
183      InvocationHandler adapter = new InvocationHandler()
184      {
185        public Object invoke (Object proxy, Method method, Object[] args)
186        throws Throwable
187        {
188          Object event = args[0];
189          if (method.getName().equals("handleQuit"))
190          {
191            quitClicked();
192
193            // quitClicked will exit if we must exit
194            Method setHandledMethod = event.getClass().getDeclaredMethod(
195                "setHandled", new Class[] { boolean.class });
196            setHandledMethod.invoke(event, new Object[] { Boolean.FALSE });
197          }
198          return null;
199        }
200      };
201      Method addListenerMethod =
202        applicationClass.getDeclaredMethod("addApplicationListener",
203            new Class[] { applicationListenerClass });
204      Object proxy = Proxy.newProxyInstance(MainMenuBar.class.getClassLoader(),
205          new Class[] { applicationListenerClass }, adapter);
206      addListenerMethod.invoke(macApplication, new Object[] { proxy });
207    } catch (Throwable t) {
208      t.printStackTrace();
209    }
210  }
211
212  /**
213   * The method called when the user clicks on 'Refresh Options'.
214   *
215   */
216  protected void refreshOptionsClicked()
217  {
218    if (panel == null)
219    {
220      panel = new RefreshOptionsPanel();
221      panel.setInfo(getInfo());
222      dlg = new GenericDialog(
223          Utilities.getFrame(MainMenuBar.this),
224          panel);
225      dlg.setModal(true);
226      Utilities.centerGoldenMean(dlg,
227          Utilities.getFrame(MainMenuBar.this));
228    }
229    dlg.setVisible(true);
230    if (!panel.isCanceled())
231    {
232      getInfo().setPoolingPeriod(panel.getPoolingPeriod());
233      getInfo().stopPooling();
234      getInfo().startPooling();
235    }
236  }
237
238  /**
239   * The method called when the user clicks on 'Connect to Server...'.
240   */
241  protected void connectToServerClicked()
242  {
243    Set<String> runningTasks = new HashSet<>();
244    for (Task task : getInfo().getTasks())
245    {
246      if (task.getState() == Task.State.RUNNING)
247      {
248        runningTasks.add(task.getTaskDescription().toString());
249      }
250    }
251    boolean confirmed = true;
252    if (!runningTasks.isEmpty())
253    {
254      String allTasks = Utilities.getStringFromCollection(runningTasks, "<br>");
255      LocalizableMessage title = INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get();
256      LocalizableMessage msg =
257        INFO_CTRL_PANEL_RUNNING_TASKS_CHANGE_SERVER_CONFIRMATION_DETAILS.get(
258            allTasks);
259      confirmed = Utilities.displayConfirmationDialog(
260          Utilities.getParentDialog(this), title, msg);
261    }
262    if (confirmed)
263    {
264      GenericDialog dlg =
265        ControlCenterMainPane.getLocalOrRemoteDialog(getInfo());
266      Utilities.centerGoldenMean(dlg,
267          Utilities.getFrame(MainMenuBar.this));
268      dlg.setVisible(true);
269    }
270  }
271}