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-2016 ForgeRock AS.
016 */
017package org.opends.quicksetup.installer.ui;
018
019import org.forgerock.i18n.LocalizableMessage;
020import static org.opends.messages.QuickSetupMessages.*;
021
022import java.awt.Component;
023import java.awt.GridBagConstraints;
024import java.awt.GridBagLayout;
025import java.awt.event.FocusEvent;
026import java.awt.event.FocusListener;
027import java.util.Comparator;
028import java.util.HashMap;
029import java.util.Map;
030import java.util.Set;
031import java.util.TreeSet;
032
033import javax.swing.Box;
034import javax.swing.JCheckBox;
035import javax.swing.JLabel;
036import javax.swing.JPanel;
037import javax.swing.JScrollPane;
038import javax.swing.text.JTextComponent;
039
040import org.opends.admin.ads.ServerDescriptor;
041
042import org.opends.quicksetup.UserData;
043import org.opends.quicksetup.installer.AuthenticationData;
044import org.opends.quicksetup.ui.FieldName;
045import org.opends.quicksetup.ui.GuiApplication;
046import org.opends.quicksetup.ui.LabelFieldDescriptor;
047import org.opends.quicksetup.ui.QuickSetupStepPanel;
048import org.opends.quicksetup.ui.UIFactory;
049import org.opends.server.types.HostPort;
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<>();
066  /** The display of the server the user provided in the replication options panel. */
067  private HostPort 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  @Override
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  @Override
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  @Override
147  protected boolean requiresScroll()
148  {
149    return false;
150  }
151
152  @Override
153  public int compare(ServerDescriptor desc1, ServerDescriptor desc2)
154  {
155    return desc1.getHostPort(true).toString().compareTo(desc2.getHostPort(true).toString());
156  }
157
158  @Override
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  @Override
182  protected LocalizableMessage getInstructions()
183  {
184    return INFO_REMOTE_REPLICATION_PORT_INSTRUCTIONS.get();
185  }
186
187  @Override
188  protected LocalizableMessage getTitle()
189  {
190    return INFO_REMOTE_REPLICATION_PORT_TITLE.get();
191  }
192
193  @Override
194  public void beginDisplay(UserData data)
195  {
196    TreeSet<ServerDescriptor> array = orderServers(
197        data.getRemoteWithNoReplicationPort().keySet());
198    AuthenticationData authData =
199      data.getReplicationOptions().getAuthenticationData();
200    HostPort newServerDisplay = authData != null ? authData.getHostPort() : new HostPort(null, 0);
201    if (!array.equals(orderedServers) ||
202        !newServerDisplay.equals(serverToConnectDisplay))
203    {
204      serverToConnectDisplay = newServerDisplay;
205      // Adds the required focus listeners to the fields.
206      final FocusListener l = new FocusListener()
207      {
208        @Override
209        public void focusGained(FocusEvent e)
210        {
211          lastFocusComponent = e.getComponent();
212        }
213
214        @Override
215        public void focusLost(FocusEvent e)
216        {
217        }
218      };
219      lastFocusComponent = null;
220      HashMap<String, String> hmOldValues = new HashMap<>();
221      for (String id : hmFields.keySet())
222      {
223        hmOldValues.put(id, hmFields.get(id).getText());
224      }
225      HashMap<String, Boolean> hmOldSecureValues = new HashMap<>();
226      for (String id : hmCbs.keySet())
227      {
228        hmOldSecureValues.put(id, hmCbs.get(id).isSelected());
229      }
230      orderedServers.clear();
231      orderedServers.addAll(array);
232      hmFields.clear();
233      hmCbs.clear();
234      hmLabels.clear();
235      for (ServerDescriptor server : orderedServers)
236      {
237        HostPort serverDisplay;
238        if (server.getHostPort(false).equals(serverToConnectDisplay))
239        {
240          serverDisplay = serverToConnectDisplay;
241        }
242        else
243        {
244          serverDisplay = server.getHostPort(true);
245        }
246        LabelFieldDescriptor desc = new LabelFieldDescriptor(
247                LocalizableMessage.raw(serverDisplay.toString()),
248                INFO_REPLICATION_PORT_TOOLTIP.get(),
249                LabelFieldDescriptor.FieldType.TEXTFIELD,
250                LabelFieldDescriptor.LabelType.PRIMARY,
251                UIFactory.PORT_FIELD_SIZE);
252        AuthenticationData auth =
253          data.getRemoteWithNoReplicationPort().get(server);
254        JTextComponent field = UIFactory.makeJTextComponent(desc,
255            String.valueOf(auth.getPort()));
256        String oldValue = hmOldValues.get(server.getId());
257        if (oldValue != null)
258        {
259          field.setText(oldValue);
260        }
261
262        JLabel label = UIFactory.makeJLabel(desc);
263
264        hmFields.put(server.getId(), field);
265        label.setLabelFor(field);
266        field.addFocusListener(l);
267        if (lastFocusComponent == null)
268        {
269          lastFocusComponent = field;
270        }
271
272        hmLabels.put(server.getId(), label);
273
274        JCheckBox cb = UIFactory.makeJCheckBox(
275            INFO_SECURE_REPLICATION_LABEL.get(),
276            INFO_SECURE_REPLICATION_TOOLTIP.get(),
277            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
278        cb.setSelected(auth.useSecureConnection());
279        Boolean oldSecureValue = hmOldSecureValues.get(server.getId());
280        if (oldSecureValue != null)
281        {
282          cb.setSelected(oldSecureValue);
283        }
284        hmCbs.put(server.getId(), cb);
285      }
286      populateFieldsPanel();
287    }
288  }
289
290  @Override
291  public void endDisplay()
292  {
293    if (lastFocusComponent != null)
294    {
295      lastFocusComponent.requestFocusInWindow();
296    }
297  }
298
299  private void populateFieldsPanel()
300  {
301    fieldsPanel.removeAll();
302    GridBagConstraints gbc = new GridBagConstraints();
303    gbc.fill = GridBagConstraints.BOTH;
304    gbc.anchor = GridBagConstraints.NORTHWEST;
305    boolean first = true;
306    for (ServerDescriptor server : orderedServers)
307    {
308      gbc.insets.left = 0;
309      gbc.weightx = 0.0;
310      if (!first)
311      {
312        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
313      }
314      gbc.gridwidth = 4;
315      fieldsPanel.add(hmLabels.get(server.getId()), gbc);
316      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
317      gbc.gridwidth--;
318      fieldsPanel.add(hmFields.get(server.getId()), gbc);
319      gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
320      gbc.gridwidth = GridBagConstraints.RELATIVE;
321      fieldsPanel.add(hmCbs.get(server.getId()), gbc);
322      gbc.gridwidth = GridBagConstraints.REMAINDER;
323      gbc.weightx = 1.0;
324      fieldsPanel.add(Box.createHorizontalGlue(), gbc);
325      first = false;
326    }
327    addVerticalGlue(fieldsPanel);
328  }
329
330  private TreeSet<ServerDescriptor> orderServers(Set<ServerDescriptor> servers)
331  {
332    TreeSet<ServerDescriptor> ordered = new TreeSet<>(this);
333    ordered.addAll(servers);
334    return ordered;
335  }
336}