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