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