001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2008-2010 Sun Microsystems, Inc.
025 *      Portions Copyright 2011-2015 ForgeRock AS
026 */
027package org.opends.guitools.controlpanel.ui;
028
029import static org.opends.messages.AdminToolMessages.*;
030import static org.opends.server.util.CollectionUtils.*;
031
032import static com.forgerock.opendj.util.OperatingSystem.isWindows;
033
034import java.awt.Component;
035import java.awt.GridBagConstraints;
036import java.awt.GridBagLayout;
037import java.awt.event.ActionEvent;
038import java.awt.event.ActionListener;
039import java.io.BufferedReader;
040import java.io.BufferedWriter;
041import java.io.File;
042import java.io.FileReader;
043import java.io.FileWriter;
044import java.io.IOException;
045import java.util.ArrayList;
046import java.util.Collection;
047import java.util.Comparator;
048import java.util.HashSet;
049import java.util.List;
050import java.util.Properties;
051import java.util.Set;
052import java.util.TreeSet;
053
054import javax.swing.ButtonGroup;
055import javax.swing.JButton;
056import javax.swing.JCheckBox;
057import javax.swing.JComponent;
058import javax.swing.JEditorPane;
059import javax.swing.JLabel;
060import javax.swing.JPanel;
061import javax.swing.JRadioButton;
062import javax.swing.JScrollPane;
063import javax.swing.JSeparator;
064import javax.swing.JTable;
065import javax.swing.JTextField;
066import javax.swing.SwingUtilities;
067
068import org.forgerock.i18n.LocalizableMessage;
069import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
070import org.opends.guitools.controlpanel.datamodel.SortableTableModel;
071import org.opends.guitools.controlpanel.event.BrowseActionListener;
072import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
073import org.opends.guitools.controlpanel.task.Task;
074import org.opends.guitools.controlpanel.ui.components.LabelWithHelpIcon;
075import org.opends.guitools.controlpanel.ui.renderer.AttributeCellEditor;
076import org.opends.guitools.controlpanel.ui.renderer.LDAPEntryTableCellRenderer;
077import org.opends.guitools.controlpanel.util.BackgroundTask;
078import org.opends.guitools.controlpanel.util.Utilities;
079import org.opends.quicksetup.Installation;
080import org.opends.quicksetup.util.Utils;
081import org.opends.server.tools.JavaPropertiesTool;
082import org.opends.server.types.OpenDsException;
083import org.opends.server.util.SetupUtils;
084import org.opends.server.util.StaticUtils;
085
086/**
087 * The panel where the user can specify the java arguments and java home to be
088 * used in the command-lines.
089 */
090public class JavaPropertiesPanel extends StatusGenericPanel
091{
092  private static final long serialVersionUID = -7886215660289880597L;
093  private JTextField javaHome;
094  private JRadioButton useOpenDSJavaHome;
095  private JRadioButton useSpecifiedJavaHome;
096  private JButton browse;
097  private JLabel lJavaHome;
098
099  private JRadioButton useOpenDSJavaArgs;
100  private JRadioButton useSpecifiedJavaArgs;
101  private JLabel lJavaArgs;
102  private JTable argumentsTable;
103  private JavaArgumentsTableModel argumentsTableModel;
104  private JScrollPane argumentsScroll;
105
106  private AttributeCellEditor editor;
107
108  private JEditorPane lInitContents;
109
110  private JCheckBox showAll;
111
112  private Set<JavaArgumentsDescriptor> readJavaArguments = new HashSet<>();
113  private Set<JavaArgumentsDescriptor> currentJavaArguments = new HashSet<>();
114  private final Set<String> allScriptNames = newHashSet(
115        "start-ds", "import-ldif.offline", "backup.online", "base64",
116        "create-rc-script", "dsconfig", "dsreplication",
117        "export-ldif.online", "import-ldif.online", "ldapcompare",
118        "ldapdelete", "ldapmodify", "ldappasswordmodify", "ldapsearch",
119        "list-backends", "manage-account", "manage-tasks", "restore.online",
120        "stop-ds", "status", "control-panel", "uninstall", "setup",
121        "backup.offline", "encode-password", "export-ldif.offline",
122        "ldif-diff", "ldifmodify", "ldifsearch", "make-ldif",
123        "rebuild-index", "restore.offline", "upgrade",
124        "verify-index", "backendstat"
125      );
126  private final Set<String> relevantScriptNames = newHashSet(
127        "start-ds", "import-ldif.offline", "backup.offline",
128        "export-ldif.offline",
129        "ldif-diff", "make-ldif", "rebuild-index", "restore.offline",
130        "verify-index", "backendstat"
131      );
132
133  private String readJavaHome;
134  private boolean readUseOpenDSJavaHome;
135  private boolean readUseOpenDSJavaArgs;
136
137  private boolean initialized;
138
139  private boolean previousLocal = true;
140
141  private final LocalizableMessage READING_JAVA_SETTINGS =
142    INFO_CTRL_PANEL_READING_JAVA_SETTINGS_SUMMARY.get();
143
144  private JComponent[] comps;
145
146  /** Default constructor. */
147  public JavaPropertiesPanel()
148  {
149    super();
150    createLayout();
151  }
152
153  @Override
154  public LocalizableMessage getTitle()
155  {
156    return INFO_CTRL_PANEL_JAVA_PROPERTIES_TITLE.get();
157  }
158
159  @Override
160  public Component getPreferredFocusComponent()
161  {
162    return javaHome;
163  }
164
165  @Override
166  public boolean requiresScroll()
167  {
168    return false;
169  }
170
171  @Override
172  public void setInfo(ControlPanelInfo info)
173  {
174    super.setInfo(info);
175    if (editor != null)
176    {
177      editor.setInfo(info);
178    }
179  }
180
181  /** Creates the layout of the panel (but the contents are not populated here). */
182  private void createLayout()
183  {
184    GridBagConstraints gbc = new GridBagConstraints();
185
186    lJavaHome = Utilities.createPrimaryLabel(
187        INFO_CTRL_PANEL_JAVA_HOME_LABEL.get());
188    useOpenDSJavaHome = Utilities.createRadioButton(LocalizableMessage.EMPTY);
189    useOpenDSJavaHome.setOpaque(false);
190    useOpenDSJavaHome.getAccessibleContext().setAccessibleName(
191        INFO_CTRL_PANEL_USE_OPENDS_JAVA_HOME.get()+" "+
192        INFO_CTRL_PANEL_USE_OPENDS_JAVA_HOME_HELP.get());
193    lJavaHome.setLabelFor(useOpenDSJavaHome);
194    gbc.gridx = 0;
195    gbc.gridy = 0;
196    gbc.weightx = 0.0;
197    gbc.anchor = GridBagConstraints.WEST;
198    gbc.gridwidth = 1;
199    add(lJavaHome, gbc);
200    gbc.insets.left = 10;
201    gbc.gridx ++;
202    add(useOpenDSJavaHome, gbc);
203    gbc.gridwidth = 3;
204    gbc.gridx ++;
205    LabelWithHelpIcon useOpenDSJavaHomeLabel =
206      new LabelWithHelpIcon(INFO_CTRL_PANEL_USE_OPENDS_JAVA_HOME.get(),
207          INFO_CTRL_PANEL_USE_OPENDS_JAVA_HOME_HELP.get());
208    gbc.insets.left = 0;
209    add(useOpenDSJavaHomeLabel, gbc);
210
211    gbc.gridx = 1;
212    gbc.gridy ++;
213    gbc.fill = GridBagConstraints.HORIZONTAL;
214    gbc.weightx = 0.0;
215    gbc.insets.top = 10;
216    gbc.gridwidth = 1;
217    useSpecifiedJavaHome = Utilities.createRadioButton(LocalizableMessage.EMPTY);
218    useSpecifiedJavaHome.setOpaque(false);
219    useSpecifiedJavaHome.getAccessibleContext().setAccessibleName(
220        INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_HOME.get() +
221        " "+INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_HOME_HELP.get());
222    useOpenDSJavaHomeLabel.setLabelFor(useSpecifiedJavaHome);
223    LabelWithHelpIcon useSpecifiedJavaHomeLabel = new LabelWithHelpIcon(
224        INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_HOME.get(),
225        INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_HOME_HELP.get());
226    gbc.insets.left = 10;
227    add(useSpecifiedJavaHome, gbc);
228    gbc.gridx ++;
229    gbc.insets.left = 0;
230    add(useSpecifiedJavaHomeLabel, gbc);
231    gbc.gridx ++;
232    javaHome = Utilities.createTextField();
233    useSpecifiedJavaHomeLabel.setLabelFor(javaHome);
234    gbc.weightx = 1.0;
235    gbc.insets.left = 5;
236    add(javaHome, gbc);
237    gbc.weightx = 0.0;
238    browse = Utilities.createButton(INFO_CTRL_PANEL_BROWSE_BUTTON_LABEL.get());
239    browse.addActionListener(
240        new BrowseActionListener(javaHome,
241            BrowseActionListener.BrowseType.LOCATION_DIRECTORY,  this));
242    browse.setOpaque(false);
243    gbc.gridx ++;
244    add(browse, gbc);
245
246    ButtonGroup group = new ButtonGroup();
247    group.add(useSpecifiedJavaHome);
248    group.add(useOpenDSJavaHome);
249
250    gbc.insets.top = 10;
251    gbc.insets.left = 0;
252    gbc.gridx = 0;
253    gbc.gridwidth = 5;
254    gbc.gridy ++;
255    add(new JSeparator(), gbc);
256
257    gbc.gridy ++;
258    JPanel p = new JPanel(new GridBagLayout());
259    p.setOpaque(false);
260    gbc.weightx = 1.0;
261    gbc.weighty = 1.0;
262    gbc.fill = GridBagConstraints.BOTH;
263    add(p, gbc);
264
265    gbc.insets.top = 10;
266    gbc.weightx = 0.0;
267    gbc.weighty = 0.0;
268    gbc.gridx = 0;
269    gbc.gridy = 0;
270
271    lJavaArgs = Utilities.createPrimaryLabel(
272        INFO_CTRL_PANEL_JAVA_ARGUMENTS_LABEL.get());
273    useSpecifiedJavaArgs = Utilities.createRadioButton(LocalizableMessage.EMPTY);
274    useSpecifiedJavaArgs.getAccessibleContext().setAccessibleName(
275        INFO_CTRL_PANEL_USE_OPENDS_JAVA_ARGS.get() +
276        " "+INFO_CTRL_PANEL_USE_OPENDS_JAVA_ARGS_HELP.get());
277    useSpecifiedJavaArgs.setOpaque(false);
278    useOpenDSJavaArgs = Utilities.createRadioButton(LocalizableMessage.EMPTY);
279    useOpenDSJavaArgs.setOpaque(false);
280    lJavaArgs.setLabelFor(useOpenDSJavaArgs);
281    gbc.gridx = 0;
282    gbc.gridy = 0;
283    gbc.gridwidth = 1;
284    gbc.fill = GridBagConstraints.HORIZONTAL;
285    gbc.weightx = 0.0;
286    gbc.insets.top = 10;
287    p.add(lJavaArgs, gbc);
288    gbc.insets.left = 10;
289    gbc.gridx ++;
290    gbc.gridwidth = 1;
291    p.add(useOpenDSJavaArgs, gbc);
292    gbc.gridx ++;
293    LabelWithHelpIcon useOpenDSJavaArgsLabel = new LabelWithHelpIcon(
294        INFO_CTRL_PANEL_USE_OPENDS_JAVA_ARGS.get(),
295        INFO_CTRL_PANEL_USE_OPENDS_JAVA_ARGS_HELP.get());
296    gbc.insets.left = 0;
297    p.add(useOpenDSJavaArgsLabel, gbc);
298
299    gbc.gridx = 1;
300    gbc.gridy ++;
301    gbc.insets.top = 10;
302    gbc.insets.left = 10;
303    p.add(useSpecifiedJavaArgs, gbc);
304    useOpenDSJavaArgsLabel.setLabelFor(useSpecifiedJavaArgs);
305    useSpecifiedJavaArgs.getAccessibleContext().setAccessibleName(
306        INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_ARGS.get() +
307        " "+INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_ARGS_HELP.get());
308
309    gbc.gridx ++;
310    LabelWithHelpIcon useSpecifiedJavaArgsLabel = new LabelWithHelpIcon(
311        INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_ARGS.get(),
312        INFO_CTRL_PANEL_USE_SPECIFIED_OPENDS_JAVA_ARGS_HELP.get());
313    gbc.insets.left = 0;
314    p.add(useSpecifiedJavaArgsLabel, gbc);
315
316    group = new ButtonGroup();
317    group.add(useSpecifiedJavaArgs);
318    group.add(useOpenDSJavaArgs);
319    useSpecifiedJavaArgsLabel.setLabelFor(useOpenDSJavaArgs);
320
321    argumentsTableModel = new JavaArgumentsTableModel();
322    LDAPEntryTableCellRenderer renderer = new LDAPEntryTableCellRenderer();
323    argumentsTable = Utilities.createSortableTable(argumentsTableModel,
324        renderer);
325    editor = new AttributeCellEditor();
326    if (getInfo() != null)
327    {
328      editor.setInfo(getInfo());
329    }
330    argumentsTable.getColumnModel().getColumn(1).setCellEditor(editor);
331    renderer.setTable(argumentsTable);
332
333    gbc.weightx = 1.0;
334    gbc.weighty = 1.0;
335    gbc.gridx = 1;
336    gbc.insets.top = 10;
337    gbc.gridy ++;
338    gbc.fill = GridBagConstraints.BOTH;
339    gbc.gridwidth = 2;
340    argumentsScroll = Utilities.createScrollPane(argumentsTable);
341    p.add(argumentsScroll, gbc);
342    lInitContents = Utilities.makePlainTextPane(
343        READING_JAVA_SETTINGS.toString(),
344        ColorAndFontConstants.defaultFont);
345    gbc.fill = GridBagConstraints.NONE;
346    gbc.anchor = GridBagConstraints.CENTER;
347    p.add(lInitContents, gbc);
348    lInitContents.setVisible(false);
349    gbc.weightx = 0.0;
350    gbc.weighty = 0.0;
351    gbc.fill = GridBagConstraints.HORIZONTAL;
352    gbc.weightx = 1.0;
353    gbc.anchor = GridBagConstraints.WEST;
354
355    showAll =
356      Utilities.createCheckBox(INFO_CTRL_PANEL_DISPLAY_ALL_COMMAND_LINES.get());
357    showAll.addActionListener(new ActionListener()
358    {
359      @Override
360      public void actionPerformed(ActionEvent ev)
361      {
362        editor.stopCellEditing();
363        currentJavaArguments = getCurrentJavaArguments();
364        argumentsTableModel.setData(filterJavaArguments(currentJavaArguments));
365        Utilities.updateTableSizes(argumentsTable, 7);
366      }
367    });
368
369    gbc.gridy ++;
370    gbc.insets.top = 5;
371    p.add(showAll, gbc);
372
373    JLabel inlineHelp = Utilities.createInlineHelpLabel(
374        INFO_CTRL_PANEL_ONLINE_COMMAND_HELP.get());
375    gbc.insets.top = 3;
376    gbc.gridy ++;
377    p.add(inlineHelp, gbc);
378
379    inlineHelp = Utilities.createInlineHelpLabel(
380        INFO_CTRL_PANEL_OFFLINE_COMMAND_HELP.get());
381    gbc.gridy ++;
382    p.add(inlineHelp, gbc);
383
384    // Just to create space.
385    Set<JavaArgumentsDescriptor> fakeArguments = new HashSet<>();
386    fakeArguments.add(
387        new JavaArgumentsDescriptor("start-ds", "-server -XM256j"));
388    fakeArguments.add(
389        new JavaArgumentsDescriptor("stop-ds", "-client"));
390    fakeArguments.add(
391        new JavaArgumentsDescriptor("import-ds.online", "-server"));
392    fakeArguments.add(
393        new JavaArgumentsDescriptor("import-ds.offline", "-server"));
394    fakeArguments.add(
395        new JavaArgumentsDescriptor("export-ds.online", "-server"));
396
397    argumentsTableModel.setData(fakeArguments);
398    Utilities.updateTableSizes(argumentsTable, 7);
399
400    comps = new JComponent[] {
401        javaHome, useOpenDSJavaHome, useSpecifiedJavaHome, browse,
402        useOpenDSJavaArgs, useSpecifiedJavaArgs, showAll
403    };
404  }
405
406  @Override
407  public void configurationChanged(ConfigurationChangeEvent ev)
408  {
409    final boolean isLocal = ev.getNewDescriptor().isLocal();
410    if (isLocal != previousLocal)
411    {
412      previousLocal = isLocal;
413      SwingUtilities.invokeLater(new Runnable()
414      {
415        @Override
416        public void run()
417        {
418          if (!isLocal)
419          {
420            displayErrorMessage(INFO_CTRL_PANEL_SERVER_REMOTE_SUMMARY.get(),
421            INFO_CTRL_PANEL_SERVER_MUST_BE_LOCAL_JAVA_PROPERTIES_SUMMARY.get());
422            setEnabledOK(false);
423          }
424          else
425          {
426            displayMainPanel();
427            setEnabledOK(true);
428          }
429        }
430      });
431    }
432  }
433
434  @Override
435  public void toBeDisplayed(boolean visible)
436  {
437    boolean isLocal = true;
438    if (getInfo() != null)
439    {
440      isLocal = getInfo().getServerDescriptor().isLocal();
441    }
442    if (visible && isLocal && (!initialized || !updatedByUser()))
443    {
444      initialized = true;
445      initContents();
446    }
447  }
448
449  /**
450   * Returns the names of all the command-line that can be displayed by this
451   * panel.
452   * @return the names of all the command-line that can be displayed by this
453   * panel.
454   */
455  private Set<String> getAllCommandLineNames()
456  {
457    return allScriptNames;
458  }
459
460  /**
461   * Returns the names of the most important command-line to be displayed by
462   * this panel.
463   * @return the names of the most important command-line to be displayed by
464   * this panel.
465   */
466  private Set<String> getRelevantCommandLineNames()
467  {
468    return relevantScriptNames;
469  }
470
471
472
473  /**
474   * Returns <CODE>true</CODE> if the user updated the contents and
475   * <CODE>false</CODE> otherwise.
476   * @return <CODE>true</CODE> if the user updated the contents and
477   * <CODE>false</CODE> otherwise.
478   */
479  private boolean updatedByUser()
480  {
481    return !javaHome.getText().equals(readJavaHome)
482        || useOpenDSJavaHome.isSelected() != readUseOpenDSJavaHome
483        || useOpenDSJavaArgs.isSelected() != readUseOpenDSJavaArgs
484        || !readJavaArguments.equals(getCurrentJavaArguments());
485  }
486
487  /**
488   * Returns the java arguments specified by the user.
489   * @return the java arguments specified by the user.
490   */
491  private Set<JavaArgumentsDescriptor> getCurrentJavaArguments()
492  {
493    HashSet<JavaArgumentsDescriptor> args = new HashSet<>(currentJavaArguments);
494
495    HashSet<JavaArgumentsDescriptor> tableArgs = new HashSet<>();
496    for (int i=0; i<argumentsTableModel.getRowCount(); i++)
497    {
498      tableArgs.add(argumentsTableModel.getJavaArguments(i));
499    }
500    for (JavaArgumentsDescriptor arg : tableArgs)
501    {
502      JavaArgumentsDescriptor foundJavaArgument = null;
503      for (JavaArgumentsDescriptor arg1 : args)
504      {
505        if (arg1.getCommandName().equals(arg.getCommandName()))
506        {
507          foundJavaArgument = arg1;
508          break;
509        }
510      }
511      if (foundJavaArgument != null)
512      {
513        args.remove(foundJavaArgument);
514      }
515      args.add(arg);
516    }
517    return args;
518  }
519
520
521  /**
522   * Filters the provided list of java arguments depending on the showing
523   * options (basically whether the 'Show All Command-lines' is selected or
524   * not).
525   * @param args the list of java arguments.
526   * @return a list of filtered java arguments (the ones that must be displayed
527   * in the table).
528   */
529  private Set<JavaArgumentsDescriptor> filterJavaArguments(
530      Set<JavaArgumentsDescriptor> args)
531  {
532    if (showAll.isSelected())
533    {
534      return args;
535    }
536    else
537    {
538      Set<JavaArgumentsDescriptor> filteredArgs = new HashSet<>();
539      for (String relevantName : getRelevantCommandLineNames())
540      {
541        for (JavaArgumentsDescriptor arg : args)
542        {
543          if (arg.getCommandName().equals(relevantName))
544          {
545            filteredArgs.add(arg);
546            break;
547          }
548        }
549      }
550      return filteredArgs;
551    }
552  }
553
554  /** Inits the contents of the table in the background. */
555  private void initContents()
556  {
557    disableComponents();
558
559    BackgroundTask<Void> worker = new BackgroundTask<Void>()
560    {
561      @Override
562      public Void processBackgroundTask() throws Throwable
563      {
564        String propertiesFile = getPropertiesFile();
565        Properties properties = new Properties();
566        BufferedReader reader = null;
567        try
568        {
569          reader = new BufferedReader(new FileReader(propertiesFile));
570          JavaPropertiesTool.updateProperties(reader, properties);
571        }
572        catch (Throwable t)
573        {
574        }
575        finally
576        {
577          StaticUtils.close(reader);
578        }
579
580        String v = properties.getProperty("overwrite-env-java-home");
581        readUseOpenDSJavaHome = v == null || "false".equalsIgnoreCase(v.trim());
582        v = properties.getProperty("overwrite-env-java-args");
583        readUseOpenDSJavaArgs = v == null || "false".equalsIgnoreCase(v.trim());
584
585        readJavaHome = properties.getProperty("default.java-home");
586        if (readJavaHome == null)
587        {
588          for (String script : getAllCommandLineNames())
589          {
590            readJavaHome = properties.getProperty(script+".java-home");
591            if (readJavaHome != null)
592            {
593              break;
594            }
595          }
596        }
597
598        readJavaArguments.clear();
599        for (String script : getAllCommandLineNames())
600        {
601          v = properties.getProperty(script+".java-args");
602          if (v != null)
603          {
604            readJavaArguments.add(new JavaArgumentsDescriptor(script, v));
605          }
606          else
607          {
608            readJavaArguments.add(new JavaArgumentsDescriptor(script, ""));
609          }
610        }
611
612        return null;
613      }
614
615      @Override
616      public void backgroundTaskCompleted(Void returnValue, Throwable t)
617      {
618        if (t == null)
619        {
620          updateContentsOfPanelWithReadValues();
621          Utilities.updateTableSizes(argumentsTable, 7);
622        }
623        else
624        {
625          String arg;
626          if (t instanceof OpenDsException)
627          {
628            arg = ((OpenDsException)t).getMessageObject().toString();
629          }
630          else
631          {
632            arg = t.toString();
633          }
634          LocalizableMessage title =
635            ERR_CTRL_PANEL_ERR_READING_JAVA_SETTINGS_SUMMARY.get();
636          LocalizableMessage details =
637            ERR_CTRL_PANEL_READING_JAVA_SETTINGS_DETAILS.get(arg);
638          updateErrorPane(errorPane, title,
639              ColorAndFontConstants.errorTitleFont, details,
640              errorPane.getFont());
641          packParentDialog();
642          errorPane.setVisible(true);
643        }
644        enableComponents();
645      }
646    };
647    worker.startBackgroundTask();
648  }
649
650  /**
651   * Disables all the components.  This is used when we are reading the
652   * java settings in the background.
653   */
654  private void disableComponents()
655  {
656    setEnabledOK(false);
657    lInitContents.setVisible(true);
658    argumentsScroll.setVisible(false);
659    for (JComponent comp : comps)
660    {
661      comp.setEnabled(false);
662    }
663  }
664
665  /**
666   * Enables all the components.  This is used when we are reading the
667   * java settings in the background.
668   */
669  private void enableComponents()
670  {
671    for (JComponent comp : comps)
672    {
673      comp.setEnabled(true);
674    }
675    lInitContents.setVisible(false);
676    argumentsScroll.setVisible(true);
677    setEnabledOK(true);
678  }
679
680  @Override
681  public void cancelClicked()
682  {
683    updateContentsOfPanelWithReadValues();
684    super.cancelClicked();
685  }
686
687  @Override
688  public void okClicked()
689  {
690    editor.stopCellEditing();
691
692    final ArrayList<LocalizableMessage> javaHomeErrors = new ArrayList<>();
693    String f = javaHome.getText().trim();
694    if (f.length() > 0)
695    {
696      File file = new File(f);
697      if (!file.exists())
698      {
699        javaHomeErrors.add(ERR_CTRL_PANEL_JAVA_PATH_DOES_NOT_EXIST.get(f));
700      }
701      else if (!file.isDirectory())
702      {
703        javaHomeErrors.add(ERR_CTRL_PANEL_JAVA_PATH_NOT_A_DIRECTORY.get(f));
704      }
705      else
706      {
707        File javaFile = getJavaFile(file);
708        if (!javaFile.exists())
709        {
710          javaHomeErrors.add(ERR_CTRL_PANEL_JAVA_BINARY_NOT_FOUND.get(javaFile));
711        }
712      }
713    }
714    if (javaHomeErrors.isEmpty())
715    {
716      final Set<String> providedArguments = new HashSet<>();
717      for (JavaArgumentsDescriptor cmd : getCurrentJavaArguments())
718      {
719        String args = cmd.getJavaArguments().trim();
720        if (args.length() > 0)
721        {
722          providedArguments.add(args);
723        }
724      }
725
726      disableComponents();
727      lInitContents.setText(
728          INFO_CTRL_PANEL_CHECKING_JAVA_OPTIONS_SUMMARY.get().toString());
729      BackgroundTask<List<LocalizableMessage>> worker =
730        new BackgroundTask<List<LocalizableMessage>>()
731      {
732        private boolean isConfirmation = false;
733        @Override
734        public List<LocalizableMessage> processBackgroundTask() throws Throwable
735        {
736          String[] jvms;
737          String userJVM = javaHome.getText();
738          ArrayList<LocalizableMessage> errorMessages = new ArrayList<>();
739          ArrayList<LocalizableMessage> confirmationMessages = new ArrayList<>();
740          String defaultJVM = System.getenv(SetupUtils.OPENDJ_JAVA_HOME);
741          if (defaultJVM == null)
742          {
743            defaultJVM = System.getProperty("java.home");
744          }
745          if (useSpecifiedJavaHome.isSelected())
746          {
747            jvms = new String[]{userJVM};
748          }
749          else if (userJVM != null && userJVM.trim().length() > 0)
750          {
751            jvms = new String[]{defaultJVM, userJVM};
752          }
753          else
754          {
755            jvms = new String[]{defaultJVM};
756          }
757          for (String jvm : jvms)
758          {
759            Set<String> notWorkingArgs = new HashSet<>();
760
761            String installPath = getInfo().getServerDescriptor().
762            getInstallPath();
763            if (!Utils.supportsOption("", jvm, installPath))
764            {
765              if (jvm == userJVM && !useSpecifiedJavaHome.isSelected())
766              {
767                errorMessages.add(
768                    ERR_CTRL_PANEL_NOT_WORKING_FALLBACK_JVM_DETAILS.get(jvm));
769              }
770              else
771              {
772                errorMessages.add(
773                    ERR_CTRL_PANEL_NOT_WORKING_JVM_DETAILS.get(jvm));
774              }
775            }
776            else
777            {
778              for (String arg : providedArguments)
779              {
780                if (!Utils.supportsOption(arg, jvm, installPath))
781                {
782                  notWorkingArgs.add(arg);
783                }
784              }
785            }
786            if (!notWorkingArgs.isEmpty())
787            {
788              File javaFile = getJavaFile(new File(jvm));
789              LocalizableMessage confirmationMessage;
790              if (useSpecifiedJavaArgs.isSelected())
791              {
792                confirmationMessage =
793                  INFO_CTRL_PANEL_CONFIRM_NOT_WORKING_ARGUMENTS_DETAILS.get(
794                    javaFile,
795                    Utilities.getStringFromCollection(notWorkingArgs, "<br>-"));
796              }
797              else
798              {
799                confirmationMessage =
800             INFO_CTRL_PANEL_CONFIRM_NOT_WORKING_FALLBACK_ARGUMENTS_DETAILS.get(
801                    javaFile,
802                    Utilities.getStringFromCollection(notWorkingArgs, "<br>-"));
803              }
804              confirmationMessages.add(confirmationMessage);
805            }
806          }
807          isConfirmation = errorMessages.isEmpty();
808          if (!errorMessages.isEmpty())
809          {
810            return errorMessages;
811          }
812          else
813          {
814            return confirmationMessages;
815          }
816        }
817
818        @Override
819        public void backgroundTaskCompleted(List<LocalizableMessage> returnValue,
820            Throwable t)
821        {
822          if (t == null)
823          {
824            boolean confirm = false;
825            if (isConfirmation && !returnValue.isEmpty())
826            {
827              confirm = displayConfirmationDialog(
828                  INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(),
829                  returnValue.iterator().next());
830            }
831            else if (!isConfirmation && !returnValue.isEmpty())
832            {
833              displayErrorDialog(returnValue);
834            }
835            else
836            {
837              confirm = true;
838            }
839
840            if (confirm)
841            {
842              launchTask();
843            }
844          }
845          else
846          {
847            String arg;
848            if (t instanceof OpenDsException)
849            {
850              arg = ((OpenDsException)t).getMessageObject().toString();
851            }
852            else
853            {
854              arg = t.toString();
855            }
856            LocalizableMessage title =
857              ERR_CTRL_PANEL_ERROR_CHECKING_JAVA_SETTINGS_SUMMARY.get();
858            LocalizableMessage details =
859              ERR_CTRL_PANEL_ERROR_CHECKING_JAVA_SETTINGS_DETAILS.get(arg);
860            updateErrorPane(errorPane, title,
861                ColorAndFontConstants.errorTitleFont, details,
862                errorPane.getFont());
863            packParentDialog();
864            errorPane.setVisible(true);
865          }
866          enableComponents();
867          lInitContents.setText(READING_JAVA_SETTINGS.toString());
868        }
869      };
870      worker.startBackgroundTask();
871      return;
872    }
873    else
874    {
875      if (useSpecifiedJavaHome.isSelected())
876      {
877        displayErrorDialog(javaHomeErrors);
878      }
879      else
880      {
881        ArrayList<String> s = new ArrayList<>();
882        for (LocalizableMessage msg : javaHomeErrors)
883        {
884          s.add(msg.toString());
885        }
886        ArrayList<LocalizableMessage> msgs = new ArrayList<>();
887        LocalizableMessage msg = ERR_CTRL_PANEL_GENERIC_ERROR_FALLBACK_JAVAHOME.get(
888            f, Utilities.getStringFromCollection(s, "<br>-"));
889        msgs.add(msg);
890        displayErrorDialog(msgs);
891      }
892    }
893  }
894
895  /**
896   * Returns the java binary (the executable) for a given java home.
897   * @param javaHome the java home.
898   * @return the java binary (the executable) for the provided java home.
899   */
900  private File getJavaFile(File javaHome)
901  {
902    File javaFile = new File(javaHome, "bin");
903    if (isWindows())
904    {
905      javaFile = new File(javaFile, "java.exe");
906    }
907    else
908    {
909      javaFile = new File(javaFile, "java");
910    }
911    return javaFile;
912  }
913
914  private void launchTask()
915  {
916    ArrayList<LocalizableMessage> errors = new ArrayList<>();
917    ProgressDialog dlg = new ProgressDialog(
918        Utilities.createFrame(),
919        Utilities.getParentDialog(this),
920        INFO_CTRL_PANEL_JAVA_PROPERTIES_TITLE.get(), getInfo());
921    JavaPropertiesTask newTask = new JavaPropertiesTask(getInfo(), dlg);
922    for (Task task : getInfo().getTasks())
923    {
924      task.canLaunch(newTask, errors);
925    }
926    if (errors.isEmpty())
927    {
928      launchOperation(newTask,
929          INFO_CTRL_PANEL_UPDATING_JAVA_SETTINGS_SUMMARY.get(),
930          INFO_CTRL_PANEL_UPDATING_JAVA_SETTINGS_COMPLETE.get(),
931          INFO_CTRL_PANEL_UPDATING_JAVA_SETTINGS_SUCCESSFUL.get(),
932          ERR_CTRL_PANEL_UPDATING_JAVA_SETTINGS_ERROR_SUMMARY.get(),
933          ERR_CTRL_PANEL_UPDATING_JAVA_SETTINGS_ERROR_DETAILS.get(),
934          ERR_CTRL_PANEL_UPDATING_JAVA_SETTINGS_ERROR_CODE,
935          dlg);
936      dlg.setVisible(true);
937      Utilities.getParentDialog(this).setVisible(false);
938      readJavaHome = javaHome.getText();
939      readUseOpenDSJavaHome = useOpenDSJavaHome.isSelected();
940      readUseOpenDSJavaArgs = useOpenDSJavaArgs.isSelected();
941      readJavaArguments = getCurrentJavaArguments();
942    }
943    else
944    {
945      displayErrorDialog(errors);
946    }
947  }
948
949  /**
950   * Returns the file containing the java properties.
951   * @return the file containing the java properties.
952   */
953  private String getPropertiesFile()
954  {
955    String installPath = getInfo().getServerDescriptor().getInstancePath();
956    return Utils.getPath(
957      Utilities.getInstanceRootDirectory(installPath).getAbsolutePath(),
958      Installation.RELATIVE_JAVA_PROPERTIES_FILE);
959  }
960
961  private void updateContentsOfPanelWithReadValues()
962  {
963    if (readJavaHome != null)
964    {
965      javaHome.setText(readJavaHome);
966    }
967    else
968    {
969      javaHome.setText("");
970    }
971    useOpenDSJavaHome.setSelected(readUseOpenDSJavaHome);
972    useSpecifiedJavaHome.setSelected(!readUseOpenDSJavaHome);
973    useOpenDSJavaArgs.setSelected(readUseOpenDSJavaArgs);
974    useSpecifiedJavaArgs.setSelected(!readUseOpenDSJavaArgs);
975    currentJavaArguments.clear();
976    currentJavaArguments.addAll(readJavaArguments);
977    argumentsTableModel.setData(
978        filterJavaArguments(currentJavaArguments));
979  }
980
981  /** Class containing the command-name and the associated java arguments. */
982  private class JavaArgumentsDescriptor
983  {
984    private String commandName;
985    private String javaArguments;
986    private int hashCode;
987    private String toString;
988    /**
989     * Constructor of the arguments descriptor.
990     * @param commandName the command-line name.
991     * @param javaArguments the java arguments.
992     */
993    public JavaArgumentsDescriptor(String commandName, String javaArguments)
994    {
995      this.commandName = commandName;
996      this.javaArguments = javaArguments;
997      hashCode = commandName.hashCode() + javaArguments.hashCode();
998      toString = commandName+ ": " +javaArguments;
999    }
1000
1001    /**
1002     * Returns the command-line name.
1003     * @return the command-line name.
1004     */
1005    public String getCommandName()
1006    {
1007      return commandName;
1008    }
1009    /**
1010     * Returns the java arguments associated with the command-line.
1011     * @return the java arguments associated with the command-line.
1012     */
1013    public String getJavaArguments()
1014    {
1015      return javaArguments;
1016    }
1017
1018    @Override
1019    public int hashCode()
1020    {
1021      return hashCode;
1022    }
1023
1024    @Override
1025    public String toString()
1026    {
1027      return toString;
1028    }
1029
1030    @Override
1031    public boolean equals(Object o)
1032    {
1033      if (o == this)
1034      {
1035        return true;
1036      }
1037      if (!(o instanceof JavaArgumentsDescriptor))
1038      {
1039        return false;
1040      }
1041      JavaArgumentsDescriptor desc = (JavaArgumentsDescriptor)o;
1042      return commandName.equals(desc.getCommandName())
1043          && javaArguments.equals(desc.getJavaArguments());
1044    }
1045  }
1046
1047  /** The table model used to display the java arguments. */
1048  private class JavaArgumentsTableModel extends SortableTableModel
1049  implements Comparator<JavaArgumentsDescriptor>
1050  {
1051    private static final long serialVersionUID = 8288418995255677560L;
1052    private final Set<JavaArgumentsDescriptor> data = new HashSet<>();
1053    private final ArrayList<String[]> dataArray = new ArrayList<>();
1054    private final ArrayList<JavaArgumentsDescriptor> argsArray = new ArrayList<>();
1055    private final String[] COLUMN_NAMES = new String[] {
1056        getHeader(INFO_CTRL_PANEL_COMMAND_LINE_NAME_COLUMN.get(), 40),
1057        getHeader(INFO_CTRL_PANEL_JAVA_ARGUMENTS_COLUMN.get(), 40)};
1058    private int sortColumn;
1059    private boolean sortAscending = true;
1060
1061    /**
1062     * Sets the data for this table model.
1063     * @param newData the data for this table model.
1064     */
1065    public void setData(Set<JavaArgumentsDescriptor> newData)
1066    {
1067      if (!newData.equals(data))
1068      {
1069        data.clear();
1070        data.addAll(newData);
1071        updateDataArray();
1072        fireTableDataChanged();
1073      }
1074    }
1075
1076    /**
1077     * Compares two java argument descriptors.
1078     * @param desc1 the first java argument descriptor.
1079     * @param desc2 the second java argument descriptor.
1080     * @return 1 if in terms of comparison the first element goes higher than
1081     * the second one.  Returns 0 if both elements are equal in terms of
1082     * comparison.  Returns -1 if the second element goes higher than the first
1083     * one.
1084     */
1085    @Override
1086    public int compare(JavaArgumentsDescriptor desc1,
1087        JavaArgumentsDescriptor desc2)
1088    {
1089      int result;
1090      int[] possibleResults = {
1091          desc1.getCommandName().compareTo(desc2.getCommandName()),
1092          desc1.getJavaArguments().compareTo(desc2.getJavaArguments())};
1093      result = possibleResults[sortColumn];
1094      if (result == 0)
1095      {
1096        for (int i : possibleResults)
1097        {
1098          if (i != 0)
1099          {
1100            result = i;
1101            break;
1102          }
1103        }
1104      }
1105      if (!sortAscending)
1106      {
1107        result = -result;
1108      }
1109      return result;
1110    }
1111
1112    /**
1113     * Updates the table model contents and sorts its contents depending on the
1114     * sort options set by the user.
1115     */
1116    @Override
1117    public void forceResort()
1118    {
1119      updateDataArray();
1120      fireTableDataChanged();
1121    }
1122
1123
1124
1125    @Override
1126    public int getColumnCount()
1127    {
1128      return COLUMN_NAMES.length;
1129    }
1130
1131    @Override
1132    public int getRowCount()
1133    {
1134      return dataArray.size();
1135    }
1136
1137    @Override
1138    public Object getValueAt(int row, int col)
1139    {
1140      return dataArray.get(row)[col];
1141    }
1142
1143    @Override
1144    public String getColumnName(int col) {
1145      return COLUMN_NAMES[col];
1146    }
1147
1148    /**
1149     * Returns the java argument descriptor in the provided row.
1150     * @param row the row number.
1151     * @return the java argument descriptor in the provided row.
1152     */
1153    private JavaArgumentsDescriptor getJavaArguments(int row)
1154    {
1155      return argsArray.get(row);
1156    }
1157
1158
1159    /**
1160     * Returns whether the sort is ascending or descending.
1161     * @return <CODE>true</CODE> if the sort is ascending and <CODE>false</CODE>
1162     * otherwise.
1163     */
1164    @Override
1165    public boolean isSortAscending()
1166    {
1167      return sortAscending;
1168    }
1169
1170    /**
1171     * Sets whether to sort ascending of descending.
1172     * @param sortAscending whether to sort ascending or descending.
1173     */
1174    @Override
1175    public void setSortAscending(boolean sortAscending)
1176    {
1177      this.sortAscending = sortAscending;
1178    }
1179
1180    /**
1181     * Returns the column index used to sort.
1182     * @return the column index used to sort.
1183     */
1184    @Override
1185    public int getSortColumn()
1186    {
1187      return sortColumn;
1188    }
1189
1190    /**
1191     * Sets the column index used to sort.
1192     * @param sortColumn column index used to sort..
1193     */
1194    @Override
1195    public void setSortColumn(int sortColumn)
1196    {
1197      this.sortColumn = sortColumn;
1198    }
1199
1200    @Override
1201    public boolean isCellEditable(int row, int col) {
1202      return col != 0;
1203    }
1204
1205    @Override
1206    public void setValueAt(Object value, int row, int col)
1207    {
1208      dataArray.get(row)[col] = (String)value;
1209      JavaArgumentsDescriptor currentArg = argsArray.get(row);
1210      JavaArgumentsDescriptor newArg =
1211        new JavaArgumentsDescriptor(currentArg.getCommandName(), (String)value);
1212      argsArray.set(row, newArg);
1213      data.remove(currentArg);
1214      data.add(newArg);
1215      fireTableCellUpdated(row, col);
1216    }
1217
1218    private void updateDataArray()
1219    {
1220      TreeSet<JavaArgumentsDescriptor> sortedSet = new TreeSet<>(this);
1221      sortedSet.addAll(data);
1222      dataArray.clear();
1223      argsArray.clear();
1224      for (JavaArgumentsDescriptor arg : sortedSet)
1225      {
1226        String[] s = getLine(arg);
1227        dataArray.add(s);
1228        argsArray.add(arg);
1229      }
1230    }
1231
1232    /**
1233     * Returns an array of String with the String representation of the cells
1234     * in the table.
1235     * @param desc the java argument descriptor for which we want to get the
1236     * cells.
1237     * @return an array of String with the String representation of the cells
1238     * in the table.
1239     */
1240    private String[] getLine(JavaArgumentsDescriptor desc)
1241    {
1242      String cmd = desc.getCommandName();
1243      if (cmd.equalsIgnoreCase("start-ds"))
1244      {
1245        cmd = INFO_CTRL_PANEL_SERVER_RUNTIME_CELL.get(
1246            desc.getCommandName()).toString();
1247      }
1248      else if (cmd.endsWith(".online"))
1249      {
1250        int index = cmd.lastIndexOf(".online");
1251        cmd = INFO_CTRL_PANEL_ONLINE_COMMAND_LINE_CELL.get(
1252            cmd.substring(0, index)).toString();
1253      }
1254      else if (desc.getCommandName().endsWith(".offline"))
1255      {
1256        int index = cmd.lastIndexOf(".offline");
1257        cmd = INFO_CTRL_PANEL_OFFLINE_COMMAND_LINE_CELL.get(
1258            cmd.substring(0, index)).toString();
1259      }
1260      return new String[] {cmd, desc.getJavaArguments()};
1261    }
1262  }
1263
1264  /** The task in charge of updating the java properties. */
1265  private class JavaPropertiesTask extends Task
1266  {
1267    private final Set<String> backendSet;
1268    private String defaultJavaHome;
1269    private final boolean overwriteOpenDSJavaHome;
1270    private final boolean overwriteOpenDSJavaArgs;
1271    private final Set<JavaArgumentsDescriptor> arguments;
1272
1273    /**
1274     * The constructor of the task.
1275     * @param info the control panel info.
1276     * @param dlg the progress dialog that shows the progress of the task.
1277     */
1278    private JavaPropertiesTask(ControlPanelInfo info, ProgressDialog dlg)
1279    {
1280      super(info, dlg);
1281      backendSet = new HashSet<>();
1282      defaultJavaHome = javaHome.getText().trim();
1283      overwriteOpenDSJavaHome = useSpecifiedJavaHome.isSelected();
1284      overwriteOpenDSJavaArgs = useSpecifiedJavaArgs.isSelected();
1285      arguments = getCurrentJavaArguments();
1286    }
1287
1288    @Override
1289    public Type getType()
1290    {
1291      return Type.JAVA_SETTINGS_UPDATE;
1292    }
1293
1294    @Override
1295    public Set<String> getBackends()
1296    {
1297      return backendSet;
1298    }
1299
1300    @Override
1301    public LocalizableMessage getTaskDescription()
1302    {
1303      return INFO_CTRL_PANEL_UPDATE_JAVA_SETTINGS_TASK_DESCRIPTION.get();
1304    }
1305
1306    @Override
1307    public boolean canLaunch(Task taskToBeLaunched,
1308        Collection<LocalizableMessage> incompatibilityReasons)
1309    {
1310      if (!isServerRunning()
1311          && state == State.RUNNING
1312          && runningOnSameServer(taskToBeLaunched))
1313      {
1314        // All the operations are incompatible if they apply to this
1315        // backend for safety.  This is a short operation so the limitation
1316        // has not a lot of impact.
1317        Set<String> backends = new TreeSet<>(taskToBeLaunched.getBackends());
1318        backends.retainAll(getBackends());
1319        if (!backends.isEmpty())
1320        {
1321          incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched));
1322          return false;
1323        }
1324      }
1325      return true;
1326    }
1327
1328    @Override
1329    protected String getCommandLinePath()
1330    {
1331      return null;
1332    }
1333
1334    @Override
1335    protected ArrayList<String> getCommandLineArguments()
1336    {
1337      return new ArrayList<>();
1338    }
1339
1340    @Override
1341    public void runTask()
1342    {
1343      state = State.RUNNING;
1344      lastException = null;
1345
1346      try
1347      {
1348        returnCode = updateJavaSettings();
1349        if (returnCode == 0)
1350        {
1351          state = State.FINISHED_SUCCESSFULLY;
1352        }
1353        else
1354        {
1355          state = State.FINISHED_WITH_ERROR;
1356        }
1357      }
1358      catch (Throwable t)
1359      {
1360        lastException = t;
1361        state = State.FINISHED_WITH_ERROR;
1362      }
1363    }
1364
1365    private int updateJavaSettings() throws IOException
1366    {
1367      final String propertiesFile = getPropertiesFile();
1368      ArrayList<String> commentLines = new ArrayList<>();
1369      BufferedReader reader = null;
1370      try
1371      {
1372        reader = new BufferedReader(new FileReader(propertiesFile));
1373        String line;
1374        while ((line = reader.readLine()) != null)
1375        {
1376          String trimmedLine = line.trim();
1377          if (trimmedLine.startsWith("#") || trimmedLine.length() == 0)
1378          {
1379            commentLines.add(line);
1380          }
1381          else
1382          {
1383            break;
1384          }
1385        }
1386      }
1387      catch (IOException ioe)
1388      {
1389        // Not critical.
1390      }
1391      finally
1392      {
1393        StaticUtils.close(reader);
1394      }
1395
1396      BufferedWriter writer = null;
1397      try
1398      {
1399        writer = new BufferedWriter(new FileWriter(propertiesFile, false));
1400        for (String comment : commentLines)
1401        {
1402          writer.write(comment);
1403          writer.newLine();
1404        }
1405        writer.newLine();
1406        writer.write("overwrite-env-java-home="+overwriteOpenDSJavaHome);
1407        writer.newLine();
1408        writer.write("overwrite-env-java-args="+overwriteOpenDSJavaArgs);
1409        writer.newLine();
1410        writer.newLine();
1411        if (defaultJavaHome != null && defaultJavaHome.length() > 0)
1412        {
1413          writer.write("default.java-home="+defaultJavaHome);
1414          writer.newLine();
1415          writer.newLine();
1416        }
1417        for (JavaArgumentsDescriptor desc : arguments)
1418        {
1419          String args = desc.getJavaArguments();
1420          if (args.trim().length() > 0)
1421          {
1422            writer.newLine();
1423            writer.write(desc.getCommandName()+".java-args="+args);
1424          }
1425        }
1426      }
1427      finally
1428      {
1429        StaticUtils.close(writer);
1430      }
1431      SwingUtilities.invokeLater(new Runnable()
1432      {
1433        @Override
1434        public void run()
1435        {
1436          getProgressDialog().appendProgressHtml(Utilities.applyFont(
1437              INFO_CTRL_PANEL_EQUIVALENT_ACTION_TO_UPDATE_JAVA_PROPERTIES.get(
1438                  propertiesFile, getCommandLinePath("dsjavaproperties")).
1439                  toString(),
1440              ColorAndFontConstants.progressFont));
1441        }
1442      });
1443
1444      // Launch the script
1445      String[] args =
1446      {
1447          "--quiet"
1448      };
1449
1450      return JavaPropertiesTool.mainCLI(args);
1451    }
1452  }
1453}