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-2009 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.*; 021 022import java.awt.Component; 023import java.awt.Dimension; 024import java.awt.GridBagConstraints; 025import java.awt.event.ActionEvent; 026import java.awt.event.ActionListener; 027import java.util.ArrayList; 028import java.util.Collection; 029import java.util.HashSet; 030import java.util.LinkedHashSet; 031import java.util.Set; 032 033import javax.swing.Box; 034import javax.swing.JButton; 035import javax.swing.JEditorPane; 036import javax.swing.JLabel; 037import javax.swing.SwingUtilities; 038 039import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 040import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; 041import org.opends.guitools.controlpanel.task.Task; 042import org.opends.guitools.controlpanel.util.Utilities; 043import org.forgerock.i18n.LocalizableMessage; 044import org.opends.server.tools.ConfigureWindowsService; 045 046/** 047 * The panel that displays the Windows Service panel configuration for the 048 * server. 049 * 050 */ 051public class WindowsServicePanel extends StatusGenericPanel 052{ 053 private static final long serialVersionUID = 6415350296295459469L; 054 private JLabel lState; 055 private JButton bEnable; 056 private JButton bDisable; 057 058 private boolean previousLocal = true; 059 060 private boolean isWindowsServiceEnabled; 061 062 /** 063 * Default constructor. 064 * 065 */ 066 public WindowsServicePanel() 067 { 068 super(); 069 createLayout(); 070 } 071 072 /** {@inheritDoc} */ 073 public LocalizableMessage getTitle() 074 { 075 return INFO_CTRL_PANEL_WINDOWS_SERVICE_TITLE.get(); 076 } 077 078 /** 079 * Creates the layout of the panel (but the contents are not populated here). 080 */ 081 private void createLayout() 082 { 083 GridBagConstraints gbc = new GridBagConstraints(); 084 gbc.anchor = GridBagConstraints.WEST; 085 gbc.weightx = 0.0; 086 gbc.gridx = 0; 087 gbc.gridy = 0; 088 gbc.gridwidth = 4; 089 gbc.weightx = 1.0; 090 gbc.fill = GridBagConstraints.BOTH; 091 092 String text = INFO_CTRL_PANEL_WINDOWS_SERVICE_PANEL_TEXT.get().toString(); 093 094 JEditorPane pane = Utilities.makeHtmlPane(text, 095 ColorAndFontConstants.defaultFont); 096 097 Utilities.updatePreferredSize(pane, 100, text, 098 ColorAndFontConstants.defaultFont, false); 099 gbc.weighty = 0.0; 100 add(pane, gbc); 101 102 gbc.gridy = 1; 103 gbc.gridwidth = 1; 104 gbc.weightx = 0.0; 105 gbc.weighty = 0.0; 106 JLabel lWindowsService =Utilities.createPrimaryLabel( 107 INFO_CTRL_PANEL_WINDOWS_SERVICE_INTEGRATION_LABEL.get()); 108 gbc.insets.top = 10; 109 add(lWindowsService, gbc); 110 lState = Utilities.createDefaultLabel(); 111 lState.setText(isWindowsServiceEnabled ? 112 INFO_ENABLED_LABEL.get().toString() : 113 INFO_DISABLED_LABEL.get().toString()); 114 gbc.insets.left = 10; 115 gbc.gridx = 1; 116 add(lState, gbc); 117 118 bEnable = Utilities.createButton( 119 INFO_CTRL_PANEL_ENABLE_WINDOWS_SERVICE_BUTTON.get()); 120 bDisable = Utilities.createButton( 121 INFO_CTRL_PANEL_DISABLE_WINDOWS_SERVICE_BUTTON.get()); 122 bEnable.setOpaque(false); 123 bDisable.setOpaque(false); 124 int maxWidth = Math.max(bEnable.getPreferredSize().width, 125 bDisable.getPreferredSize().width); 126 int maxHeight = Math.max(bEnable.getPreferredSize().height, 127 bDisable.getPreferredSize().height); 128 bEnable.setPreferredSize(new Dimension(maxWidth, maxHeight)); 129 bDisable.setPreferredSize(new Dimension(maxWidth, maxHeight)); 130 131 ActionListener listener = new ActionListener() 132 { 133 /** {@inheritDoc} */ 134 public void actionPerformed(ActionEvent ev) 135 { 136 updateWindowsService(); 137 } 138 }; 139 bEnable.addActionListener(listener); 140 bDisable.addActionListener(listener); 141 142 gbc.gridx = 2; 143 add(bEnable, gbc); 144 add(bDisable, gbc); 145 146 gbc.weightx = 1.0; 147 gbc.gridx = 3; 148 add(Box.createHorizontalGlue(), gbc); 149 150 bEnable.setVisible(!isWindowsServiceEnabled); 151 bDisable.setVisible(isWindowsServiceEnabled); 152 addBottomGlue(gbc); 153 } 154 155 /** {@inheritDoc} */ 156 public GenericDialog.ButtonType getButtonType() 157 { 158 return GenericDialog.ButtonType.CLOSE; 159 } 160 161 /** {@inheritDoc} */ 162 public Component getPreferredFocusComponent() 163 { 164 if (!isWindowsServiceEnabled) 165 { 166 return bEnable; 167 } 168 else 169 { 170 return bDisable; 171 } 172 } 173 174 /** {@inheritDoc} */ 175 public void configurationChanged(ConfigurationChangeEvent ev) 176 { 177 boolean previousValue = isWindowsServiceEnabled; 178 isWindowsServiceEnabled = ev.getNewDescriptor().isWindowsServiceEnabled(); 179 180 final boolean isLocal = ev.getNewDescriptor().isLocal(); 181 if (isLocal != previousLocal || isWindowsServiceEnabled != previousValue) 182 { 183 previousLocal = isLocal; 184 SwingUtilities.invokeLater(new Runnable() 185 { 186 /** {@inheritDoc} */ 187 public void run() 188 { 189 lState.setText(isWindowsServiceEnabled ? 190 INFO_ENABLED_LABEL.get().toString() : 191 INFO_DISABLED_LABEL.get().toString()); 192 bEnable.setVisible(!isWindowsServiceEnabled); 193 bDisable.setVisible(isWindowsServiceEnabled); 194 195 if (!isLocal) 196 { 197 displayErrorMessage(INFO_CTRL_PANEL_SERVER_REMOTE_SUMMARY.get(), 198 INFO_CTRL_PANEL_SERVER_MUST_BE_LOCAL_WINDOWS_SERVICE_SUMMARY.get()); 199 packParentDialog(); 200 } 201 else 202 { 203 displayMainPanel(); 204 } 205 } 206 }); 207 } 208 } 209 210 /** {@inheritDoc} */ 211 public void okClicked() 212 { 213 // NO ok button 214 } 215 216 private void updateWindowsService() 217 { 218 LinkedHashSet<LocalizableMessage> errors = new LinkedHashSet<>(); 219 ProgressDialog progressDialog = new ProgressDialog( 220 Utilities.createFrame(), Utilities.getParentDialog(this), getTitle(), 221 getInfo()); 222 WindowsServiceTask newTask = new WindowsServiceTask(getInfo(), 223 progressDialog, !isWindowsServiceEnabled); 224 for (Task task : getInfo().getTasks()) 225 { 226 task.canLaunch(newTask, errors); 227 } 228 if (errors.isEmpty()) 229 { 230 if (isWindowsServiceEnabled) 231 { 232 launchOperation(newTask, 233 INFO_CTRL_PANEL_DISABLING_WINDOWS_SERVICE_SUMMARY.get(), 234 INFO_CTRL_PANEL_DISABLING_WINDOWS_SERVICE_SUCCESSFUL_SUMMARY.get(), 235 INFO_CTRL_PANEL_DISABLING_WINDOWS_SERVICE_SUCCESSFUL_DETAILS.get(), 236 ERR_CTRL_PANEL_DISABLING_WINDOWS_SERVICE_ERROR_SUMMARY.get(), 237 null, 238 ERR_CTRL_PANEL_DISABLING_WINDOWS_SERVICE_ERROR_DETAILS, 239 progressDialog); 240 } 241 else 242 { 243 launchOperation(newTask, 244 INFO_CTRL_PANEL_ENABLING_WINDOWS_SERVICE_SUMMARY.get(), 245 INFO_CTRL_PANEL_ENABLING_WINDOWS_SERVICE_SUCCESSFUL_SUMMARY.get(), 246 INFO_CTRL_PANEL_ENABLING_WINDOWS_SERVICE_SUCCESSFUL_DETAILS.get(), 247 ERR_CTRL_PANEL_ENABLING_WINDOWS_SERVICE_ERROR_SUMMARY.get(), 248 null, 249 ERR_CTRL_PANEL_ENABLING_WINDOWS_SERVICE_ERROR_DETAILS, 250 progressDialog); 251 } 252 progressDialog.setVisible(true); 253 } 254 else 255 { 256 displayErrorDialog(errors); 257 } 258 } 259 260 /** 261 * The task in charge of updating the windows service configuration. 262 * 263 */ 264 protected class WindowsServiceTask extends Task 265 { 266 Set<String> backendSet; 267 private boolean enableService; 268 /** 269 * The constructor of the task. 270 * @param info the control panel info. 271 * @param dlg the progress dialog that shows the progress of the task. 272 * @param enableService whether the windows service must be enabled or 273 * disabled. 274 */ 275 public WindowsServiceTask(ControlPanelInfo info, ProgressDialog dlg, 276 boolean enableService) 277 { 278 super(info, dlg); 279 this.enableService = enableService; 280 backendSet = new HashSet<>(); 281 } 282 283 /** {@inheritDoc} */ 284 public Type getType() 285 { 286 if (enableService) 287 { 288 return Type.ENABLE_WINDOWS_SERVICE; 289 } 290 else 291 { 292 return Type.DISABLE_WINDOWS_SERVICE; 293 } 294 } 295 296 /** {@inheritDoc} */ 297 public LocalizableMessage getTaskDescription() 298 { 299 if (enableService) 300 { 301 return INFO_CTRL_PANEL_ENABLE_WINDOWS_SERVICE_TASK_DESCRIPTION.get(); 302 } 303 else 304 { 305 return INFO_CTRL_PANEL_DISABLE_WINDOWS_SERVICE_TASK_DESCRIPTION.get(); 306 } 307 } 308 309 /** {@inheritDoc} */ 310 public boolean canLaunch(Task taskToBeLaunched, 311 Collection<LocalizableMessage> incompatibilityReasons) 312 { 313 Type type = taskToBeLaunched.getType(); 314 if (state == State.RUNNING 315 && runningOnSameServer(taskToBeLaunched) 316 && (type == Type.ENABLE_WINDOWS_SERVICE 317 || type == Type.DISABLE_WINDOWS_SERVICE)) 318 { 319 incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); 320 return false; 321 } 322 return true; 323 } 324 325 /** {@inheritDoc} */ 326 public void runTask() 327 { 328 state = State.RUNNING; 329 lastException = null; 330 try 331 { 332 if (enableService) 333 { 334 returnCode = ConfigureWindowsService.enableService(outPrintStream, errorPrintStream); 335 if (returnCode != ConfigureWindowsService.SERVICE_ALREADY_ENABLED && 336 returnCode != ConfigureWindowsService.SERVICE_ENABLE_SUCCESS) 337 { 338 state = State.FINISHED_WITH_ERROR; 339 } 340 else 341 { 342 state = State.FINISHED_SUCCESSFULLY; 343 } 344 } 345 else 346 { 347 returnCode = ConfigureWindowsService.disableService(outPrintStream, errorPrintStream); 348 if (returnCode != ConfigureWindowsService.SERVICE_ALREADY_DISABLED 349 && returnCode != ConfigureWindowsService.SERVICE_DISABLE_SUCCESS) 350 { 351 state = State.FINISHED_WITH_ERROR; 352 } 353 else 354 { 355 state = State.FINISHED_SUCCESSFULLY; 356 } 357 } 358 } 359 catch (Throwable t) 360 { 361 lastException = t; 362 state = State.FINISHED_WITH_ERROR; 363 } 364 } 365 366 /** {@inheritDoc} */ 367 public Set<String> getBackends() 368 { 369 return backendSet; 370 } 371 372 /** {@inheritDoc} */ 373 protected ArrayList<String> getCommandLineArguments() 374 { 375 ArrayList<String> args = new ArrayList<>(); 376 377 if (enableService) 378 { 379 args.add("--enableService"); 380 } 381 else 382 { 383 args.add("--disableService"); 384 } 385 386 return args; 387 } 388 389 /** {@inheritDoc} */ 390 protected String getCommandLinePath() 391 { 392 return getCommandLinePath("windows-service"); 393 } 394 } 395}