opends/src/guitools/org/opends/guitools/controlpanel/task/DeleteSchemaElementsTask.java
@@ -32,8 +32,12 @@ import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.naming.NamingException; @@ -60,6 +64,7 @@ import org.opends.server.types.ModificationType; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; import org.opends.server.types.Schema; import org.opends.server.types.SchemaFileElement; import org.opends.server.util.LDIFReader; import org.opends.server.util.LDIFWriter; @@ -69,24 +74,94 @@ */ public class DeleteSchemaElementsTask extends Task { ArrayList<ObjectClass> ocsToDelete = new ArrayList<ObjectClass>(); ArrayList<AttributeType> attrsToDelete = new ArrayList<AttributeType>(); private Set<String> backendSet; // The list of object classes that the user asked to delete. LinkedHashSet<ObjectClass> providedOcsToDelete = new LinkedHashSet<ObjectClass>(); // The list of attributes that the user asked to delete. LinkedHashSet<AttributeType> providedAttrsToDelete = new LinkedHashSet<AttributeType>(); // The list of object classes that will be actually deleted (some might be // recreated). LinkedHashSet<ObjectClass> ocsToDelete = new LinkedHashSet<ObjectClass>(); // The list of attributes that will be actually deleted (some might be // recreated). LinkedHashSet<AttributeType> attrsToDelete = new LinkedHashSet<AttributeType>(); // The list of object classes that will be recreated. LinkedHashSet<ObjectClass> ocsToAdd = new LinkedHashSet<ObjectClass>(); // The list of attributes that will be recreated. LinkedHashSet<AttributeType> attrsToAdd = new LinkedHashSet<AttributeType>(); /** * Constructor of the task. * @param info the control panel information. * @param dlg the progress dialog where the task progress will be displayed. * @param ocsToDelete the object classes that must be deleted. * @param attrsToDelete the attributes that must be deleted. * @param ocsToDelete the object classes that must be deleted (ordered). * @param attrsToDelete the attributes that must be deleted (ordered). */ public DeleteSchemaElementsTask(ControlPanelInfo info, ProgressDialog dlg, List<ObjectClass> ocsToDelete, List<AttributeType> attrsToDelete) LinkedHashSet<ObjectClass> ocsToDelete, LinkedHashSet<AttributeType> attrsToDelete) { super(info, dlg); this.ocsToDelete.addAll(ocsToDelete); this.attrsToDelete.addAll(attrsToDelete); backendSet = new HashSet<String>(); this.providedOcsToDelete.addAll(ocsToDelete); this.providedAttrsToDelete.addAll(attrsToDelete); Schema schema = info.getServerDescriptor().getSchema(); LinkedHashSet<AttributeType> allAttrsToDelete = DeleteSchemaElementsTask.getOrderedAttributesToDelete(attrsToDelete, schema); LinkedHashSet<ObjectClass> allOcsToDelete = null; if (!attrsToDelete.isEmpty()) { allOcsToDelete = DeleteSchemaElementsTask.getOrderedObjectClassesToDeleteFromAttrs( attrsToDelete, schema); } if (!ocsToDelete.isEmpty()) { if (allOcsToDelete == null) { allOcsToDelete = DeleteSchemaElementsTask.getOrderedObjectClassesToDelete( ocsToDelete, schema); } else { allOcsToDelete.addAll( DeleteSchemaElementsTask.getOrderedObjectClassesToDelete( ocsToDelete, schema)); } } ArrayList<AttributeType> lAttrsToDelete = new ArrayList<AttributeType>(allAttrsToDelete); for (int i = lAttrsToDelete.size() - 1; i >= 0; i--) { AttributeType attrToDelete = lAttrsToDelete.get(i); if (!attrsToDelete.contains(attrToDelete)) { AttributeType attrToAdd = getAttributeToAdd(attrToDelete); if (attrToAdd != null) { attrsToAdd.add(attrToAdd); } } } ArrayList<ObjectClass> lOcsToDelete = new ArrayList<ObjectClass>(allOcsToDelete); for (int i = lOcsToDelete.size() - 1; i >= 0; i--) { ObjectClass ocToDelete = lOcsToDelete.get(i); if (!ocsToDelete.contains(ocToDelete)) { ocsToAdd.add(getObjectClassToAdd(lOcsToDelete.get(i))); } } this.ocsToDelete.addAll(allOcsToDelete); this.attrsToDelete.addAll(allAttrsToDelete); } /** @@ -94,7 +169,7 @@ */ public Set<String> getBackends() { return backendSet; return Collections.emptySet(); } /** @@ -103,7 +178,17 @@ public boolean canLaunch(Task taskToBeLaunched, Collection<Message> incompatibilityReasons) { return true; boolean canLaunch = true; if (state == State.RUNNING && (taskToBeLaunched.getType() == Task.Type.DELETE_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.MODIFY_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.NEW_SCHEMA_ELEMENT)) { incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); canLaunch = false; } return canLaunch; } /** @@ -111,18 +196,7 @@ */ public Type getType() { if (attrsToDelete.isEmpty()) { return Type.DELETE_OBJECTCLASS; } else if (ocsToDelete.isEmpty()) { return Type.DELETE_ATTRIBUTE; } else { return Type.DELETE_OBJECTCLASS; } return Type.NEW_SCHEMA_ELEMENT; } /** @@ -156,9 +230,9 @@ /** * {@inheritDoc} */ protected ArrayList<String> getCommandLineArguments() protected List<String> getCommandLineArguments() { return new ArrayList<String>(); return Collections.emptyList(); } /** @@ -178,8 +252,9 @@ final boolean[] isFirst = {true}; final int totalNumber = ocsToDelete.size() + attrsToDelete.size(); int numberDeleted = 0; for (final ObjectClass objectClass : ocsToDelete) for (ObjectClass objectClass : ocsToDelete) { final ObjectClass fObjectclass = objectClass; SwingUtilities.invokeLater(new Runnable() { public void run() @@ -189,11 +264,11 @@ getProgressDialog().appendProgressHtml("<br><br>"); } isFirst[0] = false; printEquivalentCommandToDelete(objectClass); printEquivalentCommandToDelete(fObjectclass); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_DELETING_OBJECTCLASS.get( objectClass.getNameOrOID()), fObjectclass.getNameOrOID()), ColorAndFontConstants.progressFont)); } }); @@ -236,8 +311,9 @@ }); } for (final AttributeType attribute : attrsToDelete) for (AttributeType attribute : attrsToDelete) { final AttributeType fAttribute = attribute; SwingUtilities.invokeLater(new Runnable() { public void run() @@ -247,11 +323,11 @@ getProgressDialog().appendProgressHtml("<br><br>"); } isFirst[0] = false; printEquivalentCommandToDelete(attribute); printEquivalentCommandToDelete(fAttribute); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_DELETING_ATTRIBUTE.get( attribute.getNameOrOID()), fAttribute.getNameOrOID()), ColorAndFontConstants.progressFont)); } }); @@ -296,6 +372,25 @@ }); } if (!ocsToAdd.isEmpty() || !attrsToAdd.isEmpty()) { SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont( "<br><br>"+ INFO_CTRL_PANEL_EXPLANATION_TO_DELETE_REFERENCED_ELEMENTS.get()+ "<br><br>", ColorAndFontConstants.progressFont)); } }); NewSchemaElementsTask createTask = new NewSchemaElementsTask(getInfo(), getProgressDialog(), ocsToAdd, attrsToAdd); createTask.runTask(); } } /** @@ -431,9 +526,19 @@ String attrValue = getSchemaFileAttributeValue(element); if (!isServerRunning()) { Message msg; if (element instanceof AttributeType) { msg = INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_ATTRIBUTE_OFFLINE.get( element.getNameOrOID(), schemaFile); } else { msg = INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_OBJECTCLASS_OFFLINE.get( element.getNameOrOID(), schemaFile); } getProgressDialog().appendProgressHtml(Utilities.applyFont( INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_SCHEMA_ELEMENT_OFFLINE.get( schemaFile)+"<br><b>"+ msg+"<br><b>"+ attrName+": "+attrValue+"</b><br><br>", ColorAndFontConstants.progressFont)); } @@ -447,10 +552,21 @@ String equiv = getEquivalentCommandLine(getCommandLinePath("ldapmodify"), args); Message msg; if (element instanceof AttributeType) { msg = INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_ATTRIBUTE_ONLINE.get( element.getNameOrOID()); } else { msg = INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_OBJECTCLASS_ONLINE.get( element.getNameOrOID()); } StringBuilder sb = new StringBuilder(); sb.append( INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_SCHEMA_ELEMENT_ONLINE.get()+ "<br><b>"); msg+"<br><b>"); sb.append(equiv); sb.append("<br>"); sb.append("dn: cn=schema<br>"); @@ -462,4 +578,262 @@ ColorAndFontConstants.progressFont)); } } private AttributeType getAttributeToAdd(AttributeType attrToDelete) { AttributeType attrToAdd; boolean isSuperior = false; AttributeType newSuperior = attrToDelete.getSuperiorType(); for (AttributeType attr : providedAttrsToDelete) { if (attr.equals(attrToDelete.getSuperiorType())) { isSuperior = true; newSuperior = attr.getSuperiorType(); while (newSuperior != null && providedAttrsToDelete.contains(newSuperior)) { newSuperior = newSuperior.getSuperiorType(); } break; } } if (isSuperior) { ArrayList<String> allNames = new ArrayList<String>(); for (String str : attrToDelete.getNormalizedNames()) { allNames.add(str); } Map<String, List<String>> extraProperties = cloneExtraProperties(attrToDelete); attrToAdd = new AttributeType( "", attrToDelete.getPrimaryName(), allNames, attrToDelete.getOID(), attrToDelete.getDescription(), null, attrToDelete.getSyntax(), attrToDelete.getApproximateMatchingRule(), attrToDelete.getEqualityMatchingRule(), attrToDelete.getOrderingMatchingRule(), attrToDelete.getSubstringMatchingRule(), attrToDelete.getUsage(), attrToDelete.isCollective(), attrToDelete.isNoUserModification(), attrToDelete.isObsolete(), attrToDelete.isSingleValue(), extraProperties); } else { // Nothing to be changed in the definition of the attribute itself. attrToAdd = attrToDelete; } return attrToAdd; } private ObjectClass getObjectClassToAdd(ObjectClass ocToDelete) { ObjectClass ocToAdd; boolean containsAttribute = false; for (AttributeType attr : providedAttrsToDelete) { if(ocToDelete.getRequiredAttributeChain().contains(attr) || ocToDelete.getOptionalAttributeChain().contains(attr)) { containsAttribute = true; break; } } boolean hasSuperior = false; ObjectClass newSuperior = ocToDelete.getSuperiorClass(); for (ObjectClass oc : providedOcsToDelete) { if (ocToDelete.getSuperiorClass().equals(oc)) { hasSuperior = true; newSuperior = oc.getSuperiorClass(); while (newSuperior != null && providedOcsToDelete.contains(newSuperior)) { newSuperior = newSuperior.getSuperiorClass(); } break; } } if (containsAttribute || hasSuperior) { ArrayList<String> allNames = new ArrayList<String>(); for (String str : ocToDelete.getNormalizedNames()) { allNames.add(str); } Map<String, List<String>> extraProperties = cloneExtraProperties(ocToDelete); Set<AttributeType> required; Set<AttributeType> optional; if (containsAttribute) { required = new HashSet<AttributeType>( ocToDelete.getRequiredAttributes()); optional = new HashSet<AttributeType>( ocToDelete.getOptionalAttributes()); required.removeAll(providedAttrsToDelete); optional.removeAll(providedAttrsToDelete); } else { required = ocToDelete.getRequiredAttributes(); optional = ocToDelete.getOptionalAttributes(); } ocToAdd = new ObjectClass("", ocToDelete.getPrimaryName(), allNames, ocToDelete.getOID(), ocToDelete.getDescription(), newSuperior, required, optional, ocToDelete.getObjectClassType(), ocToDelete.isObsolete(), extraProperties); } else { // Nothing to be changed in the definition of the object class itself. ocToAdd = ocToDelete; } return ocToAdd; } /** * Returns an ordered set of the attributes that must be deleted. * @param attrsToDelete the attributes to be deleted. * @param schema the server schema. * @return an ordered list of the attributes that must be deleted. */ public static LinkedHashSet<AttributeType> getOrderedAttributesToDelete( Collection<AttributeType> attrsToDelete, Schema schema) { LinkedHashSet<AttributeType> orderedAttributes = new LinkedHashSet<AttributeType>(); for (AttributeType attribute : attrsToDelete) { orderedAttributes.addAll(getOrderedChildrenToDelete(attribute, schema)); orderedAttributes.add(attribute); } return orderedAttributes; } /** * Returns an ordered list of the object classes that must be deleted. * @param ocsToDelete the object classes to be deleted. * @param schema the server schema. * @return an ordered list of the object classes that must be deleted. */ public static LinkedHashSet<ObjectClass> getOrderedObjectClassesToDelete( Collection<ObjectClass> ocsToDelete, Schema schema) { LinkedHashSet<ObjectClass> orderedOcs = new LinkedHashSet<ObjectClass>(); for (ObjectClass oc : ocsToDelete) { orderedOcs.addAll(getOrderedChildrenToDelete(oc, schema)); orderedOcs.add(oc); } return orderedOcs; } /** * Returns an ordered list of the object classes that must be deleted when * deleting a list of attributes that must be deleted. * @param attrsToDelete the attributes to be deleted. * @param schema the server schema. * @return an ordered list of the object classes that must be deleted when * deleting a list of attributes that must be deleted. */ public static LinkedHashSet<ObjectClass> getOrderedObjectClassesToDeleteFromAttrs( Collection<AttributeType> attrsToDelete, Schema schema) { LinkedHashSet<ObjectClass> orderedOcs = new LinkedHashSet<ObjectClass>(); ArrayList<ObjectClass> dependentClasses = new ArrayList<ObjectClass>(); for (AttributeType attr : attrsToDelete) { for (ObjectClass oc : schema.getObjectClasses().values()) { if (oc.getRequiredAttributeChain().contains(attr)) { dependentClasses.add(oc); } else if (oc.getOptionalAttributeChain().contains(attr)) { dependentClasses.add(oc); } } } for (ObjectClass oc : dependentClasses) { orderedOcs.addAll(getOrderedChildrenToDelete(oc, schema)); orderedOcs.add(oc); } return orderedOcs; } /** * Clones the extra properties of the provided schema element. This can * be used when copying schema elements. * @param element the schema element. * @return the extra properties of the provided schema element. */ public static Map<String, List<String>> cloneExtraProperties( CommonSchemaElements element) { Map<String, List<String>> extraProperties = new HashMap<String, List<String>>(); for (String name : element.getExtraPropertyNames()) { List<String> values = new ArrayList<String>(); Iterable<String> properties = element.getExtraProperty(name); for (String v : properties) { values.add(v); } extraProperties.put(name, values); } return extraProperties; } private static LinkedHashSet<AttributeType> getOrderedChildrenToDelete( AttributeType attribute, Schema schema) { LinkedHashSet<AttributeType> children = new LinkedHashSet<AttributeType>(); for (AttributeType attr : schema.getAttributeTypes().values()) { if (attribute.equals(attr.getSuperiorType())) { children.addAll(getOrderedChildrenToDelete(attr, schema)); children.add(attr); } } return children; } private static LinkedHashSet<ObjectClass> getOrderedChildrenToDelete( ObjectClass objectClass, Schema schema) { LinkedHashSet<ObjectClass> children = new LinkedHashSet<ObjectClass>(); for (ObjectClass oc : schema.getObjectClasses().values()) { if (objectClass.equals(oc.getSuperiorClass())) { children.addAll(getOrderedChildrenToDelete(oc, schema)); children.add(oc); } } return children; } } opends/src/guitools/org/opends/guitools/controlpanel/task/ModifyAttributeTask.java
New file @@ -0,0 +1,328 @@ /* * 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 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.task; import static org.opends.messages.AdminToolMessages.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.SwingUtilities; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; import org.opends.guitools.controlpanel.ui.ProgressDialog; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.server.types.AttributeType; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; import org.opends.server.types.Schema; /** * The task that is in charge of modifying an attribute definition (and all * the references to this attribute). * */ public class ModifyAttributeTask extends Task { private AttributeType oldAttribute; private AttributeType newAttribute; /** * The constructor of the task. * @param info the control panel info. * @param dlg the progress dialog that shows the progress of the task. * @param oldAttribute the old attribute definition. * @param newAttribute the new attribute definition. */ public ModifyAttributeTask(ControlPanelInfo info, ProgressDialog dlg, AttributeType oldAttribute, AttributeType newAttribute) { super(info, dlg); if (oldAttribute == null) { throw new IllegalArgumentException("oldAttribute cannot be null."); } if (newAttribute == null) { throw new IllegalArgumentException("newAttribute cannot be null."); } this.oldAttribute = oldAttribute; this.newAttribute = newAttribute; } /** * {@inheritDoc} */ public Type getType() { return Type.MODIFY_SCHEMA_ELEMENT; } /** * {@inheritDoc} */ public Message getTaskDescription() { return INFO_CTRL_PANEL_MODIFY_ATTRIBUTE_TASK_DESCRIPTION.get( oldAttribute.getNameOrOID()); } /** * {@inheritDoc} */ public boolean canLaunch(Task taskToBeLaunched, Collection<Message> incompatibilityReasons) { boolean canLaunch = true; if (state == State.RUNNING && (taskToBeLaunched.getType() == Task.Type.DELETE_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.MODIFY_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.NEW_SCHEMA_ELEMENT)) { incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); canLaunch = false; } return canLaunch; } /** * {@inheritDoc} */ public Set<String> getBackends() { return Collections.emptySet(); } /** * {@inheritDoc} */ protected List<String> getCommandLineArguments() { return Collections.emptyList(); } /** * {@inheritDoc} */ protected String getCommandLinePath() { return null; } /** * {@inheritDoc} */ public void runTask() { try { updateSchema(); state = State.FINISHED_SUCCESSFULLY; } catch (Throwable t) { // TODO //revertChanges(); lastException = t; state = State.FINISHED_WITH_ERROR; } } private AttributeType getAttributeToAdd(AttributeType attrToDelete) { AttributeType attrToAdd; if (attrToDelete.equals(oldAttribute)) { attrToAdd = newAttribute; } else { if (oldAttribute.equals(attrToDelete.getSuperiorType())) { ArrayList<String> allNames = new ArrayList<String>(); for (String str : attrToDelete.getNormalizedNames()) { allNames.add(str); } Map<String, List<String>> extraProperties = DeleteSchemaElementsTask.cloneExtraProperties(attrToDelete); AttributeType newSuperior = newAttribute; attrToAdd = new AttributeType( "", attrToDelete.getPrimaryName(), allNames, attrToDelete.getOID(), attrToDelete.getDescription(), newSuperior, attrToDelete.getSyntax(), attrToDelete.getApproximateMatchingRule(), attrToDelete.getEqualityMatchingRule(), attrToDelete.getOrderingMatchingRule(), attrToDelete.getSubstringMatchingRule(), attrToDelete.getUsage(), attrToDelete.isCollective(), attrToDelete.isNoUserModification(), attrToDelete.isObsolete(), attrToDelete.isSingleValue(), extraProperties); } else { // Nothing to be changed in the definition of the attribute itself. attrToAdd = attrToDelete; } } return attrToAdd; } private ObjectClass getObjectClassToAdd(ObjectClass ocToDelete) { ObjectClass ocToAdd; boolean containsAttribute = ocToDelete.getRequiredAttributeChain().contains(oldAttribute) || ocToDelete.getOptionalAttributeChain().contains(oldAttribute); if (containsAttribute) { ArrayList<String> allNames = new ArrayList<String>(); for (String str : ocToDelete.getNormalizedNames()) { allNames.add(str); } Map<String, List<String>> extraProperties = DeleteSchemaElementsTask.cloneExtraProperties(ocToDelete); Set<AttributeType> required = new HashSet<AttributeType>( ocToDelete.getRequiredAttributes()); Set<AttributeType> optional = new HashSet<AttributeType>( ocToDelete.getOptionalAttributes()); if (required.contains(oldAttribute)) { required.remove(oldAttribute); required.add(newAttribute); } else if (optional.contains(oldAttribute)) { optional.remove(oldAttribute); optional.add(newAttribute); } ocToAdd = new ObjectClass("", ocToDelete.getPrimaryName(), allNames, ocToDelete.getOID(), ocToDelete.getDescription(), ocToDelete.getSuperiorClass(), required, optional, ocToDelete.getObjectClassType(), ocToDelete.isObsolete(), extraProperties); } else { // Nothing to be changed in the definition of the object class itself. ocToAdd = ocToDelete; } return ocToAdd; } /** * Updates the schema. * @throws OpenDsException if an error occurs. */ private void updateSchema() throws OpenDsException { Schema schema = getInfo().getServerDescriptor().getSchema(); ArrayList<AttributeType> attrs = new ArrayList<AttributeType>(); attrs.add(oldAttribute); LinkedHashSet<AttributeType> attrsToDelete = DeleteSchemaElementsTask.getOrderedAttributesToDelete(attrs, schema); LinkedHashSet<ObjectClass> ocsToDelete = DeleteSchemaElementsTask.getOrderedObjectClassesToDeleteFromAttrs( attrsToDelete, schema); LinkedHashSet<AttributeType> attrsToAdd = new LinkedHashSet<AttributeType>(); ArrayList<AttributeType> lAttrsToDelete = new ArrayList<AttributeType>(attrsToDelete); for (int i = lAttrsToDelete.size() - 1; i >= 0; i--) { AttributeType attrToAdd = getAttributeToAdd(lAttrsToDelete.get(i)); if (attrToAdd != null) { attrsToAdd.add(attrToAdd); } } ArrayList<ObjectClass> lOcsToDelete = new ArrayList<ObjectClass>(ocsToDelete); LinkedHashSet<ObjectClass> ocsToAdd = new LinkedHashSet<ObjectClass>(); for (int i = lOcsToDelete.size() - 1; i >= 0; i--) { ocsToAdd.add(getObjectClassToAdd(lOcsToDelete.get(i))); } SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont( INFO_CTRL_PANEL_EXPLANATION_TO_MODIFY_ATTRIBUTE.get( oldAttribute.getNameOrOID())+"<br><br>", ColorAndFontConstants.progressFont)); } }); DeleteSchemaElementsTask deleteTask = new DeleteSchemaElementsTask(getInfo(), getProgressDialog(), ocsToDelete, attrsToDelete); deleteTask.runTask(); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont("<br><br>", ColorAndFontConstants.progressFont)); } }); NewSchemaElementsTask createTask = new NewSchemaElementsTask(getInfo(), getProgressDialog(), ocsToAdd, attrsToAdd); createTask.runTask(); notifyConfigurationElementCreated(newAttribute); } } opends/src/guitools/org/opends/guitools/controlpanel/task/ModifyObjectClassTask.java
New file @@ -0,0 +1,255 @@ /* * 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 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.task; import static org.opends.messages.AdminToolMessages.*; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.swing.SwingUtilities; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; import org.opends.guitools.controlpanel.ui.ProgressDialog; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.server.types.AttributeType; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; import org.opends.server.types.Schema; /** * The task that is in charge of modifying an object class definition (and all * the references to this object class). * */ public class ModifyObjectClassTask extends Task { private ObjectClass oldObjectClass; private ObjectClass newObjectClass; /** * The constructor of the task. * @param info the control panel info. * @param dlg the progress dialog that shows the progress of the task. * @param oldObjectClass the old object class definition. * @param newObjectClass the new object class definition. */ public ModifyObjectClassTask(ControlPanelInfo info, ProgressDialog dlg, ObjectClass oldObjectClass, ObjectClass newObjectClass) { super(info, dlg); this.oldObjectClass = oldObjectClass; this.newObjectClass = newObjectClass; if (oldObjectClass == null) { throw new IllegalArgumentException("oldObjectClass cannot be null."); } if (newObjectClass == null) { throw new IllegalArgumentException("newObjectClass cannot be null."); } } /** * {@inheritDoc} */ public Type getType() { return Type.MODIFY_SCHEMA_ELEMENT; } /** * {@inheritDoc} */ public Message getTaskDescription() { return INFO_CTRL_PANEL_MODIFY_OBJECTCLASS_TASK_DESCRIPTION.get( oldObjectClass.getNameOrOID()); } /** * {@inheritDoc} */ public boolean canLaunch(Task taskToBeLaunched, Collection<Message> incompatibilityReasons) { boolean canLaunch = true; if (state == State.RUNNING && (taskToBeLaunched.getType() == Task.Type.DELETE_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.MODIFY_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.NEW_SCHEMA_ELEMENT)) { incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); canLaunch = false; } return canLaunch; } /** * {@inheritDoc} */ public Set<String> getBackends() { return Collections.emptySet(); } /** * {@inheritDoc} */ protected List<String> getCommandLineArguments() { return Collections.emptyList(); } /** * {@inheritDoc} */ protected String getCommandLinePath() { return null; } /** * {@inheritDoc} */ public void runTask() { try { updateSchema(); state = State.FINISHED_SUCCESSFULLY; } catch (Throwable t) { // TODO //revertChanges(); lastException = t; state = State.FINISHED_WITH_ERROR; } } private ObjectClass getObjectClassToAdd(ObjectClass ocToDelete) { ObjectClass ocToAdd; if (ocToDelete.equals(oldObjectClass)) { ocToAdd = newObjectClass; } else if (oldObjectClass.equals(ocToDelete.getSuperiorClass())) { ArrayList<String> allNames = new ArrayList<String>(); for (String str : ocToDelete.getNormalizedNames()) { allNames.add(str); } Map<String, List<String>> extraProperties = DeleteSchemaElementsTask.cloneExtraProperties(ocToDelete); ocToAdd = new ObjectClass("", ocToDelete.getPrimaryName(), allNames, ocToDelete.getOID(), ocToDelete.getDescription(), newObjectClass, ocToDelete.getRequiredAttributes(), ocToDelete.getOptionalAttributes(), ocToDelete.getObjectClassType(), ocToDelete.isObsolete(), extraProperties); } else { // Nothing to be changed in the definition of the object class itself. ocToAdd = ocToDelete; } return ocToAdd; } /** * Updates the schema. * @throws OpenDsException if an error occurs. */ private void updateSchema() throws OpenDsException { Schema schema = getInfo().getServerDescriptor().getSchema(); ArrayList<ObjectClass> ocs = new ArrayList<ObjectClass>(); ocs.add(oldObjectClass); LinkedHashSet<ObjectClass> ocsToDelete = DeleteSchemaElementsTask.getOrderedObjectClassesToDelete(ocs, schema); ArrayList<ObjectClass> lOcsToDelete = new ArrayList<ObjectClass>(ocsToDelete); LinkedHashSet<ObjectClass> ocsToAdd = new LinkedHashSet<ObjectClass>(); for (int i = lOcsToDelete.size() - 1; i >= 0; i--) { ocsToAdd.add(getObjectClassToAdd(lOcsToDelete.get(i))); } SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont( INFO_CTRL_PANEL_EXPLANATION_TO_MODIFY_OBJECTCLASS.get( oldObjectClass.getNameOrOID())+"<br><br>", ColorAndFontConstants.progressFont)); } }); DeleteSchemaElementsTask deleteTask = new DeleteSchemaElementsTask(getInfo(), getProgressDialog(), ocsToDelete, new LinkedHashSet<AttributeType>(0)); deleteTask.runTask(); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont("<br><br>", ColorAndFontConstants.progressFont)); } }); NewSchemaElementsTask createTask = new NewSchemaElementsTask(getInfo(), getProgressDialog(), ocsToAdd, new LinkedHashSet<AttributeType>(0)); createTask.runTask(); notifyConfigurationElementCreated(newObjectClass); } } opends/src/guitools/org/opends/guitools/controlpanel/task/NewSchemaElementsTask.java
New file @@ -0,0 +1,824 @@ /* * 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 2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.task; import static org.opends.messages.AdminToolMessages.*; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import javax.naming.NamingException; import javax.naming.directory.BasicAttribute; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.swing.SwingUtilities; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; import org.opends.guitools.controlpanel.ui.ProgressDialog; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.quicksetup.util.Utils; import org.opends.server.config.ConfigConstants; import org.opends.server.core.DirectoryServer; import org.opends.server.types.AttributeType; import org.opends.server.types.Attributes; import org.opends.server.types.CommonSchemaElements; import org.opends.server.types.Entry; import org.opends.server.types.ExistingFileBehavior; import org.opends.server.types.LDIFExportConfig; import org.opends.server.types.LDIFImportConfig; import org.opends.server.types.Modification; import org.opends.server.types.ModificationType; import org.opends.server.types.ObjectClass; import org.opends.server.types.OpenDsException; import org.opends.server.util.LDIFReader; import org.opends.server.util.LDIFWriter; import org.opends.server.util.ServerConstants; /** * An abstract class used to re-factor some code between the different tasks * that create elements in the schema. * */ public class NewSchemaElementsTask extends Task { LinkedHashSet<ObjectClass> ocsToAdd = new LinkedHashSet<ObjectClass>(); LinkedHashSet<AttributeType> attrsToAdd = new LinkedHashSet<AttributeType>(); /** * Constructor of the task. * @param info the control panel information. * @param dlg the progress dialog where the task progress will be displayed. * @param ocsToAdd the object classes that must be created in order. * @param attrsToAdd the attributes that must be created in order. */ public NewSchemaElementsTask(ControlPanelInfo info, ProgressDialog dlg, LinkedHashSet<ObjectClass> ocsToAdd, LinkedHashSet<AttributeType> attrsToAdd) { super(info, dlg); this.ocsToAdd.addAll(ocsToAdd); this.attrsToAdd.addAll(attrsToAdd); } /** * {@inheritDoc} */ public Set<String> getBackends() { return Collections.emptySet(); } /** * {@inheritDoc} */ public boolean canLaunch(Task taskToBeLaunched, Collection<Message> incompatibilityReasons) { boolean canLaunch = true; if (state == State.RUNNING && (taskToBeLaunched.getType() == Task.Type.DELETE_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.MODIFY_SCHEMA_ELEMENT || taskToBeLaunched.getType() == Task.Type.NEW_SCHEMA_ELEMENT)) { incompatibilityReasons.add(getIncompatibilityMessage(this, taskToBeLaunched)); canLaunch = false; } return canLaunch; } /** * {@inheritDoc} */ public void runTask() { state = State.RUNNING; lastException = null; try { updateSchema(); state = State.FINISHED_SUCCESSFULLY; } catch (Throwable t) { lastException = t; state = State.FINISHED_WITH_ERROR; } } /** * {@inheritDoc} */ public Type getType() { return Type.NEW_SCHEMA_ELEMENT; } /** * {@inheritDoc} */ public Message getTaskDescription() { if (attrsToAdd.size() == 1 && ocsToAdd.isEmpty()) { String attributeName = attrsToAdd.iterator().next().getNameOrOID(); return INFO_CTRL_PANEL_NEW_ATTRIBUTE_TASK_DESCRIPTION.get(attributeName); } else if (ocsToAdd.size() == 1 && attrsToAdd.isEmpty()) { String ocName = ocsToAdd.iterator().next().getNameOrOID(); return INFO_CTRL_PANEL_NEW_OBJECTCLASS_TASK_DESCRIPTION.get(ocName); } else { ArrayList<String> attrNames = new ArrayList<String>(); for (AttributeType attribute : attrsToAdd) { attrNames.add(attribute.getNameOrOID()); } ArrayList<String> ocNames = new ArrayList<String>(); for (ObjectClass oc : ocsToAdd) { ocNames.add(oc.getNameOrOID()); } if (ocNames.isEmpty()) { return INFO_CTRL_PANEL_NEW_ATTRIBUTES_TASK_DESCRIPTION.get( Utils.getStringFromCollection(attrNames, ", ")); } else if (attrNames.isEmpty()) { return INFO_CTRL_PANEL_NEW_OBJECTCLASSES_TASK_DESCRIPTION.get( Utils.getStringFromCollection(ocNames, ", ")); } else { return INFO_CTRL_PANEL_NEW_SCHEMA_ELEMENTS_TASK_DESCRIPTION.get( Utils.getStringFromCollection(attrNames, ", "), Utils.getStringFromCollection(ocNames, ", ")); } } } /** * Update the schema. * @throws OpenDsException if an error occurs. */ private void updateSchema() throws OpenDsException { if (isServerRunning()) { updateSchemaOnline(); } else { updateSchemaOffline(); } } /** * {@inheritDoc} */ protected String getCommandLinePath() { return null; } /** * {@inheritDoc} */ protected List<String> getCommandLineArguments() { return Collections.emptyList(); } private void updateSchemaOnline() throws OpenDsException { // Add the schema elements one by one: we are not sure that the server // will handle the adds sequentially if we only send one modification. for (AttributeType attr : attrsToAdd) { addAttributeOnline(attr); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont("<br><br>", ColorAndFontConstants.progressFont)); } }); } for (ObjectClass oc : ocsToAdd) { addObjectClassOnline(oc); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont("<br><br>", ColorAndFontConstants.progressFont)); } }); } } private void updateSchemaOffline() throws OpenDsException { // Group the changes in the same schema file. LinkedHashMap<String, List<AttributeType>> hmAttrs = new LinkedHashMap<String, List<AttributeType>>(); for (AttributeType attr : attrsToAdd) { String fileName = getFileName(attr); if (fileName == null) { fileName = ""; } List<AttributeType> attrs = hmAttrs.get(fileName); if (attrs == null) { attrs = new ArrayList<AttributeType>(); hmAttrs.put(fileName, attrs); } attrs.add(attr); } LinkedHashMap<String, List<ObjectClass>> hmOcs = new LinkedHashMap<String, List<ObjectClass>>(); for (ObjectClass oc : ocsToAdd) { String fileName = getFileName(oc); if (fileName == null) { fileName = ""; } List<ObjectClass> ocs = hmOcs.get(fileName); if (ocs == null) { ocs = new ArrayList<ObjectClass>(); hmOcs.put(fileName, ocs); } ocs.add(oc); } LinkedHashSet<String> allFileNames = new LinkedHashSet<String>(); allFileNames.addAll(hmAttrs.keySet()); allFileNames.addAll(hmOcs.keySet()); for (String fileName : allFileNames) { List<AttributeType> attrs = hmAttrs.get(fileName); List<ObjectClass> ocs = hmOcs.get(fileName); if (attrs == null) { attrs = Collections.emptyList(); } if (ocs == null) { ocs = Collections.emptyList(); } if (fileName.equals("")) { fileName = null; } updateSchemaOffline(fileName, attrs, ocs); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml(Utilities.applyFont("<br><br>", ColorAndFontConstants.progressFont)); } }); } } private void addAttributeOnline(final AttributeType attribute) throws OpenDsException { SwingUtilities.invokeLater(new Runnable() { /** * {@inheritDoc} */ public void run() { printEquivalentCommandLineToAddOnline(attribute); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_CREATING_ATTRIBUTE_PROGRESS.get( attribute.getNameOrOID()), ColorAndFontConstants.progressFont)); } }); try { BasicAttribute attr = new BasicAttribute(getAttributeName(attribute)); attr.add(getValueOnline(attribute)); ModificationItem mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr); getInfo().getDirContext().modifyAttributes( ConfigConstants.DN_DEFAULT_SCHEMA_ROOT, new ModificationItem[] { mod }); } catch (NamingException ne) { throw new OnlineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(ne.toString()), ne); } notifyConfigurationElementCreated(attribute); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml( Utilities.getProgressDone(ColorAndFontConstants.progressFont)); } }); } private void addObjectClassOnline(final ObjectClass objectClass) throws OpenDsException { SwingUtilities.invokeLater(new Runnable() { /** * {@inheritDoc} */ public void run() { printEquivalentCommandLineToAddOnline(objectClass); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_CREATING_OBJECTCLASS_PROGRESS.get( objectClass.getNameOrOID()), ColorAndFontConstants.progressFont)); } }); try { BasicAttribute attr = new BasicAttribute(getAttributeName(objectClass)); attr.add(getValueOnline(objectClass)); ModificationItem mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr); getInfo().getDirContext().modifyAttributes( ConfigConstants.DN_DEFAULT_SCHEMA_ROOT, new ModificationItem[] { mod }); } catch (NamingException ne) { throw new OnlineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(ne.toString()), ne); } notifyConfigurationElementCreated(objectClass); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml( Utilities.getProgressDone(ColorAndFontConstants.progressFont)); } }); } private String getValueOnline(CommonSchemaElements element) { return element.toString(); } private String getValueOffline(CommonSchemaElements element) { Iterable<String> previousValues = element.getExtraProperty(ServerConstants.SCHEMA_PROPERTY_FILENAME); element.setExtraProperty(ServerConstants.SCHEMA_PROPERTY_FILENAME, (String)null); String attributeWithoutFileDefinition = element.toString(); if (previousValues != null) { ArrayList<String> vs = new ArrayList<String>(); for (String s : previousValues) { vs.add(s); } if (!vs.isEmpty()) { element.setExtraProperty(ServerConstants.SCHEMA_PROPERTY_FILENAME, vs); } } return attributeWithoutFileDefinition; } private void printEquivalentCommandLineToAddOnline( CommonSchemaElements element) { ArrayList<String> args = new ArrayList<String>(); args.add("-a"); args.addAll(getObfuscatedCommandLineArguments( getConnectionCommandLineArguments(true, true))); args.add(getNoPropertiesFileArgument()); String equiv = getEquivalentCommandLine(getCommandLinePath("ldapmodify"), args); StringBuilder sb = new StringBuilder(); Message msg; if (element instanceof AttributeType) { msg = INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_ATTRIBUTE_ONLINE.get( element.getNameOrOID()); } else { msg = INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_OBJECTCLASS_ONLINE.get( element.getNameOrOID()); } sb.append(msg+"<br><b>"); sb.append(equiv); sb.append("<br>"); sb.append("dn: cn=schema<br>"); sb.append("changetype: modify<br>"); sb.append("add: "+getAttributeName(element)+"<br>"); sb.append(getAttributeName(element)+": "+getValueOnline(element)); sb.append("</b><br><br>"); getProgressDialog().appendProgressHtml(Utilities.applyFont(sb.toString(), ColorAndFontConstants.progressFont)); } private String getAttributeName(CommonSchemaElements element) { if (element instanceof AttributeType) { return ConfigConstants.ATTR_ATTRIBUTE_TYPES; } else { return ConfigConstants.ATTR_OBJECTCLASSES; } } private String getFileName(CommonSchemaElements element) { String value = null; Iterable<String> vs = element.getExtraProperty(ServerConstants.SCHEMA_PROPERTY_FILENAME); if (vs != null) { if (vs.iterator().hasNext()) { value = vs.iterator().next(); } } return value; } private void updateSchemaOffline(String file, final List<AttributeType> attributes, final List<ObjectClass> objectClasses) throws OpenDsException { final boolean userSchema; final String fileName; if (file == null) { file = ConfigConstants.FILE_USER_SCHEMA_ELEMENTS; userSchema = true; } else { userSchema = false; } File f = new File(file); if (!f.isAbsolute()) { f = new File( DirectoryServer.getEnvironmentConfig().getSchemaDirectory(userSchema), file); } fileName = f.getAbsolutePath(); final boolean isSchemaFileDefined = isSchemaFileDefined(fileName); SwingUtilities.invokeLater(new Runnable() { /** * {@inheritDoc} */ public void run() { printEquivalentCommandToAddOffline(fileName, isSchemaFileDefined, attributes, objectClasses); if (attributes.size() == 1 && objectClasses.isEmpty()) { String attributeName = attributes.get(0).getNameOrOID(); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_CREATING_ATTRIBUTE_PROGRESS.get( attributeName), ColorAndFontConstants.progressFont)); } else if (objectClasses.size() == 1 && attributes.isEmpty()) { String ocName = objectClasses.get(0).getNameOrOID(); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_CREATING_OBJECTCLASS_PROGRESS.get( ocName), ColorAndFontConstants.progressFont)); } else { getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_UPDATING_SCHEMA_FILE_PROGRESS.get( fileName), ColorAndFontConstants.progressFont)); } } }); updateSchemaFile(fileName, isSchemaFileDefined, attributes, objectClasses); for (AttributeType attr : attributes) { notifyConfigurationElementCreated(attr); } for (ObjectClass oc : objectClasses) { notifyConfigurationElementCreated(oc); } SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml( Utilities.getProgressDone(ColorAndFontConstants.progressFont)); } }); } private void printEquivalentCommandToAddOffline(String schemaFile, boolean isSchemaFileDefined, List<AttributeType> attributes, List<ObjectClass> objectClasses) { ArrayList<String> names = new ArrayList<String>(); for (AttributeType attr : attributes) { names.add(attr.getNameOrOID()); } for (ObjectClass oc : objectClasses) { names.add(oc.getNameOrOID()); } if (isSchemaFileDefined) { StringBuilder sb = new StringBuilder(); sb.append( INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_SCHEMA_ELEMENT_OFFLINE.get( Utils.getStringFromCollection(names, ", "), schemaFile)+"<br><b>"); for (AttributeType attribute : attributes) { sb.append( getAttributeName(attribute)+": "+getValueOffline(attribute)+"<br>"); } for (ObjectClass oc : objectClasses) { sb.append(getAttributeName(oc)+": "+getValueOffline(oc)+"<br>"); } sb.append("</b><br><br>"); getProgressDialog().appendProgressHtml(Utilities.applyFont(sb.toString(), ColorAndFontConstants.progressFont)); } else { StringBuilder sb = new StringBuilder(); sb.append(INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_SCHEMA_ENTRY_OFFLINE.get( Utils.getStringFromCollection(names, ", "), schemaFile)+"<br><b>"); for (String line : getSchemaEntryLines()) { sb.append(line); sb.append("<br>"); } for (AttributeType attribute : attributes) { sb.append( getAttributeName(attribute)+": "+getValueOffline(attribute)+"<br>"); } for (ObjectClass oc : objectClasses) { sb.append(getAttributeName(oc)+": "+getValueOffline(oc)+"<br>"); } sb.append("</b><br><br>"); getProgressDialog().appendProgressHtml(Utilities.applyFont(sb.toString(), ColorAndFontConstants.progressFont)); } } /** * Returns whether the file defined in the schema element exists or not. * @param the path to the schema file. * @return <CODE>true</CODE> if the schema file is defined and * <CODE>false</CODE> otherwise. */ private boolean isSchemaFileDefined(String schemaFile) { boolean schemaDefined = false; LDIFReader reader = null; try { reader = new LDIFReader(new LDIFImportConfig(schemaFile)); Entry entry = reader.readEntry(); if (entry != null) { schemaDefined = true; } } catch (Throwable t) { } finally { if (reader != null) { try { reader.close(); } catch (Throwable t) { } } } return schemaDefined; } /** * Returns the list of LDIF lines that are enough to create the entry * containing only the schema element associated with this task. * @return the list of LDIF lines that are enough to create the entry * containing only the schema element associated with this task. */ private ArrayList<String> getSchemaEntryLines() { ArrayList<String> lines = new ArrayList<String>(); lines.add("dn: cn=schema"); lines.add("objectClass: top"); lines.add("objectClass: ldapSubentry"); lines.add("objectClass: subschema"); return lines; } /** * Updates the contents of the schema file. * * @param schemaFile the schema file. * @param isSchemaFileDefined whether the schema is defined or not. * @param attributes the attributes to add. * @param objectClasses the object classes to add. * @throws OpenDsException if an error occurs updating the schema file. */ private void updateSchemaFile(String schemaFile, boolean isSchemaFileDefined, List<AttributeType> attributes, List<ObjectClass> objectClasses) throws OpenDsException { if (isSchemaFileDefined) { LDIFExportConfig exportConfig = new LDIFExportConfig(schemaFile, ExistingFileBehavior.OVERWRITE); LDIFReader reader = null; Entry schemaEntry = null; try { reader = new LDIFReader(new LDIFImportConfig(schemaFile)); schemaEntry = reader.readEntry(); for (AttributeType attribute : attributes) { Modification mod = new Modification(ModificationType.ADD, Attributes.create(getAttributeName(attribute).toLowerCase(), getValueOffline(attribute))); schemaEntry.applyModification(mod); } for (ObjectClass oc : objectClasses) { Modification mod = new Modification(ModificationType.ADD, Attributes.create(getAttributeName(oc).toLowerCase(), getValueOffline(oc))); schemaEntry.applyModification(mod); } LDIFWriter writer = new LDIFWriter(exportConfig); writer.writeEntry(schemaEntry); exportConfig.getWriter().newLine(); } catch (Throwable t) { } finally { if (reader != null) { try { reader.close(); } catch (Throwable t) { } } if (exportConfig != null) { try { exportConfig.close(); } catch (Throwable t) { } } } } else { LDIFExportConfig exportConfig = new LDIFExportConfig(schemaFile, ExistingFileBehavior.FAIL); try { ArrayList<String> lines = getSchemaEntryLines(); for (AttributeType attribute : attributes) { lines.add( getAttributeName(attribute)+": "+getValueOffline(attribute)); } for (ObjectClass oc : objectClasses) { lines.add(getAttributeName(oc)+": "+getValueOffline(oc)); } for (String line : lines) { LDIFWriter.writeLDIFLine(new StringBuilder(line), exportConfig.getWriter(), exportConfig.getWrapColumn() > 1, exportConfig.getWrapColumn()); } exportConfig.getWriter().newLine(); } catch (Throwable t) { throw new OfflineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(t.toString()), t); } finally { if (exportConfig != null) { try { exportConfig.close(); } catch (Throwable t) { } } } } } } opends/src/guitools/org/opends/guitools/controlpanel/task/SchemaTask.java
File was deleted opends/src/guitools/org/opends/guitools/controlpanel/task/Task.java
@@ -45,6 +45,9 @@ import org.opends.admin.ads.util.ConnectionUtils; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.event.ConfigurationElementCreatedEvent; import org.opends.guitools.controlpanel.event. ConfigurationElementCreatedListener; import org.opends.guitools.controlpanel.event.PrintStreamListener; import org.opends.guitools.controlpanel.ui.ColorAndFontConstants; import org.opends.guitools.controlpanel.ui.ProgressDialog; @@ -150,21 +153,17 @@ */ JAVA_SETTINGS_UPDATE, /** * Creating a new attribute in the schema. * Creating a new element in the schema. */ NEW_ATTRIBUTE, NEW_SCHEMA_ELEMENT, /** * Creating a new objectclass in the schema. * Deleting an schema element. */ NEW_OBJECTCLASS, DELETE_SCHEMA_ELEMENT, /** * Deleting an attribute in the schema. * Modify an schema element. */ DELETE_ATTRIBUTE, /** * Deleting an objectclass in the schema. */ DELETE_OBJECTCLASS, MODIFY_SCHEMA_ELEMENT, /** * Modifying an entry. */ @@ -269,6 +268,9 @@ private ProgressDialog progressDialog; private ArrayList<ConfigurationElementCreatedListener> confListeners = new ArrayList<ConfigurationElementCreatedListener>(); private static int MAX_BINARY_LENGTH_TO_DISPLAY = 1024; /** @@ -424,6 +426,40 @@ public abstract Message getTaskDescription(); /** * Adds a configuration element created listener. * @param listener the listener. */ public void addConfigurationElementCreatedListener( ConfigurationElementCreatedListener listener) { confListeners.add(listener); } /** * Removes a configuration element created listener. * @param listener the listener. */ public void removeConfigurationElementCreatedListener( ConfigurationElementCreatedListener listener) { confListeners.remove(listener); } /** * Notifies the configuration element created listener that a new object has * been created. * @param configObject the created object. */ protected void notifyConfigurationElementCreated(Object configObject) { for (ConfigurationElementCreatedListener listener : confListeners) { listener.elementCreated( new ConfigurationElementCreatedEvent(this, configObject)); } } /** * Returns a String representation of a value. In general this is called * to display the command-line equivalent when we do a modification in an * entry. But since some attributes must be obfuscated (like the user opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseSchemaPanel.java
@@ -44,6 +44,7 @@ import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.Set; import java.util.TreeSet; @@ -86,6 +87,7 @@ import org.opends.guitools.controlpanel.util.Utilities; import org.opends.guitools.controlpanel.util.ViewPositions; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.server.api.AttributeSyntax; import org.opends.server.api.MatchingRule; import org.opends.server.types.AttributeType; @@ -518,6 +520,14 @@ selectElementUnder(root, element, model); } }); entryPane.addConfigurationElementCreatedListener( new ConfigurationElementCreatedListener() { public void elementCreated(ConfigurationElementCreatedEvent ev) { configurationElementCreated(ev); } }); treePane.getTree().addTreeSelectionListener(new TreeSelectionListener() { @@ -632,32 +642,49 @@ { final ServerDescriptor desc = ev.getNewDescriptor(); final boolean forceScroll = lastSchema == null; if ((lastSchema == null) || !ServerDescriptor.areSchemasEqual(lastSchema, desc.getSchema())|| true) Schema schema = desc.getSchema(); boolean schemaChanged; if (schema != null && lastSchema != null) { lastSchema = desc.getSchema(); if (lastSchema != null) schemaChanged = !ServerDescriptor.areSchemasEqual(lastSchema, schema); } else if (schema == null && lastSchema != null) { schemaChanged = false; } else if (lastSchema == null && schema != null) { schemaChanged = true; } else { schemaChanged = false; } if (schemaChanged) { lastSchema = schema; SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() public void run() { public void run() repopulateTree(treePane.getTree(), forceScroll); if (errorPane.isVisible()) { repopulateTree(treePane.getTree(), forceScroll); errorPane.setVisible(false); } }); } else { updateErrorPane(errorPane, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_SUMMARY.get(), ColorAndFontConstants.errorTitleFont, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get(), ColorAndFontConstants.defaultFont); if (!errorPane.isVisible()) { errorPane.setVisible(true); } }); } else if (lastSchema == null) { updateErrorPane(errorPane, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_SUMMARY.get(), ColorAndFontConstants.errorTitleFont, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get(), ColorAndFontConstants.defaultFont); if (!errorPane.isVisible()) { errorPane.setVisible(true); } } } @@ -1099,8 +1126,8 @@ } else if (node instanceof CustomObjectClassTreeNode) { entryPane.updateCustomObjectClass( ((CustomObjectClassTreeNode)node).getObjectClass(), lastSchema); ObjectClass oc = ((CustomObjectClassTreeNode)node).getObjectClass(); entryPane.updateCustomObjectClass(oc, lastSchema); } else if (node instanceof StandardAttributeTreeNode) { @@ -1114,8 +1141,8 @@ } else if (node instanceof CustomAttributeTreeNode) { entryPane.updateCustomAttribute( ((CustomAttributeTreeNode)node).getAttribute(), lastSchema); AttributeType attr = ((CustomAttributeTreeNode)node).getAttribute(); entryPane.updateCustomAttribute(attr, lastSchema); } else if (node instanceof MatchingRuleTreeNode) { @@ -1248,146 +1275,20 @@ } Schema schema = getInfo().getServerDescriptor().getSchema(); ArrayList<String> ocNames = new ArrayList<String>(); ArrayList<String> attrNames = new ArrayList<String>(); if (schema != null) { // Analyze objectClasses for (ObjectClass objectClass : ocsToDelete) { ArrayList<ObjectClass> childClasses = new ArrayList<ObjectClass>(); for (ObjectClass o : schema.getObjectClasses().values()) { if (objectClass.equals(o.getSuperiorClass())) { childClasses.add(o); } } childClasses.removeAll(ocsToDelete); if (!childClasses.isEmpty()) { ArrayList<String> childNames = new ArrayList<String>(); for (ObjectClass oc : childClasses) { childNames.add(oc.getNameOrOID()); } String ocName = objectClass.getNameOrOID(); errors.add(ERR_CANNOT_DELETE_PARENT_OBJECTCLASS.get(ocName, Utilities.getStringFromCollection(childNames, ", "), ocName)); } ocNames.add(objectClass.getNameOrOID()); } // Analyze attributes for (AttributeType attribute : attrsToDelete) { String attrName = attribute.getNameOrOID(); ArrayList<AttributeType> childAttributes = new ArrayList<AttributeType>(); for (AttributeType attr : schema.getAttributeTypes().values()) { if (attribute.equals(attr.getSuperiorType())) { childAttributes.add(attr); } } childAttributes.removeAll(attrsToDelete); if (!childAttributes.isEmpty()) { ArrayList<String> childNames = new ArrayList<String>(); for (AttributeType attr : childAttributes) { childNames.add(attr.getNameOrOID()); } errors.add(ERR_CANNOT_DELETE_PARENT_ATTRIBUTE.get(attrName, Utilities.getStringFromCollection(childNames, ", "), attrName)); } ArrayList<String> dependentClasses = new ArrayList<String>(); for (ObjectClass o : schema.getObjectClasses().values()) { if (o.getRequiredAttributeChain().contains(attribute)) { dependentClasses.add(o.getNameOrOID()); } } dependentClasses.removeAll(ocsToDelete); if (!dependentClasses.isEmpty()) { errors.add(ERR_CANNOT_DELETE_ATTRIBUTE_WITH_DEPENDENCIES.get( attrName, Utilities.getStringFromCollection(dependentClasses, ", "), attrName)); } attrNames.add(attribute.getNameOrOID()); } } else if (schema == null) { errors.add(ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get()); } if (errors.isEmpty()) { // Reorder objectClasses and attributes to delete them in the proper // order. ArrayList<ObjectClass> orderedObjectClasses = new ArrayList<ObjectClass>(); for (ObjectClass oc : ocsToDelete) { int index = -1; for (int i=0; i<orderedObjectClasses.size(); i++) { ObjectClass parent = orderedObjectClasses.get(i).getSuperiorClass(); while ((parent != null) && (index == -1)) { if (parent.equals(oc)) { index = i+1; } else { parent = parent.getSuperiorClass(); } } } if (index == -1) { orderedObjectClasses.add(oc); } else { orderedObjectClasses.add(index, oc); } } Message confirmationMessage = getConfirmationMessage(ocsToDelete, attrsToDelete, schema); ArrayList<AttributeType> orderedAttributes = new ArrayList<AttributeType>(); for (AttributeType attr : attrsToDelete) { int index = -1; for (int i=0; i<orderedAttributes.size(); i++) { AttributeType parent = orderedAttributes.get(i).getSuperiorType(); while ((parent != null) && (index == -1)) { if (parent.equals(attr)) { index = i+1; } else { parent = parent.getSuperiorType(); } } } if (index == -1) { orderedAttributes.add(attr); } else { orderedAttributes.add(index, attr); } } LinkedHashSet<AttributeType> orderedAttributes = getOrderedAttributesToDelete(attrsToDelete); LinkedHashSet<ObjectClass> orderedObjectClasses = getOrderedObjectClassesToDelete(ocsToDelete); Message title; if (orderedAttributes.isEmpty()) { @@ -1414,11 +1315,6 @@ if (errors.isEmpty()) { ArrayList<String> allNames = new ArrayList<String>(); allNames.addAll(ocNames); allNames.addAll(attrNames); Message confirmationMessage = INFO_CTRL_PANEL_CONFIRMATION_DELETE_SCHEMA_ELEMENTS_DETAILS.get( Utilities.getStringFromCollection(allNames, ", ")); if (displayConfirmationDialog( INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), confirmationMessage)) @@ -1474,7 +1370,7 @@ * do the filtering based on the name. * @param oc the object class. * @param ocName the name provided by the user. * @return <CODE>true</CODE> if the objectclass must be added and * @return <CODE>true</CODE> if the object class must be added and * <CODE>false</CODE> otherwise. */ private boolean mustAddObjectClassName(ObjectClass oc, String ocName) @@ -1749,11 +1645,7 @@ { public void elementCreated(ConfigurationElementCreatedEvent ev) { Object o = ev.getConfigurationObject(); if (o instanceof CommonSchemaElements) { lastCreatedElement = (CommonSchemaElements)o; } configurationElementCreated(ev); } }); } @@ -1775,17 +1667,22 @@ { public void elementCreated(ConfigurationElementCreatedEvent ev) { Object o = ev.getConfigurationObject(); if (o instanceof CommonSchemaElements) { lastCreatedElement = (CommonSchemaElements)o; } configurationElementCreated(ev); } }); } newObjectClassDialog.setVisible(true); } private void configurationElementCreated(ConfigurationElementCreatedEvent ev) { Object o = ev.getConfigurationObject(); if (o instanceof CommonSchemaElements) { lastCreatedElement = (CommonSchemaElements)o; } } private HashMap<Object, ImageIcon> hmCategoryImages = new HashMap<Object, ImageIcon>(); private HashMap<Class<?>, ImageIcon> hmImages = @@ -1850,4 +1747,198 @@ return icon; } } private LinkedHashSet<ObjectClass> getOrderedObjectClassesToDelete( Collection<ObjectClass> ocsToDelete) { ArrayList<ObjectClass> lOrderedOcs = new ArrayList<ObjectClass>(); // Reorder objectClasses and attributes to delete them in the proper // order. for (ObjectClass oc : ocsToDelete) { int index = -1; for (int i=0; i<lOrderedOcs.size(); i++) { ObjectClass parent = lOrderedOcs.get(i).getSuperiorClass(); while ((parent != null) && (index == -1)) { if (parent.equals(oc)) { index = i+1; } else { parent = parent.getSuperiorClass(); } } } if (index == -1) { lOrderedOcs.add(oc); } else { lOrderedOcs.add(index, oc); } } return new LinkedHashSet<ObjectClass>(lOrderedOcs); } private LinkedHashSet<AttributeType> getOrderedAttributesToDelete( Collection<AttributeType> attrsToDelete) { ArrayList<AttributeType> lOrderedAttributes = new ArrayList<AttributeType>(); for (AttributeType attr : attrsToDelete) { int index = -1; for (int i=0; i<lOrderedAttributes.size(); i++) { AttributeType parent = lOrderedAttributes.get(i).getSuperiorType(); while ((parent != null) && (index == -1)) { if (parent.equals(attr)) { index = i+1; } else { parent = parent.getSuperiorType(); } } } if (index == -1) { lOrderedAttributes.add(attr); } else { lOrderedAttributes.add(index, attr); } } return new LinkedHashSet<AttributeType>(lOrderedAttributes); } private Message getConfirmationMessage( Collection<ObjectClass> ocsToDelete, Collection<AttributeType> attrsToDelete, Schema schema) { ArrayList<ObjectClass> childClasses = new ArrayList<ObjectClass>(); // Analyze objectClasses for (ObjectClass objectClass : ocsToDelete) { for (ObjectClass o : schema.getObjectClasses().values()) { if (objectClass.equals(o.getSuperiorClass())) { childClasses.add(o); } } childClasses.removeAll(ocsToDelete); } ArrayList<AttributeType> childAttributes = new ArrayList<AttributeType>(); TreeSet<String> dependentClasses = new TreeSet<String>(); // Analyze attributes for (AttributeType attribute : attrsToDelete) { for (AttributeType attr : schema.getAttributeTypes().values()) { if (attribute.equals(attr.getSuperiorType())) { childAttributes.add(attr); } } childAttributes.removeAll(attrsToDelete); for (ObjectClass o : schema.getObjectClasses().values()) { if (o.getRequiredAttributeChain().contains(attribute)) { dependentClasses.add(o.getNameOrOID()); } else if (o.getOptionalAttributeChain().contains(attribute)) { dependentClasses.add(o.getNameOrOID()); } } for (ObjectClass oc : ocsToDelete) { dependentClasses.remove(oc.getNameOrOID()); } } MessageBuilder mb = new MessageBuilder(); if (!childClasses.isEmpty()) { TreeSet<String> childNames = new TreeSet<String>(); for (ObjectClass oc : childClasses) { childNames.add(oc.getNameOrOID()); } if (ocsToDelete.size() == 1) { mb.append(INFO_OBJECTCLASS_IS_SUPERIOR.get( ocsToDelete.iterator().next().getNameOrOID(), Utilities.getStringFromCollection(childNames, ", "))); } else { mb.append(INFO_OBJECTCLASSES_ARE_SUPERIOR.get( Utilities.getStringFromCollection(childNames, ", "))); } mb.append("<br>"); } if (!childAttributes.isEmpty()) { TreeSet<String> childNames = new TreeSet<String>(); for (AttributeType attr : childAttributes) { childNames.add(attr.getNameOrOID()); } if (attrsToDelete.size() == 1) { mb.append(INFO_ATTRIBUTE_IS_SUPERIOR.get( attrsToDelete.iterator().next().getNameOrOID(), Utilities.getStringFromCollection(childNames, ", "))); } else { mb.append(INFO_ATTRIBUTES_ARE_SUPERIOR.get( Utilities.getStringFromCollection(childNames, ", "))); } mb.append("<br>"); } if (!dependentClasses.isEmpty()) { if (attrsToDelete.size() == 1) { mb.append(INFO_ATTRIBUTE_WITH_DEPENDENCIES.get( attrsToDelete.iterator().next().getNameOrOID(), Utilities.getStringFromCollection(dependentClasses, ", "))); } else { mb.append(INFO_ATTRIBUTES_WITH_DEPENDENCIES.get( Utilities.getStringFromCollection(dependentClasses, ", "))); } mb.append("<br>"); } ArrayList<String> allNames = new ArrayList<String>(); for (ObjectClass ocToDelete : ocsToDelete) { allNames.add(ocToDelete.getNameOrOID()); } for (AttributeType attrToDelete : attrsToDelete) { allNames.add(attrToDelete.getNameOrOID()); } Message confirmationMessage = INFO_CTRL_PANEL_CONFIRMATION_DELETE_SCHEMA_ELEMENTS_MSG.get( Utilities.getStringFromCollection(allNames, ", ")); mb.append(confirmationMessage); return mb.toMessage(); } } opends/src/guitools/org/opends/guitools/controlpanel/ui/CustomAttributePanel.java
@@ -29,41 +29,168 @@ import static org.opends.messages.AdminToolMessages.*; import java.awt.Component; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.event. ConfigurationElementCreatedListener; import org.opends.guitools.controlpanel.event.ScrollPaneBorderListener; import org.opends.guitools.controlpanel.task.DeleteSchemaElementsTask; import org.opends.guitools.controlpanel.task.ModifyAttributeTask; import org.opends.guitools.controlpanel.task.Task; import org.opends.guitools.controlpanel.ui.components.BasicExpander; import org.opends.guitools.controlpanel.ui.components.TitlePanel; 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.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.server.api.ApproximateMatchingRule; import org.opends.server.api.AttributeSyntax; import org.opends.server.api.EqualityMatchingRule; import org.opends.server.api.MatchingRule; import org.opends.server.api.OrderingMatchingRule; import org.opends.server.api.SubstringMatchingRule; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeUsage; import org.opends.server.types.ObjectClass; import org.opends.server.types.Schema; import org.opends.server.util.ServerConstants; import org.opends.server.util.StaticUtils; /** * The panel that displays a custom attribute definition. * */ public class CustomAttributePanel extends StandardAttributePanel public class CustomAttributePanel extends SchemaElementPanel { private static final long serialVersionUID = 2850763193735843746L; private JButton delete; private JButton saveChanges; private AttributeType attribute; private String attrName; private ScrollPaneBorderListener scrollListener; private TitlePanel titlePanel = new TitlePanel(Message.EMPTY, Message.EMPTY); private JLabel lName = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_NAME_LABEL.get()); private JLabel lSuperior = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_PARENT_LABEL.get()); private JLabel lOID = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_OID_LABEL.get()); private JLabel lAliases = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_ALIASES_LABEL.get()); private JLabel lOrigin = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_ORIGIN_LABEL.get()); private JLabel lFile = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_FILE_LABEL.get()); private JLabel lDescription = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_DESCRIPTION_LABEL.get()); private JLabel lUsage = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_USAGE_LABEL.get()); private JLabel lSyntax = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_SYNTAX_LABEL.get()); private JLabel lApproximate = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_APPROXIMATE_MATCHING_RULE_LABEL.get()); private JLabel lEquality = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_EQUALITY_MATCHING_RULE_LABEL.get()); private JLabel lOrdering = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_ORDERING_MATCHING_RULE_LABEL.get()); private JLabel lSubstring = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_ATTRIBUTE_SUBSTRING_MATCHING_RULE_LABEL.get()); private JLabel lType = Utilities.createPrimaryLabel(); private JLabel[] labels = {lName, lSuperior, lOID, lAliases, lOrigin, lFile, lDescription, lUsage, lSyntax, lApproximate, lEquality, lOrdering, lSubstring, lType }; private JTextField name = Utilities.createMediumTextField(); private JComboBox parent = Utilities.createComboBox(); private JTextField oid = Utilities.createMediumTextField(); private JTextField aliases = Utilities.createLongTextField(); private JTextField description = Utilities.createLongTextField(); private JTextField origin = Utilities.createLongTextField(); private JTextField file = Utilities.createLongTextField(); private JComboBox usage = Utilities.createComboBox(); private JComboBox syntax = Utilities.createComboBox(); private JComboBox approximate = Utilities.createComboBox(); private JComboBox equality = Utilities.createComboBox(); private JComboBox ordering = Utilities.createComboBox(); private JComboBox substring = Utilities.createComboBox(); private JCheckBox nonModifiable = Utilities.createCheckBox( INFO_CTRL_PANEL_ATTRIBUTE_NON_MODIFIABLE_LABEL.get()); private JCheckBox singleValued = Utilities.createCheckBox( INFO_CTRL_PANEL_ATTRIBUTE_SINGLE_VALUED_LABEL.get()); private JCheckBox collective = Utilities.createCheckBox( INFO_CTRL_PANEL_ATTRIBUTE_COLLECTIVE_LABEL.get()); private JCheckBox obsolete = Utilities.createCheckBox( INFO_CTRL_PANEL_ATTRIBUTE_OBSOLETE_LABEL.get()); private JList requiredBy = new JList(new DefaultListModel()); private JList optionalBy = new JList(new DefaultListModel()); private Set<String> lastAliases = new LinkedHashSet<String>(); private Message NO_PARENT = INFO_CTRL_PANEL_NO_PARENT_FOR_ATTRIBUTE.get(); private Message NO_MATCHING_RULE = INFO_CTRL_PANEL_NO_MATCHING_RULE_FOR_ATTRIBUTE.get(); private Schema schema; private boolean ignoreChangeEvents; /** * Default constructor of the panel. * */ public CustomAttributePanel() { super(); createLayout(); } /** * {@inheritDoc} */ @@ -81,10 +208,11 @@ JPanel p = new JPanel(new GridBagLayout()); p.setOpaque(false); p.setBorder(PANEL_BORDER); super.createBasicLayout(p, gbc); createBasicLayout(p, gbc); gbc = new GridBagConstraints(); gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.BOTH; gbc.gridx = 0; gbc.gridy = 0; @@ -98,6 +226,7 @@ gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(10, 10, 10, 10); gbc.gridwidth = 1; delete = Utilities.createButton( INFO_CTRL_PANEL_DELETE_ATTRIBUTE_BUTTON.get()); delete.setOpaque(false); @@ -112,6 +241,325 @@ deleteAttribute(); } }); gbc.anchor = GridBagConstraints.EAST; gbc.gridx ++; saveChanges = Utilities.createButton(INFO_CTRL_PANEL_SAVE_CHANGES_LABEL.get()); saveChanges.setOpaque(false); add(saveChanges, gbc); saveChanges.addActionListener(new ActionListener() { /** * {@inheritDoc} */ public void actionPerformed(ActionEvent ev) { ArrayList<Message> errors = new ArrayList<Message>(); saveChanges(false, errors); } }); } /** * Creates the basic layout of the panel. * @param c the container where all the components will be layed out. * @param gbc the grid bag constraints. */ protected void createBasicLayout(Container c, GridBagConstraints gbc) { requiredBy.setVisibleRowCount(5); optionalBy.setVisibleRowCount(9); gbc.gridy = 0; gbc.gridwidth = 2; addErrorPane(c, gbc); gbc.gridy ++; gbc.anchor = GridBagConstraints.WEST; titlePanel.setTitle(INFO_CTRL_PANEL_ATTRIBUTE_DETAILS.get()); gbc.fill = GridBagConstraints.NONE; gbc.insets.top = 5; gbc.insets.bottom = 7; c.add(titlePanel, gbc); gbc.insets.bottom = 0; gbc.insets.top = 8; gbc.gridy ++; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; JComboBox[] comboBoxes = {parent, syntax, approximate, equality, ordering, substring}; Message[] defaultValues = {NO_PARENT, Message.EMPTY, NO_MATCHING_RULE, NO_MATCHING_RULE, NO_MATCHING_RULE, NO_MATCHING_RULE }; SchemaElementComboBoxCellRenderer renderer = new SchemaElementComboBoxCellRenderer(syntax); for (int i=0; i<comboBoxes.length; i++) { DefaultComboBoxModel model = new DefaultComboBoxModel( new Object[]{defaultValues[i]}); comboBoxes[i].setModel(model); comboBoxes[i].setRenderer(renderer); } DefaultComboBoxModel model = new DefaultComboBoxModel(); for (AttributeUsage us : AttributeUsage.values()) { model.addElement(us); } usage.setModel(model); usage.setSelectedItem(AttributeUsage.USER_APPLICATIONS); usage.setRenderer(renderer); Component[] basicComps = {name, oid, description, syntax}; JLabel[] basicLabels = {lName, lOID, lDescription, lSyntax}; JLabel[] basicInlineHelp = new JLabel[] {null, null, null, Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_SYNTAX_INLINE_HELP.get())}; add(basicLabels, basicComps, basicInlineHelp, c, gbc); BasicExpander[] expanders = new BasicExpander[] { new BasicExpander(INFO_CTRL_PANEL_EXTRA_OPTIONS_EXPANDER.get()), new BasicExpander( INFO_CTRL_PANEL_ATTRIBUTE_TYPE_OPTIONS_EXPANDER.get()), new BasicExpander(INFO_CTRL_PANEL_MATCHING_RULE_OPTIONS_EXPANDER.get()) }; Component[][] comps = {{parent, aliases, origin, file}, {usage, singleValued, nonModifiable, collective, obsolete}, {approximate, equality, ordering, substring}}; JLabel[][] labels = {{lSuperior, lAliases, lOrigin, lFile}, {lUsage, lType, null, null, null}, {lApproximate, lEquality, lOrdering, lSubstring}}; JLabel[][] inlineHelps = {{null, Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_SEPARATED_WITH_COMMAS_HELP.get()), null, Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_SCHEMA_FILE_ATTRIBUTE_HELP.get(File.separator))}, {null, null, null, null, null, null}, {Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_MATCHING_RULE_APPROXIMATE_HELP.get()), Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_MATCHING_RULE_EQUALITY_HELP.get()), Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_MATCHING_RULE_ORDERING_HELP.get()), Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_MATCHING_RULE_SUBSTRING_HELP.get()) } }; for (int i=0; i<expanders.length; i++) { gbc.gridwidth = 2; gbc.gridx = 0; gbc.insets.left = 0; c.add(expanders[i], gbc); final JPanel p = new JPanel(new GridBagLayout()); gbc.insets.left = 15; gbc.gridy ++; c.add(p, gbc); gbc.gridy ++; p.setOpaque(false); GridBagConstraints gbc1 = new GridBagConstraints(); gbc1.fill = GridBagConstraints.HORIZONTAL; gbc1.gridy = 0; add(labels[i], comps[i], inlineHelps[i], p, gbc1); final BasicExpander expander = expanders[i]; ChangeListener changeListener = new ChangeListener() { /** * {@inheritDoc} */ public void stateChanged(ChangeEvent e) { p.setVisible(expander.isSelected()); } }; expander.addChangeListener(changeListener); expander.setSelected(false); changeListener.stateChanged(null); } ItemListener itemListener = new ItemListener() { /** * {@inheritDoc} */ public void itemStateChanged(ItemEvent ev) { if (ev.getStateChange() == ItemEvent.SELECTED) { updateDefaultMatchingRuleNames(); approximate.setSelectedIndex(0); substring.setSelectedIndex(0); equality.setSelectedIndex(0); ordering.setSelectedIndex(0); } } }; syntax.addItemListener(itemListener); Message[] msgs = new Message[] { INFO_CTRL_PANEL_REQUIRED_BY_LABEL.get(), INFO_CTRL_PANEL_ALLOWED_BY_LABEL.get() }; JList[] lists = {requiredBy, optionalBy}; gbc.anchor = GridBagConstraints.NORTHWEST; for (int i=0; i<msgs.length; i++) { gbc.insets.left = 0; gbc.weightx = 0.0; gbc.gridx = 0; if (i == 0) { gbc.insets.top = 15; } else { gbc.insets.top = 10; } c.add(Utilities.createPrimaryLabel(msgs[i]), gbc); gbc.insets.left = 10; gbc.gridx = 1; if (i == 0) { gbc.weighty = 0.35; } else { gbc.weighty = 0.65; } gbc.weightx = 1.0; c.add(Utilities.createScrollPane(lists[i]), gbc); gbc.gridy ++; final JList list = lists[i]; MouseAdapter clickListener = new MouseAdapter() { /** * {@inheritDoc} */ public void mouseClicked(MouseEvent ev) { if (ev.getClickCount() == 1) { objectClassSelected(list); } } }; list.addMouseListener(clickListener); KeyAdapter keyListener = new KeyAdapter() { /** * {@inheritDoc} */ public void keyTyped(KeyEvent ev) { if ((ev.getKeyChar() == KeyEvent.VK_SPACE) || (ev.getKeyChar() == KeyEvent.VK_ENTER)) { objectClassSelected(list); } } }; list.addKeyListener(keyListener); } DocumentListener docListener = new DocumentListener() { /** * {@inheritDoc} */ public void insertUpdate(DocumentEvent ev) { checkEnableSaveChanges(); } /** * {@inheritDoc} */ public void removeUpdate(DocumentEvent ev) { checkEnableSaveChanges(); } /** * {@inheritDoc} */ public void changedUpdate(DocumentEvent arg0) { checkEnableSaveChanges(); } }; JTextField[] tfs = {name, description, oid, aliases, origin, file}; for (JTextField tf : tfs) { tf.getDocument().addDocumentListener(docListener); } ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent ev) { checkEnableSaveChanges(); } }; JComboBox[] combos = {parent, usage, syntax, approximate, equality, ordering, substring}; for (JComboBox combo : combos) { combo.addActionListener(actionListener); } JCheckBox[] checkBoxes = {nonModifiable, singleValued, collective, obsolete}; for (JCheckBox cb : checkBoxes) { cb.addActionListener(actionListener); } } /** * {@inheritDoc} */ public boolean mustCheckUnsavedChanges() { return saveChanges.isEnabled(); } /** * {@inheritDoc} */ public UnsavedChangesDialog.Result checkUnsavedChanges() { UnsavedChangesDialog.Result result; UnsavedChangesDialog unsavedChangesDlg = new UnsavedChangesDialog( Utilities.getParentDialog(this), getInfo()); unsavedChangesDlg.setMessage(INFO_CTRL_PANEL_UNSAVED_CHANGES_SUMMARY.get(), INFO_CTRL_PANEL_UNSAVED_ATTRIBUTE_CHANGES_DETAILS.get( attribute.getNameOrOID())); Utilities.centerGoldenMean(unsavedChangesDlg, Utilities.getParentDialog(this)); unsavedChangesDlg.setVisible(true); result = unsavedChangesDlg.getResult(); if (result == UnsavedChangesDialog.Result.SAVE) { ArrayList<Message> errors = new ArrayList<Message>(); saveChanges(true, errors); if (!errors.isEmpty()) { result = UnsavedChangesDialog.Result.CANCEL; } } return result; } /** @@ -127,11 +575,119 @@ */ public void update(AttributeType attr, Schema schema) { super.update(attr, schema); ignoreChangeEvents = true; String n = attr.getPrimaryName(); if (n == null) { n = ""; } titlePanel.setDetails(Message.raw(n)); name.setText(n); oid.setText(attr.getOID()); n = attr.getDescription(); if (n == null) { n = ""; } description.setText(n); syntax.setSelectedItem(attr.getSyntax()); AttributeType superior = attr.getSuperiorType(); if (superior == null) { parent.setSelectedItem(NO_PARENT); } else { parent.setSelectedItem(superior); } Set<String> aliases = getAliases(attr); lastAliases.clear(); lastAliases.addAll(aliases); this.aliases.setText(Utilities.getStringFromCollection(aliases, ", ")); String sOrigin = Utilities.getOrigin(attr); if (sOrigin == null) { sOrigin = ""; } origin.setText(sOrigin); String sFile = attr.getSchemaFile(); if (sFile == null) { sFile = ""; } file.setText(sFile); usage.setSelectedItem(attr.getUsage()); singleValued.setSelected(attr.isSingleValue()); nonModifiable.setSelected(attr.isNoUserModification()); collective.setSelected(attr.isCollective()); obsolete.setSelected(attr.isObsolete()); JComboBox[] matchingRules = {approximate, equality, ordering, substring}; MatchingRule[] rules = {attr.getApproximateMatchingRule(), attr.getEqualityMatchingRule(), attr.getOrderingMatchingRule(), attr.getSubstringMatchingRule() }; for (int i=0; i<matchingRules.length; i++) { if (rules[i] != null) { matchingRules[i].setSelectedItem(rules[i]); } else { matchingRules[i].setSelectedItem(NO_MATCHING_RULE); } } Comparator<String> lowerCaseComparator = new LowerCaseComparator(); SortedSet<String> requiredByOcs = new TreeSet<String>(lowerCaseComparator); for (ObjectClass oc : schema.getObjectClasses().values()) { if (oc.getRequiredAttributeChain().contains(attr)) { requiredByOcs.add(oc.getNameOrOID()); } } DefaultListModel model = (DefaultListModel)requiredBy.getModel(); model.clear(); for (String oc : requiredByOcs) { model.addElement(oc); } SortedSet<String> optionalByOcs = new TreeSet<String>(lowerCaseComparator); for (ObjectClass oc : schema.getObjectClasses().values()) { if (oc.getOptionalAttributeChain().contains(attr)) { optionalByOcs.add(oc.getNameOrOID()); } } model = (DefaultListModel)optionalBy.getModel(); model.clear(); for (String oc : optionalByOcs) { model.addElement(oc); } attribute = attr; attrName = attribute.getNameOrOID(); attrName = attr.getNameOrOID(); scrollListener.updateBorder(); for (JLabel label : labels) { setPrimaryValid(label); } saveChanges.setEnabled(false); ignoreChangeEvents = false; } /** @@ -139,11 +695,146 @@ */ public void configurationChanged(ConfigurationChangeEvent ev) { ArrayList<AttributeSyntax<?>> newSyntaxes = new ArrayList<AttributeSyntax<?>>(); final ServerDescriptor desc = ev.getNewDescriptor(); Schema s = desc.getSchema(); boolean schemaChanged; if (schema != null && s != null) { schemaChanged = !ServerDescriptor.areSchemasEqual(s, schema); } else if (schema == null && s != null) { schemaChanged = true; } else if (s == null && schema != null) { schemaChanged = false; } else { schemaChanged = false; } if (schemaChanged) { schema = s; HashMap<String, AttributeSyntax<?>> syntaxNameMap = new HashMap<String, AttributeSyntax<?>>(); for (String key : schema.getSyntaxes().keySet()) { AttributeSyntax<?> syntax = schema.getSyntax(key); String name = syntax.getSyntaxName(); if (name == null) { name = syntax.getOID(); } syntaxNameMap.put(name, syntax); } SortedSet<String> orderedKeys = new TreeSet<String>(syntaxNameMap.keySet()); for (String key : orderedKeys) { newSyntaxes.add(syntaxNameMap.get(key)); } updateComboBoxModel(newSyntaxes, ((DefaultComboBoxModel)syntax.getModel())); HashMap<String, AttributeType> attributeNameMap = new HashMap<String, AttributeType>(); for (String key : schema.getAttributeTypes().keySet()) { AttributeType attr = schema.getAttributeType(key); attributeNameMap.put(attr.getNameOrOID(), attr); } orderedKeys.clear(); orderedKeys.addAll(attributeNameMap.keySet()); ArrayList<Object> newParents = new ArrayList<Object>(); for (String key : orderedKeys) { newParents.add(attributeNameMap.get(key)); } newParents.add(0, NO_PARENT); updateComboBoxModel(newParents, ((DefaultComboBoxModel)parent.getModel())); ArrayList<MatchingRule> approximateElements = new ArrayList<MatchingRule>(); ArrayList<MatchingRule> equalityElements = new ArrayList<MatchingRule>(); ArrayList<MatchingRule> orderingElements = new ArrayList<MatchingRule>(); ArrayList<MatchingRule> substringElements = new ArrayList<MatchingRule>(); HashMap<String, MatchingRule> matchingRuleNameMap = new HashMap<String, MatchingRule>(); for (String key : schema.getMatchingRules().keySet()) { MatchingRule rule = schema.getMatchingRule(key); matchingRuleNameMap.put(rule.getNameOrOID(), rule); } orderedKeys.clear(); orderedKeys.addAll(matchingRuleNameMap.keySet()); for (String key : orderedKeys) { MatchingRule matchingRule = matchingRuleNameMap.get(key); if (matchingRule instanceof ApproximateMatchingRule) { approximateElements.add(matchingRule); } else if (matchingRule instanceof EqualityMatchingRule) { equalityElements.add(matchingRule); } else if (matchingRule instanceof OrderingMatchingRule) { orderingElements.add(matchingRule); } else if (matchingRule instanceof SubstringMatchingRule) { substringElements.add(matchingRule); } } JComboBox[] combos = {approximate, equality, ordering, substring}; ArrayList<ArrayList<MatchingRule>> ruleNames = new ArrayList<ArrayList<MatchingRule>>(); ruleNames.add(approximateElements); ruleNames.add(equalityElements); ruleNames.add(orderingElements); ruleNames.add(substringElements); for (int i=0; i<combos.length; i++) { DefaultComboBoxModel model = (DefaultComboBoxModel)combos[i].getModel(); ArrayList<Object> el = new ArrayList<Object>(); el.addAll(ruleNames.get(i)); if (model.getSize() == 0) { el.add(0, NO_MATCHING_RULE); } else { el.add(0, model.getElementAt(0)); } updateComboBoxModel(el, model); } } else if (schema == null) { updateErrorPane(errorPane, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_SUMMARY.get(), ColorAndFontConstants.errorTitleFont, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get(), ColorAndFontConstants.defaultFont); } if (schema != null) { updateErrorPaneIfAuthRequired(desc, isLocal() ? INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_ATTRIBUTE_DELETE.get() : INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_ATTRIBUTE_DELETE.get() : INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname())); } SwingUtilities.invokeLater(new Runnable() { /** @@ -151,32 +842,55 @@ */ public void run() { delete.setEnabled(!authenticationRequired(desc)); delete.setEnabled(!authenticationRequired(desc) && delete.isEnabled() && schema != null); checkEnableSaveChanges(); saveChanges.setEnabled(saveChanges.isEnabled() && !authenticationRequired(desc) && schema != null); } }); } /** * {@inheritDoc} */ public Component getPreferredFocusComponent() { return name; } /** * {@inheritDoc} */ public void okClicked() { } private void deleteAttribute() { ArrayList<Message> errors = new ArrayList<Message>(); Schema schema = getInfo().getServerDescriptor().getSchema(); ProgressDialog dlg = new ProgressDialog( Utilities.createFrame(), Utilities.getParentDialog(this), INFO_CTRL_PANEL_DELETE_ATTRIBUTE_TITLE.get(), getInfo()); ArrayList<ObjectClass> ocsToDelete = new ArrayList<ObjectClass>(); ArrayList<AttributeType> attrsToDelete = new ArrayList<AttributeType>(); LinkedHashSet<AttributeType> attrsToDelete = new LinkedHashSet<AttributeType>(1); attrsToDelete.add(attribute); DeleteSchemaElementsTask newTask = new DeleteSchemaElementsTask(getInfo(), dlg, ocsToDelete, attrsToDelete); Task newTask = new DeleteSchemaElementsTask(getInfo(), dlg, new LinkedHashSet<ObjectClass>(0), attrsToDelete); for (Task task : getInfo().getTasks()) { task.canLaunch(newTask, errors); } Schema schema = getInfo().getServerDescriptor().getSchema(); TreeSet<String> childAttributes = new TreeSet<String>(); TreeSet<String> dependentClasses = new TreeSet<String>(); if (schema != null) { ArrayList<String> childAttributes = new ArrayList<String>(); for (AttributeType attr : schema.getAttributeTypes().values()) { if (attribute.equals(attr.getSuperiorType())) @@ -184,37 +898,48 @@ childAttributes.add(attr.getNameOrOID()); } } if (!childAttributes.isEmpty()) { errors.add(ERR_CANNOT_DELETE_PARENT_ATTRIBUTE.get(attrName, Utilities.getStringFromCollection(childAttributes, ", "), attrName)); } ArrayList<String> dependentClasses = new ArrayList<String>(); for (ObjectClass o : schema.getObjectClasses().values()) { if (o.getRequiredAttributeChain().contains(attribute)) { dependentClasses.add(o.getNameOrOID()); } else if (o.getOptionalAttributeChain().contains(attribute)) { dependentClasses.add(o.getNameOrOID()); } } if (!dependentClasses.isEmpty()) { errors.add(ERR_CANNOT_DELETE_ATTRIBUTE_WITH_DEPENDENCIES.get( attrName, Utilities.getStringFromCollection(dependentClasses, ", "), attrName)); } } else { errors.add(ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get()); } if (errors.size() == 0) { MessageBuilder mb = new MessageBuilder(); if (!childAttributes.isEmpty()) { mb.append(INFO_ATTRIBUTE_IS_SUPERIOR.get(attrName, Utilities.getStringFromCollection(childAttributes, ", "))); mb.append("<br>"); } if (!dependentClasses.isEmpty()) { mb.append(INFO_ATTRIBUTE_WITH_DEPENDENCIES.get( attrName, Utilities.getStringFromCollection(dependentClasses, ", "))); mb.append("<br>"); } Message confirmationMessage = INFO_CTRL_PANEL_CONFIRMATION_DELETE_ATTRIBUTE_DETAILS.get( attribute.getNameOrOID()); mb.append(confirmationMessage); if (displayConfirmationDialog( INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), confirmationMessage)) mb.toMessage())) { launchOperation(newTask, INFO_CTRL_PANEL_DELETING_ATTRIBUTE_SUMMARY.get(attrName), @@ -232,4 +957,376 @@ displayErrorDialog(errors); } } private void saveChanges(boolean modal, ArrayList<Message> errors) { // Check if the aliases or the name have changed for (JLabel label : labels) { setPrimaryValid(label); } String n = getAttributeName(); MessageBuilder err = new MessageBuilder(); if (n.length() == 0) { errors.add(ERR_CTRL_PANEL_ATTRIBUTE_NAME_REQUIRED.get()); setPrimaryInvalid(lName); } else if (!n.equalsIgnoreCase(attribute.getNameOrOID())) { if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err)) { errors.add(ERR_CTRL_PANEL_INVALID_ATTRIBUTE_NAME.get(err.toString())); setPrimaryInvalid(lName); err = new MessageBuilder(); } else { Message elementType = NewAttributePanel.getSchemaElementType(n, schema); if (elementType != null) { errors.add(ERR_CTRL_PANEL_ATTRIBUTE_NAME_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lName); } } } n = oid.getText().trim(); if (n.length() > 0 && !n.equalsIgnoreCase(attribute.getOID())) { if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err)) { errors.add(ERR_CTRL_PANEL_OID_NOT_VALID.get(err.toString())); setPrimaryInvalid(lOID); err = new MessageBuilder(); } else { Message elementType = NewAttributePanel.getSchemaElementType(n, schema); if (elementType != null) { errors.add(ERR_CTRL_PANEL_OID_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lOID); } } } Collection<String> aliases = getAliases(); Collection<String> oldAliases = getAliases(attribute); if (!aliases.equals(oldAliases)) { for (String alias : aliases) { if (alias.trim().length() == 0) { errors.add(ERR_CTRL_PANEL_EMPTY_ALIAS.get()); setPrimaryInvalid(lAliases); } else { boolean notPreviouslyDefined = true; for (String oldAlias : oldAliases) { if (oldAlias.equalsIgnoreCase(alias)) { notPreviouslyDefined = false; break; } } if (notPreviouslyDefined) { Message elementType = NewAttributePanel.getSchemaElementType(alias, schema); if (elementType != null) { errors.add(ERR_CTRL_PANEL_ALIAS_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lAliases); } } } } } AttributeType superior = getSuperior(); if (superior != null) { if (superior.getNameOrOID().equalsIgnoreCase(attribute.getNameOrOID())) { errors.add(ERR_CTRL_PANEL_ATTRIBUTE_CANNOT_BE_ITS_SUPERIOR.get()); setPrimaryInvalid(lSuperior); } else { // Check whether this object class is defined as parent as the superior. superior = superior.getSuperiorType(); while (superior != null) { if (superior.getNameOrOID().equalsIgnoreCase( attribute.getNameOrOID())) { errors.add( ERR_CTRL_PANEL_ATTRIBUTE_IS_SUPERIOR_OF_SUPERIOR.get( getSuperior().getNameOrOID())); setPrimaryInvalid(lSuperior); break; } superior = superior.getSuperiorType(); } } } setPrimaryValid(lUsage); if (nonModifiable.isSelected()) { if (AttributeUsage.USER_APPLICATIONS.equals(usage.getSelectedItem())) { errors.add(ERR_NON_MODIFIABLE_CANNOT_BE_USER_APPLICATIONS.get()); setPrimaryInvalid(lUsage); } } if (errors.size() == 0) { ProgressDialog dlg = new ProgressDialog( Utilities.createFrame(), Utilities.getParentDialog(this), INFO_CTRL_PANEL_MODIFY_ATTRIBUTE_TITLE.get(), getInfo()); ModifyAttributeTask newTask = new ModifyAttributeTask(getInfo(), dlg, attribute, getNewAttribute()); for (ConfigurationElementCreatedListener listener : getConfigurationElementCreatedListeners()) { newTask.addConfigurationElementCreatedListener(listener); } for (Task task : getInfo().getTasks()) { task.canLaunch(newTask, errors); } if (errors.size() == 0) { launchOperation(newTask, INFO_CTRL_PANEL_MODIFYING_ATTRIBUTE_SUMMARY.get(attrName), INFO_CTRL_PANEL_MODIFYING_ATTRIBUTE_COMPLETE.get(), INFO_CTRL_PANEL_MODIFYING_ATTRIBUTE_SUCCESSFUL.get(attrName), ERR_CTRL_PANEL_MODIFYING_ATTRIBUTE_ERROR_SUMMARY.get(), ERR_CTRL_PANEL_MODIFYING_ATTRIBUTE_ERROR_DETAILS.get(attrName), null, dlg); dlg.setVisible(true); } } if (!errors.isEmpty()) { displayErrorDialog(errors); } } private void checkEnableSaveChanges() { if (ignoreChangeEvents) return; boolean changed; if (attribute != null) { try { changed = !attribute.toString().equals(getNewAttribute().toString()); } catch (Throwable t) { changed = true; } } else { changed = false; } saveChanges.setEnabled(changed); } private String getAttributeName() { return name.getText().trim(); } private String getOID() { String o = oid.getText().trim(); if (o.length() == 0) { o = getAttributeName()+"-oid"; } return o; } private ArrayList<String> getAliases() { ArrayList<String> al = new ArrayList<String>(); String s = aliases.getText().trim(); if (s.length() > 0) { String[] a = s.split(","); for (String alias : a) { al.add(alias.trim()); } } return al; } private ArrayList<String> getAllNames() { ArrayList<String> al = new ArrayList<String>(); al.add(getAttributeName()); al.addAll(getAliases()); return al; } private AttributeType getSuperior() { Object o = parent.getSelectedItem(); if (NO_PARENT.equals(o)) { return null; } else { return (AttributeType)o; } } private ApproximateMatchingRule getApproximateMatchingRule() { if (approximate.getSelectedIndex() == 0) { return null; } else { return (ApproximateMatchingRule)approximate.getSelectedItem(); } } private EqualityMatchingRule getEqualityMatchingRule() { if (equality.getSelectedIndex() == 0) { return null; } else { return (EqualityMatchingRule)equality.getSelectedItem(); } } private SubstringMatchingRule getSubstringMatchingRule() { if (substring.getSelectedIndex() == 0) { return null; } else { return (SubstringMatchingRule)substring.getSelectedItem(); } } private OrderingMatchingRule getOrderingMatchingRule() { if (ordering.getSelectedIndex() == 0) { return null; } else { return (OrderingMatchingRule)ordering.getSelectedItem(); } } private Map<String, List<String>> getExtraProperties() { Map<String, List<String>> map = new HashMap<String, List<String>>(); String f = file.getText().trim(); if (f.length() > 0) { ArrayList<String> list = new ArrayList<String>(); list.add(f); map.put(ServerConstants.SCHEMA_PROPERTY_FILENAME, list); } String or = origin.getText().trim(); if (or.length() > 0) { ArrayList<String> list = new ArrayList<String>(); list.add(or); map.put(ServerConstants.SCHEMA_PROPERTY_ORIGIN, list); } return map; } private String getDescription() { return description.getText().trim(); } private AttributeType getNewAttribute() { AttributeType attr = new AttributeType("", getAttributeName(), getAllNames(), getOID(), getDescription(), getSuperior(), (AttributeSyntax<?>)syntax.getSelectedItem(), getApproximateMatchingRule(), getEqualityMatchingRule(), getOrderingMatchingRule(), getSubstringMatchingRule(), (AttributeUsage)usage.getSelectedItem(), collective.isSelected(), nonModifiable.isSelected(), obsolete.isSelected(), singleValued.isSelected(), getExtraProperties()); return attr; } private void updateDefaultMatchingRuleNames() { AttributeSyntax<?> syn = (AttributeSyntax<?>)syntax.getSelectedItem(); if (syn != null) { MatchingRule[] rules = {syn.getApproximateMatchingRule(), syn.getSubstringMatchingRule(), syn.getEqualityMatchingRule(), syn.getOrderingMatchingRule()}; JComboBox[] combos = {approximate, substring, equality, ordering}; for (int i=0; i<rules.length; i++) { DefaultComboBoxModel model = (DefaultComboBoxModel)combos[i].getModel(); int index = combos[i].getSelectedIndex(); if (rules[i] != null) { if (model.getSize() > 0) { model.removeElementAt(0); } model.insertElementAt(INFO_CTRL_PANEL_DEFAULT_DEFINED_IN_SYNTAX.get( rules[i].getNameOrOID()), 0); } else { if (model.getSize() > 0) { model.removeElementAt(0); } model.insertElementAt(NO_MATCHING_RULE, 0); } combos[i].setSelectedIndex(index); } } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/CustomObjectClassPanel.java
@@ -29,41 +29,140 @@ import static org.opends.messages.AdminToolMessages.*; import java.awt.Component; import java.awt.Container; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.io.File; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.ListCellRenderer; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.datamodel.SortableListModel; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.event. ConfigurationElementCreatedListener; import org.opends.guitools.controlpanel.event.ScrollPaneBorderListener; import org.opends.guitools.controlpanel.task.DeleteSchemaElementsTask; import org.opends.guitools.controlpanel.task.ModifyObjectClassTask; import org.opends.guitools.controlpanel.task.Task; import org.opends.guitools.controlpanel.ui.components.BasicExpander; import org.opends.guitools.controlpanel.ui.components.DoubleAddRemovePanel; import org.opends.guitools.controlpanel.ui.components.TitlePanel; import org.opends.guitools.controlpanel.ui.renderer. SchemaElementComboBoxCellRenderer; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.server.types.AttributeType; import org.opends.server.types.ObjectClass; import org.opends.server.types.ObjectClassType; import org.opends.server.types.Schema; import org.opends.server.util.ServerConstants; import org.opends.server.util.StaticUtils; /** * The panel that displays a custom object class definition. * */ public class CustomObjectClassPanel extends StandardObjectClassPanel public class CustomObjectClassPanel extends SchemaElementPanel { private static final long serialVersionUID = 2105520588901380L; private JButton delete; private JButton saveChanges; private ObjectClass objectClass; private String ocName; private ScrollPaneBorderListener scrollListener; private TitlePanel titlePanel = new TitlePanel(Message.EMPTY, Message.EMPTY); private JLabel lName = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_NAME_LABEL.get()); private JLabel lParent = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_PARENT_LABEL.get()); private JLabel lOID = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_OID_LABEL.get()); private JLabel lAliases = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_ALIASES_LABEL.get()); private JLabel lOrigin = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_ORIGIN_LABEL.get()); private JLabel lFile = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_FILE_LABEL.get()); private JTextField aliases = Utilities.createLongTextField(); private JLabel lDescription = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_DESCRIPTION_LABEL.get()); private JLabel lType = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_TYPE_LABEL.get()); private JLabel lAttributes = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_OBJECTCLASS_ATTRIBUTES_LABEL.get()); private Set<AttributeType> inheritedOptionalAttributes = new HashSet<AttributeType>(); private Set<AttributeType> inheritedRequiredAttributes = new HashSet<AttributeType>(); private JLabel[] labels = {lName, lParent, lOID, lAliases, lOrigin, lFile, lDescription, lType, lAttributes }; private JTextField name = Utilities.createMediumTextField(); private JComboBox parent = Utilities.createComboBox(); private JComboBox type = Utilities.createComboBox(); private JTextField oid = Utilities.createMediumTextField(); private JTextField description = Utilities.createLongTextField(); private JTextField origin = Utilities.createLongTextField(); private JTextField file = Utilities.createLongTextField(); private JCheckBox obsolete = Utilities.createCheckBox( INFO_CTRL_PANEL_OBJECTCLASS_OBSOLETE_LABEL.get()); private DoubleAddRemovePanel<AttributeType> attributes; private Schema schema; private Set<String> lastAliases = new LinkedHashSet<String>(); private boolean ignoreChangeEvents; /** * Default constructor of the panel. * */ public CustomObjectClassPanel() { super(); createLayout(); } /** * {@inheritDoc} */ @@ -81,10 +180,11 @@ GridBagConstraints gbc = new GridBagConstraints(); p.setOpaque(false); p.setBorder(PANEL_BORDER); super.createBasicLayout(p, gbc); createBasicLayout(p, gbc); gbc = new GridBagConstraints(); gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.gridwidth = 2; gbc.fill = GridBagConstraints.BOTH; gbc.gridx = 0; gbc.gridy = 0; @@ -98,6 +198,7 @@ gbc.anchor = GridBagConstraints.WEST; gbc.fill = GridBagConstraints.NONE; gbc.insets = new Insets(10, 10, 10, 10); gbc.gridwidth = 1; delete = Utilities.createButton( INFO_CTRL_PANEL_DELETE_OBJECTCLASS_BUTTON.get()); delete.setOpaque(false); @@ -112,6 +213,343 @@ deleteObjectclass(); } }); gbc.anchor = GridBagConstraints.EAST; gbc.gridx ++; saveChanges = Utilities.createButton(INFO_CTRL_PANEL_SAVE_CHANGES_LABEL.get()); saveChanges.setOpaque(false); add(saveChanges, gbc); saveChanges.addActionListener(new ActionListener() { /** * {@inheritDoc} */ public void actionPerformed(ActionEvent ev) { ArrayList<Message> errors = new ArrayList<Message>(); saveChanges(false, errors); } }); } /** * Creates the basic layout of the panel. * @param c the container where all the components will be layed out. * @param gbc the grid bag constraints. */ protected void createBasicLayout(Container c, GridBagConstraints gbc) { SchemaElementComboBoxCellRenderer renderer = new SchemaElementComboBoxCellRenderer(parent); DefaultComboBoxModel model = new DefaultComboBoxModel(); parent.setModel(model); parent.setRenderer(renderer); ItemListener itemListener = new ItemListener() { /** * {@inheritDoc} */ public void itemStateChanged(ItemEvent ev) { if (ignoreChangeEvents) return; updateAttributesWithParent(true); } }; parent.addItemListener(itemListener); model = new DefaultComboBoxModel(); for (ObjectClassType t : ObjectClassType.values()) { model.addElement(t); } type.setModel(model); type.setSelectedItem(ObjectClassType.STRUCTURAL); type.setRenderer(renderer); attributes = new DoubleAddRemovePanel<AttributeType>(0, AttributeType.class); Comparator<AttributeType> comparator = new Comparator<AttributeType>() { /** * {@inheritDoc} */ public int compare(AttributeType attr1, AttributeType attr2) { return attr1.getNameOrOID().compareTo(attr2.getNameOrOID()); } }; attributes.getAvailableListModel().setComparator(comparator); attributes.getSelectedListModel1().setComparator(comparator); attributes.getSelectedListModel2().setComparator(comparator); gbc.gridy = 0; gbc.gridwidth = 2; addErrorPane(c, gbc); gbc.gridy ++; gbc.anchor = GridBagConstraints.WEST; titlePanel.setTitle(INFO_CTRL_PANEL_OBJECTCLASS_DETAILS.get()); gbc.fill = GridBagConstraints.NONE; gbc.insets.top = 5; gbc.insets.bottom = 7; c.add(titlePanel, gbc); gbc.insets.bottom = 0; gbc.insets.top = 8; gbc.gridy ++; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.HORIZONTAL; Component[] basicComps = {name, oid, description, parent}; JLabel[] basicLabels = {lName, lOID, lDescription, lParent}; JLabel[] basicInlineHelp = new JLabel[] {null, null, null, null}; add(basicLabels, basicComps, basicInlineHelp, c, gbc); gbc.gridx = 0; gbc.weightx = 0.0; gbc.insets.left = 0; gbc.fill = GridBagConstraints.HORIZONTAL; gbc.anchor = GridBagConstraints.NORTHWEST; c.add(lAttributes, gbc); gbc.gridx ++; gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; gbc.weighty = 1.0; gbc.insets.left = 10; c.add(attributes, gbc); attributes.getAvailableLabel().setText( INFO_CTRL_PANEL_ADDREMOVE_AVAILABLE_ATTRIBUTES.get().toString()); attributes.getSelectedLabel1().setText( INFO_CTRL_PANEL_ADDREMOVE_REQUIRED_ATTRIBUTES.get().toString()); attributes.getSelectedLabel2().setText( INFO_CTRL_PANEL_ADDREMOVE_OPTIONAL_ATTRIBUTES.get().toString()); AttributeTypeCellRenderer listRenderer = new AttributeTypeCellRenderer(); attributes.getAvailableList().setCellRenderer(listRenderer); attributes.getSelectedList1().setCellRenderer(listRenderer); attributes.getSelectedList2().setCellRenderer(listRenderer); gbc.gridy ++; gbc.weighty = 0.0; gbc.insets.top = 3; JLabel explanation = Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_INHERITED_ATTRIBUTES_HELP.get()); gbc.insets.top = 3; c.add(explanation, gbc); final BasicExpander expander = new BasicExpander( INFO_CTRL_PANEL_EXTRA_OPTIONS_EXPANDER.get()); obsolete.setText("Obsolete"); Component[] comps = {aliases, origin, file, type, obsolete}; JLabel[] labels = {lAliases, lOrigin, lFile, lType, null}; JLabel[] inlineHelps = { Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_SEPARATED_WITH_COMMAS_HELP.get()), null, Utilities.createInlineHelpLabel( INFO_CTRL_PANEL_SCHEMA_FILE_OBJECTCLASS_HELP.get(File.separator)), null, null}; gbc.gridwidth = 2; gbc.gridx = 0; gbc.weighty = 0.0; gbc.insets.left = 0; gbc.gridy ++; c.add(expander, gbc); final JPanel p = new JPanel(new GridBagLayout()); gbc.insets.left = 15; gbc.gridy ++; c.add(p, gbc); gbc.gridy ++; p.setOpaque(false); GridBagConstraints gbc1 = new GridBagConstraints(); gbc1.fill = GridBagConstraints.HORIZONTAL; gbc1.gridy = 0; add(labels, comps, inlineHelps, p, gbc1); ChangeListener changeListener = new ChangeListener() { /** * {@inheritDoc} */ public void stateChanged(ChangeEvent e) { p.setVisible(expander.isSelected()); } }; expander.addChangeListener(changeListener); expander.setSelected(false); changeListener.stateChanged(null); DocumentListener docListener = new DocumentListener() { /** * {@inheritDoc} */ public void insertUpdate(DocumentEvent ev) { checkEnableSaveChanges(); } /** * {@inheritDoc} */ public void removeUpdate(DocumentEvent ev) { checkEnableSaveChanges(); } /** * {@inheritDoc} */ public void changedUpdate(DocumentEvent arg0) { checkEnableSaveChanges(); } }; JTextField[] tfs = {name, description, oid, aliases, origin, file}; for (JTextField tf : tfs) { tf.getDocument().addDocumentListener(docListener); } ActionListener actionListener = new ActionListener() { public void actionPerformed(ActionEvent ev) { checkEnableSaveChanges(); } }; JComboBox[] combos = {parent, type}; for (JComboBox combo : combos) { combo.addActionListener(actionListener); } ListDataListener dataListener = new ListDataListener() { /** * {@inheritDoc} */ public void contentsChanged(ListDataEvent e) { checkEnableSaveChanges(); } /** * {@inheritDoc} */ public void intervalAdded(ListDataEvent e) { checkEnableSaveChanges(); } /** * {@inheritDoc} */ public void intervalRemoved(ListDataEvent e) { checkEnableSaveChanges(); } }; SortableListModel<AttributeType> list1 = attributes.getSelectedListModel1(); SortableListModel<AttributeType> list2 = attributes.getSelectedListModel2(); list1.addListDataListener(dataListener); list2.addListDataListener(dataListener); obsolete.addActionListener(actionListener); } /** * Updates the contents of the panel with the provided object class. * @param oc the object class. * @param schema the schema. */ public void update(ObjectClass oc, Schema schema) { ignoreChangeEvents = true; objectClass = oc; if ((oc == null) || (schema == null)) { // Ignore: this is called to get an initial panel size. return; } String n = oc.getPrimaryName(); if (n == null) { n = NOT_APPLICABLE.toString(); } titlePanel.setDetails(Message.raw(n)); name.setText(n); SortableListModel<AttributeType> modelRequired = attributes.getSelectedListModel1(); SortableListModel<AttributeType> modelAvailable = attributes.getSelectedListModel2(); SortableListModel<AttributeType> availableModel = attributes.getAvailableListModel(); availableModel.addAll(modelRequired.getData()); availableModel.addAll(modelAvailable.getData()); modelRequired.clear(); modelAvailable.clear(); parent.setSelectedItem(oc.getSuperiorClass()); updateAttributesWithParent(false); for (AttributeType attr : oc.getRequiredAttributes()) { availableModel.remove(attr); modelRequired.add(attr); } for (AttributeType attr : oc.getOptionalAttributes()) { availableModel.remove(attr); modelAvailable.add(attr); } notifyAttributesChanged(); oid.setText(oc.getOID()); n = oc.getDescription(); if (n == null) { n = ""; } description.setText(n); Set<String> aliases = getAliases(oc); lastAliases.clear(); lastAliases.addAll(aliases); this.aliases.setText(Utilities.getStringFromCollection(aliases, ", ")); String sOrigin = Utilities.getOrigin(oc); if (sOrigin == null) { sOrigin = ""; } origin.setText(sOrigin); String sFile = oc.getSchemaFile(); if (sFile == null) { sFile = ""; } file.setText(sFile); type.setSelectedItem(oc.getObjectClassType()); obsolete.setSelected(oc.isObsolete()); ocName = objectClass.getNameOrOID(); scrollListener.updateBorder(); for (JLabel label : labels) { setPrimaryValid(label); } saveChanges.setEnabled(false); ignoreChangeEvents = false; } /** @@ -120,10 +558,67 @@ public void configurationChanged(ConfigurationChangeEvent ev) { final ServerDescriptor desc = ev.getNewDescriptor(); updateErrorPaneIfAuthRequired(desc, isLocal() ? INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_OBJECTCLASS_DELETE.get() : Schema s = desc.getSchema(); final boolean schemaChanged; if (schema != null && s != null) { schemaChanged = !ServerDescriptor.areSchemasEqual(s, schema); } else if (schema == null && s != null) { schemaChanged = true; } else if (s == null && schema != null) { schemaChanged = false; } else { schemaChanged = false; } if (schemaChanged) { schema = s; HashMap<String, ObjectClass> objectClassNameMap = new HashMap<String, ObjectClass>(); for (String key : schema.getObjectClasses().keySet()) { ObjectClass oc = schema.getObjectClass(key); objectClassNameMap.put(oc.getNameOrOID(), oc); } SortedSet<String> orderedKeys = new TreeSet<String>(); orderedKeys.addAll(objectClassNameMap.keySet()); ArrayList<ObjectClass> newParents = new ArrayList<ObjectClass>(); for (String key : orderedKeys) { newParents.add(objectClassNameMap.get(key)); } updateComboBoxModel(newParents, ((DefaultComboBoxModel)parent.getModel()), new Comparator<Object>() { /** * {@inheritDoc} */ public int compare(Object arg0, Object arg1) { return String.valueOf(arg0).compareTo(String.valueOf(arg1)); } }); updateErrorPaneIfAuthRequired(desc, isLocal() ? INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_OBJECTCLASS_EDIT.get() : INFO_CTRL_PANEL_CANNOT_CONNECT_TO_REMOTE_DETAILS.get(desc.getHostname())); } else if (schema == null) { updateErrorPane(errorPane, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_SUMMARY.get(), ColorAndFontConstants.errorTitleFont, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get(), ColorAndFontConstants.defaultFont); } SwingUtilities.invokeLater(new Runnable() { /** @@ -131,7 +626,18 @@ */ public void run() { delete.setEnabled(!authenticationRequired(desc)); delete.setEnabled(!authenticationRequired(desc) && !authenticationRequired(desc) && schema != null); checkEnableSaveChanges(); saveChanges.setEnabled(saveChanges.isEnabled() && !authenticationRequired(desc) && !authenticationRequired(desc) && schema != null); if (schemaChanged) { updateAttributes(); } } }); } @@ -139,15 +645,52 @@ /** * {@inheritDoc} */ public void update(ObjectClass oc, Schema schema) public boolean mustCheckUnsavedChanges() { super.update(oc, schema); objectClass = oc; if (objectClass != null) return saveChanges.isEnabled(); } /** * {@inheritDoc} */ public UnsavedChangesDialog.Result checkUnsavedChanges() { UnsavedChangesDialog.Result result; UnsavedChangesDialog unsavedChangesDlg = new UnsavedChangesDialog( Utilities.getParentDialog(this), getInfo()); unsavedChangesDlg.setMessage(INFO_CTRL_PANEL_UNSAVED_CHANGES_SUMMARY.get(), INFO_CTRL_PANEL_UNSAVED_OBJECTCLASS_CHANGES_DETAILS.get( objectClass.getNameOrOID())); Utilities.centerGoldenMean(unsavedChangesDlg, Utilities.getParentDialog(this)); unsavedChangesDlg.setVisible(true); result = unsavedChangesDlg.getResult(); if (result == UnsavedChangesDialog.Result.SAVE) { ocName = objectClass.getNameOrOID(); ArrayList<Message> errors = new ArrayList<Message>(); saveChanges(true, errors); if (!errors.isEmpty()) { result = UnsavedChangesDialog.Result.CANCEL; } } scrollListener.updateBorder(); return result; } /** * {@inheritDoc} */ public Component getPreferredFocusComponent() { return name; } /** * {@inheritDoc} */ public void okClicked() { } private void deleteObjectclass() @@ -157,9 +700,10 @@ Utilities.createFrame(), Utilities.getParentDialog(this), INFO_CTRL_PANEL_DELETE_OBJECTCLASS_TITLE.get(), getInfo()); ArrayList<ObjectClass> ocsToDelete = new ArrayList<ObjectClass>(); LinkedHashSet<ObjectClass> ocsToDelete = new LinkedHashSet<ObjectClass>(); ocsToDelete.add(objectClass); ArrayList<AttributeType> attrsToDelete = new ArrayList<AttributeType>(); LinkedHashSet<AttributeType> attrsToDelete = new LinkedHashSet<AttributeType>(0); DeleteSchemaElementsTask newTask = new DeleteSchemaElementsTask(getInfo(), dlg, ocsToDelete, attrsToDelete); @@ -168,9 +712,9 @@ task.canLaunch(newTask, errors); } Schema schema = getInfo().getServerDescriptor().getSchema(); ArrayList<String> childClasses = new ArrayList<String>(); if (schema != null) { ArrayList<String> childClasses = new ArrayList<String>(); for (ObjectClass o : schema.getObjectClasses().values()) { if (objectClass.equals(o.getSuperiorClass())) @@ -178,17 +722,26 @@ childClasses.add(o.getNameOrOID()); } } if (!childClasses.isEmpty()) { errors.add(ERR_CANNOT_DELETE_PARENT_OBJECTCLASS.get(ocName, Utilities.getStringFromCollection(childClasses, ", "), ocName)); } } else { errors.add(ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_DETAILS.get()); } if (errors.size() == 0) { MessageBuilder mb = new MessageBuilder(); if (!childClasses.isEmpty()) { mb.append(INFO_OBJECTCLASS_IS_SUPERIOR.get( ocName, Utilities.getStringFromCollection(childClasses, ", "))); mb.append("<br>"); } Message confirmationMessage = INFO_CTRL_PANEL_CONFIRMATION_DELETE_OBJECTCLASS_DETAILS.get( ocName); mb.append(confirmationMessage); if (displayConfirmationDialog( INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), confirmationMessage)) @@ -209,4 +762,476 @@ displayErrorDialog(errors); } } private void saveChanges(boolean modal, ArrayList<Message> errors) { for (JLabel label : labels) { setPrimaryValid(label); } String n = getObjectClassName(); MessageBuilder err = new MessageBuilder(); if (n.length() == 0) { errors.add(ERR_CTRL_PANEL_OBJECTCLASS_NAME_REQUIRED.get()); setPrimaryInvalid(lName); } else if (!n.equalsIgnoreCase(objectClass.getNameOrOID())) { if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err)) { errors.add(ERR_CTRL_PANEL_INVALID_OBJECTCLASS_NAME.get(err.toString())); setPrimaryInvalid(lName); err = new MessageBuilder(); } else { Message elementType = NewAttributePanel.getSchemaElementType(n, schema); if (elementType != null) { errors.add(ERR_CTRL_PANEL_OBJECTCLASS_NAME_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lName); } } } n = oid.getText().trim(); if (n.length() > 0 && !n.equalsIgnoreCase(objectClass.getOID())) { if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err)) { errors.add(ERR_CTRL_PANEL_OID_NOT_VALID.get(err.toString())); setPrimaryInvalid(lOID); err = new MessageBuilder(); } else { Message elementType = NewAttributePanel.getSchemaElementType(n, schema); if (elementType != null) { errors.add(ERR_CTRL_PANEL_OID_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lOID); } } } Collection<String> aliases = getAliases(); Collection<String> oldAliases = getAliases(objectClass); if (!aliases.equals(oldAliases)) { for (String alias : aliases) { if (alias.trim().length() == 0) { errors.add(ERR_CTRL_PANEL_EMPTY_ALIAS.get()); setPrimaryInvalid(lAliases); } else { boolean notPreviouslyDefined = true; for (String oldAlias : oldAliases) { if (oldAlias.equalsIgnoreCase(alias)) { notPreviouslyDefined = false; break; } } if (notPreviouslyDefined) { Message elementType = NewAttributePanel.getSchemaElementType(alias, schema); if (elementType != null) { errors.add(ERR_CTRL_PANEL_ALIAS_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lAliases); } } } } } ObjectClass superior = getSuperior(); if (superior != null) { if (superior.getNameOrOID().equalsIgnoreCase(objectClass.getNameOrOID())) { errors.add(ERR_CTRL_PANEL_OBJECTCLASS_CANNOT_BE_ITS_SUPERIOR.get()); setPrimaryInvalid(lParent); } else { // Check whether this object class is defined as parent as the superior. superior = superior.getSuperiorClass(); while (superior != null) { if (superior.getNameOrOID().equalsIgnoreCase( objectClass.getNameOrOID())) { errors.add( ERR_CTRL_PANEL_OBJECTCLASS_IS_SUPERIOR_OF_SUPERIOR.get( getSuperior().getNameOrOID())); setPrimaryInvalid(lParent); break; } superior = superior.getSuperiorClass(); } } } if (errors.size() == 0) { ProgressDialog dlg = new ProgressDialog( Utilities.createFrame(), Utilities.getParentDialog(this), INFO_CTRL_PANEL_MODIFY_ATTRIBUTE_TITLE.get(), getInfo()); ModifyObjectClassTask newTask = new ModifyObjectClassTask(getInfo(), dlg, objectClass, getNewObjectClass()); for (ConfigurationElementCreatedListener listener : getConfigurationElementCreatedListeners()) { newTask.addConfigurationElementCreatedListener(listener); } for (Task task : getInfo().getTasks()) { task.canLaunch(newTask, errors); } if (errors.size() == 0) { launchOperation(newTask, INFO_CTRL_PANEL_MODIFYING_OBJECTCLASS_SUMMARY.get(ocName), INFO_CTRL_PANEL_MODIFYING_OBJECTCLASS_COMPLETE.get(), INFO_CTRL_PANEL_MODIFYING_OBJECTCLASS_SUCCESSFUL.get(ocName), ERR_CTRL_PANEL_MODIFYING_OBJECTCLASS_ERROR_SUMMARY.get(), ERR_CTRL_PANEL_MODIFYING_OBJECTCLASS_ERROR_DETAILS.get(ocName), null, dlg); dlg.setVisible(true); } } if (!errors.isEmpty()) { displayErrorDialog(errors); } } private void checkEnableSaveChanges() { if (ignoreChangeEvents) return; boolean changed; if (objectClass != null) { try { changed = !objectClass.toString().equals( getNewObjectClass().toString()); } catch (Throwable t) { changed = true; } } else { changed = false; } saveChanges.setEnabled(changed); } private Set<String> getAliases() { Set<String> al = new LinkedHashSet<String>(); String s = aliases.getText().trim(); if (s.length() > 0) { String[] a = s.split(","); for (String alias : a) { al.add(alias.trim()); } } return al; } private String getObjectClassName() { return name.getText().trim(); } private String getOID() { String o = oid.getText().trim(); if (o.length() == 0) { o = getObjectClassName()+"-oid"; } return o; } private Map<String, List<String>> getExtraProperties() { Map<String, List<String>> map = new HashMap<String, List<String>>(); String f = file.getText().trim(); if (f.length() > 0) { ArrayList<String> list = new ArrayList<String>(); list.add(f); map.put(ServerConstants.SCHEMA_PROPERTY_FILENAME, list); } String or = origin.getText().trim(); if (or.length() > 0) { ArrayList<String> list = new ArrayList<String>(); list.add(or); map.put(ServerConstants.SCHEMA_PROPERTY_ORIGIN, list); } return map; } private ArrayList<String> getAllNames() { ArrayList<String> al = new ArrayList<String>(); al.add(getObjectClassName()); al.addAll(getAliases()); return al; } private String getDescription() { return description.getText().trim(); } private ObjectClass getSuperior() { return (ObjectClass)parent.getSelectedItem(); } private ObjectClassType getObjectClassType() { return (ObjectClassType)type.getSelectedItem(); } private Set<AttributeType> getRequiredAttributes() { HashSet<AttributeType> attrs = new HashSet<AttributeType>(); attrs.addAll(attributes.getSelectedListModel1().getData()); attrs.removeAll(inheritedRequiredAttributes); return attrs; } private Set<AttributeType> getOptionalAttributes() { HashSet<AttributeType> attrs = new HashSet<AttributeType>(); attrs.addAll(attributes.getSelectedListModel2().getData()); attrs.removeAll(inheritedOptionalAttributes); return attrs; } private ObjectClass getNewObjectClass() { ObjectClass newObjectClass = new ObjectClass("", getObjectClassName(), getAllNames(), getOID(), getDescription(), getSuperior(), getRequiredAttributes(), getOptionalAttributes(), getObjectClassType(), obsolete.isSelected(), getExtraProperties()); return newObjectClass; } private void updateAttributes() { int[][] selected = { attributes.getAvailableList().getSelectedIndices(), attributes.getSelectedList1().getSelectedIndices(), attributes.getSelectedList2().getSelectedIndices() }; JList[] lists = { attributes.getAvailableList(), attributes.getSelectedList1(), attributes.getSelectedList2() }; attributes.getAvailableListModel().clear(); Collection<AttributeType> allAttrs = schema.getAttributeTypes().values(); attributes.getAvailableListModel().addAll(allAttrs); HashSet<AttributeType> toDelete = new HashSet<AttributeType>(); for (AttributeType attr : attributes.getSelectedListModel1().getData()) { if (!allAttrs.contains(attr)) { toDelete.add(attr); } else { attributes.getAvailableListModel().remove(attr); } } for (AttributeType attr : toDelete) { attributes.getSelectedListModel1().remove(attr); } toDelete = new HashSet<AttributeType>(); for (AttributeType attr : attributes.getSelectedListModel2().getData()) { if (!allAttrs.contains(attr)) { toDelete.add(attr); } else { attributes.getAvailableListModel().remove(attr); } } for (AttributeType attr : toDelete) { attributes.getSelectedListModel1().remove(attr); } int i = 0; for (int[] sel : selected) { if (sel != null) { ArrayList<Integer> indexes = new ArrayList<Integer>(); for (int j=0; j<sel.length; j++) { if (sel[j] < lists[i].getModel().getSize()) { indexes.add(sel[j]); } } int[] newSelection = new int[indexes.size()]; for (int j=0; j<newSelection.length; j++) { newSelection[j] = indexes.get(j); } lists[i].setSelectedIndices(newSelection); } i++; } } private void updateAttributesWithParent(boolean notify) { // Remove the previous inherited attributes. for (AttributeType attr : inheritedRequiredAttributes) { attributes.getAvailableListModel().add(attr); attributes.getSelectedListModel1().remove(attr); } for (AttributeType attr : inheritedOptionalAttributes) { attributes.getAvailableListModel().add(attr); attributes.getSelectedListModel2().remove(attr); } inheritedOptionalAttributes.clear(); inheritedRequiredAttributes.clear(); ObjectClass p = (ObjectClass)parent.getSelectedItem(); if (p != null) { for (AttributeType attr : p.getRequiredAttributeChain()) { inheritedRequiredAttributes.add(attr); } for (AttributeType attr : p.getOptionalAttributeChain()) { inheritedOptionalAttributes.add(attr); } } for (AttributeType attr : inheritedRequiredAttributes) { attributes.getAvailableListModel().remove(attr); attributes.getSelectedListModel1().add(attr); } for (AttributeType attr : inheritedOptionalAttributes) { attributes.getAvailableListModel().remove(attr); attributes.getSelectedListModel2().add(attr); } Collection<AttributeType> unmovableItems = new ArrayList<AttributeType>(inheritedRequiredAttributes); unmovableItems.addAll(inheritedOptionalAttributes); attributes.setUnmovableItems(unmovableItems); if (notify) { notifyAttributesChanged(); } } private void notifyAttributesChanged() { attributes.getAvailableListModel().fireContentsChanged( attributes.getAvailableList(), 0, attributes.getAvailableListModel().getSize() - 1); attributes.getSelectedListModel1().fireContentsChanged( attributes.getSelectedList1(), 0, attributes.getSelectedListModel1().getSize() - 1); attributes.getSelectedListModel2().fireContentsChanged( attributes.getSelectedList2(), 0, attributes.getSelectedListModel2().getSize() - 1); } /** * A renderer for the attribute lists. The renderer basically marks the * inherited attributes with an asterisk. * */ private class AttributeTypeCellRenderer implements ListCellRenderer { private ListCellRenderer defaultRenderer; /** * Renderer constructor. * */ public AttributeTypeCellRenderer() { defaultRenderer = attributes.getAvailableList().getCellRenderer(); } /** * {@inheritDoc} */ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { if (value instanceof AttributeType) { AttributeType attr = (AttributeType)value; if (inheritedOptionalAttributes.contains(value) || inheritedRequiredAttributes.contains(value)) { value = attr.getNameOrOID()+ " (*)"; } else { value = attr.getNameOrOID(); } } return defaultRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/NewAttributePanel.java
@@ -37,15 +37,12 @@ import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.SortedSet; import java.util.TreeSet; import javax.naming.NamingException; import javax.naming.directory.BasicAttribute; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.swing.DefaultComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; @@ -56,12 +53,11 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.task.OfflineUpdateException; import org.opends.guitools.controlpanel.task.OnlineUpdateException; import org.opends.guitools.controlpanel.task.SchemaTask; import org.opends.guitools.controlpanel.event. ConfigurationElementCreatedListener; import org.opends.guitools.controlpanel.task.NewSchemaElementsTask; import org.opends.guitools.controlpanel.task.Task; import org.opends.guitools.controlpanel.ui.components.BasicExpander; import @@ -78,18 +74,8 @@ import org.opends.server.config.ConfigConstants; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeUsage; import org.opends.server.types.Attributes; import org.opends.server.types.CommonSchemaElements; import org.opends.server.types.Entry; import org.opends.server.types.ExistingFileBehavior; import org.opends.server.types.LDIFExportConfig; import org.opends.server.types.LDIFImportConfig; import org.opends.server.types.Modification; import org.opends.server.types.ModificationType; import org.opends.server.types.OpenDsException; import org.opends.server.types.ObjectClass; import org.opends.server.types.Schema; import org.opends.server.util.LDIFReader; import org.opends.server.util.LDIFWriter; import org.opends.server.util.ServerConstants; import org.opends.server.util.StaticUtils; @@ -207,22 +193,39 @@ final boolean[] repack = {firstSchema}; final boolean[] error = {false}; if (s != null) boolean schemaChanged; if (schema != null && s != null) { schemaChanged = !ServerDescriptor.areSchemasEqual(s, schema); } else if (schema == null && s != null) { schemaChanged = true; } else if (s == null && schema != null) { schemaChanged = false; } else { schemaChanged = false; } if (schemaChanged) { schema = s; HashMap<String, AttributeSyntax<?>> syntaxNameMap = new HashMap<String, AttributeSyntax<?>>(); for (String key : schema.getSyntaxes().keySet()) { AttributeSyntax<?> syntax = schema.getSyntax(key); String name = syntax.getSyntaxName(); if (name == null) { name = syntax.getOID(); } syntaxNameMap.put(name, syntax); } HashMap<String, AttributeSyntax<?>> syntaxNameMap = new HashMap<String, AttributeSyntax<?>>(); for (String key : schema.getSyntaxes().keySet()) { AttributeSyntax<?> syntax = schema.getSyntax(key); String name = syntax.getSyntaxName(); if (name == null) { name = syntax.getOID(); } syntaxNameMap.put(name, syntax); } SortedSet<String> orderedKeys = new TreeSet<String>(syntaxNameMap.keySet()); @@ -310,7 +313,7 @@ updateComboBoxModel(el, model); } } else else if (schema == null) { updateErrorPane(errorPane, ERR_CTRL_PANEL_SCHEMA_NOT_FOUND_SUMMARY.get(), @@ -383,10 +386,12 @@ if (n.length() == 0) { errors.add(ERR_CTRL_PANEL_ATTRIBUTE_NAME_REQUIRED.get()); setPrimaryInvalid(lName); } else if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err)) { errors.add(ERR_CTRL_PANEL_INVALID_ATTRIBUTE_NAME.get(err.toString())); setPrimaryInvalid(lName); err = new MessageBuilder(); } else @@ -396,6 +401,7 @@ { errors.add(ERR_CTRL_PANEL_ATTRIBUTE_NAME_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lName); } } @@ -405,6 +411,7 @@ if (!StaticUtils.isValidSchemaElement(n, 0, n.length(), err)) { errors.add(ERR_CTRL_PANEL_OID_NOT_VALID.get(err.toString())); setPrimaryInvalid(lOID); err = new MessageBuilder(); } else @@ -414,6 +421,7 @@ { errors.add(ERR_CTRL_PANEL_OID_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lOID); } } } @@ -428,6 +436,7 @@ if (alias.trim().length() == 0) { errors.add(ERR_CTRL_PANEL_EMPTY_ALIAS.get()); setPrimaryInvalid(lAliases); } else { @@ -436,24 +445,44 @@ { errors.add(ERR_CTRL_PANEL_ALIAS_ALREADY_IN_USE.get(n, elementType.toString())); setPrimaryInvalid(lAliases); } } } } } setPrimaryValid(lUsage); if (nonModifiable.isSelected()) { if (AttributeUsage.USER_APPLICATIONS.equals(usage.getSelectedItem())) { errors.add(ERR_NON_MODIFIABLE_CANNOT_BE_USER_APPLICATIONS.get()); setPrimaryInvalid(lUsage); } } ProgressDialog dlg = new ProgressDialog( Utilities.createFrame(), Utilities.getParentDialog(this), INFO_CTRL_PANEL_NEW_ATTRIBUTE_PANEL_TITLE.get(), getInfo()); NewAttributeTask newTask = null; NewSchemaElementsTask newTask = null; if (errors.size() == 0) { newTask = new NewAttributeTask(getInfo(), dlg); LinkedHashSet<AttributeType> attributes = new LinkedHashSet<AttributeType>(); attributes.add(getAttribute()); LinkedHashSet<ObjectClass> ocs = new LinkedHashSet<ObjectClass>(0); newTask = new NewSchemaElementsTask(getInfo(), dlg, ocs, attributes); for (Task task : getInfo().getTasks()) { task.canLaunch(newTask, errors); } for (ConfigurationElementCreatedListener listener : getConfigurationElementCreatedListeners()) { newTask.addConfigurationElementCreatedListener(listener); } } if (errors.size() == 0) { @@ -834,11 +863,17 @@ return map; } private String getDescription() { return description.getText().trim(); } private AttributeType getAttribute() { AttributeType attr = new AttributeType("", getAttributeName(), getAllNames(), getOID(), description.getText().trim(), getOID(), getDescription(), getSuperior(), (AttributeSyntax<?>)syntax.getSelectedItem(), getApproximateMatchingRule(), @@ -852,228 +887,4 @@ return attr; } /** * The task in charge of creating the attribute. * */ protected class NewAttributeTask extends SchemaTask { private AttributeType attribute; private String attributeName; private String attributeDefinition; private String attributeWithoutFileDefinition; /** * The constructor of the task. * @param info the control panel info. * @param dlg the progress dialog that shows the progress of the task. */ public NewAttributeTask(ControlPanelInfo info, ProgressDialog dlg) { super(info, dlg); attributeName = getAttributeName(); attributeDefinition = attribute.toString(); AttributeType attr = getAttribute(); attr.setExtraProperty(ServerConstants.SCHEMA_PROPERTY_FILENAME, (String)null); attributeWithoutFileDefinition = attr.toString(); } /** * {@inheritDoc} */ public Type getType() { return Type.NEW_ATTRIBUTE; } /** * {@inheritDoc} */ protected CommonSchemaElements getSchemaElement() { if (attribute == null) { attribute = getAttribute(); } return attribute; } /** * {@inheritDoc} */ public Message getTaskDescription() { return INFO_CTRL_PANEL_NEW_ATTRIBUTE_TASK_DESCRIPTION.get(attributeName); } /** * {@inheritDoc} */ protected String getSchemaFileAttributeName() { return "attributeTypes"; } /** * {@inheritDoc} */ protected String getSchemaFileAttributeValue() { if (isServerRunning()) { return attributeDefinition; } else { return attributeWithoutFileDefinition; } } /** * {@inheritDoc} */ protected void updateSchema() throws OpenDsException { SwingUtilities.invokeLater(new Runnable() { /** * {@inheritDoc} */ public void run() { printEquivalentCommandToAdd(); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_CREATING_ATTRIBUTE_PROGRESS.get( attributeName), ColorAndFontConstants.progressFont)); } }); if (isServerRunning()) { try { BasicAttribute attr = new BasicAttribute(getSchemaFileAttributeName()); attr.add(getSchemaFileAttributeValue()); ModificationItem mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr); getInfo().getDirContext().modifyAttributes( ConfigConstants.DN_DEFAULT_SCHEMA_ROOT, new ModificationItem[] { mod }); } catch (NamingException ne) { throw new OnlineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(ne.toString()), ne); } } else { updateSchemaFile(); } notifyConfigurationElementCreated(attribute); SwingUtilities.invokeLater(new Runnable() { public void run() { getProgressDialog().appendProgressHtml( Utilities.getProgressDone(ColorAndFontConstants.progressFont)); } }); } /** * Updates the contents of the schema file. * @throws OpenDsException if an error occurs updating the schema file. */ private void updateSchemaFile() throws OpenDsException { if (isSchemaFileDefined) { LDIFExportConfig exportConfig = new LDIFExportConfig(schemaFile, ExistingFileBehavior.OVERWRITE); LDIFReader reader = null; Entry schemaEntry = null; try { reader = new LDIFReader(new LDIFImportConfig(schemaFile)); schemaEntry = reader.readEntry(); Modification mod = new Modification(ModificationType.ADD, Attributes.create(getSchemaFileAttributeName().toLowerCase(), getSchemaFileAttributeValue())); schemaEntry.applyModification(mod); LDIFWriter writer = new LDIFWriter(exportConfig); writer.writeEntry(schemaEntry); exportConfig.getWriter().newLine(); } catch (Throwable t) { } finally { if (reader != null) { try { reader.close(); } catch (Throwable t) { } } if (exportConfig != null) { try { exportConfig.close(); } catch (Throwable t) { } } } } else { LDIFExportConfig exportConfig = new LDIFExportConfig(schemaFile, ExistingFileBehavior.FAIL); try { ArrayList<String> lines = getSchemaEntryLines(); for (String line : lines) { LDIFWriter.writeLDIFLine(new StringBuilder(line), exportConfig.getWriter(), exportConfig.getWrapColumn() > 1, exportConfig.getWrapColumn()); } exportConfig.getWriter().newLine(); } catch (Throwable t) { throw new OfflineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(t.toString()), t); } finally { if (exportConfig != null) { try { exportConfig.close(); } catch (Throwable t) { } } } } } } } opends/src/guitools/org/opends/guitools/controlpanel/ui/NewObjectClassPanel.java
@@ -40,16 +40,13 @@ import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import javax.naming.NamingException; import javax.naming.directory.BasicAttribute; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.swing.DefaultComboBoxModel; import javax.swing.JCheckBox; import javax.swing.JComboBox; @@ -62,12 +59,11 @@ import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.datamodel.ServerDescriptor; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.task.OfflineUpdateException; import org.opends.guitools.controlpanel.task.OnlineUpdateException; import org.opends.guitools.controlpanel.task.SchemaTask; import org.opends.guitools.controlpanel.event. ConfigurationElementCreatedListener; import org.opends.guitools.controlpanel.task.NewSchemaElementsTask; import org.opends.guitools.controlpanel.task.Task; import org.opends.guitools.controlpanel.ui.components.BasicExpander; import org.opends.guitools.controlpanel.ui.components.DoubleAddRemovePanel; @@ -78,20 +74,9 @@ import org.opends.messages.MessageBuilder; import org.opends.server.config.ConfigConstants; import org.opends.server.types.AttributeType; import org.opends.server.types.Attributes; import org.opends.server.types.CommonSchemaElements; import org.opends.server.types.Entry; import org.opends.server.types.ExistingFileBehavior; import org.opends.server.types.LDIFExportConfig; import org.opends.server.types.LDIFImportConfig; import org.opends.server.types.Modification; import org.opends.server.types.ModificationType; import org.opends.server.types.ObjectClass; import org.opends.server.types.ObjectClassType; import org.opends.server.types.OpenDsException; import org.opends.server.types.Schema; import org.opends.server.util.LDIFReader; import org.opends.server.util.LDIFWriter; import org.opends.server.util.ServerConstants; import org.opends.server.util.StaticUtils; @@ -187,7 +172,24 @@ final boolean[] repack = {firstSchema}; final boolean[] error = {false}; if (s != null) final boolean schemaChanged; if (schema != null && s != null) { schemaChanged = !ServerDescriptor.areSchemasEqual(s, schema); } else if (schema == null && s != null) { schemaChanged = true; } else if (s == null && schema != null) { schemaChanged = false; } else { schemaChanged = false; } if (schemaChanged) { schema = s; @@ -230,7 +232,10 @@ { parent.setSelectedItem(schema.getObjectClass("top")); } updateAttributes(); if (schemaChanged) { updateAttributes(); } } if (repack[0]) { @@ -332,14 +337,23 @@ Utilities.createFrame(), Utilities.getParentDialog(this), INFO_CTRL_PANEL_NEW_OBJECTCLASS_PANEL_TITLE.get(), getInfo()); NewObjectClassTask newTask = null; NewSchemaElementsTask newTask = null; if (errors.size() == 0) { newTask = new NewObjectClassTask(getInfo(), dlg); LinkedHashSet<AttributeType> attributes = new LinkedHashSet<AttributeType>(1); LinkedHashSet<ObjectClass> ocs = new LinkedHashSet<ObjectClass>(); ocs.add(getObjectClass()); newTask = new NewSchemaElementsTask(getInfo(), dlg, ocs, attributes); for (Task task : getInfo().getTasks()) { task.canLaunch(newTask, errors); } for (ConfigurationElementCreatedListener listener : getConfigurationElementCreatedListeners()) { newTask.addConfigurationElementCreatedListener(listener); } } if (errors.size() == 0) { @@ -712,13 +726,19 @@ return al; } private String getDescription() { return description.getText().trim(); } private ObjectClass getObjectClass() { ObjectClass oc = new ObjectClass("", getObjectClassName(), getAllNames(), getOID(), description.getText().trim(), getOID(), getDescription(), getSuperior(), getRequiredAttributes(), getAllowedAttributes(), getOptionalAttributes(), getObjectClassType(), obsolete.isSelected(), getExtraProperties()); @@ -735,243 +755,19 @@ { HashSet<AttributeType> attrs = new HashSet<AttributeType>(); attrs.addAll(attributes.getSelectedListModel1().getData()); attrs.removeAll(inheritedRequiredAttributes); return attrs; } private Set<AttributeType> getAllowedAttributes() private Set<AttributeType> getOptionalAttributes() { HashSet<AttributeType> attrs = new HashSet<AttributeType>(); attrs.addAll(attributes.getSelectedListModel2().getData()); attrs.removeAll(inheritedOptionalAttributes); return attrs; } /** * The task in charge of creating the object class. * */ protected class NewObjectClassTask extends SchemaTask { private ObjectClass oc; private String ocName; private String ocDefinition; private String ocWithoutFileDefinition; /** * The constructor of the task. * @param info the control panel info. * @param dlg the progress dialog that shows the progress of the task. */ public NewObjectClassTask(ControlPanelInfo info, ProgressDialog dlg) { super(info, dlg); ocName = getObjectClassName(); ocDefinition = getSchemaElement().toString(); ObjectClass oc = getObjectClass(); oc.setExtraProperty(ServerConstants.SCHEMA_PROPERTY_FILENAME, (String)null); ocWithoutFileDefinition = oc.toString(); } /** * {@inheritDoc} */ public Type getType() { return Type.NEW_OBJECTCLASS; } /** * {@inheritDoc} */ protected CommonSchemaElements getSchemaElement() { if (oc == null) { oc = getObjectClass(); } return oc; } /** * {@inheritDoc} */ public Message getTaskDescription() { return INFO_CTRL_PANEL_NEW_OBJECTCLASS_TASK_DESCRIPTION.get(ocName); } /** * {@inheritDoc} */ protected String getSchemaFileAttributeName() { return "objectClasses"; } /** * {@inheritDoc} */ protected String getSchemaFileAttributeValue() { if (isServerRunning()) { return ocDefinition; } else { return ocWithoutFileDefinition; } } /** * {@inheritDoc} */ protected void updateSchema() throws OpenDsException { SwingUtilities.invokeLater(new Runnable() { /** * {@inheritDoc} */ public void run() { printEquivalentCommandToAdd(); getProgressDialog().appendProgressHtml( Utilities.getProgressWithPoints( INFO_CTRL_PANEL_CREATING_OBJECTCLASS_PROGRESS.get(ocName), ColorAndFontConstants.progressFont)); } }); if (isServerRunning()) { try { BasicAttribute attr = new BasicAttribute(getSchemaFileAttributeName()); attr.add(getSchemaFileAttributeValue()); ModificationItem mod = new ModificationItem(DirContext.ADD_ATTRIBUTE, attr); getInfo().getDirContext().modifyAttributes( ConfigConstants.DN_DEFAULT_SCHEMA_ROOT, new ModificationItem[] { mod }); } catch (NamingException ne) { throw new OnlineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(ne.toString()), ne); } } else { updateSchemaFile(); } notifyConfigurationElementCreated(oc); SwingUtilities.invokeLater(new Runnable() { /** * {@inheritDoc} */ public void run() { getProgressDialog().appendProgressHtml( Utilities.getProgressDone(ColorAndFontConstants.progressFont)); } }); } /** * Updates the contents of the schema file. * @throws OpenDsException if an error occurs updating the schema file. */ private void updateSchemaFile() throws OpenDsException { if (isSchemaFileDefined) { LDIFExportConfig exportConfig = new LDIFExportConfig(schemaFile, ExistingFileBehavior.OVERWRITE); LDIFReader reader = null; Entry schemaEntry = null; try { reader = new LDIFReader(new LDIFImportConfig(schemaFile)); schemaEntry = reader.readEntry(); Modification mod = new Modification(ModificationType.ADD, Attributes.create(getSchemaFileAttributeName().toLowerCase(), getSchemaFileAttributeValue())); schemaEntry.applyModification(mod); LDIFWriter writer = new LDIFWriter(exportConfig); writer.writeEntry(schemaEntry); exportConfig.getWriter().newLine(); } catch (Throwable t) { } finally { if (reader != null) { try { reader.close(); } catch (Throwable t) { } } if (exportConfig != null) { try { exportConfig.close(); } catch (Throwable t) { } } } } else { LDIFExportConfig exportConfig = new LDIFExportConfig(schemaFile, ExistingFileBehavior.FAIL); try { ArrayList<String> lines = getSchemaEntryLines(); for (String line : lines) { LDIFWriter.writeLDIFLine(new StringBuilder(line), exportConfig.getWriter(), exportConfig.getWrapColumn() > 1, exportConfig.getWrapColumn()); } exportConfig.getWriter().newLine(); } catch (Throwable t) { throw new OfflineUpdateException( ERR_CTRL_PANEL_ERROR_UPDATING_SCHEMA.get(t.toString()), t); } finally { if (exportConfig != null) { try { exportConfig.close(); } catch (Throwable t) { } } } } } } /** * A renderer for the attribute lists. The renderer basically marks the * inherited attributes with an asterisk. * opends/src/guitools/org/opends/guitools/controlpanel/ui/SchemaBrowserRightPanel.java
@@ -22,7 +22,7 @@ * CDDL HEADER END * * * Copyright 2008 Sun Microsystems, Inc. * Copyright 2008-2009 Sun Microsystems, Inc. */ package org.opends.guitools.controlpanel.ui; @@ -37,6 +37,8 @@ import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.event. ConfigurationElementCreatedListener; import org.opends.guitools.controlpanel.event.SchemaElementSelectionListener; import org.opends.guitools.controlpanel.util.Utilities; import org.opends.messages.Message; @@ -74,8 +76,9 @@ private final SchemaElementPanel[] panels = { standardObjectClassPanel, configurationObjectClassPanel, customObjectClassPanel, standardAttributePanel, configurationAttributePanel, customAttributePanel, matchingRulePanel, customObjectClassPanel, standardAttributePanel, configurationAttributePanel, customAttributePanel, matchingRulePanel, attributeSyntaxPanel }; @@ -145,6 +148,34 @@ } /** * Adds a configuration element created listener. * @param listener the listener. */ public void addConfigurationElementCreatedListener( ConfigurationElementCreatedListener listener) { super.addConfigurationElementCreatedListener(listener); for (SchemaElementPanel panel : panels) { panel.addConfigurationElementCreatedListener(listener); } } /** * Removes a configuration element created listener. * @param listener the listener. */ public void removeConfigurationElementCreatedListener( ConfigurationElementCreatedListener listener) { super.removeConfigurationElementCreatedListener(listener); for (SchemaElementPanel panel : panels) { panel.removeConfigurationElementCreatedListener(listener); } } /** * Updates the contents of the panel with the provided standard object class. * @param oc the object class. * @param schema the schema. @@ -242,7 +273,7 @@ * @param syntax the attribute syntax. * @param schema the schema. */ public void updateAttributeSyntax(AttributeSyntax syntax, Schema schema) public void updateAttributeSyntax(AttributeSyntax<?> syntax, Schema schema) { attributeSyntaxPanel.update(syntax, schema); schemaElementPanel = attributeSyntaxPanel; @@ -348,9 +379,9 @@ /** * Tells whether the user chose to save the changes in the panel, to not save * them or simply cancelled the selection in the tree. * them or simply canceled the selection in the tree. * @return the value telling whether the user chose to save the changes in the * panel, to not save them or simply cancelled the selection in the tree. * panel, to not save them or simply canceled the selection in the tree. */ public UnsavedChangesDialog.Result checkUnsavedChanges() { opends/src/guitools/org/opends/guitools/controlpanel/ui/StatusGenericPanel.java
@@ -47,6 +47,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -55,6 +56,8 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import javax.naming.NamingEnumeration; import javax.naming.directory.SearchControls; @@ -143,6 +146,9 @@ private static final String MAIN_PANEL = "mainPanel"; private static final String MESSAGE_PANEL = "messagePanel"; private static final Logger LOG = Logger.getLogger(StatusGenericPanel.class.getName()); /** * The error pane. */ @@ -538,7 +544,7 @@ public void addConfigurationElementCreatedListener( ConfigurationElementCreatedListener listener) { confListeners.add(listener); getConfigurationElementCreatedListeners().add(listener); } /** @@ -548,7 +554,7 @@ public void removeConfigurationElementCreatedListener( ConfigurationElementCreatedListener listener) { confListeners.remove(listener); getConfigurationElementCreatedListeners().remove(listener); } /** @@ -558,7 +564,8 @@ */ protected void notifyConfigurationElementCreated(Object configObject) { for (ConfigurationElementCreatedListener listener : confListeners) for (ConfigurationElementCreatedListener listener : getConfigurationElementCreatedListeners()) { listener.elementCreated( new ConfigurationElementCreatedEvent(this, configObject)); @@ -566,6 +573,16 @@ } /** * Returns the list of configuration listeners. * @return the list of configuration listeners. */ protected List<ConfigurationElementCreatedListener> getConfigurationElementCreatedListeners() { return confListeners; } /** * Notification that cancel was clicked, the panel is in charge * of doing whatever is required (close the dialog, etc.). * @@ -1404,6 +1421,20 @@ protected void updateComboBoxModel(final Collection<?> newElements, final DefaultComboBoxModel model) { updateComboBoxModel(newElements, model, null); } /** * Updates a combo box model with a number of items. * @param newElements the new items for the combo box model. * @param model the combo box model to be updated. * @param comparator the object that will be used to compare the objects in * the model. If <CODE>null</CODE>, the equals method will be used. */ protected void updateComboBoxModel(final Collection<?> newElements, final DefaultComboBoxModel model, final Comparator<Object> comparator) { SwingUtilities.invokeLater(new Runnable() { public void run() @@ -1414,7 +1445,15 @@ int i = 0; for (Object newElement : newElements) { changed = !newElement.equals(model.getElementAt(i)); if (comparator == null) { changed = !newElement.equals(model.getElementAt(i)); } else { changed = comparator.compare(newElement, model.getElementAt(i)) != 0; } if (changed) { break; @@ -1799,6 +1838,7 @@ if (t != null) { LOG.log(Level.WARNING, "Error occurred running task: "+t, t); if ((task.getReturnCode() != null) && (errorDetailCode != null)) { opends/src/guitools/org/opends/guitools/controlpanel/util/ControlPanelLog.java
@@ -61,7 +61,7 @@ for (String packageName : packages) { Logger logger = Logger.getLogger(packageName); logger.setUseParentHandlers(false); // disable logging to console //logger.setUseParentHandlers(false); // disable logging to console logger.addHandler(fileHandler); } Logger logger = Logger.getLogger(packages[0]); @@ -78,7 +78,7 @@ */ static public void initPackage(String packageName) throws IOException { Logger logger = Logger.getLogger(packageName); logger.setUseParentHandlers(false); // disable logging to console //logger.setUseParentHandlers(false); // disable logging to console logger.addHandler(fileHandler); logger.log(Level.INFO, getInitialLogRecord()); } opends/src/messages/messages/admin_tool.properties
@@ -1104,6 +1104,8 @@ INFO_CTRL_PANEL_DELETING_INDEX=Deleting index '%s' INFO_CTRL_PANEL_DELETING_VLV_INDEX=Deleting VLV index '%s' INFO_CTRL_PANEL_CONFIRMATION_DELETE_SCHEMA_ELEMENTS_MSG=Are you sure you want \ to delete the elements '%s' defined in the schema? INFO_CTRL_PANEL_DELETE_SCHEMA_ELEMENT_TASK_DESCRIPTION=Delete schema elements. INFO_CTRL_PANEL_DELETING_OBJECTCLASS=Deleting objectclass '%s' INFO_CTRL_PANEL_DELETING_ATTRIBUTE=Deleting attribute '%s' @@ -1113,11 +1115,16 @@ configuration. Details: %s MILD_ERR_CTRL_PANEL_ERROR_CHECKING_ENTRY=Error checking entry. Details: %s INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_SCHEMA_ELEMENT_OFFLINE=This operation \ is equivalent to removing the following attribute from the schema definition \ entry (cn=schema) in file '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_SCHEMA_ELEMENT_ONLINE=Equivalent \ command line to update the schema: INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_ATTRIBUTE_OFFLINE=Deleting attribute \ '%s' can also be done removing the following attribute from the schema \ definition entry (cn=schema) in file '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_OBJECTCLASS_OFFLINE=Deleting object \ class '%s' can also be done removing the following attribute from the schema \ definition entry (cn=schema) in file '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_ATTRIBUTE_ONLINE=Equivalent \ command line to delete attribute '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_DELETE_OBJECTCLASS_ONLINE=Equivalent \ command line to delete object class '%s': INFO_CTRL_PANEL_MODIFY_ENTRY_TASK_DESCRIPTION=Modify entry '%s'. INFO_CTRL_PANEL_RENAMING_ENTRY=Renaming entry '%s' to '%s' INFO_CTRL_PANEL_MODIFYING_ENTRY=Modifying entry '%s' @@ -1152,14 +1159,15 @@ INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_START_SERVER=Equivalent command line to \ start the server: INFO_CTRL_PANEL_SERVER_STOPPED=Server Stopped INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_SCHEMA_ELEMENT_OFFLINE=This operation is \ equivalent to adding the following attribute to the schema definition entry \ (cn=schema) in file '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_SCHEMA_ENTRY_OFFLINE=This operation is \ equivalent to adding the following entry to the file '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_SCHEMA_ELEMENT_ONLINE=Equivalent command \ line to update the schema: INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_SCHEMA_ENTRY_OFFLINE=Adding the schema \ elements '%s' can also be done adding the following entry to the file '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_SCHEMA_ELEMENT_OFFLINE=Adding the schema \ elements '%s' can also be done adding the following attributes to the \ schema definition entry (cn=schema) in file '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_ATTRIBUTE_ONLINE=Equivalent \ command line to add attribute '%s': INFO_CTRL_PANEL_EQUIVALENT_CMD_TO_ADD_OBJECTCLASS_ONLINE=Equivalent \ command line to add object class '%s': MILD_ERR_CTRL_PANEL_BACKEND_NOT_FOUND_SUMMARY=Could not find backend MILD_ERR_CTRL_PANEL_BACKEND_NOT_FOUND_DETAILS=The backend '%s' could not be \ found. Check main panel for more information. @@ -1608,7 +1616,7 @@ INFO_CTRL_PANEL_SCHEMA_ELEMENT_NAME=Name INFO_CTRL_PANEL_SCHEMA_ELEMENT_TYPE=Type INFO_CTRL_PANEL_PARENT_CLASS=Parent Class INFO_CTRL_PANEL_PARENT_CLASS=Superior Class INFO_CTRL_PANEL_CHILD_CLASS=Child Class INFO_CTRL_PANEL_REQUIRED_ATTRIBUTES=Required Attributes INFO_CTRL_PANEL_OPTIONAL_ATTRIBUTES=Optional Attributes @@ -1618,25 +1626,29 @@ INFO_CTRL_PANEL_CATEGORY_ITEM_SELECTED=Category Item Selected INFO_CTRL_PANEL_MULTIPLE_SCHEMA_ITEMS_SELECTED=Multiple Schema Items Selected MILD_ERR_CANNOT_DELETE_PARENT_OBJECTCLASS=ObjectClass '%s' is superior of the \ following classes: %s. You must redefine these classes so that they do not \ inherit from objectClass '%s' before deleting it. MILD_ERR_CANNOT_DELETE_PARENT_ATTRIBUTE=Attribute '%s' is superior of the \ following attributes: %s. You must redefine these attributes so that they do \ not inherit from attribute '%s' before deleting it. MILD_ERR_CANNOT_DELETE_ATTRIBUTE_WITH_DEPENDENCIES=Attribute '%s' is optional \ or required by the following objectClasses: %s. You must redefine these \ classes so that they do not depend on attribute '%s' before deleting it. MILD_ERR_CANNOT_MODIFY_PARENT_ATTRIBUTE=Attribute '%s' is superior of the \ following attributes: %s. You must redefine these attributes so that they do \ not inherit from attribute '%s' before modifying it. INFO_OBJECTCLASS_IS_SUPERIOR=Object class '%s' is superior of the \ following object classes: %s. If you continue, these object classes will be \ updated with a new superior. INFO_OBJECTCLASSES_ARE_SUPERIOR=The selected object classes are superior of \ the following object classes: %s. If you continue, these object classes will \ be updated with a new superior. INFO_ATTRIBUTE_IS_SUPERIOR=Attribute '%s' is superior of the \ following attributes: %s. If you continue, these attributes will be updated \ with a new superior. INFO_ATTRIBUTES_ARE_SUPERIOR=The selected attributes are superior of the \ following attributes: %s. If you continue, these attributes will be updated \ with a new superior. INFO_ATTRIBUTE_WITH_DEPENDENCIES=Attribute '%s' is optional or required by the \ following object classes: %s. If you continue, the definition of the object \ classes will be modified. INFO_ATTRIBUTES_WITH_DEPENDENCIES=The selected attributes are optional or \ required by the following object classes: %s. If you continue, the \ definition of the object classes will be modified. INFO_CTRL_PANEL_MANAGE_SCHEMA_TITLE=Manage Schema INFO_CTRL_PANEL_DELETE_OBJECTCLASSES_TITLE=Delete Objectclasses INFO_CTRL_PANEL_DELETE_ATTRIBUTES_TITLE=Delete Attributes INFO_CTRL_PANEL_DELETE_OBJECTCLASSES_AND_ATTRIBUTES_TITLE=Delete Objectclasses \ and Attributes INFO_CTRL_PANEL_CONFIRMATION_DELETE_SCHEMA_ELEMENTS_DETAILS=Are you sure you \ want to delete the elements '%s' defined in the schema? INFO_CTRL_PANEL_DELETING_SCHEMA_ELEMENTS_SUMMARY=Deleting... INFO_CTRL_PANEL_DELETING_SCHEMA_ELEMENTS_COMPLETE=Schema Definitions Deleted INFO_CTRL_PANEL_DELETING_SCHEMA_ELEMENTS_SUCCESSFUL=The schema elements '%s' \ @@ -1653,6 +1665,7 @@ INFO_CTRL_PANEL_DELETE_ATTRIBUTE_BUTTON=Delete Attribute... INFO_CTRL_PANEL_DELETE_ATTRIBUTE_TITLE=Delete Attribute INFO_CTRL_PANEL_MODIFY_ATTRIBUTE_TITLE=Modify Attribute INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_ATTRIBUTE_DELETE=The server is \ running. You must provide authentication to delete the attribute. INFO_CTRL_PANEL_CONFIRMATION_DELETE_ATTRIBUTE_DETAILS=Are you sure you want to \ @@ -1663,13 +1676,30 @@ successfully deleted MILD_ERR_CTRL_PANEL_DELETING_ATTRIBUTE_ERROR_SUMMARY=Error deleting \ attribute MILD_ERR_CTRL_PANEL_DELETING_ATTRIBUTE_ERROR_DETAILS=An error occurred deleting \ attribute '%s'. Check details for more information. MILD_ERR_CTRL_PANEL_DELETING_ATTRIBUTE_ERROR_DETAILS=An error occurred \ deleting attribute '%s'. Check details for more information. INFO_CTRL_PANEL_MODIFYING_ATTRIBUTE_SUMMARY=Modifying attribute '%s'... INFO_CTRL_PANEL_MODIFYING_ATTRIBUTE_COMPLETE=Attribute Modified INFO_CTRL_PANEL_MODIFYING_ATTRIBUTE_SUCCESSFUL=The attribute '%s' was \ successfully modified MILD_ERR_CTRL_PANEL_MODIFYING_ATTRIBUTE_ERROR_SUMMARY=Error modifying \ attribute MILD_ERR_CTRL_PANEL_MODIFYING_ATTRIBUTE_ERROR_DETAILS=An error occurred \ modifying attribute '%s'. Check details for more information. INFO_CTRL_PANEL_MODIFYING_OBJECTCLASS_SUMMARY=Modifying object class '%s'... INFO_CTRL_PANEL_MODIFYING_OBJECTCLASS_COMPLETE=Object Class Modified INFO_CTRL_PANEL_MODIFYING_OBJECTCLASS_SUCCESSFUL=The object class '%s' was \ successfully modified MILD_ERR_CTRL_PANEL_MODIFYING_OBJECTCLASS_ERROR_SUMMARY=Error modifying \ object class MILD_ERR_CTRL_PANEL_MODIFYING_OBJECTCLASS_ERROR_DETAILS=An error occurred \ modifying object class '%s'. Check details for more information. INFO_CTRL_PANEL_DELETE_OBJECTCLASS_BUTTON=Delete Object Class... INFO_CTRL_PANEL_DELETE_OBJECTCLASS_TITLE=Delete Object Class INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_OBJECTCLASS_DELETE=The server is \ running. You must provide authentication to delete the object class. INFO_CTRL_PANEL_AUTHENTICATION_REQUIRED_FOR_OBJECTCLASS_EDIT=The server is \ running. You must provide authentication to edit the object class. INFO_CTRL_PANEL_CONFIRMATION_DELETE_OBJECTCLASS_DETAILS=Are you sure you want \ to delete the object class '%s' defined in the schema? INFO_CTRL_PANEL_DELETING_OBJECTCLASS_SUMMARY=Deleting object class '%s'... @@ -2073,7 +2103,19 @@ MILD_ERR_CTRL_PANEL_EMPTY_ALIAS=You have provided an empty alias. MILD_ERR_CTRL_PANEL_ALIAS_ALREADY_IN_USE=The provided alias '%s' \ already exists in the schema (defined as %s). MILD_ERR_NON_MODIFIABLE_CANNOT_BE_USER_APPLICATIONS=Non Modifiable attributes \ must have an operational usage. MILD_ERR_CTRL_PANEL_ATTRIBUTE_CANNOT_BE_ITS_SUPERIOR=An attribute cannot be \ its own superior. MILD_ERR_CTRL_PANEL_OBJECTCLASS_CANNOT_BE_ITS_SUPERIOR=An object class cannot \ be its own superior. MILD_ERR_CTRL_PANEL_OBJECTCLASS_IS_SUPERIOR_OF_SUPERIOR=The object class is \ superior (directly or indirectly) of '%s'. MILD_ERR_CTRL_PANEL_ATTRIBUTE_IS_SUPERIOR_OF_SUPERIOR=The attribute is \ superior (directly or indirectly) of '%s'. INFO_CTRL_PANEL_CREATING_ATTRIBUTE_SUMMARY=Creating attribute '%s'... INFO_CTRL_PANEL_UPDATING_SCHEMA_FILE_PROGRESS=Adding schema elements to schema \ file '%s'... INFO_CTRL_PANEL_CREATING_ATTRIBUTE_COMPLETE=Attribute created in schema INFO_CTRL_PANEL_CREATING_ATTRIBUTE_SUCCESSFUL=The attribute '%s' was \ successfully created. @@ -2104,9 +2146,28 @@ INFO_CTRL_PANEL_DEFAULT_DEFINED_IN_SYNTAX=- Default defined in syntax (%s) - INFO_CTRL_PANEL_NEW_ATTRIBUTE_TASK_DESCRIPTION=Create new attribute '%s' in \ schema. INFO_CTRL_PANEL_NEW_ATTRIBUTES_TASK_DESCRIPTION=Creating new attributes '%s' \ in schema. INFO_CTRL_PANEL_NEW_OBJECTCLASSES_TASK_DESCRIPTION=Creating new object classes \ '%s' in schema. INFO_CTRL_PANEL_NEW_SCHEMA_ELEMENTS_TASK_DESCRIPTION=Creating attributes '%s' \ and object classes '%s' in schema. INFO_CTRL_PANEL_EXPLANATION_TO_MODIFY_ATTRIBUTE=To modify attribute '%s' it \ will be deleted and then recreated. The same applies to all the schema \ elements that have references to it. INFO_CTRL_PANEL_EXPLANATION_TO_MODIFY_OBJECTCLASS=To modify object class '%s' \ it will be deleted and then recreated. The same applies to all the schema \ elements that have references to it. INFO_CTRL_PANEL_EXPLANATION_TO_DELETE_REFERENCED_ELEMENTS=To modify \ references to the deleted attributes and object classes the schema elements \ that refer to them must be deleted and then added again. INFO_CTRL_PANEL_CREATING_ATTRIBUTE_PROGRESS=Creating attribute '%s' INFO_CTRL_PANEL_MODIFY_ATTRIBUTE_TASK_DESCRIPTION=Modify attribute '%s' in \ schema INFO_CTRL_PANEL_MODIFY_OBJECTCLASS_TASK_DESCRIPTION=Modify object class '%s' \ in schema INFO_CTRL_PANEL_ATTRIBUTE_NAME_LABEL=Name: INFO_CTRL_PANEL_ATTRIBUTE_PARENT_LABEL=Parent: INFO_CTRL_PANEL_ATTRIBUTE_PARENT_LABEL=Superior: INFO_CTRL_PANEL_ATTRIBUTE_OID_LABEL=OID: INFO_CTRL_PANEL_ATTRIBUTE_ALIASES_LABEL=Aliases: INFO_CTRL_PANEL_ATTRIBUTE_ORIGIN_LABEL=Origin: @@ -2274,7 +2335,7 @@ in schema. INFO_CTRL_PANEL_CREATING_OBJECTCLASS_PROGRESS=Creating object class '%s' INFO_CTRL_PANEL_OBJECTCLASS_NAME_LABEL=Name: INFO_CTRL_PANEL_OBJECTCLASS_PARENT_LABEL=Parent: INFO_CTRL_PANEL_OBJECTCLASS_PARENT_LABEL=Superior: INFO_CTRL_PANEL_OBJECTCLASS_OID_LABEL=OID: INFO_CTRL_PANEL_OBJECTCLASS_ALIASES_LABEL=Aliases: INFO_CTRL_PANEL_OBJECTCLASS_ORIGIN_LABEL=Origin: