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