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 2011-2016 ForgeRock AS.
016 */
017
018package org.opends.quicksetup.installer.ui;
019
020import java.awt.CardLayout;
021import java.awt.Component;
022import java.awt.GridBagConstraints;
023import java.awt.GridBagLayout;
024import java.awt.Insets;
025import java.awt.event.ActionEvent;
026import java.awt.event.ActionListener;
027import java.awt.event.WindowAdapter;
028import java.awt.event.WindowEvent;
029import java.util.ArrayList;
030import java.util.Collection;
031
032import javax.swing.Box;
033import javax.swing.JButton;
034import javax.swing.JComponent;
035import javax.swing.JDialog;
036import javax.swing.JFrame;
037import javax.swing.JLabel;
038import javax.swing.JPanel;
039import javax.swing.JTextField;
040import javax.swing.SwingUtilities;
041import javax.swing.text.JTextComponent;
042
043import org.opends.quicksetup.JavaArguments;
044import org.opends.quicksetup.event.MinimumSizeComponentListener;
045import org.opends.quicksetup.ui.UIFactory;
046import org.opends.quicksetup.ui.Utilities;
047import org.opends.quicksetup.util.BackgroundTask;
048import org.opends.quicksetup.util.Utils;
049import org.opends.server.util.SetupUtils;
050import org.forgerock.i18n.LocalizableMessage;
051import org.forgerock.i18n.LocalizableMessageBuilder;
052
053import static org.opends.messages.QuickSetupMessages.*;
054import static com.forgerock.opendj.cli.Utils.getThrowableMsg;
055
056/**
057 * This class is a dialog that appears when the user wants to configure
058 * java parameters in the runtime settings panel.
059 */
060public class JavaArgumentsDialog extends JDialog
061{
062  private static final long serialVersionUID = -7950773258109643264L;
063  private JLabel lInitialMemory;
064  private JLabel lMaxMemory;
065  private JLabel lOtherArguments;
066
067  private JTextField tfInitialMemory;
068  private JTextField tfMaxMemory;
069  private JTextField tfOtherArguments;
070
071  private JButton cancelButton;
072  private JButton okButton;
073
074  private boolean isCanceled = true;
075
076  private LocalizableMessage message;
077
078  private JavaArguments javaArguments;
079
080  private JPanel inputContainer;
081
082  private static final String INPUT_PANEL = "input";
083  private static final String CHECKING_PANEL = "checking";
084
085  private boolean isCheckingVisible;
086
087  /**
088   * Constructor of the JavaArgumentsDialog.
089   * @param parent the parent frame for this dialog.
090   * @param javaArguments the java arguments used to populate this dialog.
091   * @param title the title of the dialog.
092   * @param message the message to be displayed in top.
093   * @throws IllegalArgumentException if options is null.
094   */
095  public JavaArgumentsDialog(JFrame parent, JavaArguments javaArguments,
096      LocalizableMessage title, LocalizableMessage message)
097  throws IllegalArgumentException
098  {
099    super(parent);
100    if (javaArguments == null)
101    {
102      throw new IllegalArgumentException("javaArguments cannot be null.");
103    }
104    if (title == null)
105    {
106      throw new IllegalArgumentException("title cannot be null.");
107    }
108    if (message == null)
109    {
110      throw new IllegalArgumentException("message cannot be null.");
111    }
112    setTitle(title.toString());
113    this.message = message;
114    this.javaArguments = javaArguments;
115    getContentPane().add(createPanel());
116    pack();
117
118    updateContents();
119
120    int minWidth = (int) getPreferredSize().getWidth();
121    int minHeight = (int) getPreferredSize().getHeight();
122    addComponentListener(new MinimumSizeComponentListener(this, minWidth,
123        minHeight));
124    getRootPane().setDefaultButton(okButton);
125
126    addWindowListener(new WindowAdapter()
127    {
128      @Override
129      public void windowClosing(WindowEvent e)
130      {
131        cancelClicked();
132      }
133    });
134    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
135
136    Utilities.centerOnComponent(this, parent);
137  }
138
139  /**
140   * Returns <CODE>true</CODE> if the user clicked on cancel and
141   * <CODE>false</CODE> otherwise.
142   * @return <CODE>true</CODE> if the user clicked on cancel and
143   * <CODE>false</CODE> otherwise.
144   */
145  public boolean isCanceled()
146  {
147    return isCanceled;
148  }
149
150  /**
151   * Returns the java arguments object representing the input of the user
152   * in this panel.  The method assumes that the values in the panel are
153   * valid.
154   * @return the java arguments object representing the input of the user
155   * in this panel.
156   */
157  public JavaArguments getJavaArguments()
158  {
159    JavaArguments javaArguments = new JavaArguments();
160
161    String sMaxMemory = tfMaxMemory.getText().trim();
162    if (sMaxMemory.length() > 0)
163    {
164      javaArguments.setMaxMemory(Integer.parseInt(sMaxMemory));
165    }
166    String sInitialMemory = tfInitialMemory.getText().trim();
167    if (sInitialMemory.length() > 0)
168    {
169      javaArguments.setInitialMemory(Integer.parseInt(sInitialMemory));
170    }
171    String[] args = getOtherArguments();
172    if (args.length > 0)
173    {
174      javaArguments.setAdditionalArguments(args);
175    }
176    return javaArguments;
177  }
178
179  private String[] getOtherArguments()
180  {
181    String sArgs = this.tfOtherArguments.getText().trim();
182    if (sArgs.length() <= 0)
183    {
184      return new String[]{};
185    }
186
187    String[] args = sArgs.split(" ");
188    ArrayList<String> array = new ArrayList<>();
189    for (String arg : args)
190    {
191      if (arg.length() > 0)
192      {
193        array.add(arg);
194      }
195    }
196    return array.toArray(new String[array.size()]);
197  }
198
199  /**
200   * Creates and returns the panel of the dialog.
201   * @return the panel of the dialog.
202   */
203  private JPanel createPanel()
204  {
205    GridBagConstraints gbc = new GridBagConstraints();
206
207    JPanel contentPanel = new JPanel(new GridBagLayout());
208    contentPanel.setBackground(UIFactory.DEFAULT_BACKGROUND);
209
210    JPanel topPanel = new JPanel(new GridBagLayout());
211    topPanel.setBorder(UIFactory.DIALOG_PANEL_BORDER);
212    topPanel.setBackground(UIFactory.CURRENT_STEP_PANEL_BACKGROUND);
213    Insets insets = UIFactory.getCurrentStepPanelInsets();
214    insets.bottom = 0;
215    gbc.insets = insets;
216    gbc.fill = GridBagConstraints.BOTH;
217    gbc.weightx = 1.0;
218    gbc.weighty = 0.0;
219    gbc.gridwidth = 3;
220    gbc.gridx = 0;
221    gbc.gridy = 0;
222    LocalizableMessage title = INFO_JAVA_RUNTIME_SETTINGS_TITLE.get();
223    JLabel l =
224        UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, title,
225            UIFactory.TextStyle.TITLE);
226    l.setOpaque(false);
227    topPanel.add(l, gbc);
228
229    JTextComponent instructionsPane =
230      UIFactory.makeHtmlPane(message, UIFactory.INSTRUCTIONS_FONT);
231    instructionsPane.setOpaque(false);
232    instructionsPane.setEditable(false);
233
234    gbc.gridy ++;
235    gbc.insets.top = UIFactory.TOP_INSET_INPUT_SUBPANEL;
236    topPanel.add(instructionsPane, gbc);
237
238    gbc.gridy ++;
239    gbc.insets.top = UIFactory.TOP_INSET_INPUT_SUBPANEL;
240    gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL;
241
242    inputContainer = new JPanel(new CardLayout());
243    inputContainer.setOpaque(false);
244    inputContainer.add(createInputPanel(), INPUT_PANEL);
245    JPanel checkingPanel = UIFactory.makeJPanel();
246    checkingPanel.setLayout(new GridBagLayout());
247    checkingPanel.add(UIFactory.makeJLabel(UIFactory.IconType.WAIT,
248        INFO_GENERAL_CHECKING_DATA.get(),
249        UIFactory.TextStyle.PRIMARY_FIELD_VALID),
250        new GridBagConstraints());
251    inputContainer.add(checkingPanel, CHECKING_PANEL);
252
253    topPanel.add(inputContainer, gbc);
254    gbc.weighty = 1.0;
255    gbc.gridy ++;
256    gbc.insets = UIFactory.getEmptyInsets();
257    topPanel.add(Box.createVerticalGlue(), gbc);
258
259    gbc.gridx = 0;
260    gbc.gridy = 0;
261    contentPanel.add(topPanel, gbc);
262    gbc.weighty = 0.0;
263    gbc.gridy ++;
264    gbc.insets = UIFactory.getButtonsPanelInsets();
265    contentPanel.add(createButtonsPanel(), gbc);
266
267    return contentPanel;
268  }
269
270  /**
271   * Creates and returns the input sub panel: the panel with all the widgets
272   * that are used to define the security options.
273   * @return the input sub panel.
274   */
275  private Component createInputPanel()
276  {
277    JPanel inputPanel = new JPanel(new GridBagLayout());
278    inputPanel.setOpaque(false);
279
280    lInitialMemory = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
281        INFO_INITIAL_MEMORY_LABEL.get(),
282        UIFactory.TextStyle.PRIMARY_FIELD_VALID);
283    lInitialMemory.setOpaque(false);
284    tfInitialMemory = UIFactory.makeJTextField(LocalizableMessage.EMPTY,
285        INFO_INITIAL_MEMORY_TOOLTIP.get(), 10, UIFactory.TextStyle.TEXTFIELD);
286    lInitialMemory.setLabelFor(tfInitialMemory);
287
288    lMaxMemory = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
289        INFO_MAX_MEMORY_LABEL.get(),
290        UIFactory.TextStyle.PRIMARY_FIELD_VALID);
291    lMaxMemory.setOpaque(false);
292    tfMaxMemory = UIFactory.makeJTextField(LocalizableMessage.EMPTY,
293        INFO_MAX_MEMORY_TOOLTIP.get(), 10, UIFactory.TextStyle.TEXTFIELD);
294    lMaxMemory.setLabelFor(tfMaxMemory);
295
296    lOtherArguments = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
297        INFO_OTHER_JAVA_ARGUMENTS_LABEL.get(),
298        UIFactory.TextStyle.PRIMARY_FIELD_VALID);
299    lOtherArguments.setOpaque(false);
300    tfOtherArguments = UIFactory.makeJTextField(LocalizableMessage.EMPTY,
301        INFO_OTHER_JAVA_ARGUMENTS_TOOLTIP.get(), 30,
302        UIFactory.TextStyle.TEXTFIELD);
303    lOtherArguments.setLabelFor(tfOtherArguments);
304
305    GridBagConstraints gbc = new GridBagConstraints();
306    gbc.fill = GridBagConstraints.HORIZONTAL;
307    gbc.gridx = 0;
308    gbc.gridy = 0;
309    gbc.weightx = 0.0;
310    inputPanel.add(lInitialMemory, gbc);
311    gbc.gridx = 1;
312    gbc.weightx = 1.0;
313    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
314    inputPanel.add(tfInitialMemory, gbc);
315    gbc.weightx = 0.0;
316    gbc.gridx = 2;
317    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
318    JLabel lMb = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
319        INFO_MEGABYTE_LABEL.get(),
320        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
321    lMb.setOpaque(false);
322    inputPanel.add(lMb, gbc);
323    gbc.gridx = 1;
324    gbc.gridy ++;
325    gbc.gridwidth = 2;
326    gbc.insets.top = 3;
327    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
328    inputPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
329        INFO_JAVA_ARGUMENTS_LEAVE_EMPTY.get(),
330        UIFactory.TextStyle.INLINE_HELP), gbc);
331
332    gbc.gridy ++;
333    gbc.gridwidth = 1;
334    gbc.gridx = 0;
335    gbc.weightx = 0.0;
336    gbc.insets.left = 0;
337    gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
338    inputPanel.add(lMaxMemory, gbc);
339    gbc.gridx = 1;
340    gbc.weightx = 1.0;
341    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
342    inputPanel.add(tfMaxMemory, gbc);
343    gbc.weightx = 0.0;
344    gbc.gridx = 2;
345    gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
346    lMb = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
347        INFO_MEGABYTE_LABEL.get(),
348        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
349    lMb.setOpaque(false);
350    inputPanel.add(lMb, gbc);
351    gbc.gridx = 1;
352    gbc.gridy ++;
353    gbc.gridwidth = 2;
354    gbc.insets.top = 3;
355    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
356    inputPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
357        INFO_JAVA_ARGUMENTS_LEAVE_EMPTY.get(),
358        UIFactory.TextStyle.INLINE_HELP), gbc);
359
360    gbc.gridy ++;
361    gbc.gridwidth = 1;
362    gbc.gridx = 0;
363    gbc.weightx = 0.0;
364    gbc.insets.left = 0;
365    gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
366    inputPanel.add(lOtherArguments, gbc);
367    gbc.gridx = 1;
368    gbc.weightx = 1.0;
369    gbc.gridwidth = 2;
370    gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
371    inputPanel.add(tfOtherArguments, gbc);
372
373    gbc.gridy ++;
374    gbc.gridx = 0;
375    gbc.weighty = 1.0;
376    gbc.insets = UIFactory.getEmptyInsets();
377    inputPanel.add(Box.createVerticalGlue(), gbc);
378
379    return inputPanel;
380  }
381
382  /**
383   * Creates and returns the buttons OK/CANCEL sub panel.
384   * @return the buttons OK/CANCEL sub panel.
385   */
386  private Component createButtonsPanel()
387  {
388    JPanel buttonsPanel = new JPanel(new GridBagLayout());
389    buttonsPanel.setOpaque(false);
390    GridBagConstraints gbc = new GridBagConstraints();
391    gbc.fill = GridBagConstraints.HORIZONTAL;
392    gbc.gridwidth = 4;
393    gbc.insets = UIFactory.getEmptyInsets();
394    gbc.insets.left = UIFactory.getCurrentStepPanelInsets().left;
395    buttonsPanel.add(UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
396        null, UIFactory.TextStyle.NO_STYLE), gbc);
397    gbc.weightx = 1.0;
398    gbc.gridwidth--;
399    gbc.insets.left = 0;
400    buttonsPanel.add(Box.createHorizontalGlue(), gbc);
401    gbc.gridwidth = GridBagConstraints.RELATIVE;
402    gbc.fill = GridBagConstraints.NONE;
403    gbc.weightx = 0.0;
404    okButton =
405      UIFactory.makeJButton(INFO_OK_BUTTON_LABEL.get(),
406          INFO_JAVA_ARGUMENTS_OK_BUTTON_TOOLTIP.get());
407    buttonsPanel.add(okButton, gbc);
408    okButton.addActionListener(new ActionListener()
409    {
410      @Override
411      public void actionPerformed(ActionEvent ev)
412      {
413        okClicked();
414      }
415    });
416
417    gbc.gridwidth = GridBagConstraints.REMAINDER;
418    gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
419    cancelButton =
420      UIFactory.makeJButton(INFO_CANCEL_BUTTON_LABEL.get(),
421          INFO_JAVA_ARGUMENTS_CANCEL_BUTTON_TOOLTIP.get());
422    buttonsPanel.add(cancelButton, gbc);
423    cancelButton.addActionListener(new ActionListener()
424    {
425      @Override
426      public void actionPerformed(ActionEvent ev)
427      {
428        cancelClicked();
429      }
430    });
431
432    return buttonsPanel;
433  }
434
435  /** Method called when user clicks on cancel. */
436  private void cancelClicked()
437  {
438    isCanceled = true;
439    dispose();
440  }
441
442  /** Method called when user clicks on OK. */
443  private void okClicked()
444  {
445    BackgroundTask<ArrayList<LocalizableMessage>> worker =
446      new BackgroundTask<ArrayList<LocalizableMessage>>()
447    {
448      @Override
449      public ArrayList<LocalizableMessage> processBackgroundTask()
450      {
451        setValidLater(lInitialMemory, true);
452        setValidLater(lMaxMemory, true);
453        setValidLater(lOtherArguments, true);
454        int initialMemory = -1;
455        int maxMemory = -1;
456        ArrayList<LocalizableMessage> errorMsgs = new ArrayList<>();
457        try
458        {
459          String sInitialMemory = tfInitialMemory.getText().trim();
460          if (sInitialMemory.length() > 0)
461          {
462            initialMemory = Integer.parseInt(sInitialMemory);
463            if (initialMemory <= 0)
464            {
465              initialMemory = -1;
466              errorMsgs.add(ERR_INITIAL_MEMORY_VALUE.get());
467              setValidLater(lInitialMemory, false);
468            }
469          }
470        }
471        catch (Throwable t)
472        {
473          errorMsgs.add(ERR_INITIAL_MEMORY_VALUE.get());
474          setValidLater(lInitialMemory, false);
475        }
476        try
477        {
478          String sMaxMemory = tfMaxMemory.getText().trim();
479          if (sMaxMemory.length() > 0)
480          {
481            maxMemory = Integer.parseInt(sMaxMemory);
482            if (maxMemory <= 0)
483            {
484              maxMemory = -1;
485              errorMsgs.add(ERR_MAX_MEMORY_VALUE.get());
486              setValidLater(lMaxMemory, false);
487            }
488          }
489        }
490        catch (Throwable t)
491        {
492          errorMsgs.add(ERR_MAX_MEMORY_VALUE.get());
493          setValidLater(lMaxMemory, false);
494        }
495        if (maxMemory != -1
496            && initialMemory != -1
497            && initialMemory > maxMemory)
498        {
499          errorMsgs.add(ERR_MAX_MEMORY_BIGGER_THAN_INITIAL_MEMORY.get());
500          setValidLater(lMaxMemory, false);
501          setValidLater(lInitialMemory, false);
502        }
503        if (errorMsgs.isEmpty())
504        {
505          // Try the options together, often there are interdependencies.
506          ArrayList<LocalizableMessage> allErrors = new ArrayList<>();
507          checkAllArgumentsTogether(initialMemory, maxMemory, allErrors);
508
509          if (!allErrors.isEmpty())
510          {
511            ArrayList<LocalizableMessage> memoryErrors = new ArrayList<>();
512            checkMemoryArguments(initialMemory, maxMemory, memoryErrors);
513            ArrayList<LocalizableMessage> otherErrors = new ArrayList<>();
514            checkOtherArguments(otherErrors);
515
516            if (!memoryErrors.isEmpty())
517            {
518              errorMsgs.addAll(memoryErrors);
519              if (!otherErrors.isEmpty())
520              {
521                errorMsgs.addAll(otherErrors);
522              }
523            }
524            else
525            {
526              if (!otherErrors.isEmpty())
527              {
528                errorMsgs.addAll(otherErrors);
529              }
530              else
531              {
532                setValidLater(lInitialMemory, false);
533                setValidLater(lMaxMemory, false);
534                setValidLater(lOtherArguments, false);
535                // It appears that the arguments are not compatible together.
536                errorMsgs.add(
537                    ERR_MEMORY_AND_OTHER_ARGUMENTS_NOT_COMPATIBLE.get());
538              }
539            }
540          }
541        }
542        return errorMsgs;
543      }
544
545      @Override
546      public void backgroundTaskCompleted(ArrayList<LocalizableMessage> returnValue,
547          Throwable throwable)
548      {
549        setCheckingVisible(false);
550        if (throwable != null)
551        {
552          // Bug
553          throwable.printStackTrace();
554          displayError(
555              getThrowableMsg(INFO_BUG_MSG.get(), throwable),
556              INFO_ERROR_TITLE.get());
557          cancelButton.setEnabled(true);
558          okButton.setEnabled(true);
559        }
560        else
561        {
562          cancelButton.setEnabled(true);
563          okButton.setEnabled(true);
564
565          if (!returnValue.isEmpty())
566          {
567            displayError(Utils.getMessageFromCollection(returnValue, "\n"),
568                INFO_ERROR_TITLE.get());
569          }
570          else
571          {
572            isCanceled = false;
573            dispose();
574          }
575        }
576      }
577    };
578    setCheckingVisible(true);
579    cancelButton.setEnabled(false);
580    okButton.setEnabled(false);
581    worker.startBackgroundTask();
582  }
583
584  /**
585   * Displays an error message dialog.
586   *
587   * @param msg
588   *          the error message.
589   * @param title
590   *          the title for the dialog.
591   */
592  private void displayError(LocalizableMessage msg, LocalizableMessage title)
593  {
594    Utilities.displayError(this, msg, title);
595    toFront();
596  }
597
598  /** Updates the widgets on the dialog with the contents of the securityOptions object. */
599  private void updateContents()
600  {
601    if (javaArguments.getInitialMemory() > 0)
602    {
603      tfInitialMemory.setText(String.valueOf(javaArguments.getInitialMemory()));
604    }
605    else
606    {
607      tfInitialMemory.setText("");
608    }
609    if (javaArguments.getMaxMemory() > 0)
610    {
611      tfMaxMemory.setText(String.valueOf(javaArguments.getMaxMemory()));
612    }
613    else
614    {
615      tfMaxMemory.setText("");
616    }
617    if (javaArguments.getAdditionalArguments() != null)
618    {
619      StringBuilder sb = new StringBuilder();
620      for (String arg : javaArguments.getAdditionalArguments())
621      {
622        if (sb.length() > 0)
623        {
624          sb.append(" ");
625        }
626        sb.append(arg);
627      }
628      tfOtherArguments.setText(sb.toString());
629    }
630    else
631    {
632      tfOtherArguments.setText("");
633    }
634  }
635
636  /**
637   * Method that updates the text style of a provided component by calling
638   * SwingUtilities.invokeLater.  This method is aimed to be called outside
639   * the event thread (calling it from the event thread will also work though).
640   * @param comp the component to be updated.
641   * @param valid whether to use a TextStyle to mark the component as valid
642   * or as invalid.
643   */
644  private void setValidLater(final JComponent comp, final boolean valid)
645  {
646    SwingUtilities.invokeLater(new Runnable()
647    {
648      @Override
649      public void run()
650      {
651        UIFactory.setTextStyle(comp,
652            valid ? UIFactory.TextStyle.PRIMARY_FIELD_VALID :
653              UIFactory.TextStyle.PRIMARY_FIELD_INVALID);
654      }
655    });
656  }
657
658  /**
659   * This method displays a working progress icon in the panel.
660   * @param visible whether the icon must be displayed or not.
661   */
662  private void setCheckingVisible(boolean visible)
663  {
664    if (visible != isCheckingVisible && inputContainer != null)
665    {
666      CardLayout cl = (CardLayout) inputContainer.getLayout();
667      if (visible)
668      {
669        cl.show(inputContainer, CHECKING_PANEL);
670      }
671      else
672      {
673        cl.show(inputContainer, INPUT_PANEL);
674      }
675      isCheckingVisible = visible;
676    }
677  }
678
679  /**
680   * Method written for testing purposes.
681   * @param args the arguments to be passed to the test program.
682   */
683  public static void main(String[] args)
684  {
685    try
686    {
687      JavaArguments javaArgs = new JavaArguments();
688      javaArgs.setInitialMemory(100);
689      javaArgs.setMaxMemory(99);
690      javaArgs.setAdditionalArguments(new String[]{"" , "-client", "-XX"});
691      // UIFactory.initialize();
692      JavaArgumentsDialog dlg = new JavaArgumentsDialog(new JFrame(), javaArgs,
693          LocalizableMessage.raw("my title"),
694          LocalizableMessage.raw("Set the java arguments for the test command-line."));
695      dlg.pack();
696      dlg.setVisible(true);
697    } catch (Exception ex)
698    {
699      ex.printStackTrace();
700    }
701  }
702
703  private static final String INSTALL_PATH =
704    Utils.getInstallPathFromClasspath();
705
706  private void checkOptions(String options, Collection<LocalizableMessage> errorMsgs,
707      JLabel l,  LocalizableMessage errorMsg)
708  {
709    checkOptions(options, errorMsgs, new JLabel[]{l}, errorMsg);
710  }
711
712  private void checkOptions(
713          String options, Collection<LocalizableMessage> errorMsgs, JLabel[] ls,  LocalizableMessage errorMsg)
714  {
715    String javaHome = System.getProperty("java.home");
716    if (javaHome == null || javaHome.length() == 0)
717    {
718      javaHome = System.getenv(SetupUtils.OPENDJ_JAVA_HOME);
719    }
720    if (!Utils.supportsOption(options, javaHome, INSTALL_PATH))
721    {
722      for (JLabel l : ls)
723      {
724        setValidLater(l, false);
725      }
726      errorMsgs.add(errorMsg);
727    }
728  }
729
730  private LocalizableMessage getMemoryErrorMessage(LocalizableMessage msg, int memValue)
731  {
732    // 2048 MB is acceptable max heap size on 32Bit OS
733    if (memValue < 2048)
734    {
735      return msg;
736    }
737    else
738    {
739      LocalizableMessageBuilder mb = new LocalizableMessageBuilder();
740      mb.append(msg);
741      mb.append("  ");
742      mb.append(ERR_MEMORY_32_BIT_LIMIT.get());
743      return mb.toMessage();
744    }
745  }
746
747  private void checkMemoryArguments(int initialMemory, int maxMemory,
748      Collection<LocalizableMessage> errorMsgs)
749  {
750    setValidLater(lInitialMemory, true);
751    setValidLater(lMaxMemory, true);
752    if (initialMemory != -1)
753    {
754      if (maxMemory != -1)
755      {
756        LocalizableMessage msg = getMemoryErrorMessage(ERR_MEMORY_VALUE_EXTENDED.get(
757              JavaArguments.getInitialMemoryGenericArgument(),
758              JavaArguments.getMaxMemoryGenericArgument()), maxMemory);
759        String sMemory =
760          JavaArguments.getInitialMemoryArgument(initialMemory) + " "+
761          JavaArguments.getMaxMemoryArgument(maxMemory);
762        checkOptions(sMemory,
763            errorMsgs,
764            new JLabel[] {lInitialMemory, lMaxMemory},
765            msg);
766      }
767      else
768      {
769        LocalizableMessage msg = getMemoryErrorMessage(
770            ERR_INITIAL_MEMORY_VALUE_EXTENDED.get(
771                JavaArguments.getInitialMemoryGenericArgument()),
772                initialMemory);
773        checkOptions(JavaArguments.getInitialMemoryArgument(initialMemory),
774            errorMsgs,
775            lInitialMemory,
776            msg);
777      }
778    }
779    else if (maxMemory != -1)
780    {
781      LocalizableMessage msg = getMemoryErrorMessage(
782          ERR_MAX_MEMORY_VALUE_EXTENDED.get(
783              JavaArguments.getMaxMemoryGenericArgument()), maxMemory);
784      checkOptions(JavaArguments.getMaxMemoryArgument(maxMemory),
785          errorMsgs,
786          lMaxMemory,
787          msg);
788    }
789  }
790
791  private void checkAllArgumentsTogether(int initialMemory, int maxMemory,
792      Collection<LocalizableMessage> errorMsgs)
793  {
794    setValidLater(lInitialMemory, true);
795    setValidLater(lMaxMemory, true);
796    setValidLater(lOtherArguments, true);
797    ArrayList<JLabel> ls = new ArrayList<>();
798    StringBuilder sb = new StringBuilder();
799
800    if (initialMemory != -1)
801    {
802      if (maxMemory != -1)
803      {
804        String sMemory =
805          JavaArguments.getInitialMemoryArgument(initialMemory) + " "+
806          JavaArguments.getMaxMemoryArgument(maxMemory);
807        sb.append(sMemory);
808        ls.add(lInitialMemory);
809        ls.add(lMaxMemory);
810      }
811      else
812      {
813        sb.append(JavaArguments.getInitialMemoryArgument(initialMemory));
814        ls.add(lInitialMemory);
815      }
816    }
817    else if (maxMemory != -1)
818    {
819      sb.append(JavaArguments.getMaxMemoryArgument(maxMemory));
820      ls.add(lMaxMemory);
821    }
822
823    String[] otherArgs = getOtherArguments();
824    if (otherArgs.length > 0)
825    {
826      ls.add(lOtherArguments);
827      for (String arg : otherArgs)
828      {
829        if (sb.length() > 0)
830        {
831          sb.append(" ");
832        }
833        sb.append(arg);
834      }
835    }
836    if (sb.length() > 0)
837    {
838      checkOptions(sb.toString(), errorMsgs,
839          ls.toArray(new JLabel[ls.size()]),
840          ERR_GENERIC_JAVA_ARGUMENT.get(sb));
841    }
842  }
843
844  private void checkOtherArguments(Collection<LocalizableMessage> errorMsgs)
845  {
846    setValidLater(lOtherArguments, true);
847    StringBuilder sb = new StringBuilder();
848
849    String[] otherArgs = getOtherArguments();
850    if (otherArgs.length > 0)
851    {
852      for (String arg : otherArgs)
853      {
854        if (sb.length() > 0)
855        {
856          sb.append(" ");
857        }
858        sb.append(arg);
859      }
860    }
861    if (sb.length() > 0)
862    {
863      checkOptions(sb.toString(), errorMsgs, lOtherArguments,
864          ERR_GENERIC_JAVA_ARGUMENT.get(sb));
865    }
866  }
867}