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}