/* * The contents of this file are subject to the terms of the Common Development and * Distribution License (the License). You may not use this file except in compliance with the * License. * * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the * specific language governing permission and limitations under the License. * * When distributing Covered Software, include this CDDL Header Notice in each file and include * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL * Header, with the fields enclosed by brackets [] replaced by your own identifying * information: "Portions Copyright [year] [name of copyright owner]". * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions Copyright 2013-2016 ForgeRock AS. */ package org.opends.quicksetup.installer.ui; import static org.forgerock.util.Utils.*; import static org.opends.messages.QuickSetupMessages.*; import java.awt.Component; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; import javax.swing.Box; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSeparator; import javax.swing.SwingConstants; import org.forgerock.i18n.LocalizableMessage; import org.opends.admin.ads.ADSContext; import org.opends.admin.ads.ReplicaDescriptor; import org.opends.admin.ads.SuffixDescriptor; import org.opends.quicksetup.Constants; import org.opends.quicksetup.UserData; import org.opends.quicksetup.installer.AuthenticationData; import org.opends.quicksetup.installer.SuffixesToReplicateOptions; import org.opends.quicksetup.ui.FieldName; import org.opends.quicksetup.ui.GuiApplication; import org.opends.quicksetup.ui.QuickSetupStepPanel; import org.opends.quicksetup.ui.UIFactory; import org.opends.quicksetup.ui.UIFactory.IconType; import org.opends.server.config.ConfigConstants; import org.opends.server.tools.BackendTypeHelper; import org.opends.server.tools.BackendTypeHelper.BackendTypeUIAdapter; import org.opends.server.types.HostPort; /** * This class is used to provide a data model for the list of suffixes that we * have to replicate on the new server. */ public class SuffixesToReplicatePanel extends QuickSetupStepPanel implements Comparator { private static final long serialVersionUID = -8051367953737385327L; private static final Insets SUFFIXES_TO_REPLICATE_INSETS = new Insets(4, 4, 4, 4); private final Set orderedSuffixes = new TreeSet<>(this); private final Map hmCheckBoxes = new HashMap<>(); private final Map> backendTypeComboBoxes = new HashMap<>(); /** The display of the server the user provided in the replication options panel. */ private HostPort serverToConnectDisplay; private JLabel noSuffixLabel; private Component labelGlue; private JPanel checkBoxPanel; private JScrollPane scroll; /** * Constructor of the panel. * * @param application * Application represented by this panel and used to initialize the * fields of the panel. */ public SuffixesToReplicatePanel(GuiApplication application) { super(application); createComponents(); } @Override public Object getFieldValue(FieldName fieldName) { if (fieldName == FieldName.SUFFIXES_TO_REPLICATE_OPTIONS) { return SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES; } else if (fieldName == FieldName.SUFFIXES_TO_REPLICATE) { return getSelectedSuffixes(); } else if (fieldName == FieldName.SUFFIXES_TO_REPLICATE_BACKEND_TYPE) { return getSelectedSuffixBackendTypes(); } return null; } private Set getSelectedSuffixes() { Set suffixes = new HashSet<>(); for (SuffixDescriptor suffix : orderedSuffixes) { if (hmCheckBoxes.get(suffix.getId()).isSelected()) { suffixes.add(suffix); } } return suffixes; } private Map getSelectedSuffixBackendTypes() { final Map backendTypes = new HashMap<>(); for (SuffixDescriptor suffix : getSelectedSuffixes()) { final String backendId = suffix.getReplicas().iterator().next().getBackendId(); backendTypes.put(backendId, (BackendTypeUIAdapter) backendTypeComboBoxes.get(backendId).getSelectedItem()); } return backendTypes; } @Override public int compare(SuffixDescriptor desc1, SuffixDescriptor desc2) { int result = compareSuffixDN(desc1, desc2); if (result == 0) { result = compareSuffixStrings(desc1, desc2); } return result; } @Override protected Component createInputPanel() { JPanel panel = new JPanel(new GridBagLayout()); panel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.weightx = 1.0; gbc.anchor = GridBagConstraints.NORTHWEST; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.insets = UIFactory.getEmptyInsets(); gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; gbc.insets.left = UIFactory.LEFT_INSET_BACKGROUND; // Add the checkboxes checkBoxPanel = new JPanel(new GridBagLayout()); checkBoxPanel.setOpaque(false); gbc.insets.top = 0; gbc.anchor = GridBagConstraints.NORTH; gbc.weighty = 1.0; gbc.fill = GridBagConstraints.BOTH; scroll = UIFactory.createBorderLessScrollBar(checkBoxPanel); panel.add(scroll, gbc); gbc.insets.left = UIFactory.LEFT_INSET_SUBPANEL_SUBORDINATE; gbc.weighty = 0.0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD; gbc.anchor = GridBagConstraints.NORTHEAST; panel.add(noSuffixLabel, gbc); noSuffixLabel.setVisible(false); labelGlue = Box.createVerticalGlue(); gbc.fill = GridBagConstraints.VERTICAL; gbc.weighty = 1.0; panel.add(labelGlue, gbc); labelGlue.setVisible(false); return panel; } @Override protected boolean requiresScroll() { return false; } @Override protected LocalizableMessage getInstructions() { return INFO_SUFFIXES_TO_REPLICATE_PANEL_INSTRUCTIONS.get(); } @Override protected LocalizableMessage getTitle() { return INFO_SUFFIXES_TO_REPLICATE_PANEL_TITLE.get(); } @Override public void beginDisplay(UserData data) { Set array = orderSuffixes(data.getSuffixesToReplicateOptions().getAvailableSuffixes()); AuthenticationData authData = data.getReplicationOptions().getAuthenticationData(); HostPort newServerDisplay = authData != null ? authData.getHostPort() : new HostPort(null, 0); if (!array.equals(orderedSuffixes) || !newServerDisplay.equals(serverToConnectDisplay)) { serverToConnectDisplay = newServerDisplay; Map hmOldValues = new HashMap<>(); for (String id : hmCheckBoxes.keySet()) { hmOldValues.put(id, hmCheckBoxes.get(id).isSelected()); } orderedSuffixes.clear(); for (SuffixDescriptor suffix : array) { if (!suffix.getDN().equals(ADSContext.getAdministrationSuffixDN()) && !suffix.getDN().equals(Constants.SCHEMA_DN) && !suffix.getDN().equals(Constants.REPLICATION_CHANGES_DN)) { orderedSuffixes.add(suffix); } } hmCheckBoxes.clear(); for (SuffixDescriptor suffix : orderedSuffixes) { JCheckBox cb = UIFactory.makeJCheckBox(LocalizableMessage.raw(suffix.getDN().toString()), INFO_SUFFIXES_TO_REPLICATE_DN_TOOLTIP.get(), UIFactory.TextStyle.SECONDARY_FIELD_VALID); cb.setOpaque(false); Boolean v = hmOldValues.get(suffix.getId()); if (v != null) { cb.setSelected(v); } hmCheckBoxes.put(suffix.getId(), cb); } populateCheckBoxPanel(); } boolean display = !orderedSuffixes.isEmpty(); noSuffixLabel.setVisible(!display); labelGlue.setVisible(!display); scroll.setVisible(display); } /** Creates the components of this panel. */ private void createComponents() { noSuffixLabel = UIFactory.makeJLabel( UIFactory.IconType.NO_ICON, INFO_SUFFIX_LIST_EMPTY.get(), UIFactory.TextStyle.SECONDARY_FIELD_VALID); } private void populateCheckBoxPanel() { checkBoxPanel.removeAll(); final GridBagConstraints gbc = new GridBagConstraints(); gbc.fill = GridBagConstraints.BOTH; gbc.insets = SUFFIXES_TO_REPLICATE_INSETS; gbc.gridy = 0; final Map> backendToSuffixes = getSuffixesForBackends(); for (Map.Entry> backendData : backendToSuffixes.entrySet()) { gbc.anchor = GridBagConstraints.LINE_START; gbc.gridwidth = 1; gbc.gridheight = 1; for (SuffixDescriptor suffix : backendData.getValue()) { gbc.gridx = 0; final JCheckBox cb = hmCheckBoxes.get(suffix.getId()); checkBoxPanel.add(cb, gbc); printReplicaTooltipButton(suffix, gbc); gbc.gridy++; } printBackendInformations(backendData, gbc); printSeparatorLine(gbc); } gbc.weighty = 1.0; gbc.insets = UIFactory.getEmptyInsets(); gbc.fill = GridBagConstraints.VERTICAL; checkBoxPanel.add(Box.createVerticalGlue(), gbc); } private Map> getSuffixesForBackends() { final Map> backendToSuffixes = new HashMap<>(); for (SuffixDescriptor suffix : orderedSuffixes) { final String backendId = suffix.getReplicas().iterator().next().getBackendId(); if (!backendToSuffixes.containsKey(backendId)) { backendToSuffixes.put(backendId, new LinkedHashSet()); } backendToSuffixes.get(backendId).add(suffix); } return backendToSuffixes; } private void printReplicaTooltipButton(SuffixDescriptor suffix, GridBagConstraints gbc) { gbc.gridx++; String imageDesc = ""; for (ReplicaDescriptor replica : suffix.getReplicas()) { imageDesc += getServerDisplay(replica) + "
"; } final int entriesNb = suffix.getReplicas().iterator().next().getEntries(); final LocalizableMessage entriesNbToPrint = getNumberOfEntriesMsg(entriesNb); imageDesc += entriesNbToPrint + ""; final JLabel helpReplicasTooltip = new JLabel(); helpReplicasTooltip.setIcon(UIFactory.getImageIcon(IconType.HELP_MEDIUM)); helpReplicasTooltip.setToolTipText(imageDesc); UIFactory.setTextStyle(helpReplicasTooltip, UIFactory.TextStyle.SECONDARY_FIELD_VALID); checkBoxPanel.add(helpReplicasTooltip, gbc); } private LocalizableMessage getNumberOfEntriesMsg(int nEntries) { if (nEntries > 0) { return INFO_SUFFIX_LIST_REPLICA_DISPLAY_ENTRIES.get(nEntries); } else if (nEntries == 0) { return INFO_SUFFIX_LIST_REPLICA_DISPLAY_NO_ENTRIES.get(); } else { return INFO_SUFFIX_LIST_REPLICA_DISPLAY_ENTRIES_NOT_AVAILABLE.get(); } } private void printBackendInformations(Map.Entry> backendData, GridBagConstraints gbc) { final int nbSuffixForBackend = backendData.getValue().size(); gbc.gridy -= nbSuffixForBackend; printBackendNameText(backendData, gbc); printComboBoxForSuffix(backendData.getValue().iterator().next(), gbc); gbc.gridy += nbSuffixForBackend; } private void printSeparatorLine(GridBagConstraints gbc) { gbc.gridwidth = gbc.gridx; gbc.gridx = 0; checkBoxPanel.add(new JSeparator(SwingConstants.HORIZONTAL), gbc); gbc.gridy++; } private void printBackendNameText(Entry> backendData, GridBagConstraints gbc) { gbc.gridx++; final JEditorPane backendNameText = UIFactory.makeTextPane( LocalizableMessage.raw(backendData.getKey()), UIFactory.TextStyle.SECONDARY_FIELD_VALID); backendNameText.setToolTipText(INFO_REPLICATED_SUFFIXES_BACKEND_NAME_TOOLTIP.get().toString()); gbc.anchor = GridBagConstraints.CENTER; checkBoxPanel.add(backendNameText, gbc); } private void printComboBoxForSuffix(SuffixDescriptor suffix, GridBagConstraints gbc) { gbc.gridx++; gbc.anchor = GridBagConstraints.LINE_END; gbc.insets = UIFactory.getEmptyInsets(); final ReplicaDescriptor backendData = suffix.getReplicas().iterator().next(); final JComboBox backendTypeComboBox = new JComboBox<>(new BackendTypeHelper().getBackendTypeUIAdaptors()); backendTypeComboBox.setToolTipText(INFO_REPLICATED_SUFFIXES_BACKEND_TYPE_TOOLTIP.get().toString()); final Set objectClasses = backendData.getObjectClasses(); backendTypeComboBox.setSelectedItem(getBackendTypeFromObjectClasses(objectClasses)); backendTypeComboBoxes.put(backendData.getBackendId(), backendTypeComboBox); checkBoxPanel.add(backendTypeComboBox, gbc); gbc.insets = SUFFIXES_TO_REPLICATE_INSETS; } /** * Returns the concrete backend type corresponding to the provided object * classes. If the backend is not found, returns the default backend of this * server configuration. * * @param objectClasses * The set of object class with one should be a concrete backend * type. * @return The concrete backend type corresponding to object classes or this * server default one. */ private BackendTypeUIAdapter getBackendTypeFromObjectClasses(Set objectClasses) { for (String objectClass : objectClasses) { BackendTypeUIAdapter adapter = BackendTypeHelper.getBackendTypeAdapter(objectClass.replace(ConfigConstants.NAME_PREFIX_CFG, "")); if (adapter != null) { return adapter; } } return new BackendTypeHelper().getBackendTypeUIAdaptors()[0]; } private String getSuffixString(SuffixDescriptor desc) { Set replicaDisplays = new TreeSet<>(); for (ReplicaDescriptor rep : desc.getReplicas()) { replicaDisplays.add(getServerDisplay(rep).toString()); } return joinAsString("\n", replicaDisplays); } private HostPort getServerDisplay(ReplicaDescriptor replica) { final boolean isServerToConnect = replica.getServer().getHostPort(false).equals(serverToConnectDisplay); return isServerToConnect ? serverToConnectDisplay : replica.getServer().getHostPort(true); } private Set orderSuffixes(Set suffixes) { Set ordered = new TreeSet<>(this); ordered.addAll(suffixes); return ordered; } private int compareSuffixDN(SuffixDescriptor desc1, SuffixDescriptor desc2) { return desc1.getDN().compareTo(desc2.getDN()); } private int compareSuffixStrings(SuffixDescriptor desc1, SuffixDescriptor desc2) { return getSuffixString(desc1).compareTo(getSuffixString(desc2)); } }