/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2010 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui.components; import static org.opends.messages.AdminToolMessages.*; import java.awt.CardLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.swing.Box; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JPanel; import org.opends.guitools.controlpanel.event.SuperiorObjectClassesChangedEvent; import org.opends.guitools.controlpanel.event. SuperiorObjectClassesChangedListener; import org.opends.guitools.controlpanel.ui.GenericDialog; import org.opends.guitools.controlpanel.ui.SelectObjectClassesPanel; import org.opends.guitools.controlpanel.ui.renderer. SchemaElementComboBoxCellRenderer; import org.opends.guitools.controlpanel.util.LowerCaseComparator; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.server.types.ObjectClass; import org.opends.server.types.Schema; /** * A panel that can be used to select one (or several) object classes. */ public class SuperiorObjectClassesEditor extends JPanel { private static final long serialVersionUID = 123123973933568L; private Set<ObjectClass> toExclude = new HashSet<ObjectClass>(); private JComboBox singleSuperior = Utilities.createComboBox(); private JLabel multipleSuperiors = Utilities.createDefaultLabel(); private JButton bSpecifyMultiple = Utilities.createButton( INFO_CTRL_PANEL_SPECIFY_MULTIPLE_SUPERIORS_LABEL.get()); private JButton bUpdateMultiple = Utilities.createButton( INFO_CTRL_PANEL_UPDATE_MULTIPLE_SUPERIORS_LABEL.get()); private SelectObjectClassesPanel superiorsPanel; private GenericDialog superiorsDialog; private String MULTIPLE = "Multiple"; private String SINGLE = "Single"; private CardLayout cardLayout = new CardLayout(); private boolean isMultiple; private Set<ObjectClass> selectedMultipleSuperiors = new HashSet<ObjectClass>(); private Set<SuperiorObjectClassesChangedListener> listeners = new HashSet<SuperiorObjectClassesChangedListener>(); private Schema schema; /** * Default constructor for this panel. */ public SuperiorObjectClassesEditor() { super(new CardLayout()); cardLayout = (CardLayout)getLayout(); setOpaque(false); createLayout(); } /** * Constructor for this panel. * @param schema a non {@code null} schema object. */ public SuperiorObjectClassesEditor(Schema schema) { this(); updateWithSchema(schema); } /** * Creates the layout of this panel. */ private void createLayout() { bSpecifyMultiple.setToolTipText( INFO_CTRL_PANEL_SPECIFY_MULTIPLE_SUPERIORS_TOOLTIP.get().toString()); bSpecifyMultiple.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { specifyMultipleClicked(); } }); bUpdateMultiple.setToolTipText( INFO_CTRL_PANEL_UPDATE_MULTIPLE_SUPERIORS_TOOLTIP.get().toString()); bUpdateMultiple.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ev) { updateMultipleClicked(); } }); SchemaElementComboBoxCellRenderer renderer = new SchemaElementComboBoxCellRenderer(singleSuperior); DefaultComboBoxModel model = new DefaultComboBoxModel(); singleSuperior.setModel(model); singleSuperior.setRenderer(renderer); ItemListener itemListener = new ItemListener() { /** * {@inheritDoc} */ public void itemStateChanged(ItemEvent ev) { notifyListeners(); } }; singleSuperior.addItemListener(itemListener); JPanel singlePanel = new JPanel(new GridBagLayout()); singlePanel.setOpaque(false); JPanel multiplePanel = new JPanel(new GridBagLayout()); multiplePanel.setOpaque(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = 0; gbc.gridy = 0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.WEST; singlePanel.add(singleSuperior, gbc); multiplePanel.add(multipleSuperiors, gbc); gbc.gridx ++; gbc.insets.left = 5; gbc.weightx = 0.0; gbc.fill = GridBagConstraints.NONE; singlePanel.add(bSpecifyMultiple, gbc); multiplePanel.add(bUpdateMultiple, gbc); gbc.gridx ++; gbc.insets.left = 0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.1; singlePanel.add(Box.createHorizontalGlue(), gbc); multiplePanel.add(Box.createHorizontalGlue(), gbc); add(singlePanel, SINGLE); add(multiplePanel, MULTIPLE); Set<ObjectClass> empty = Collections.emptySet(); setSelectedSuperiors(empty); } /** * Sets the list of object classes that this panel should not display * (mainly used to not display the object class for which we are editing * the superior object classes). * @param toExclude the list of object classes to exclude. */ public void setObjectClassesToExclude(Set<ObjectClass> toExclude) { this.toExclude.clear(); this.toExclude.addAll(toExclude); updateWithSchema(schema); if (superiorsPanel != null) { superiorsPanel.setObjectClassesToExclude(toExclude); } } /** * Returns the list of object classes that this panel will not display. * @return the list of object classes that this panel will not display. */ public Set<ObjectClass> getObjectClassToExclude() { return Collections.unmodifiableSet(toExclude); } /** * Sets the list of superior object classes that must be displayed by * this panel. * @param objectClasses the list of superior object classes to be displayed. */ public void setSelectedSuperiors(Set<ObjectClass> objectClasses) { isMultiple = objectClasses.size() > 1; if (isMultiple) { cardLayout.show(this, MULTIPLE); selectedMultipleSuperiors.clear(); selectedMultipleSuperiors.addAll(objectClasses); updateMultipleSuperiorsLabel(selectedMultipleSuperiors); } else { if (objectClasses.size() == 1) { singleSuperior.setSelectedItem(objectClasses.iterator().next()); } cardLayout.show(this, SINGLE); } } private void updateMultipleSuperiorsLabel( Set<ObjectClass> superiors) { SortedSet<String> orderedOcs = new TreeSet<String>(new LowerCaseComparator()); for (ObjectClass oc : superiors) { orderedOcs.add(oc.getNameOrOID()); } String s = Utilities.getStringFromCollection(orderedOcs, ", "); multipleSuperiors.setText(s); } /** * Returns the list of superior object classes displayed by this panel. * @return the list of superior object classes displayed by this panel. */ public Set<ObjectClass> getSelectedSuperiors() { if (isMultiple) { return Collections.unmodifiableSet(selectedMultipleSuperiors); } else { ObjectClass oc = (ObjectClass)singleSuperior.getSelectedItem(); if (oc == null) { return Collections.emptySet(); } else { return Collections.singleton( (ObjectClass)(singleSuperior.getSelectedItem())); } } } /** * Sets the schema to be used by this panel. This method assumes that it * is being called from the event thread. * @param schema the schema to be used by this panel. */ public void setSchema(Schema schema) { updateWithSchema(schema); if (superiorsPanel != null) { superiorsPanel.setSchema(schema); } } private void updateWithSchema(Schema schema) { HashMap<String, ObjectClass> objectClassNameMap = new HashMap<String, ObjectClass>(); for (String key : schema.getObjectClasses().keySet()) { ObjectClass oc = schema.getObjectClass(key); if (!toExclude.contains(oc)) { objectClassNameMap.put(oc.getNameOrOID(), oc); } } SortedSet<String> orderedKeys = new TreeSet<String>(new LowerCaseComparator()); orderedKeys.addAll(objectClassNameMap.keySet()); ArrayList<Object> newParents = new ArrayList<Object>(); for (String key : orderedKeys) { newParents.add(objectClassNameMap.get(key)); } Utilities.updateComboBoxModel(newParents, (DefaultComboBoxModel)singleSuperior.getModel()); if (this.schema == null) { // Select the values. ObjectClass topClass = schema.getObjectClass("top"); singleSuperior.setSelectedItem(topClass); } this.schema = schema; } /** * Adds a listener that will receive events when a change is made in the * displayed superior object classes. * @param listener the listener to be added. */ public void addParentObjectClassesChangedListener( SuperiorObjectClassesChangedListener listener) { listeners.add(listener); } /** * Removes the provided listener. * @param listener the listener to be removed. */ public void removeParentObjectClassesChangedListener( SuperiorObjectClassesChangedListener listener) { listeners.remove(listener); } private void specifyMultipleClicked() { updateMultipleClicked(); } private void updateMultipleClicked() { Set<ObjectClass> selectedObjectClasses = getSelectedSuperiors(); // Display the panel with all the stuff. if (superiorsPanel == null) { superiorsPanel = new SelectObjectClassesPanel(); superiorsPanel.setSchema(schema); if (!toExclude.isEmpty()) { superiorsPanel.setObjectClassesToExclude(toExclude); } superiorsDialog = new GenericDialog(Utilities.getFrame(this), superiorsPanel); Utilities.centerGoldenMean(superiorsDialog, Utilities.getParentDialog(this)); superiorsDialog.setModal(true); superiorsDialog.pack(); } superiorsPanel.setSelectedObjectClasses(selectedObjectClasses); superiorsDialog.setVisible(true); if (!superiorsPanel.isCanceled()) { setSelectedSuperiors(superiorsPanel.getSelectedObjectClasses()); notifyListeners(); } } private void notifyListeners() { SuperiorObjectClassesChangedEvent ev = new SuperiorObjectClassesChangedEvent(this, getSelectedSuperiors()); for (SuperiorObjectClassesChangedListener listener : listeners) { listener.parentObjectClassesChanged(ev); } } }