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 2008 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2015 ForgeRock AS. 016 */ 017 018package org.opends.guitools.controlpanel.ui; 019 020import static org.opends.messages.AdminToolMessages.*; 021 022import java.awt.Component; 023import java.awt.GridBagConstraints; 024import java.util.SortedSet; 025import java.util.TreeSet; 026 027import javax.swing.DefaultComboBoxModel; 028import javax.swing.JComboBox; 029import javax.swing.JLabel; 030import javax.swing.SwingUtilities; 031 032import org.opends.guitools.controlpanel.datamodel.ObjectClassValue; 033import org.opends.guitools.controlpanel.datamodel.SortableListModel; 034import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; 035import org.opends.guitools.controlpanel.ui.components.AddRemovePanel; 036import org.opends.guitools.controlpanel.util.Utilities; 037import org.forgerock.i18n.LocalizableMessage; 038import org.opends.server.types.ObjectClass; 039import org.forgerock.opendj.ldap.schema.ObjectClassType; 040import org.opends.server.types.Schema; 041 042/** 043 * This is the class used to edit the object class of a given entry, it displays 044 * the structural objectclass of the entry and its auxiliary objectclasses. 045 * 046 */ 047public class ObjectClassEditorPanel extends StatusGenericPanel 048{ 049 private static final long serialVersionUID = 6632731109835897496L; 050 private JComboBox structural; 051 private AddRemovePanel<String> auxiliary; 052 053 private ObjectClassValue value; 054 055 private boolean valueChanged; 056 057 /** 058 * Default constructor. 059 * 060 */ 061 public ObjectClassEditorPanel() 062 { 063 super(); 064 createLayout(); 065 } 066 067 /** 068 * Sets the object class to be displayed in the panel. 069 * @param value the object class to be displayed in the panel. 070 */ 071 public void setValue(ObjectClassValue value) 072 { 073 this.value = value; 074 String struct = value.getStructural(); 075 if (struct != null) 076 { 077 DefaultComboBoxModel structuralModel = 078 (DefaultComboBoxModel)structural.getModel(); 079 for (int i=0; i<structuralModel.getSize(); i++) 080 { 081 if (struct.equalsIgnoreCase((String)structuralModel.getElementAt(i))) 082 { 083 structural.setSelectedIndex(i); 084 break; 085 } 086 } 087 } 088 SortableListModel<String> availableListModel = 089 auxiliary.getAvailableListModel(); 090 SortableListModel<String> selectedListModel = 091 auxiliary.getSelectedListModel(); 092 availableListModel.addAll(selectedListModel.getData()); 093 selectedListModel.clear(); 094 095 for (String oc : value.getAuxiliary()) 096 { 097 int index = -1; 098 for (int i=0; i<availableListModel.getSize(); i++) 099 { 100 if (availableListModel.getElementAt(i).equalsIgnoreCase(oc)) 101 { 102 index = i; 103 break; 104 } 105 } 106 if (index != -1) 107 { 108 oc = availableListModel.getElementAt(index); 109 selectedListModel.add(oc); 110 availableListModel.remove(oc); 111 } 112 } 113 selectedListModel.fireContentsChanged( 114 selectedListModel, 0, selectedListModel.getSize()); 115 availableListModel.fireContentsChanged( 116 availableListModel, 0, availableListModel.getSize()); 117 } 118 119 /** {@inheritDoc} */ 120 public Component getPreferredFocusComponent() 121 { 122 return structural; 123 } 124 125 /** {@inheritDoc} */ 126 public void cancelClicked() 127 { 128 valueChanged = false; 129 super.cancelClicked(); 130 } 131 132 /** 133 * Returns the object class value displayed by the panel. 134 * @return the object class value displayed by the panel. 135 */ 136 public ObjectClassValue getObjectClassValue() 137 { 138 return value; 139 } 140 141 /** {@inheritDoc} */ 142 public void okClicked() 143 { 144 String struct = (String) structural.getSelectedItem(); 145 TreeSet<String> aux = new TreeSet<>(auxiliary.getSelectedListModel().getData()); 146 aux.add("top"); 147 ObjectClassValue newValue = new ObjectClassValue(struct, aux); 148 valueChanged = !newValue.equals(value); 149 value = newValue; 150 Utilities.getParentDialog(this).setVisible(false); 151 } 152 153 /** {@inheritDoc} */ 154 public LocalizableMessage getTitle() 155 { 156 return INFO_CTRL_PANEL_EDIT_OBJECTCLASS_TITLE.get(); 157 } 158 159 /** {@inheritDoc} */ 160 public void configurationChanged(ConfigurationChangeEvent ev) 161 { 162 final Schema schema = ev.getNewDescriptor().getSchema(); 163 if (schema != null) 164 { 165 final SortedSet<String> auxiliaryOcs = new TreeSet<>(); 166 final SortedSet<String> structuralOcs = new TreeSet<>(); 167 for (ObjectClass oc : schema.getObjectClasses().values()) 168 { 169 if (oc.getObjectClassType() == ObjectClassType.AUXILIARY) 170 { 171 if (!oc.getNameOrOID().equals("top")) 172 { 173 auxiliaryOcs.add(oc.getNameOrOID()); 174 } 175 } 176 else if (oc.getObjectClassType() == ObjectClassType.STRUCTURAL) 177 { 178 structuralOcs.add(oc.getNameOrOID()); 179 } 180 } 181 182 SwingUtilities.invokeLater(new Runnable() 183 { 184 /** {@inheritDoc} */ 185 public void run() 186 { 187 String currentStruct = (String)structural.getSelectedItem(); 188 189 SortedSet<String> currentAux; 190 if (currentStruct != null) 191 { 192 currentAux = auxiliary.getSelectedListModel().getData(); 193 } 194 else if (value != null) 195 { 196 // This is to handle the case where the schema is updated after 197 // a value was set. 198 currentStruct = value.getStructural(); 199 currentAux = value.getAuxiliary(); 200 } 201 else 202 { 203 currentAux = new TreeSet<>(); 204 } 205 SortableListModel<String> availableListModel = 206 auxiliary.getAvailableListModel(); 207 SortableListModel<String> selectedListModel = 208 auxiliary.getSelectedListModel(); 209 DefaultComboBoxModel structuralModel = 210 (DefaultComboBoxModel)structural.getModel(); 211 structuralModel.removeAllElements(); 212 availableListModel.clear(); 213 selectedListModel.clear(); 214 for (String oc : structuralOcs) 215 { 216 structuralModel.addElement(oc); 217 } 218 for (String oc : auxiliaryOcs) 219 { 220 availableListModel.add(oc); 221 } 222 if (currentStruct != null) 223 { 224 structural.setSelectedItem(currentStruct); 225 } 226 for (String oc : currentAux) 227 { 228 availableListModel.remove(oc); 229 selectedListModel.add(oc); 230 } 231 selectedListModel.fireContentsChanged( 232 selectedListModel, 0, selectedListModel.getSize()); 233 availableListModel.fireContentsChanged( 234 availableListModel, 0, availableListModel.getSize()); 235 setEnabledOK(true); 236 } 237 }); 238 } 239 else 240 { 241 updateErrorPane(errorPane, 242 ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_SUMMARY.get(), 243 ColorAndFontConstants.errorTitleFont, 244 ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get(), 245 ColorAndFontConstants.defaultFont); 246 SwingUtilities.invokeLater(new Runnable() 247 { 248 /** {@inheritDoc} */ 249 public void run() 250 { 251 setEnabledOK(false); 252 } 253 }); 254 } 255 } 256 257 /** 258 * Returns <CODE>true</CODE> if the value changed and <CODE>false</CODE> 259 * otherwise. 260 * @return <CODE>true</CODE> if the value changed and <CODE>false</CODE> 261 * otherwise. 262 */ 263 public boolean valueChanged() 264 { 265 return valueChanged; 266 } 267 268 /** {@inheritDoc} */ 269 public boolean requiresScroll() 270 { 271 return false; 272 } 273 274 /** 275 * Creates the layout of the panel (but the contents are not populated here). 276 */ 277 private void createLayout() 278 { 279 GridBagConstraints gbc = new GridBagConstraints(); 280 gbc.gridx = 0; 281 gbc.gridy = 0; 282 gbc.weighty = 0.0; 283 gbc.weightx = 1.0; 284 gbc.fill = GridBagConstraints.BOTH; 285 gbc.gridwidth = 2; 286 addErrorPane(gbc); 287 288 gbc.gridwidth = 1; 289 gbc.fill = GridBagConstraints.HORIZONTAL; 290 gbc.weightx = 0.0; 291 JLabel l = Utilities.createPrimaryLabel( 292 INFO_CTRL_PANEL_STRUCTURAL_OBJECTCLASS_LABEL.get()); 293 add(l, gbc); 294 gbc.gridx ++; 295 gbc.insets.left = 10; 296 gbc.anchor = GridBagConstraints.WEST; 297 DefaultComboBoxModel model = new DefaultComboBoxModel(); 298 structural = Utilities.createComboBox(); 299 structural.setModel(model); 300 gbc.weightx = 1.0; 301 add(structural, gbc); 302 303 gbc.gridy ++; 304 gbc.gridwidth = 2; 305 gbc.gridx = 0; 306 gbc.insets.top = 10; 307 gbc.insets.left = 0; 308 l = Utilities.createPrimaryLabel( 309 INFO_CTRL_PANEL_AUXILIARY_OBJECTCLASS_LABEL.get()); 310 add(l, gbc); 311 gbc.gridy ++; 312 gbc.weightx = 1.0; 313 gbc.weighty = 1.0; 314 gbc.fill = GridBagConstraints.BOTH; 315 auxiliary = new AddRemovePanel<>(String.class); 316 gbc.insets.left = 30; 317 add(auxiliary, gbc); 318 } 319}