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