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