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