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      public void actionPerformed(ActionEvent ev)
411      {
412        okClicked();
413      }
414    });
415
416    gbc.gridwidth = GridBagConstraints.REMAINDER;
417    gbc.insets.left = UIFactory.HORIZONTAL_INSET_BETWEEN_BUTTONS;
418    cancelButton =
419      UIFactory.makeJButton(INFO_CANCEL_BUTTON_LABEL.get(),
420          INFO_JAVA_ARGUMENTS_CANCEL_BUTTON_TOOLTIP.get());
421    buttonsPanel.add(cancelButton, gbc);
422    cancelButton.addActionListener(new ActionListener()
423    {
424      public void actionPerformed(ActionEvent ev)
425      {
426        cancelClicked();
427      }
428    });
429
430    return buttonsPanel;
431  }
432
433  /**
434   * Method called when user clicks on cancel.
435   *
436   */
437  private void cancelClicked()
438  {
439    isCanceled = true;
440    dispose();
441  }
442
443  /**
444   * Method called when user clicks on OK.
445   *
446   */
447  private void okClicked()
448  {
449    BackgroundTask<ArrayList<LocalizableMessage>> worker =
450      new BackgroundTask<ArrayList<LocalizableMessage>>()
451    {
452      @Override
453      public ArrayList<LocalizableMessage> processBackgroundTask()
454      {
455        setValidLater(lInitialMemory, true);
456        setValidLater(lMaxMemory, true);
457        setValidLater(lOtherArguments, true);
458        int initialMemory = -1;
459        int maxMemory = -1;
460        ArrayList<LocalizableMessage> errorMsgs = new ArrayList<>();
461        try
462        {
463          String sInitialMemory = tfInitialMemory.getText().trim();
464          if (sInitialMemory.length() > 0)
465          {
466            initialMemory = Integer.parseInt(sInitialMemory);
467            if (initialMemory <= 0)
468            {
469              initialMemory = -1;
470              errorMsgs.add(ERR_INITIAL_MEMORY_VALUE.get());
471              setValidLater(lInitialMemory, false);
472            }
473          }
474        }
475        catch (Throwable t)
476        {
477          errorMsgs.add(ERR_INITIAL_MEMORY_VALUE.get());
478          setValidLater(lInitialMemory, false);
479        }
480        try
481        {
482          String sMaxMemory = tfMaxMemory.getText().trim();
483          if (sMaxMemory.length() > 0)
484          {
485            maxMemory = Integer.parseInt(sMaxMemory);
486            if (maxMemory <= 0)
487            {
488              maxMemory = -1;
489              errorMsgs.add(ERR_MAX_MEMORY_VALUE.get());
490              setValidLater(lMaxMemory, false);
491            }
492          }
493        }
494        catch (Throwable t)
495        {
496          errorMsgs.add(ERR_MAX_MEMORY_VALUE.get());
497          setValidLater(lMaxMemory, false);
498        }
499        if (maxMemory != -1
500            && initialMemory != -1
501            && initialMemory > maxMemory)
502        {
503          errorMsgs.add(ERR_MAX_MEMORY_BIGGER_THAN_INITIAL_MEMORY.get());
504          setValidLater(lMaxMemory, false);
505          setValidLater(lInitialMemory, false);
506        }
507        if (errorMsgs.isEmpty())
508        {
509          // Try the options together, often there are interdependencies.
510          ArrayList<LocalizableMessage> allErrors = new ArrayList<>();
511          checkAllArgumentsTogether(initialMemory, maxMemory, allErrors);
512
513          if (!allErrors.isEmpty())
514          {
515            ArrayList<LocalizableMessage> memoryErrors = new ArrayList<>();
516            checkMemoryArguments(initialMemory, maxMemory, memoryErrors);
517            ArrayList<LocalizableMessage> otherErrors = new ArrayList<>();
518            checkOtherArguments(otherErrors);
519
520            if (!memoryErrors.isEmpty())
521            {
522              errorMsgs.addAll(memoryErrors);
523              if (!otherErrors.isEmpty())
524              {
525                errorMsgs.addAll(otherErrors);
526              }
527            }
528            else
529            {
530              if (!otherErrors.isEmpty())
531              {
532                errorMsgs.addAll(otherErrors);
533              }
534              else
535              {
536                setValidLater(lInitialMemory, false);
537                setValidLater(lMaxMemory, false);
538                setValidLater(lOtherArguments, false);
539                // It appears that the arguments are not compatible together.
540                errorMsgs.add(
541                    ERR_MEMORY_AND_OTHER_ARGUMENTS_NOT_COMPATIBLE.get());
542              }
543            }
544          }
545        }
546        return errorMsgs;
547      }
548
549      @Override
550      public void backgroundTaskCompleted(ArrayList<LocalizableMessage> returnValue,
551          Throwable throwable)
552      {
553        setCheckingVisible(false);
554        if (throwable != null)
555        {
556          // Bug
557          throwable.printStackTrace();
558          displayError(
559              getThrowableMsg(INFO_BUG_MSG.get(), throwable),
560              INFO_ERROR_TITLE.get());
561          cancelButton.setEnabled(true);
562          okButton.setEnabled(true);
563        }
564        else
565        {
566          cancelButton.setEnabled(true);
567          okButton.setEnabled(true);
568
569          if (!returnValue.isEmpty())
570          {
571            displayError(Utils.getMessageFromCollection(returnValue, "\n"),
572                INFO_ERROR_TITLE.get());
573          }
574          else
575          {
576            isCanceled = false;
577            dispose();
578          }
579        }
580      }
581    };
582    setCheckingVisible(true);
583    cancelButton.setEnabled(false);
584    okButton.setEnabled(false);
585    worker.startBackgroundTask();
586  }
587
588  /**
589   * Displays an error message dialog.
590   *
591   * @param msg
592   *          the error message.
593   * @param title
594   *          the title for the dialog.
595   */
596  private void displayError(LocalizableMessage msg, LocalizableMessage title)
597  {
598    Utilities.displayError(this, msg, title);
599    toFront();
600  }
601
602  /**
603   * Updates the widgets on the dialog with the contents of the securityOptions
604   * object.
605   *
606   */
607  private void updateContents()
608  {
609    if (javaArguments.getInitialMemory() > 0)
610    {
611      tfInitialMemory.setText(String.valueOf(javaArguments.getInitialMemory()));
612    }
613    else
614    {
615      tfInitialMemory.setText("");
616    }
617    if (javaArguments.getMaxMemory() > 0)
618    {
619      tfMaxMemory.setText(String.valueOf(javaArguments.getMaxMemory()));
620    }
621    else
622    {
623      tfMaxMemory.setText("");
624    }
625    if (javaArguments.getAdditionalArguments() != null)
626    {
627      StringBuilder sb = new StringBuilder();
628      for (String arg : javaArguments.getAdditionalArguments())
629      {
630        if (sb.length() > 0)
631        {
632          sb.append(" ");
633        }
634        sb.append(arg);
635      }
636      tfOtherArguments.setText(sb.toString());
637    }
638    else
639    {
640      tfOtherArguments.setText("");
641    }
642  }
643
644  /**
645   * Method that updates the text style of a provided component by calling
646   * SwingUtilities.invokeLater.  This method is aimed to be called outside
647   * the event thread (calling it from the event thread will also work though).
648   * @param comp the component to be updated.
649   * @param valid whether to use a TextStyle to mark the component as valid
650   * or as invalid.
651   */
652  private void setValidLater(final JComponent comp, final boolean valid)
653  {
654    SwingUtilities.invokeLater(new Runnable()
655    {
656      public void run()
657      {
658        UIFactory.setTextStyle(comp,
659            valid ? UIFactory.TextStyle.PRIMARY_FIELD_VALID :
660              UIFactory.TextStyle.PRIMARY_FIELD_INVALID);
661      }
662    });
663  }
664
665  /**
666   * This method displays a working progress icon in the panel.
667   * @param visible whether the icon must be displayed or not.
668   */
669  private void setCheckingVisible(boolean visible)
670  {
671    if (visible != isCheckingVisible && inputContainer != null)
672    {
673      CardLayout cl = (CardLayout) inputContainer.getLayout();
674      if (visible)
675      {
676        cl.show(inputContainer, CHECKING_PANEL);
677      }
678      else
679      {
680        cl.show(inputContainer, INPUT_PANEL);
681      }
682      isCheckingVisible = visible;
683    }
684  }
685
686  /**
687   * Method written for testing purposes.
688   * @param args the arguments to be passed to the test program.
689   */
690  public static void main(String[] args)
691  {
692    try
693    {
694      JavaArguments javaArgs = new JavaArguments();
695      javaArgs.setInitialMemory(100);
696      javaArgs.setMaxMemory(99);
697      javaArgs.setAdditionalArguments(new String[]{"" , "-client", "-XX"});
698      // UIFactory.initialize();
699      JavaArgumentsDialog dlg = new JavaArgumentsDialog(new JFrame(), javaArgs,
700          LocalizableMessage.raw("my title"),
701          LocalizableMessage.raw("Set the java arguments for the test command-line."));
702      dlg.pack();
703      dlg.setVisible(true);
704    } catch (Exception ex)
705    {
706      ex.printStackTrace();
707    }
708  }
709
710  private static final String INSTALL_PATH =
711    Utils.getInstallPathFromClasspath();
712
713  private void checkOptions(String options, Collection<LocalizableMessage> errorMsgs,
714      JLabel l,  LocalizableMessage errorMsg)
715  {
716    checkOptions(options, errorMsgs, new JLabel[]{l}, errorMsg);
717  }
718
719  private void checkOptions(
720          String options, Collection<LocalizableMessage> errorMsgs, JLabel[] ls,  LocalizableMessage errorMsg)
721  {
722    String javaHome = System.getProperty("java.home");
723    if (javaHome == null || javaHome.length() == 0)
724    {
725      javaHome = System.getenv(SetupUtils.OPENDJ_JAVA_HOME);
726    }
727    if (!Utils.supportsOption(options, javaHome, INSTALL_PATH))
728    {
729      for (JLabel l : ls)
730      {
731        setValidLater(l, false);
732      }
733      errorMsgs.add(errorMsg);
734    }
735  }
736
737  private LocalizableMessage getMemoryErrorMessage(LocalizableMessage msg, int memValue)
738  {
739    // 2048 MB is acceptable max heap size on 32Bit OS
740    if (memValue < 2048)
741    {
742      return msg;
743    }
744    else
745    {
746      LocalizableMessageBuilder mb = new LocalizableMessageBuilder();
747      mb.append(msg);
748      mb.append("  ");
749      mb.append(ERR_MEMORY_32_BIT_LIMIT.get());
750      return mb.toMessage();
751    }
752  }
753
754  private void checkMemoryArguments(int initialMemory, int maxMemory,
755      Collection<LocalizableMessage> errorMsgs)
756  {
757    setValidLater(lInitialMemory, true);
758    setValidLater(lMaxMemory, true);
759    if (initialMemory != -1)
760    {
761      if (maxMemory != -1)
762      {
763        LocalizableMessage msg = getMemoryErrorMessage(ERR_MEMORY_VALUE_EXTENDED.get(
764              JavaArguments.getInitialMemoryGenericArgument(),
765              JavaArguments.getMaxMemoryGenericArgument()), maxMemory);
766        String sMemory =
767          JavaArguments.getInitialMemoryArgument(initialMemory) + " "+
768          JavaArguments.getMaxMemoryArgument(maxMemory);
769        checkOptions(sMemory,
770            errorMsgs,
771            new JLabel[] {lInitialMemory, lMaxMemory},
772            msg);
773      }
774      else
775      {
776        LocalizableMessage msg = getMemoryErrorMessage(
777            ERR_INITIAL_MEMORY_VALUE_EXTENDED.get(
778                JavaArguments.getInitialMemoryGenericArgument()),
779                initialMemory);
780        checkOptions(JavaArguments.getInitialMemoryArgument(initialMemory),
781            errorMsgs,
782            lInitialMemory,
783            msg);
784      }
785    }
786    else if (maxMemory != -1)
787    {
788      LocalizableMessage msg = getMemoryErrorMessage(
789          ERR_MAX_MEMORY_VALUE_EXTENDED.get(
790              JavaArguments.getMaxMemoryGenericArgument()), maxMemory);
791      checkOptions(JavaArguments.getMaxMemoryArgument(maxMemory),
792          errorMsgs,
793          lMaxMemory,
794          msg);
795    }
796  }
797
798  private void checkAllArgumentsTogether(int initialMemory, int maxMemory,
799      Collection<LocalizableMessage> errorMsgs)
800  {
801    setValidLater(lInitialMemory, true);
802    setValidLater(lMaxMemory, true);
803    setValidLater(lOtherArguments, true);
804    ArrayList<JLabel> ls = new ArrayList<>();
805    StringBuilder sb = new StringBuilder();
806
807    if (initialMemory != -1)
808    {
809      if (maxMemory != -1)
810      {
811        String sMemory =
812          JavaArguments.getInitialMemoryArgument(initialMemory) + " "+
813          JavaArguments.getMaxMemoryArgument(maxMemory);
814        sb.append(sMemory);
815        ls.add(lInitialMemory);
816        ls.add(lMaxMemory);
817      }
818      else
819      {
820        sb.append(JavaArguments.getInitialMemoryArgument(initialMemory));
821        ls.add(lInitialMemory);
822      }
823    }
824    else if (maxMemory != -1)
825    {
826      sb.append(JavaArguments.getMaxMemoryArgument(maxMemory));
827      ls.add(lMaxMemory);
828    }
829
830    String[] otherArgs = getOtherArguments();
831    if (otherArgs.length > 0)
832    {
833      ls.add(lOtherArguments);
834      for (String arg : otherArgs)
835      {
836        if (sb.length() > 0)
837        {
838          sb.append(" ");
839        }
840        sb.append(arg);
841      }
842    }
843    if (sb.length() > 0)
844    {
845      checkOptions(sb.toString(), errorMsgs,
846          ls.toArray(new JLabel[ls.size()]),
847          ERR_GENERIC_JAVA_ARGUMENT.get(sb));
848    }
849  }
850
851  private void checkOtherArguments(Collection<LocalizableMessage> errorMsgs)
852  {
853    setValidLater(lOtherArguments, true);
854    StringBuilder sb = new StringBuilder();
855
856    String[] otherArgs = getOtherArguments();
857    if (otherArgs.length > 0)
858    {
859      for (String arg : otherArgs)
860      {
861        if (sb.length() > 0)
862        {
863          sb.append(" ");
864        }
865        sb.append(arg);
866      }
867    }
868    if (sb.length() > 0)
869    {
870      checkOptions(sb.toString(), errorMsgs, lOtherArguments,
871          ERR_GENERIC_JAVA_ARGUMENT.get(sb));
872    }
873  }
874}