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 2006-2010 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2015 ForgeRock AS.
016 */
017package org.opends.quicksetup.installer.ui;
018
019import java.awt.Component;
020import java.awt.GridBagConstraints;
021import java.awt.GridBagLayout;
022import java.awt.event.ActionEvent;
023import java.awt.event.ActionListener;
024import java.awt.event.FocusEvent;
025import java.awt.event.FocusListener;
026import java.io.File;
027import java.util.HashMap;
028
029import javax.swing.Box;
030import javax.swing.JButton;
031import javax.swing.JFrame;
032import javax.swing.JLabel;
033import javax.swing.JPanel;
034import javax.swing.text.JTextComponent;
035
036import org.opends.quicksetup.event.BrowseActionListener;
037import org.opends.quicksetup.ui.FieldName;
038import org.opends.quicksetup.ui.GuiApplication;
039import org.opends.quicksetup.ui.LabelFieldDescriptor;
040import org.opends.quicksetup.ui.QuickSetupStepPanel;
041import org.opends.quicksetup.ui.UIFactory;
042import org.opends.quicksetup.util.Utils;
043import org.opends.quicksetup.SecurityOptions;
044import org.opends.quicksetup.UserData;
045
046import org.opends.server.util.CertificateManager;
047import org.forgerock.i18n.LocalizableMessage;
048import static org.opends.messages.QuickSetupMessages.*;
049
050/**
051 * This is the panel that contains the Server Settings: the port, the Directory
052 * Manager DN, etc.
053 *
054 */
055public class ServerSettingsPanel extends QuickSetupStepPanel
056{
057  private UserData defaultUserData;
058
059  private Component lastFocusComponent;
060  private JLabel lSecurity;
061  private JButton secureAccessButton;
062  private JButton browseButton;
063
064  private boolean canUpdateSecurity;
065
066  private SecurityOptions securityOptions;
067
068  private HashMap<FieldName, JLabel> hmLabels = new HashMap<>();
069  private HashMap<FieldName, JTextComponent> hmFields = new HashMap<>();
070
071  private JTextComponent tfServerLocationParent;
072  private JTextComponent tfServerLocationRelativePath;
073
074  private JLabel lServerLocation;
075
076  private SecurityOptionsDialog dlg;
077
078  private static final long serialVersionUID = -15911406930993035L;
079
080  /**
081   * Constructor of the panel.
082   * @param application Application this panel represents
083   * the fields of the panel.
084   */
085  public ServerSettingsPanel(GuiApplication application)
086  {
087    super(application);
088    this.defaultUserData = application.getUserData();
089    canUpdateSecurity = CertificateManager.mayUseCertificateManager();
090    securityOptions = defaultUserData.getSecurityOptions();
091    populateLabelAndFieldMaps();
092    addFocusListeners();
093  }
094
095  /** {@inheritDoc} */
096  public Object getFieldValue(FieldName fieldName)
097  {
098    Object value = null;
099
100    if (fieldName == FieldName.SERVER_LOCATION)
101    {
102      String parent = tfServerLocationParent.getText();
103      String relative = tfServerLocationRelativePath.getText();
104      if (parent != null && parent.length() > 0)
105      {
106        value = parent;
107      }
108      if (relative != null && relative.length() > 0)
109      {
110        if (value == null)
111        {
112          value = File.separator + relative;
113        } else
114        {
115          value = value + File.separator + relative;
116        }
117      }
118
119    }
120    else if (fieldName == FieldName.SECURITY_OPTIONS)
121    {
122      value = securityOptions;
123    }
124    else
125    {
126      JTextComponent field = getField(fieldName);
127      if (field != null)
128      {
129        value = field.getText();
130      }
131    }
132
133    return value;
134  }
135
136  /** {@inheritDoc} */
137  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
138  {
139    JLabel label = getLabel(fieldName);
140    if (label != null)
141    {
142      if (invalid)
143      {
144        UIFactory.setTextStyle(label,
145            UIFactory.TextStyle.PRIMARY_FIELD_INVALID);
146      } else
147      {
148        UIFactory
149            .setTextStyle(label, UIFactory.TextStyle.PRIMARY_FIELD_VALID);
150      }
151    }
152  }
153
154  /** {@inheritDoc} */
155  protected Component createInputPanel()
156  {
157    JPanel panel = new JPanel(new GridBagLayout());
158    panel.setOpaque(false);
159
160    GridBagConstraints gbc = new GridBagConstraints();
161
162    FieldName[] fieldNames =
163    {
164        FieldName.HOST_NAME,
165        FieldName.SERVER_PORT,
166        FieldName.ADMIN_CONNECTOR_PORT,
167        FieldName.SECURITY_OPTIONS,
168        FieldName.DIRECTORY_MANAGER_DN,
169        FieldName.DIRECTORY_MANAGER_PWD,
170        FieldName.DIRECTORY_MANAGER_PWD_CONFIRM
171    };
172
173
174    // Add widgets
175    for (FieldName fieldName : fieldNames) {
176      gbc.gridwidth = GridBagConstraints.RELATIVE;
177      gbc.weightx = 0.0;
178      gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
179      gbc.insets.left = 0;
180      boolean isSecurityField = fieldName == FieldName.SECURITY_OPTIONS;
181
182      int securityInsetsTop = Math.abs(
183          getLDAPSecureAccessButton().getPreferredSize().height -
184          getLabel(fieldName).getPreferredSize().height) / 2;
185
186      if (isSecurityField)
187      {
188        gbc.anchor = GridBagConstraints.NORTHWEST;
189        gbc.insets.top += securityInsetsTop;
190      }
191      else
192      {
193        gbc.anchor = GridBagConstraints.WEST;
194      }
195      panel.add(getLabel(fieldName), gbc);
196
197      final JPanel auxPanel = new JPanel(new GridBagLayout());
198      auxPanel.setOpaque(false);
199      gbc.weightx = 1.0;
200      gbc.fill = GridBagConstraints.HORIZONTAL;
201      gbc.insets.top = UIFactory.TOP_INSET_PRIMARY_FIELD;
202      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
203      gbc.gridwidth = GridBagConstraints.REMAINDER;
204
205      panel.add(auxPanel, gbc);
206
207      boolean isPortField = fieldName == FieldName.SERVER_PORT;
208      boolean isAdminConnectorPortField =
209        fieldName == FieldName.ADMIN_CONNECTOR_PORT;
210      gbc.insets = UIFactory.getEmptyInsets();
211      if (isPortField || isAdminConnectorPortField ||
212          (isSecurityField && canUpdateSecurity))
213      {
214        gbc.gridwidth = 3;
215      }
216      else
217      {
218        gbc.gridwidth = GridBagConstraints.RELATIVE;
219      }
220      gbc.weightx = 0.0;
221      if (isSecurityField)
222      {
223        gbc.insets.top = securityInsetsTop;
224        if (canUpdateSecurity)
225        {
226          auxPanel.add(lSecurity, gbc);
227        }
228        else
229        {
230          auxPanel.add(UIFactory.makeJLabel(UIFactory.IconType.WARNING,
231              INFO_CANNOT_UPDATE_SECURITY_WARNING.get(),
232              UIFactory.TextStyle.SECONDARY_FIELD_VALID), gbc);
233        }
234      }
235      else
236      {
237        auxPanel.add(getField(fieldName), gbc);
238      }
239
240      if (isPortField)
241      {
242        JLabel l =
243                UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
244                        getPortHelpMessage(),
245                        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
246        gbc.gridwidth = GridBagConstraints.RELATIVE;
247        gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
248        auxPanel.add(l, gbc);
249      }
250      else if (isAdminConnectorPortField)
251      {
252        JLabel l =
253          UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
254              getAdminConnectorPortHelpMessage(),
255              UIFactory.TextStyle.SECONDARY_FIELD_VALID);
256        gbc.gridwidth = GridBagConstraints.RELATIVE;
257        gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
258        auxPanel.add(l, gbc);
259      }
260      else if (isSecurityField && canUpdateSecurity)
261      {
262        gbc.gridwidth = GridBagConstraints.RELATIVE;
263        gbc.insets.left = UIFactory.LEFT_INSET_BROWSE;
264        gbc.anchor = GridBagConstraints.NORTHWEST;
265        gbc.insets.top = 0;
266        auxPanel.add(getLDAPSecureAccessButton(), gbc);
267      }
268      gbc.gridwidth = GridBagConstraints.REMAINDER;
269      gbc.weightx = 1.0;
270      gbc.fill = GridBagConstraints.HORIZONTAL;
271      auxPanel.add(Box.createHorizontalGlue(), gbc);
272    }
273    addVerticalGlue(panel);
274    return panel;
275  }
276
277  /** {@inheritDoc} */
278  protected LocalizableMessage getInstructions()
279  {
280    return INFO_SERVER_SETTINGS_PANEL_INSTRUCTIONS.get();
281  }
282
283  /** {@inheritDoc} */
284  protected LocalizableMessage getTitle()
285  {
286    return INFO_SERVER_SETTINGS_PANEL_TITLE.get();
287  }
288
289  /** {@inheritDoc} */
290  public void endDisplay()
291  {
292    if (lastFocusComponent != null)
293    {
294      lastFocusComponent.requestFocusInWindow();
295    }
296  }
297
298  /**
299   * Returns the default value for the provided field Name.
300   * @param fieldName the field name for which we want to get the default
301   * value.
302   * @return the default value for the provided field Name.
303   */
304  private String getDefaultValue(FieldName fieldName)
305  {
306    String value;
307    value = null;
308    switch (fieldName)
309    {
310    case SERVER_LOCATION:
311      value = defaultUserData.getServerLocation();
312      break;
313
314    case HOST_NAME:
315      value = defaultUserData.getHostName();
316      break;
317
318    case SERVER_PORT:
319      if (defaultUserData.getServerPort() > 0)
320      {
321        value = String.valueOf(defaultUserData.getServerPort());
322      }
323      else
324      {
325        value = "";
326      }
327      break;
328
329    case ADMIN_CONNECTOR_PORT:
330      if (defaultUserData.getAdminConnectorPort() > 0)
331      {
332        value = String.valueOf(defaultUserData.getAdminConnectorPort());
333      }
334      else
335      {
336        value = "";
337      }
338      break;
339
340    case DIRECTORY_MANAGER_DN:
341      value = defaultUserData.getDirectoryManagerDn();
342      break;
343
344    case DIRECTORY_MANAGER_PWD:
345      value = defaultUserData.getDirectoryManagerPwd();
346      break;
347
348    case DIRECTORY_MANAGER_PWD_CONFIRM:
349      value = defaultUserData.getDirectoryManagerPwd();
350      break;
351
352    case SECURITY_OPTIONS:
353      value = Utils.getSecurityOptionsString(
354          defaultUserData.getSecurityOptions(),
355          true);
356      break;
357
358    default:
359      throw new IllegalArgumentException("Unknown field name: " +
360          fieldName);
361    }
362
363    return value;
364  }
365
366  /**
367   * Creates the components and populates the Maps with them.
368   */
369  private void populateLabelAndFieldMaps()
370  {
371    HashMap<FieldName, LabelFieldDescriptor> hm = new HashMap<>();
372
373    hm.put(FieldName.HOST_NAME, new LabelFieldDescriptor(
374        INFO_HOST_NAME_LABEL.get(),
375        INFO_HOST_NAME_TOOLTIP.get(),
376        LabelFieldDescriptor.FieldType.TEXTFIELD,
377        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.HOST_FIELD_SIZE));
378
379    hm.put(FieldName.SERVER_PORT, new LabelFieldDescriptor(
380        INFO_SERVER_PORT_LABEL.get(),
381        INFO_SERVER_PORT_TOOLTIP.get(),
382        LabelFieldDescriptor.FieldType.TEXTFIELD,
383        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PORT_FIELD_SIZE));
384
385    hm.put(FieldName.ADMIN_CONNECTOR_PORT, new LabelFieldDescriptor(
386        INFO_ADMIN_CONNECTOR_PORT_LABEL.get(),
387        INFO_ADMIN_CONNECTOR_PORT_TOOLTIP.get(),
388        LabelFieldDescriptor.FieldType.TEXTFIELD,
389        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PORT_FIELD_SIZE));
390
391    hm.put(FieldName.SECURITY_OPTIONS, new LabelFieldDescriptor(
392        INFO_SERVER_SECURITY_LABEL.get(),
393        INFO_SERVER_SECURITY_TOOLTIP.get(),
394        LabelFieldDescriptor.FieldType.READ_ONLY,
395        LabelFieldDescriptor.LabelType.PRIMARY, 0));
396
397    hm.put(FieldName.DIRECTORY_MANAGER_DN, new LabelFieldDescriptor(
398        INFO_SERVER_DIRECTORY_MANAGER_DN_LABEL.get(),
399        INFO_SERVER_DIRECTORY_MANAGER_DN_TOOLTIP.get(),
400        LabelFieldDescriptor.FieldType.TEXTFIELD,
401        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.DN_FIELD_SIZE));
402
403    hm.put(FieldName.DIRECTORY_MANAGER_PWD, new LabelFieldDescriptor(
404        INFO_SERVER_DIRECTORY_MANAGER_PWD_LABEL.get(),
405        INFO_SERVER_DIRECTORY_MANAGER_PWD_TOOLTIP.get(),
406        LabelFieldDescriptor.FieldType.PASSWORD,
407        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PASSWORD_FIELD_SIZE));
408
409    hm.put(FieldName.DIRECTORY_MANAGER_PWD_CONFIRM,
410        new LabelFieldDescriptor(
411        INFO_SERVER_DIRECTORY_MANAGER_PWD_CONFIRM_LABEL.get(),
412        INFO_SERVER_DIRECTORY_MANAGER_PWD_CONFIRM_TOOLTIP.get(),
413        LabelFieldDescriptor.FieldType.PASSWORD,
414        LabelFieldDescriptor.LabelType.PRIMARY,
415        UIFactory.PASSWORD_FIELD_SIZE));
416
417    for (FieldName fieldName : hm.keySet())
418    {
419      LabelFieldDescriptor desc = hm.get(fieldName);
420      String defaultValue = getDefaultValue(fieldName);
421
422      JLabel label = UIFactory.makeJLabel(desc);
423
424      if (fieldName != FieldName.SECURITY_OPTIONS)
425      {
426        JTextComponent field = UIFactory.makeJTextComponent(desc, defaultValue);
427        hmFields.put(fieldName, field);
428        label.setLabelFor(field);
429      }
430      else
431      {
432        lSecurity = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
433                LocalizableMessage.raw(defaultValue),
434                UIFactory.TextStyle.SECONDARY_FIELD_VALID);
435      }
436
437      hmLabels.put(fieldName, label);
438    }
439
440    /* Create the elements for the location */
441    LabelFieldDescriptor desc =
442        new LabelFieldDescriptor(INFO_SERVER_LOCATION_LABEL.get(),
443            INFO_SERVER_LOCATION_PARENT_TOOLTIP.get(),
444            LabelFieldDescriptor.FieldType.TEXTFIELD,
445            LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PATH_FIELD_SIZE);
446    lServerLocation = UIFactory.makeJLabel(desc);
447    tfServerLocationParent = UIFactory.makeJTextComponent(desc, "");
448    lServerLocation.setLabelFor(tfServerLocationParent);
449    hmLabels.put(FieldName.SERVER_LOCATION, lServerLocation);
450
451    desc =
452        new LabelFieldDescriptor(INFO_SERVER_LOCATION_LABEL.get(),
453            INFO_SERVER_LOCATION_RELATIVE_TOOLTIP.get(),
454            LabelFieldDescriptor.FieldType.TEXTFIELD,
455            LabelFieldDescriptor.LabelType.PRIMARY,
456            UIFactory.RELATIVE_PATH_FIELD_SIZE);
457    tfServerLocationRelativePath = UIFactory.makeJTextComponent(desc, "");
458    String defaultPath = getDefaultValue(FieldName.SERVER_LOCATION);
459    if (defaultPath != null)
460    {
461      int index = defaultPath.lastIndexOf(File.separator);
462      if (index != -1)
463      {
464        String parent = defaultPath.substring(0, index);
465        String relativeDir = defaultPath.substring(index + 1);
466
467        tfServerLocationParent.setText(parent);
468        tfServerLocationRelativePath.setText(relativeDir);
469      }
470    }
471  }
472
473  /**
474   * Returns the browse button.
475   * If it does not exist creates the browse button.
476   * @return the browse button.
477   */
478  private JButton getBrowseButton()
479  {
480    if (browseButton == null)
481    {
482      browseButton =
483          UIFactory.makeJButton(INFO_BROWSE_BUTTON_LABEL.get(),
484              INFO_BROWSE_BUTTON_TOOLTIP.get());
485
486      BrowseActionListener l =
487          new BrowseActionListener(tfServerLocationParent,
488              BrowseActionListener.BrowseType.LOCATION_DIRECTORY,
489              getMainWindow());
490      browseButton.addActionListener(l);
491    }
492    return browseButton;
493  }
494
495  /**
496   * Returns the configure secure access button.
497   * If it does not exist creates the secure access button.
498   * @return the secure access button.
499   */
500  private JButton getLDAPSecureAccessButton()
501  {
502    if (secureAccessButton == null)
503    {
504      secureAccessButton =
505          UIFactory.makeJButton(INFO_SERVER_SECURITY_BUTTON_LABEL.get(),
506              INFO_SERVER_SECURITY_BUTTON_TOOLTIP.get());
507
508      secureAccessButton.addActionListener(new ActionListener()
509      {
510        public void actionPerformed(ActionEvent ev)
511        {
512          getConfigureSecureAccessDialog().display(securityOptions);
513          if (!getConfigureSecureAccessDialog().isCanceled())
514          {
515            securityOptions =
516              getConfigureSecureAccessDialog().getSecurityOptions();
517            lSecurity.setText(
518                Utils.getSecurityOptionsString(securityOptions, true));
519          }
520        }
521      });
522    }
523    return secureAccessButton;
524  }
525
526  /**
527   * Returns the label associated with the given field name.
528   * @param fieldName the field name for which we want to retrieve the JLabel.
529   * @return the label associated with the given field name.
530   */
531  private JLabel getLabel(FieldName fieldName)
532  {
533    return hmLabels.get(fieldName);
534  }
535
536  /**
537   * Returns the JTextComponent associated with the given field name.
538   * @param fieldName the field name for which we want to retrieve the
539   * JTextComponent.
540   * @return the JTextComponent associated with the given field name.
541   */
542  private JTextComponent getField(FieldName fieldName)
543  {
544    return hmFields.get(fieldName);
545  }
546
547  /**
548   * Adds the required focus listeners to the fields.
549   */
550  private void addFocusListeners()
551  {
552    final FocusListener l = new FocusListener()
553    {
554      public void focusGained(FocusEvent e)
555      {
556        lastFocusComponent = e.getComponent();
557      }
558
559      public void focusLost(FocusEvent e)
560      {
561      }
562    };
563
564    for (JTextComponent tf : hmFields.values())
565    {
566      tf.addFocusListener(l);
567    }
568    getLDAPSecureAccessButton().addFocusListener(l);
569    getBrowseButton().addFocusListener(l);
570    lastFocusComponent = getField(FieldName.DIRECTORY_MANAGER_PWD);
571  }
572
573  /**
574   * Returns the port help message that we display when we cannot use the
575   * default admin connector port (4444).
576   * @return the port help message that we display when we cannot use the
577   * default admin connector port (4444).
578   */
579  private LocalizableMessage getAdminConnectorPortHelpMessage()
580  {
581    LocalizableMessage s = LocalizableMessage.EMPTY;
582    if (defaultUserData.getAdminConnectorPort() != 4444)
583    {
584      s = INFO_CANNOT_USE_DEFAULT_ADMIN_CONNECTOR_PORT.get();
585    }
586    return s;
587  }
588
589  /**
590   * Returns the port help message that we display when we cannot use the
591   * default port (389).
592   * @return the port help message that we display when we cannot use the
593   * default port (389).
594   */
595  private LocalizableMessage getPortHelpMessage()
596  {
597    LocalizableMessage s = LocalizableMessage.EMPTY;
598    if (defaultUserData.getServerPort() != 389)
599    {
600      s = INFO_CANNOT_USE_DEFAULT_PORT.get();
601    }
602    return s;
603  }
604
605  private SecurityOptionsDialog getConfigureSecureAccessDialog()
606  {
607    if (dlg == null)
608    {
609      dlg = new SecurityOptionsDialog((JFrame)getMainWindow(), securityOptions);
610      dlg.setModal(true);
611    }
612    return dlg;
613  }
614}