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 2010 Sun Microsystems, Inc. 015 * Portions Copyright 2013-2015 ForgeRock AS. 016 */ 017package org.opends.quicksetup.installer.ui; 018 019import static org.opends.messages.QuickSetupMessages.*; 020 021import java.awt.Component; 022import java.awt.GridBagConstraints; 023import java.awt.GridBagLayout; 024import java.awt.event.ActionEvent; 025import java.awt.event.ActionListener; 026import java.awt.event.FocusEvent; 027import java.awt.event.FocusListener; 028import java.io.File; 029import java.util.Set; 030 031import javax.swing.Box; 032import javax.swing.JButton; 033import javax.swing.JEditorPane; 034import javax.swing.JFrame; 035import javax.swing.JLabel; 036import javax.swing.JPanel; 037 038import org.opends.admin.ads.ReplicaDescriptor; 039import org.opends.admin.ads.SuffixDescriptor; 040import org.forgerock.i18n.LocalizableMessage; 041import org.opends.quicksetup.JavaArguments; 042import org.opends.quicksetup.UserData; 043import org.opends.quicksetup.installer.DataReplicationOptions; 044import org.opends.quicksetup.installer.NewSuffixOptions; 045import org.opends.quicksetup.installer.SuffixesToReplicateOptions; 046import org.opends.quicksetup.ui.FieldName; 047import org.opends.quicksetup.ui.GuiApplication; 048import org.opends.quicksetup.ui.QuickSetupStepPanel; 049import org.opends.quicksetup.ui.UIFactory; 050import org.opends.quicksetup.util.HtmlProgressMessageFormatter; 051 052/** 053 * The panel where the user specifies the runtime settings. 054 * 055 */ 056public class RuntimeOptionsPanel extends QuickSetupStepPanel 057{ 058 private static final long serialVersionUID = -8303034619200476754L; 059 060 private JButton bServer; 061 private JButton bImport; 062 private JLabel lServer; 063 private JLabel lImport; 064 private JEditorPane warning; 065 private Component lastFocusComponent; 066 067 private JavaArguments serverJavaArgs; 068 private JavaArguments importJavaArgs; 069 070 private JavaArguments defaultServerJavaArgs; 071 private JavaArguments defaultImportJavaArgs; 072 073 /** 074 * The size of the LDIF file to be imported used as threshold to display 075 * a warning message, telling the user to update the import runtime settings. 076 */ 077 private static final long WARNING_THRESOLD_FOR_IMPORT = 200 * 1024 * 1024; 078 private static final int WARNING_THRESOLD_AUTOMATICALLY_GENERATED_IMPORT 079 = 100000; 080 private static final int WARNING_THRESOLD_REPLICATED_ENTRIES = 100000; 081 082 /** 083 * Constructor of the panel. 084 * @param application Application represented by this panel and used to 085 * initialize the fields of the panel. 086 */ 087 public RuntimeOptionsPanel(GuiApplication application) 088 { 089 super(application); 090 createComponents(); 091 addFocusListeners(); 092 } 093 094 /** {@inheritDoc} */ 095 protected Component createInputPanel() 096 { 097 JPanel panel = new JPanel(new GridBagLayout()); 098 panel.setOpaque(false); 099 GridBagConstraints gbc = new GridBagConstraints(); 100 gbc.gridwidth = 4; 101 gbc.fill = GridBagConstraints.HORIZONTAL; 102 gbc.anchor = GridBagConstraints.NORTHWEST; 103 gbc.gridx = 0; 104 gbc.gridy = 0; 105 gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD; 106 gbc.insets.bottom = UIFactory.TOP_INSET_PRIMARY_FIELD; 107 gbc.weightx = 1.0; 108 panel.add(warning, gbc); 109 warning.setVisible(false); 110 111 gbc.gridy ++; 112 gbc.gridwidth = 1; 113 gbc.weightx = 0.0; 114 gbc.insets.bottom = 0; 115 116 JLabel l = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, 117 INFO_SERVER_RUNTIME_ARGS_LABEL.get(), 118 UIFactory.TextStyle.PRIMARY_FIELD_VALID); 119 120 gbc.insets.top = Math.abs( 121 bServer.getPreferredSize().height - 122 l.getPreferredSize().height) / 2; 123 panel.add(l, gbc); 124 gbc.gridx ++; 125 gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD; 126 gbc.weightx = 0.5; 127 panel.add(lServer, gbc); 128 gbc.gridx ++; 129 gbc.insets.top = 0; 130 gbc.weightx = 0.0; 131 panel.add(bServer, gbc); 132 gbc.gridx ++; 133 gbc.weightx = 1.0; 134 gbc.insets.left = 0; 135 panel.add(Box.createHorizontalGlue(), gbc); 136 137 gbc.gridy++; 138 gbc.gridx = 0; 139 gbc.weightx = 0.0; 140 141 l = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, 142 INFO_IMPORT_RUNTIME_ARGS_LABEL.get(), 143 UIFactory.TextStyle.PRIMARY_FIELD_VALID); 144 int importInsetsTop = Math.abs( 145 bImport.getPreferredSize().height - 146 l.getPreferredSize().height) / 2; 147 gbc.insets.top = importInsetsTop + UIFactory.TOP_INSET_SECONDARY_FIELD; 148 panel.add(l, gbc); 149 gbc.gridx ++; 150 gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD; 151 gbc.weightx = 0.5; 152 panel.add(lImport, gbc); 153 gbc.gridx ++; 154 gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; 155 gbc.weightx = 0.0; 156 panel.add(bImport, gbc); 157 gbc.gridx ++; 158 gbc.weightx = 1.0; 159 gbc.insets.left = 0; 160 panel.add(Box.createHorizontalGlue(), gbc); 161 162 gbc.gridx = 0; 163 gbc.gridwidth = 4; 164 gbc.gridy ++; 165 gbc.insets = UIFactory.getEmptyInsets(); 166 gbc.weightx = 1.0; 167 gbc.weighty = 1.0; 168 gbc.fill = GridBagConstraints.VERTICAL; 169 panel.add(Box.createVerticalGlue(), gbc); 170 171 return panel; 172 } 173 174 /** {@inheritDoc} */ 175 protected LocalizableMessage getInstructions() 176 { 177 return INFO_JAVA_RUNTIME_OPTIONS_PANEL_INSTRUCTIONS.get(); 178 } 179 180 /** {@inheritDoc} */ 181 protected LocalizableMessage getTitle() 182 { 183 return INFO_JAVA_RUNTIME_OPTIONS_PANEL_TITLE.get(); 184 } 185 186 /** {@inheritDoc} */ 187 @Override 188 public Object getFieldValue(FieldName fieldName) 189 { 190 Object value = null; 191 if (fieldName == FieldName.SERVER_JAVA_ARGUMENTS) 192 { 193 value = serverJavaArgs; 194 } 195 else if (fieldName == FieldName.IMPORT_JAVA_ARGUMENTS) 196 { 197 value = importJavaArgs; 198 } 199 return value; 200 } 201 202 /** {@inheritDoc} */ 203 @Override 204 public void beginDisplay(UserData uData) 205 { 206 if (defaultServerJavaArgs == null) 207 { 208 defaultServerJavaArgs = 209 uData.getDefaultJavaArguments(UserData.SERVER_SCRIPT_NAME); 210 } 211 if (defaultImportJavaArgs == null) 212 { 213 defaultImportJavaArgs = 214 uData.getDefaultJavaArguments(UserData.IMPORT_SCRIPT_NAME); 215 } 216 boolean updatePanel = false; 217 if (serverJavaArgs == null) 218 { 219 serverJavaArgs = uData.getJavaArguments(UserData.SERVER_SCRIPT_NAME); 220 updatePanel = true; 221 } 222 if (importJavaArgs == null) 223 { 224 importJavaArgs = uData.getJavaArguments(UserData.IMPORT_SCRIPT_NAME); 225 updatePanel = true; 226 } 227 if (updatePanel) 228 { 229 lServer.setText(JavaArguments.getMessageForJLabel( 230 serverJavaArgs, defaultServerJavaArgs, 231 UIFactory.SECONDARY_FIELD_VALID_FONT).toString()); 232 lImport.setText(JavaArguments.getMessageForJLabel( 233 importJavaArgs, defaultImportJavaArgs, 234 UIFactory.SECONDARY_FIELD_VALID_FONT).toString()); 235 } 236 237 updateWarningMessage(uData); 238 } 239 240 /** {@inheritDoc} */ 241 public void endDisplay() 242 { 243 if (lastFocusComponent != null) 244 { 245 lastFocusComponent.requestFocusInWindow(); 246 } 247 } 248 249 /** {@inheritDoc} */ 250 public boolean requiresScroll() 251 { 252 return false; 253 } 254 255 /** 256 * Adds the required focus listeners to the fields. 257 */ 258 private void addFocusListeners() 259 { 260 FocusListener l = new FocusListener() 261 { 262 public void focusGained(FocusEvent e) 263 { 264 lastFocusComponent = e.getComponent(); 265 } 266 267 public void focusLost(FocusEvent e) 268 { 269 } 270 }; 271 272 bServer.addFocusListener(l); 273 bImport.addFocusListener(l); 274 lastFocusComponent = bServer; 275 } 276 277 private void changeServerClicked() 278 { 279 JavaArgumentsDialog dlg = new JavaArgumentsDialog( 280 getFrame(), serverJavaArgs, 281 INFO_SERVER_JAVA_ARGUMENTS_TITLE.get(), 282 INFO_SERVER_JAVA_ARGUMENTS_MSG.get()); 283 dlg.pack(); 284 dlg.setModal(true); 285 dlg.setVisible(true); 286 if (!dlg.isCanceled()) 287 { 288 serverJavaArgs = dlg.getJavaArguments(); 289 lServer.setText(JavaArguments.getMessageForJLabel( 290 serverJavaArgs, defaultServerJavaArgs, 291 UIFactory.SECONDARY_FIELD_VALID_FONT).toString()); 292 } 293 } 294 295 private void changeImportClicked() 296 { 297 JavaArgumentsDialog dlg = new JavaArgumentsDialog( 298 getFrame(), importJavaArgs, 299 INFO_IMPORT_JAVA_ARGUMENTS_TITLE.get(), 300 INFO_IMPORT_JAVA_ARGUMENTS_MSG.get()); 301 dlg.pack(); 302 dlg.setModal(true); 303 dlg.setVisible(true); 304 if (!dlg.isCanceled()) 305 { 306 importJavaArgs = dlg.getJavaArguments(); 307 lImport.setText(JavaArguments.getMessageForJLabel( 308 importJavaArgs, defaultImportJavaArgs, 309 UIFactory.SECONDARY_FIELD_VALID_FONT).toString()); 310 } 311 } 312 313 private void createComponents() 314 { 315 warning = UIFactory.makeHtmlPane(LocalizableMessage.EMPTY, 316 UIFactory.INSTRUCTIONS_FONT); 317 warning.setOpaque(false); 318 319 lServer = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, 320 LocalizableMessage.EMPTY, UIFactory.TextStyle.SECONDARY_FIELD_VALID); 321 bServer = UIFactory.makeJButton(INFO_JAVA_RUNTIME_CHANGE_LABEL.get(), 322 INFO_JAVA_RUNTIME_CHANGE_SERVER_TOOLTIP.get()); 323 bServer.addActionListener(new ActionListener() 324 { 325 public void actionPerformed(ActionEvent ev) 326 { 327 changeServerClicked(); 328 } 329 }); 330 331 lImport = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, 332 LocalizableMessage.EMPTY, UIFactory.TextStyle.SECONDARY_FIELD_VALID); 333 bImport = UIFactory.makeJButton(INFO_JAVA_RUNTIME_CHANGE_LABEL.get(), 334 INFO_JAVA_RUNTIME_CHANGE_IMPORT_TOOLTIP.get()); 335 bImport.addActionListener(new ActionListener() 336 { 337 public void actionPerformed(ActionEvent ev) 338 { 339 changeImportClicked(); 340 } 341 }); 342 } 343 344 private JFrame getFrame() 345 { 346 Component mainWindow = getMainWindow(); 347 JFrame frame = null; 348 if (mainWindow instanceof JFrame) 349 { 350 frame = (JFrame)mainWindow; 351 } 352 return frame; 353 } 354 355 private void updateWarningMessage(UserData uData) 356 { 357 LocalizableMessage msg = null; 358 359 DataReplicationOptions repl = uData.getReplicationOptions(); 360 SuffixesToReplicateOptions suf = uData.getSuffixesToReplicateOptions(); 361 boolean createSuffix = 362 repl.getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY || 363 repl.getType() == DataReplicationOptions.Type.STANDALONE || 364 suf.getType() == SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY; 365 366 if (createSuffix) 367 { 368 NewSuffixOptions options = uData.getNewSuffixOptions(); 369 370 switch (options.getType()) 371 { 372 case IMPORT_FROM_LDIF_FILE: 373 File ldifFile = new File(options.getLDIFPaths().getFirst()); 374 if (ldifFile.length() > WARNING_THRESOLD_FOR_IMPORT) 375 { 376 msg = INFO_IMPORT_FILE_WARNING_UPDATE_RUNTIME_ARGS.get(); 377 } 378 break; 379 380 case IMPORT_AUTOMATICALLY_GENERATED_DATA: 381 if (options.getNumberEntries() > 382 WARNING_THRESOLD_AUTOMATICALLY_GENERATED_IMPORT) 383 { 384 msg = 385 INFO_AUTOMATICALLY_GENERATED_DATA_WARNING_UPDATE_RUNTIME_ARGS. 386 get(); 387 } 388 break; 389 } 390 } 391 else if (repl.getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY) 392 { 393 int maxReplicatedEntries = 0; 394 395 Set<SuffixDescriptor> suffixes = suf.getSuffixes(); 396 for (SuffixDescriptor suffix : suffixes) 397 { 398 int suffixEntries = 0; 399 for (ReplicaDescriptor replica : suffix.getReplicas()) 400 { 401 suffixEntries = Math.max(suffixEntries, replica.getEntries()); 402 } 403 maxReplicatedEntries += suffixEntries; 404 } 405 406 if (maxReplicatedEntries > WARNING_THRESOLD_REPLICATED_ENTRIES) 407 { 408 msg = INFO_REPLICATED_ENTRIES_WARNING_UPDATE_RUNTIME_ARGS.get(); 409 } 410 } 411 412 if (msg != null) 413 { 414 HtmlProgressMessageFormatter formatter = 415 new HtmlProgressMessageFormatter(); 416 StringBuilder buf = new StringBuilder(); 417 String space = formatter.getSpace().toString(); 418 String lBreak = formatter.getLineBreak().toString(); 419 String title = UIFactory.applyFontToHtml( 420 INFO_GENERAL_WARNING.get().toString(), 421 UIFactory.TITLE_FONT); 422 String details = UIFactory.applyFontToHtml(msg.toString(), 423 UIFactory.SECONDARY_FIELD_VALID_FONT); 424 buf.append(UIFactory.getIconHtml(UIFactory.IconType.WARNING_LARGE)) 425 .append(space).append(space) 426 .append(title) 427 .append(lBreak).append(lBreak) 428 .append(details); 429 String s = "<form>"+UIFactory.applyErrorBackgroundToHtml(buf.toString())+ 430 "</form>"; 431 432 warning.setText(s); 433 warning.setVisible(true); 434 } 435 else 436 { 437 warning.setText(""); 438 warning.setVisible(false); 439 } 440 } 441}