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 2010 Sun Microsystems, Inc.
015 * Portions Copyright 2014-2016 ForgeRock AS.
016 */
017package org.opends.guitools.controlpanel.ui;
018
019import static org.opends.messages.AdminToolMessages.*;
020
021import java.awt.Component;
022import java.awt.GridBagConstraints;
023import java.util.ArrayList;
024import java.util.Collections;
025import java.util.Comparator;
026import java.util.HashSet;
027import java.util.Set;
028
029import javax.swing.JEditorPane;
030
031import org.forgerock.i18n.LocalizableMessage;
032import org.forgerock.opendj.ldap.schema.ObjectClass;
033import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent;
034import org.opends.guitools.controlpanel.ui.components.AddRemovePanel;
035import org.opends.guitools.controlpanel.ui.renderer.
036 SchemaElementComboBoxCellRenderer;
037import org.opends.guitools.controlpanel.util.Utilities;
038import org.opends.server.types.Schema;
039
040/**
041 * This is a class where the user can choose from a list of available object
042 * classes one or more object classes.
043 */
044public class SelectObjectClassesPanel extends StatusGenericPanel
045{
046  private static final long serialVersionUID = 1230982500028334L;
047  private AddRemovePanel<ObjectClass> addRemove = new AddRemovePanel<>(ObjectClass.class);
048  private Set<ObjectClass> toExclude = new HashSet<>();
049  private Schema schema;
050  private boolean isCanceled = true;
051
052  /** Default constructor of this panel. */
053  public SelectObjectClassesPanel()
054  {
055    createLayout();
056  }
057
058  private void createLayout()
059  {
060    GridBagConstraints gbc = new GridBagConstraints();
061    gbc.anchor = GridBagConstraints.WEST;
062    gbc.weightx = 0.0;
063    gbc.gridx = 0;
064    gbc.gridy = 0;
065    JEditorPane instructions = Utilities.makePlainTextPane(
066        INFO_CTRL_PANEL_SUPERIOR_OBJECTCLASSES_INSTRUCTIONS.get().toString(),
067        ColorAndFontConstants.defaultFont);
068    gbc.weightx = 1.0;
069    gbc.fill = GridBagConstraints.HORIZONTAL;
070    add(instructions, gbc);
071    gbc.gridy ++;
072    gbc.fill = GridBagConstraints.BOTH;
073    gbc.weightx = 1.0;
074    gbc.weighty = 1.0;
075    addRemove.getAvailableLabel().setText(
076        INFO_CTRL_PANEL_ADDREMOVE_AVAILABLE_OBJECTCLASSES.get().toString());
077    addRemove.getSelectedLabel().setText(
078        INFO_CTRL_PANEL_ADDREMOVE_SELECTED_OBJECTCLASSES.get().toString());
079
080    Comparator<ObjectClass> comparator = new Comparator<ObjectClass>()
081    {
082      @Override
083      public int compare(ObjectClass oc1, ObjectClass oc2)
084      {
085        return oc1.getNameOrOID().toLowerCase().compareTo(
086            oc2.getNameOrOID().toLowerCase());
087      }
088    };
089    addRemove.getAvailableListModel().setComparator(comparator);
090    addRemove.getSelectedListModel().setComparator(comparator);
091    SchemaElementComboBoxCellRenderer renderer =
092      new SchemaElementComboBoxCellRenderer(addRemove.getAvailableList());
093    addRemove.getAvailableList().setCellRenderer(renderer);
094    renderer =
095      new SchemaElementComboBoxCellRenderer(addRemove.getSelectedList());
096    addRemove.getSelectedList().setCellRenderer(renderer);
097    gbc.insets.top = 10;
098    add(addRemove, gbc);
099  }
100
101  @Override
102  public Component getPreferredFocusComponent()
103  {
104    return addRemove;
105  }
106
107  @Override
108  public LocalizableMessage getTitle()
109  {
110    return INFO_CTRL_PANEL_SUPERIOR_OBJECTCLASSES_TITLE.get();
111  }
112
113  @Override
114  public void okClicked()
115  {
116    isCanceled = true;
117    Set<ObjectClass> selectedObjectClasses =
118      addRemove.getSelectedListModel().getData();
119    if (selectedObjectClasses.isEmpty())
120    {
121      displayErrorMessage(INFO_CTRL_PANEL_ERROR_DIALOG_TITLE.get(),
122          INFO_CTRL_PANEL_ERROR_NO_SUPERIOR_SELECTED.get());
123    }
124    else
125    {
126      isCanceled = false;
127      closeClicked();
128    }
129  }
130
131  /**
132   * Returns whether this dialog has been canceled or not.
133   * @return whether this dialog has been canceled or not.
134   */
135  public boolean isCanceled()
136  {
137    return isCanceled;
138  }
139
140  @Override
141  public void toBeDisplayed(boolean visible)
142  {
143    if (visible)
144    {
145      isCanceled = true;
146    }
147  }
148
149  @Override
150  public void configurationChanged(ConfigurationChangeEvent ev)
151  {
152  }
153
154  /**
155   * Returns the selected object classes.
156   * @return the selected object classes.
157   */
158  public Set<ObjectClass> getSelectedObjectClasses()
159  {
160    return addRemove.getSelectedListModel().getData();
161  }
162
163  /**
164   * Sets the selected object classes.
165   * @param selectedObjectClasses the selected object classes.
166   */
167  public void setSelectedObjectClasses(Set<ObjectClass> selectedObjectClasses)
168  {
169    Set<ObjectClass> toAdd = new HashSet<>();
170    Set<ObjectClass> previouslySelected =
171      addRemove.getSelectedListModel().getData();
172    for (ObjectClass oc : previouslySelected)
173    {
174      if (!selectedObjectClasses.contains(oc))
175      {
176        addRemove.getSelectedListModel().remove(oc);
177        toAdd.add(oc);
178      }
179    }
180
181    addRemove.getAvailableListModel().addAll(toAdd);
182
183    for (ObjectClass oc : selectedObjectClasses)
184    {
185      if (!previouslySelected.contains(oc))
186      {
187        addRemove.getSelectedListModel().add(oc);
188      }
189      addRemove.getAvailableListModel().remove(oc);
190    }
191    fireAddRemoveNotifications();
192  }
193
194  /**
195   * Sets the list of object classes that this panel should not display
196   * (mainly used to not display the object class for which we are editing
197   * the superior object classes).
198   * @param toExclude the list of object classes to exclude.
199   */
200  public void setObjectClassesToExclude(Set<ObjectClass> toExclude)
201  {
202    this.toExclude.clear();
203    this.toExclude.addAll(toExclude);
204
205    updateWithSchema(schema);
206    fireAddRemoveNotifications();
207  }
208
209  /**
210   * Sets the schema to be used by this panel.
211   * @param schema the schema to be used by this panel.
212   */
213  public void setSchema(Schema schema)
214  {
215    updateWithSchema(schema);
216    fireAddRemoveNotifications();
217  }
218
219  private void updateWithSchema(Schema schema)
220  {
221    ArrayList<ObjectClass> allOcs = new ArrayList<>();
222    for (ObjectClass oc : schema.getObjectClasses())
223    {
224      if (!toExclude.contains(oc))
225      {
226        allOcs.add(oc);
227      }
228    }
229
230    for (ObjectClass oc : addRemove.getSelectedListModel().getData())
231    {
232      if (!allOcs.contains(oc))
233      {
234        addRemove.getSelectedListModel().remove(oc);
235      }
236      else
237      {
238        allOcs.remove(oc);
239      }
240    }
241
242    addRemove.getAvailableListModel().clear();
243    addRemove.getAvailableListModel().addAll(allOcs);
244
245    this.schema = schema;
246  }
247
248  /**
249   * Returns the list of object classes that this panel will not display.
250   * @return the list of object classes that this panel will not display.
251   */
252  public Set<ObjectClass> getObjectClassToExclude()
253  {
254    return Collections.unmodifiableSet(toExclude);
255  }
256
257  private void fireAddRemoveNotifications()
258  {
259    addRemove.getSelectedListModel().fireContentsChanged(this, 0,
260        addRemove.getSelectedListModel().getSize() - 1);
261    addRemove.getAvailableListModel().fireContentsChanged(this, 0,
262        addRemove.getAvailableListModel().getSize() - 1);
263  }
264}