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