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-2009 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027
028package org.opends.quicksetup.installer.ui;
029
030import org.forgerock.i18n.LocalizableMessage;
031import static org.opends.messages.QuickSetupMessages.*;
032
033import java.awt.Component;
034import java.awt.GridBagConstraints;
035import java.awt.GridBagLayout;
036import java.awt.event.FocusEvent;
037import java.awt.event.FocusListener;
038import java.util.Comparator;
039import java.util.HashMap;
040import java.util.Map;
041import java.util.Set;
042import java.util.TreeSet;
043
044import javax.swing.Box;
045import javax.swing.JCheckBox;
046import javax.swing.JLabel;
047import javax.swing.JPanel;
048import javax.swing.JScrollPane;
049import javax.swing.text.JTextComponent;
050
051import org.opends.admin.ads.ServerDescriptor;
052
053import org.opends.quicksetup.UserData;
054import org.opends.quicksetup.installer.AuthenticationData;
055import org.opends.quicksetup.ui.FieldName;
056import org.opends.quicksetup.ui.GuiApplication;
057import org.opends.quicksetup.ui.LabelFieldDescriptor;
058import org.opends.quicksetup.ui.QuickSetupStepPanel;
059import org.opends.quicksetup.ui.UIFactory;
060
061/**
062 * This class is used to provide a data model for the list of servers for which
063 * we must provide a replication port.
064 */
065public class RemoteReplicationPortsPanel extends QuickSetupStepPanel
066implements Comparator<ServerDescriptor>
067{
068  private static final long serialVersionUID = -3742350600617826375L;
069  private Component lastFocusComponent;
070  private HashMap<String, JLabel> hmLabels = new HashMap<>();
071  private HashMap<String, JTextComponent> hmFields = new HashMap<>();
072  private HashMap<String, JCheckBox> hmCbs = new HashMap<>();
073  private JScrollPane scroll;
074  private JPanel fieldsPanel;
075  private TreeSet<ServerDescriptor> orderedServers = new TreeSet<>(this);
076  /** The display of the server the user provided in the replication options panel. */
077  private String serverToConnectDisplay;
078
079  /**
080   * Constructor of the panel.
081   * @param application Application represented by this panel and used to
082   * initialize the fields of the panel.
083   */
084  public RemoteReplicationPortsPanel(GuiApplication application)
085  {
086    super(application);
087  }
088
089  /** {@inheritDoc} */
090  public Object getFieldValue(FieldName fieldName)
091  {
092    Object value = null;
093
094    if (fieldName == FieldName.REMOTE_REPLICATION_PORT)
095    {
096      Map<String, String> hm = new HashMap<>();
097      for (String id : hmFields.keySet())
098      {
099        hm.put(id, hmFields.get(id).getText());
100      }
101      value = hm;
102    }
103    else if (fieldName == FieldName.REMOTE_REPLICATION_SECURE)
104    {
105      Map<String, Boolean> hm = new HashMap<>();
106      for (String id : hmCbs.keySet())
107      {
108        hm.put(id, hmCbs.get(id).isSelected());
109      }
110      value = hm;
111    }
112    return value;
113  }
114
115  /** {@inheritDoc} */
116  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
117  {
118    if (fieldName == FieldName.REMOTE_REPLICATION_PORT)
119    {
120      for (String id : hmLabels.keySet())
121      {
122        UIFactory.setTextStyle(hmLabels.get(id),
123            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
124      }
125      if (invalid)
126      {
127        for (String id : hmLabels.keySet())
128        {
129          String sPort = hmFields.get(id).getText();
130          if (!isValid(sPort))
131          {
132            UIFactory.setTextStyle(hmLabels.get(id),
133              UIFactory.TextStyle.SECONDARY_FIELD_INVALID);
134          }
135        }
136      }
137    }
138  }
139
140  private boolean isValid(String sPort)
141  {
142    try
143    {
144      int port = Integer.parseInt(sPort);
145      if (port >= 1 && port <= 65535)
146      {
147        return true;
148      }
149    }
150    catch (Throwable t)
151    {
152    }
153    return false;
154  }
155
156  /** {@inheritDoc} */
157  protected boolean requiresScroll()
158  {
159    return false;
160  }
161
162  /** {@inheritDoc} */
163  public int compare(ServerDescriptor desc1, ServerDescriptor desc2)
164  {
165    return desc1.getHostPort(true).compareTo(desc2.getHostPort(true));
166  }
167
168  /** {@inheritDoc} */
169  protected Component createInputPanel()
170  {
171    JPanel panel = new JPanel(new GridBagLayout());
172    panel.setOpaque(false);
173
174    GridBagConstraints gbc = new GridBagConstraints();
175    gbc.weightx = 1.0;
176    gbc.anchor = GridBagConstraints.NORTHWEST;
177    gbc.fill = GridBagConstraints.HORIZONTAL;
178    gbc.gridwidth = GridBagConstraints.REMAINDER;
179    gbc.insets = UIFactory.getEmptyInsets();
180    gbc.weighty = 1.0;
181    gbc.fill = GridBagConstraints.BOTH;
182    fieldsPanel = new JPanel(new GridBagLayout());
183    fieldsPanel.setOpaque(false);
184    scroll = UIFactory.createBorderLessScrollBar(fieldsPanel);
185
186    panel.add(scroll, gbc);
187
188    return panel;
189  }
190
191  /** {@inheritDoc} */
192  protected LocalizableMessage getInstructions()
193  {
194    return INFO_REMOTE_REPLICATION_PORT_INSTRUCTIONS.get();
195  }
196
197  /** {@inheritDoc} */
198  protected LocalizableMessage getTitle()
199  {
200    return INFO_REMOTE_REPLICATION_PORT_TITLE.get();
201  }
202
203  /** {@inheritDoc} */
204  public void beginDisplay(UserData data)
205  {
206    TreeSet<ServerDescriptor> array = orderServers(
207        data.getRemoteWithNoReplicationPort().keySet());
208    AuthenticationData authData =
209      data.getReplicationOptions().getAuthenticationData();
210    String newServerDisplay;
211    if (authData != null)
212    {
213      newServerDisplay = authData.getHostName()+":"+authData.getPort();
214    }
215    else
216    {
217      newServerDisplay = "";
218    }
219    if (!array.equals(orderedServers) ||
220        !newServerDisplay.equals(serverToConnectDisplay))
221    {
222      serverToConnectDisplay = newServerDisplay;
223      // Adds the required focus listeners to the fields.
224      final FocusListener l = new FocusListener()
225      {
226        public void focusGained(FocusEvent e)
227        {
228          lastFocusComponent = e.getComponent();
229        }
230
231        public void focusLost(FocusEvent e)
232        {
233        }
234      };
235      lastFocusComponent = null;
236      HashMap<String, String> hmOldValues = new HashMap<>();
237      for (String id : hmFields.keySet())
238      {
239        hmOldValues.put(id, hmFields.get(id).getText());
240      }
241      HashMap<String, Boolean> hmOldSecureValues = new HashMap<>();
242      for (String id : hmCbs.keySet())
243      {
244        hmOldSecureValues.put(id, hmCbs.get(id).isSelected());
245      }
246      orderedServers.clear();
247      orderedServers.addAll(array);
248      hmFields.clear();
249      hmCbs.clear();
250      hmLabels.clear();
251      for (ServerDescriptor server : orderedServers)
252      {
253        String serverDisplay;
254        if (server.getHostPort(false).equalsIgnoreCase(serverToConnectDisplay))
255        {
256          serverDisplay = serverToConnectDisplay;
257        }
258        else
259        {
260          serverDisplay = server.getHostPort(true);
261        }
262        LabelFieldDescriptor desc = new LabelFieldDescriptor(
263                LocalizableMessage.raw(serverDisplay),
264                INFO_REPLICATION_PORT_TOOLTIP.get(),
265                LabelFieldDescriptor.FieldType.TEXTFIELD,
266                LabelFieldDescriptor.LabelType.PRIMARY,
267                UIFactory.PORT_FIELD_SIZE);
268        AuthenticationData auth =
269          data.getRemoteWithNoReplicationPort().get(server);
270        JTextComponent field = UIFactory.makeJTextComponent(desc,
271            String.valueOf(auth.getPort()));
272        String oldValue = hmOldValues.get(server.getId());
273        if (oldValue != null)
274        {
275          field.setText(oldValue);
276        }
277
278        JLabel label = UIFactory.makeJLabel(desc);
279
280        hmFields.put(server.getId(), field);
281        label.setLabelFor(field);
282        field.addFocusListener(l);
283        if (lastFocusComponent == null)
284        {
285          lastFocusComponent = field;
286        }
287
288        hmLabels.put(server.getId(), label);
289
290        JCheckBox cb = UIFactory.makeJCheckBox(
291            INFO_SECURE_REPLICATION_LABEL.get(),
292            INFO_SECURE_REPLICATION_TOOLTIP.get(),
293            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
294        cb.setSelected(auth.useSecureConnection());
295        Boolean oldSecureValue = hmOldSecureValues.get(server.getId());
296        if (oldSecureValue != null)
297        {
298          cb.setSelected(oldSecureValue);
299        }
300        hmCbs.put(server.getId(), cb);
301      }
302      populateFieldsPanel();
303    }
304  }
305
306  /** {@inheritDoc} */
307  public void endDisplay()
308  {
309    if (lastFocusComponent != null)
310    {
311      lastFocusComponent.requestFocusInWindow();
312    }
313  }
314
315  private void populateFieldsPanel()
316  {
317    fieldsPanel.removeAll();
318    GridBagConstraints gbc = new GridBagConstraints();
319    gbc.fill = GridBagConstraints.BOTH;
320    gbc.anchor = GridBagConstraints.NORTHWEST;
321    boolean first = true;
322    for (ServerDescriptor server : orderedServers)
323    {
324      gbc.insets.left = 0;
325      gbc.weightx = 0.0;
326      if (!first)
327      {
328        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
329      }
330      gbc.gridwidth = 4;
331      fieldsPanel.add(hmLabels.get(server.getId()), gbc);
332      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
333      gbc.gridwidth--;
334      fieldsPanel.add(hmFields.get(server.getId()), gbc);
335      gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
336      gbc.gridwidth = GridBagConstraints.RELATIVE;
337      fieldsPanel.add(hmCbs.get(server.getId()), gbc);
338      gbc.gridwidth = GridBagConstraints.REMAINDER;
339      gbc.weightx = 1.0;
340      fieldsPanel.add(Box.createHorizontalGlue(), gbc);
341      first = false;
342    }
343    addVerticalGlue(fieldsPanel);
344  }
345
346  private TreeSet<ServerDescriptor> orderServers(Set<ServerDescriptor> servers)
347  {
348    TreeSet<ServerDescriptor> ordered = new TreeSet<>(this);
349    ordered.addAll(servers);
350    return ordered;
351  }
352}