From eed4e59d6f423c3a35af3cb91b329ec5bdf72478 Mon Sep 17 00:00:00 2001 From: Mattias Arthursson Date: Wed, 18 Jun 2008 13:29:16 +0000 Subject: [PATCH] Fix for LDAP-96 - added handing of updated multivalue attributes in DirContextAdapter#collectAttributes(). --- .../ldap/core/DirContextAdapter.java | 2340 ++++++++--------- .../ldap/core/DirContextAdapterTest.java | 1934 +++++++------- 2 files changed, 2132 insertions(+), 2142 deletions(-) diff --git a/mvn-build/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java b/mvn-build/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java index 3bd4b8ae..04359b2d 100644 --- a/mvn-build/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java +++ b/mvn-build/core/src/main/java/org/springframework/ldap/core/DirContextAdapter.java @@ -76,1179 +76,1171 @@ import org.springframework.ldap.support.LdapUtils; */ public class DirContextAdapter implements DirContextOperations { - private static final boolean ORDER_DOESNT_MATTER = false; - - private static Log log = LogFactory.getLog(DirContextAdapter.class); - - private final Attributes originalAttrs; - - private DistinguishedName dn; - - private DistinguishedName base; - - private boolean updateMode = false; - - private Attributes updatedAttrs; - - /** - * Default constructor. - */ - public DirContextAdapter() { - this(null, null, null); - } - - /** - * Create a new adapter from the supplied dn. - * - * @param dn - * the dn. - */ - public DirContextAdapter(Name dn) { - this(null, dn); - } - - /** - * Create a new adapter from the supplied attributes and dn. - * - * @param attrs - * the attributes. - * @param dn - * the dn. - */ - public DirContextAdapter(Attributes attrs, Name dn) { - this(attrs, dn, null); - } - - /** - * Create a new adapter from the supplied attributes, dn, and base. - * - * @param attrs - * the attributes. - * @param dn - * the dn. - * @param base - * the base name. - */ - public DirContextAdapter(Attributes attrs, Name dn, Name base) { - if (attrs != null) { - this.originalAttrs = attrs; - } else { - this.originalAttrs = new BasicAttributes(true); - } - if (dn != null) { - this.dn = new DistinguishedName(dn.toString()); - } else { - this.dn = new DistinguishedName(); - } - if (base != null) { - this.base = new DistinguishedName(base.toString()); - } else { - this.base = new DistinguishedName(); - } - } - - /** - * Constructor for cloning an existing adapter. - * - * @param master - * The adapter to be copied. - */ - protected DirContextAdapter(DirContextAdapter master) { - this.originalAttrs = (Attributes) master.originalAttrs.clone(); - this.dn = master.dn; - this.updatedAttrs = (Attributes) master.updatedAttrs.clone(); - this.updateMode = master.updateMode; - } - - /** - * Sets the update mode. The update mode should be false for - * a new entry and true for an existing entry that is being - * updated. - * - * @param mode - * Update mode. - */ - public void setUpdateMode(boolean mode) { - this.updateMode = mode; - if (updateMode) { - updatedAttrs = new BasicAttributes(true); - } - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#isUpdateMode() - */ - public boolean isUpdateMode() { - return updateMode; - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#getNamesOfModifiedAttributes() - */ - public String[] getNamesOfModifiedAttributes() { - - List tmpList = new ArrayList(); - - NamingEnumeration attributesEnumeration; - if (isUpdateMode()) { - attributesEnumeration = updatedAttrs.getAll(); - } else { - attributesEnumeration = originalAttrs.getAll(); - } - - try { - while (attributesEnumeration.hasMore()) { - Attribute oneAttribute = (Attribute) attributesEnumeration - .next(); - tmpList.add(oneAttribute.getID()); - } - } catch (NamingException e) { - throw LdapUtils.convertLdapException(e); - } finally { - closeNamingEnumeration(attributesEnumeration); - } - - return (String[]) tmpList.toArray(new String[0]); - } - - private void closeNamingEnumeration(NamingEnumeration enumeration) { - try { - if (enumeration != null) { - enumeration.close(); - } - } catch (NamingException e) { - // Never mind this - } - } - - /* - * @see org.springframework.ldap.support.AttributeModificationsAware#getModificationItems() - */ - public ModificationItem[] getModificationItems() { - if (!updateMode) { - return new ModificationItem[0]; - } - - List tmpList = new LinkedList(); - NamingEnumeration attributesEnumeration = null; - try { - attributesEnumeration = updatedAttrs.getAll(); - - // find attributes that have been changed, removed or added - while (attributesEnumeration.hasMore()) { - Attribute oneAttr = (Attribute) attributesEnumeration.next(); - - collectModifications(oneAttr, tmpList); - } - } catch (NamingException e) { - throw LdapUtils.convertLdapException(e); - } finally { - closeNamingEnumeration(attributesEnumeration); - } - - if (log.isDebugEnabled()) { - log.debug("Number of modifications:" + tmpList.size()); - } - - return (ModificationItem[]) tmpList - .toArray(new ModificationItem[tmpList.size()]); - } - - /** - * Collect all modifications for the changed attribute. If no changes have - * been made, return immediately. If modifications have been made, and the - * original size as well as the updated size of the attribute is 1, replace - * the attribute. If the size of the updated attribute is 0, remove the - * attribute. Otherwise, the attribute is a multi-value attribute, in which - * case all modifications to the original value (removals and additions) - * will be collected individually. - * - * @param changedAttr - * the value of the changed attribute. - * @param modificationList - * the list in which to add the modifications. - * @throws NamingException - * if thrown by called Attribute methods. - */ - private void collectModifications(Attribute changedAttr, - List modificationList) throws NamingException { - Attribute currentAttribute = originalAttrs.get(changedAttr.getID()); - - if (changedAttr.equals(currentAttribute)) { - // No changes - return; - } else if (currentAttribute != null && currentAttribute.size() == 1 - && changedAttr.size() == 1) { - // Replace single-vale attribute. - modificationList.add(new ModificationItem( - DirContext.REPLACE_ATTRIBUTE, changedAttr)); - } else if (changedAttr.size() == 0 && currentAttribute != null) { - // Attribute has been removed. - modificationList.add(new ModificationItem( - DirContext.REMOVE_ATTRIBUTE, changedAttr)); - } else if ((currentAttribute == null || currentAttribute.size() == 0) - && changedAttr.size() > 0) { - // Attribute has been added. - modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE, - changedAttr)); - } else if (changedAttr.size() > 0) { - // Change of multivalue Attribute. Collect additions and removals - // individually. - List myModifications = new LinkedList(); - collectModifications(currentAttribute, changedAttr, myModifications); - - if (myModifications.isEmpty()) { - // This means that the attributes are not equal, but the - // actual values are the same - thus the order must have - // changed. This should result in a REPLACE_ATTRIBUTE operation. - myModifications.add(new ModificationItem( - DirContext.REPLACE_ATTRIBUTE, changedAttr)); - } - - modificationList.addAll(myModifications); - } - } - - private void collectModifications(Attribute originalAttr, - Attribute changedAttr, List modificationList) - throws NamingException { - - Attribute originalClone = (Attribute) originalAttr.clone(); - Attribute addedValuesAttribute = new BasicAttribute(originalAttr - .getID()); - - for (int i = 0; i < changedAttr.size(); i++) { - Object attributeValue = changedAttr.get(i); - if (!originalClone.remove(attributeValue)) { - addedValuesAttribute.add(attributeValue); - } - } - - // We have now traversed and removed all values from the original that - // were also present in the new values. The remaining values in the - // original must be the ones that were removed. - if (originalClone.size() > 0) { - modificationList.add(new ModificationItem( - DirContext.REMOVE_ATTRIBUTE, originalClone)); - } - - if (addedValuesAttribute.size() > 0) { - modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE, - addedValuesAttribute)); - } - } - - /** - * returns true if the attribute is empty. It is empty if a == null, size == - * 0 or get() == null or an exception if thrown when accessing the get - * method - */ - private boolean isEmptyAttribute(Attribute a) { - try { - return (a == null || a.size() == 0 || a.get() == null); - } catch (NamingException e) { - return true; - } - } - - /** - * Compare the existing attribute name with the values on the - * array values. The order of the array must be the same - * order as the existing multivalued attribute. - *

- * Also handles the case where the values have been reset to the original - * values after a previous change. For example, changing - * [a,b,c] to [a,b] and then back to - * [a,b,c] again must result in this method returning - * true so the first change can be overwritten with the - * latest change. - * - * @param name - * Name of the original multi-valued attribute. - * @param values - * Array of values to check if they have been changed. - * @return true if there has been a change compared to original attribute, - * or a previous update - */ - private boolean isChanged(String name, Object[] values, boolean orderMatters) { - - Attribute orig = originalAttrs.get(name); - Attribute prev = updatedAttrs.get(name); - - // values == null and values.length == 0 is treated the same way - boolean emptyNewValue = (values == null || values.length == 0); - - // Setting to empty --------------------- - if (emptyNewValue) { - // FALSE: if both are null, it is not changed (both don't exist) - // TRUE: if new value is null and old value exists (should be - // removed) - // TODO Also include prev in null check - // TODO Also check if there is a single null element - if (orig != null) { - return true; - } - return false; - } - - // NOT setting to empty ------------------- - - // TRUE if existing value is null - if (orig == null) { - return true; - } - - // TRUE if different length compared to original attributes - if (orig.size() != values.length) { - return true; - } - - // TRUE if different length compared to previously updated attributes - if (prev != null && prev.size() != values.length) { - return true; - } - - // Check contents of arrays - - // Order DOES matter, e.g. first names - try { - for (int i = 0; i < orig.size(); i++) { - Object obj = orig.get(i); - // TRUE if one value is not equal - if (!(obj instanceof String)) { - return true; - } - if (orderMatters) { - // check only the string with same index - if (!values[i].equals(obj)) { - return true; - } - } else { - // check all strings - if (!ArrayUtils.contains(values, obj)) { - return true; - } - } - } - - } catch (NamingException e) { - // TRUE if we can't access the value - return true; - } - - if (prev != null) { - // Also check against updatedAttrs, since there might have been - // a previous update - try { - for (int i = 0; i < prev.size(); i++) { - Object obj = prev.get(i); - // TRUE if one value is not equal - if (!(obj instanceof String)) { - return true; - } - if (orderMatters) { - // check only the string with same index - if (!values[i].equals(obj)) { - return true; - } - } else { - // check all strings - if (!ArrayUtils.contains(values, obj)) { - return true; - } - } - } - - } catch (NamingException e) { - // TRUE if we can't access the value - return true; - } - } - // FALSE since we have compared all values - return false; - } - - /** - * Checks if an entry has a specific attribute. - * - * This method simply calls exists(String) with the attribute name. - * - * @param attr - * the attribute to check. - * @return true if attribute exists in entry. - */ - protected final boolean exists(Attribute attr) { - return exists(attr.getID()); - } - - /** - * Checks if the attribute exists in this entry, either it was read or it - * has been added and update() has been called. - * - * @param attrId - * id of the attribute to check. - * @return true if the attribute exists in the entry. - */ - protected final boolean exists(String attrId) { - return originalAttrs.get(attrId) != null; - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#getStringAttribute(java.lang.String) - */ - public String getStringAttribute(String name) { - return (String) getObjectAttribute(name); - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#getObjectAttribute(java.lang.String) - */ - public Object getObjectAttribute(String name) { - Attribute oneAttr = originalAttrs.get(name); - if (oneAttr == null) { - return null; - } - try { - return oneAttr.get(); - } catch (NamingException e) { - throw LdapUtils.convertLdapException(e); - } - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#setAttributeValue(java.lang.String, - * java.lang.Object) - */ - public void setAttributeValue(String name, Object value) { - // new entry - if (!updateMode && value != null) { - originalAttrs.put(name, value); - } - - // updating entry - if (updateMode) { - BasicAttribute attribute = new BasicAttribute(name); - if (value != null) { - attribute.add(value); - } - updatedAttrs.put(attribute); - } - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.DirContextOperations#addAttributeValue(java.lang.String, - * java.lang.Object) - */ - public void addAttributeValue(String name, Object value) { - if (!updateMode && value != null) { - Attribute attr = originalAttrs.get(name); - if (attr == null) { - originalAttrs.put(name, value); - } else { - attr.add(value); - } - } else if (updateMode) { - Attribute attr = updatedAttrs.get(name); - if (attr == null) { - if (originalAttrs.get(name) == null) { - // No match in the original attributes - - // add a new Attribute to updatedAttrs - updatedAttrs.put(name, value); - } else { - // The attribute exists in the original attributes - clone - // that and add the new entry to it - attr = (Attribute) originalAttrs.get(name).clone(); - attr.add(value); - updatedAttrs.put(attr); - } - } else { - attr.add(value); - } - } - - // Null values will not be added - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.core.DirContextOperations#removeAttributeValue(java.lang.String, - * java.lang.Object) - */ - public void removeAttributeValue(String name, Object value) { - if (!updateMode && value != null) { - Attribute attr = originalAttrs.get(name); - if (attr != null) { - attr.remove(value); - if (attr.size() == 0) { - originalAttrs.remove(name); - } - } - } else if (updateMode) { - Attribute attr = updatedAttrs.get(name); - if (attr == null) { - if (originalAttrs.get(name) != null) { - attr = (Attribute) originalAttrs.get(name).clone(); - attr.remove(value); - updatedAttrs.put(attr); - } - } else { - attr.remove(value); - } - } - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#setAttributeValues(java.lang.String, - * java.lang.Object[]) - */ - public void setAttributeValues(String name, Object[] values) { - setAttributeValues(name, values, ORDER_DOESNT_MATTER); - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#setAttributeValues(java.lang.String, - * java.lang.Object[], boolean) - */ - public void setAttributeValues(String name, Object[] values, - boolean orderMatters) { - Attribute a = new BasicAttribute(name, orderMatters); - - for (int i = 0; values != null && i < values.length; i++) { - a.add(values[i]); - } - - // only change the original attribute if not in update mode - if (!updateMode && values != null && values.length > 0) { - // don't save empty arrays - originalAttrs.put(a); - } - - // possible to set an already existing attribute to an empty array - if (updateMode && isChanged(name, values, orderMatters)) { - updatedAttrs.put(a); - } - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#update() - */ - public void update() { - NamingEnumeration attributesEnumeration = null; - - try { - attributesEnumeration = updatedAttrs.getAll(); - - // find what to update - while (attributesEnumeration.hasMore()) { - Attribute a = (Attribute) attributesEnumeration.next(); - - // if it does not exist it should be added - if (isEmptyAttribute(a)) { - originalAttrs.remove(a.getID()); - } else { - // Otherwise it should be set. - originalAttrs.put(a); - } - } - } catch (NamingException e) { - throw LdapUtils.convertLdapException(e); - } finally { - closeNamingEnumeration(attributesEnumeration); - } - - // Reset the attributes to be updated - updatedAttrs = new BasicAttributes(true); - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#getStringAttributes(java.lang.String) - */ - public String[] getStringAttributes(String name) { - String[] attributes; - - Attribute attribute = originalAttrs.get(name); - if (attribute != null && attribute.size() > 0) { - attributes = new String[attribute.size()]; - for (int i = 0; i < attribute.size(); i++) { - try { - attributes[i] = (String) attribute.get(i); - } catch (NamingException e) { - throw LdapUtils.convertLdapException(e); - } - } - } else { - return null; - } - - return attributes; - } - - /* - * @see org.springframework.ldap.support.DirContextOperations#getAttributeSortedStringSet(java.lang.String) - */ - public SortedSet getAttributeSortedStringSet(String name) { - TreeSet attrSet = new TreeSet(); - - Attribute attribute = originalAttrs.get(name); - if (attribute != null) { - for (int i = 0; i < attribute.size(); i++) { - try { - attrSet.add(attribute.get(i)); - } catch (NamingException e) { - throw LdapUtils.convertLdapException(e); - } - } - } else { - return null; - } - - return attrSet; - } - - /** - * Set the supplied attribute. - * - * @param attribute - * the attribute to set. - */ - public void setAttribute(Attribute attribute) { - if (!updateMode) { - originalAttrs.put(attribute); - } else { - updatedAttrs.put(attribute); - } - } - - /** - * Get all attributes. - * - * @return all attributes. - */ - public Attributes getAttributes() { - return originalAttrs; - } - - /** - * @see javax.naming.directory.DirContext#getAttributes(Name) - */ - public Attributes getAttributes(Name name) throws NamingException { - return getAttributes(name.toString()); - } - - /** - * @see javax.naming.directory.DirContext#getAttributes(String) - */ - public Attributes getAttributes(String name) throws NamingException { - if (!StringUtils.isEmpty(name)) { - throw new NameNotFoundException(); - } - return (Attributes) originalAttrs.clone(); - } - - /** - * @see javax.naming.directory.DirContext#getAttributes(Name, String[]) - */ - public Attributes getAttributes(Name name, String[] attrIds) - throws NamingException { - return getAttributes(name.toString(), attrIds); - } - - /** - * @see javax.naming.directory.DirContext#getAttributes(String, String[]) - */ - public Attributes getAttributes(String name, String[] attrIds) - throws NamingException { - if (!StringUtils.isEmpty(name)) { - throw new NameNotFoundException(); - } - - Attributes a = new BasicAttributes(true); - Attribute target; - for (int i = 0; i < attrIds.length; i++) { - target = originalAttrs.get(attrIds[i]); - if (target != null) { - a.put(target); - } - } - - return a; - } - - /** - * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, - * int, javax.naming.directory.Attributes) - */ - public void modifyAttributes(Name name, int modOp, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#modifyAttributes(String, int, - * Attributes) - */ - public void modifyAttributes(String name, int modOp, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#modifyAttributes(Name, - * ModificationItem[]) - */ - public void modifyAttributes(Name name, ModificationItem[] mods) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#modifyAttributes(String, - * ModificationItem[]) - */ - public void modifyAttributes(String name, ModificationItem[] mods) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#bind(Name, Object, Attributes) - */ - public void bind(Name name, Object obj, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#bind(String, Object, Attributes) - */ - public void bind(String name, Object obj, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#rebind(Name, Object, Attributes) - */ - public void rebind(Name name, Object obj, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#rebind(String, Object, Attributes) - */ - public void rebind(String name, Object obj, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#createSubcontext(Name, Attributes) - */ - public DirContext createSubcontext(Name name, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#createSubcontext(String, - * Attributes) - */ - public DirContext createSubcontext(String name, Attributes attrs) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#getSchema(Name) - */ - public DirContext getSchema(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#getSchema(String) - */ - public DirContext getSchema(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#getSchemaClassDefinition(Name) - */ - public DirContext getSchemaClassDefinition(Name name) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#getSchemaClassDefinition(String) - */ - public DirContext getSchemaClassDefinition(String name) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(Name, Attributes, String[]) - */ - public NamingEnumeration search(Name name, Attributes matchingAttributes, - String[] attributesToReturn) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(String, Attributes, - * String[]) - */ - public NamingEnumeration search(String name, Attributes matchingAttributes, - String[] attributesToReturn) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(Name, Attributes) - */ - public NamingEnumeration search(Name name, Attributes matchingAttributes) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(String, Attributes) - */ - public NamingEnumeration search(String name, Attributes matchingAttributes) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(Name, String, - * SearchControls) - */ - public NamingEnumeration search(Name name, String filter, - SearchControls cons) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(String, String, - * SearchControls) - */ - public NamingEnumeration search(String name, String filter, - SearchControls cons) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(Name, String, Object[], - * SearchControls) - */ - public NamingEnumeration search(Name name, String filterExpr, - Object[] filterArgs, SearchControls cons) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.directory.DirContext#search(String, String, Object[], - * SearchControls) - */ - public NamingEnumeration search(String name, String filterExpr, - Object[] filterArgs, SearchControls cons) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#lookup(Name) - */ - public Object lookup(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#lookup(String) - */ - public Object lookup(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#bind(Name, Object) - */ - public void bind(Name name, Object obj) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#bind(String, Object) - */ - public void bind(String name, Object obj) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#rebind(Name, Object) - */ - public void rebind(Name name, Object obj) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#rebind(String, Object) - */ - public void rebind(String name, Object obj) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#unbind(Name) - */ - public void unbind(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#unbind(String) - */ - public void unbind(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#rename(Name, Name) - */ - public void rename(Name oldName, Name newName) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#rename(String, String) - */ - public void rename(String oldName, String newName) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#list(Name) - */ - public NamingEnumeration list(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#list(String) - */ - public NamingEnumeration list(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#listBindings(Name) - */ - public NamingEnumeration listBindings(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#listBindings(String) - */ - public NamingEnumeration listBindings(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#destroySubcontext(Name) - */ - public void destroySubcontext(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#destroySubcontext(String) - */ - public void destroySubcontext(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#createSubcontext(Name) - */ - public Context createSubcontext(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#createSubcontext(String) - */ - public Context createSubcontext(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#lookupLink(Name) - */ - public Object lookupLink(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#lookupLink(String) - */ - public Object lookupLink(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#getNameParser(Name) - */ - public NameParser getNameParser(Name name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#getNameParser(String) - */ - public NameParser getNameParser(String name) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#composeName(Name, Name) - */ - public Name composeName(Name name, Name prefix) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#composeName(String, String) - */ - public String composeName(String name, String prefix) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#addToEnvironment(String, Object) - */ - public Object addToEnvironment(String propName, Object propVal) - throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#removeFromEnvironment(String) - */ - public Object removeFromEnvironment(String propName) throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#getEnvironment() - */ - public Hashtable getEnvironment() throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#close() - */ - public void close() throws NamingException { - throw new UnsupportedOperationException("Not implemented."); - } - - /** - * @see javax.naming.Context#getNameInNamespace() - */ - public String getNameInNamespace() { - DistinguishedName result = new DistinguishedName(dn); - result.prepend(base); - return result.toString(); - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.support.DirContextOperations#getDn() - */ - public Name getDn() { - return dn; - } - - /* - * (non-Javadoc) - * - * @see org.springframework.ldap.support.DirContextOperations#setDn(javax.naming.Name) - */ - public final void setDn(Name dn) { - if (!updateMode) { - this.dn = new DistinguishedName(dn.toString()); - } - } - - /** - * @see java.lang.Object#equals(java.lang.Object) - */ - public boolean equals(Object obj) { - // A subclass with identical values should NOT be considered equal. - // EqualsBuilder in commons-lang cannot handle subclasses correctly. - if (obj == null || obj.getClass() != this.getClass()) { - return false; - } - return EqualsBuilder.reflectionEquals(this, obj); - } - - /** - * @see Object#hashCode() - */ - public int hashCode() { - return HashCodeBuilder.reflectionHashCode(this); - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - StringBuffer buf = new StringBuffer(); - buf.append(getClass().getName()); - buf.append(":"); - if (dn != null) { - buf.append(" dn=" + dn); - } - buf.append(" {"); - - try { - for (NamingEnumeration i = originalAttrs.getAll(); i.hasMore();) { - Attribute attribute = (Attribute) i.next(); - if (attribute.size() == 1) { - buf.append(attribute.getID()); - buf.append('='); - buf.append(attribute.get()); - } else { - for (int j = 0; j < attribute.size(); j++) { - if (j > 0) { - buf.append(", "); - } - buf.append(attribute.getID()); - buf.append('['); - buf.append(j); - buf.append("]="); - buf.append(attribute.get(j)); - } - } - - if (i.hasMore()) { - buf.append(", "); - } - } - } catch (NamingException e) { - log.warn("Error in toString()"); - } - buf.append('}'); - - return buf.toString(); - } + private static final boolean ORDER_DOESNT_MATTER = false; + + private static Log log = LogFactory.getLog(DirContextAdapter.class); + + private final Attributes originalAttrs; + + private DistinguishedName dn; + + private DistinguishedName base; + + private boolean updateMode = false; + + private Attributes updatedAttrs; + + /** + * Default constructor. + */ + public DirContextAdapter() { + this(null, null, null); + } + + /** + * Create a new adapter from the supplied dn. + * + * @param dn the dn. + */ + public DirContextAdapter(Name dn) { + this(null, dn); + } + + /** + * Create a new adapter from the supplied attributes and dn. + * + * @param attrs the attributes. + * @param dn the dn. + */ + public DirContextAdapter(Attributes attrs, Name dn) { + this(attrs, dn, null); + } + + /** + * Create a new adapter from the supplied attributes, dn, and base. + * + * @param attrs the attributes. + * @param dn the dn. + * @param base the base name. + */ + public DirContextAdapter(Attributes attrs, Name dn, Name base) { + if (attrs != null) { + this.originalAttrs = attrs; + } + else { + this.originalAttrs = new BasicAttributes(true); + } + if (dn != null) { + this.dn = new DistinguishedName(dn.toString()); + } + else { + this.dn = new DistinguishedName(); + } + if (base != null) { + this.base = new DistinguishedName(base.toString()); + } + else { + this.base = new DistinguishedName(); + } + } + + /** + * Constructor for cloning an existing adapter. + * + * @param master The adapter to be copied. + */ + protected DirContextAdapter(DirContextAdapter master) { + this.originalAttrs = (Attributes) master.originalAttrs.clone(); + this.dn = master.dn; + this.updatedAttrs = (Attributes) master.updatedAttrs.clone(); + this.updateMode = master.updateMode; + } + + /** + * Sets the update mode. The update mode should be false for + * a new entry and true for an existing entry that is being + * updated. + * + * @param mode Update mode. + */ + public void setUpdateMode(boolean mode) { + this.updateMode = mode; + if (updateMode) { + updatedAttrs = new BasicAttributes(true); + } + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#isUpdateMode() + */ + public boolean isUpdateMode() { + return updateMode; + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#getNamesOfModifiedAttributes() + */ + public String[] getNamesOfModifiedAttributes() { + + List tmpList = new ArrayList(); + + NamingEnumeration attributesEnumeration; + if (isUpdateMode()) { + attributesEnumeration = updatedAttrs.getAll(); + } + else { + attributesEnumeration = originalAttrs.getAll(); + } + + try { + while (attributesEnumeration.hasMore()) { + Attribute oneAttribute = (Attribute) attributesEnumeration.next(); + tmpList.add(oneAttribute.getID()); + } + } + catch (NamingException e) { + throw LdapUtils.convertLdapException(e); + } + finally { + closeNamingEnumeration(attributesEnumeration); + } + + return (String[]) tmpList.toArray(new String[0]); + } + + private void closeNamingEnumeration(NamingEnumeration enumeration) { + try { + if (enumeration != null) { + enumeration.close(); + } + } + catch (NamingException e) { + // Never mind this + } + } + + /* + * @see org.springframework.ldap.support.AttributeModificationsAware#getModificationItems() + */ + public ModificationItem[] getModificationItems() { + if (!updateMode) { + return new ModificationItem[0]; + } + + List tmpList = new LinkedList(); + NamingEnumeration attributesEnumeration = null; + try { + attributesEnumeration = updatedAttrs.getAll(); + + // find attributes that have been changed, removed or added + while (attributesEnumeration.hasMore()) { + Attribute oneAttr = (Attribute) attributesEnumeration.next(); + + collectModifications(oneAttr, tmpList); + } + } + catch (NamingException e) { + throw LdapUtils.convertLdapException(e); + } + finally { + closeNamingEnumeration(attributesEnumeration); + } + + if (log.isDebugEnabled()) { + log.debug("Number of modifications:" + tmpList.size()); + } + + return (ModificationItem[]) tmpList.toArray(new ModificationItem[tmpList.size()]); + } + + /** + * Collect all modifications for the changed attribute. If no changes have + * been made, return immediately. If modifications have been made, and the + * original size as well as the updated size of the attribute is 1, replace + * the attribute. If the size of the updated attribute is 0, remove the + * attribute. Otherwise, the attribute is a multi-value attribute; if it's + * an ordered one it should be replaced in its entirety to preserve the new + * ordering, if not all modifications to the original value (removals and + * additions) will be collected individually. + * + * @param changedAttr the value of the changed attribute. + * @param modificationList the list in which to add the modifications. + * @throws NamingException if thrown by called Attribute methods. + */ + private void collectModifications(Attribute changedAttr, List modificationList) throws NamingException { + Attribute currentAttribute = originalAttrs.get(changedAttr.getID()); + + if (changedAttr.equals(currentAttribute)) { + // No changes + return; + } + else if (currentAttribute != null && currentAttribute.size() == 1 && changedAttr.size() == 1) { + // Replace single-vale attribute. + modificationList.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, changedAttr)); + } + else if (changedAttr.size() == 0 && currentAttribute != null) { + // Attribute has been removed. + modificationList.add(new ModificationItem(DirContext.REMOVE_ATTRIBUTE, changedAttr)); + } + else if ((currentAttribute == null || currentAttribute.size() == 0) && changedAttr.size() > 0) { + // Attribute has been added. + modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE, changedAttr)); + } + else if (changedAttr.size() > 0 && changedAttr.isOrdered()) { + // This is a multivalue attribute and it is ordered - the original + // value should be replaced with the new values so that the ordering + // is preserved. + modificationList.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, changedAttr)); + } + else if (changedAttr.size() > 0) { + // Change of multivalue Attribute. Collect additions and removals + // individually. + List myModifications = new LinkedList(); + collectModifications(currentAttribute, changedAttr, myModifications); + + if (myModifications.isEmpty()) { + // This means that the attributes are not equal, but the + // actual values are the same - thus the order must have + // changed. This should result in a REPLACE_ATTRIBUTE operation. + myModifications.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE, changedAttr)); + } + + modificationList.addAll(myModifications); + } + } + + private void collectModifications(Attribute originalAttr, Attribute changedAttr, List modificationList) + throws NamingException { + + Attribute originalClone = (Attribute) originalAttr.clone(); + Attribute addedValuesAttribute = new BasicAttribute(originalAttr.getID()); + + for (int i = 0; i < changedAttr.size(); i++) { + Object attributeValue = changedAttr.get(i); + if (!originalClone.remove(attributeValue)) { + addedValuesAttribute.add(attributeValue); + } + } + + // We have now traversed and removed all values from the original that + // were also present in the new values. The remaining values in the + // original must be the ones that were removed. + if (originalClone.size() > 0) { + modificationList.add(new ModificationItem(DirContext.REMOVE_ATTRIBUTE, originalClone)); + } + + if (addedValuesAttribute.size() > 0) { + modificationList.add(new ModificationItem(DirContext.ADD_ATTRIBUTE, addedValuesAttribute)); + } + } + + /** + * returns true if the attribute is empty. It is empty if a == null, size == + * 0 or get() == null or an exception if thrown when accessing the get + * method + */ + private boolean isEmptyAttribute(Attribute a) { + try { + return (a == null || a.size() == 0 || a.get() == null); + } + catch (NamingException e) { + return true; + } + } + + /** + * Compare the existing attribute name with the values on the + * array values. The order of the array must be the same + * order as the existing multivalued attribute. + *

+ * Also handles the case where the values have been reset to the original + * values after a previous change. For example, changing + * [a,b,c] to [a,b] and then back to + * [a,b,c] again must result in this method returning + * true so the first change can be overwritten with the + * latest change. + * + * @param name Name of the original multi-valued attribute. + * @param values Array of values to check if they have been changed. + * @return true if there has been a change compared to original attribute, + * or a previous update + */ + private boolean isChanged(String name, Object[] values, boolean orderMatters) { + + Attribute orig = originalAttrs.get(name); + Attribute prev = updatedAttrs.get(name); + + // values == null and values.length == 0 is treated the same way + boolean emptyNewValue = (values == null || values.length == 0); + + // Setting to empty --------------------- + if (emptyNewValue) { + // FALSE: if both are null, it is not changed (both don't exist) + // TRUE: if new value is null and old value exists (should be + // removed) + // TODO Also include prev in null check + // TODO Also check if there is a single null element + if (orig != null) { + return true; + } + return false; + } + + // NOT setting to empty ------------------- + + // TRUE if existing value is null + if (orig == null) { + return true; + } + + // TRUE if different length compared to original attributes + if (orig.size() != values.length) { + return true; + } + + // TRUE if different length compared to previously updated attributes + if (prev != null && prev.size() != values.length) { + return true; + } + + // Check contents of arrays + + // Order DOES matter, e.g. first names + try { + for (int i = 0; i < orig.size(); i++) { + Object obj = orig.get(i); + // TRUE if one value is not equal + if (!(obj instanceof String)) { + return true; + } + if (orderMatters) { + // check only the string with same index + if (!values[i].equals(obj)) { + return true; + } + } + else { + // check all strings + if (!ArrayUtils.contains(values, obj)) { + return true; + } + } + } + + } + catch (NamingException e) { + // TRUE if we can't access the value + return true; + } + + if (prev != null) { + // Also check against updatedAttrs, since there might have been + // a previous update + try { + for (int i = 0; i < prev.size(); i++) { + Object obj = prev.get(i); + // TRUE if one value is not equal + if (!(obj instanceof String)) { + return true; + } + if (orderMatters) { + // check only the string with same index + if (!values[i].equals(obj)) { + return true; + } + } + else { + // check all strings + if (!ArrayUtils.contains(values, obj)) { + return true; + } + } + } + + } + catch (NamingException e) { + // TRUE if we can't access the value + return true; + } + } + // FALSE since we have compared all values + return false; + } + + /** + * Checks if an entry has a specific attribute. + * + * This method simply calls exists(String) with the attribute name. + * + * @param attr the attribute to check. + * @return true if attribute exists in entry. + */ + protected final boolean exists(Attribute attr) { + return exists(attr.getID()); + } + + /** + * Checks if the attribute exists in this entry, either it was read or it + * has been added and update() has been called. + * + * @param attrId id of the attribute to check. + * @return true if the attribute exists in the entry. + */ + protected final boolean exists(String attrId) { + return originalAttrs.get(attrId) != null; + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#getStringAttribute(java.lang.String) + */ + public String getStringAttribute(String name) { + return (String) getObjectAttribute(name); + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#getObjectAttribute(java.lang.String) + */ + public Object getObjectAttribute(String name) { + Attribute oneAttr = originalAttrs.get(name); + if (oneAttr == null) { + return null; + } + try { + return oneAttr.get(); + } + catch (NamingException e) { + throw LdapUtils.convertLdapException(e); + } + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#setAttributeValue(java.lang.String, + * java.lang.Object) + */ + public void setAttributeValue(String name, Object value) { + // new entry + if (!updateMode && value != null) { + originalAttrs.put(name, value); + } + + // updating entry + if (updateMode) { + BasicAttribute attribute = new BasicAttribute(name); + if (value != null) { + attribute.add(value); + } + updatedAttrs.put(attribute); + } + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.DirContextOperations#addAttributeValue(java.lang.String, + * java.lang.Object) + */ + public void addAttributeValue(String name, Object value) { + if (!updateMode && value != null) { + Attribute attr = originalAttrs.get(name); + if (attr == null) { + originalAttrs.put(name, value); + } + else { + attr.add(value); + } + } + else if (updateMode) { + Attribute attr = updatedAttrs.get(name); + if (attr == null) { + if (originalAttrs.get(name) == null) { + // No match in the original attributes - + // add a new Attribute to updatedAttrs + updatedAttrs.put(name, value); + } + else { + // The attribute exists in the original attributes - clone + // that and add the new entry to it + attr = (Attribute) originalAttrs.get(name).clone(); + attr.add(value); + updatedAttrs.put(attr); + } + } + else { + attr.add(value); + } + } + + // Null values will not be added + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.core.DirContextOperations#removeAttributeValue(java.lang.String, + * java.lang.Object) + */ + public void removeAttributeValue(String name, Object value) { + if (!updateMode && value != null) { + Attribute attr = originalAttrs.get(name); + if (attr != null) { + attr.remove(value); + if (attr.size() == 0) { + originalAttrs.remove(name); + } + } + } + else if (updateMode) { + Attribute attr = updatedAttrs.get(name); + if (attr == null) { + if (originalAttrs.get(name) != null) { + attr = (Attribute) originalAttrs.get(name).clone(); + attr.remove(value); + updatedAttrs.put(attr); + } + } + else { + attr.remove(value); + } + } + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#setAttributeValues(java.lang.String, + * java.lang.Object[]) + */ + public void setAttributeValues(String name, Object[] values) { + setAttributeValues(name, values, ORDER_DOESNT_MATTER); + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#setAttributeValues(java.lang.String, + * java.lang.Object[], boolean) + */ + public void setAttributeValues(String name, Object[] values, boolean orderMatters) { + Attribute a = new BasicAttribute(name, orderMatters); + + for (int i = 0; values != null && i < values.length; i++) { + a.add(values[i]); + } + + // only change the original attribute if not in update mode + if (!updateMode && values != null && values.length > 0) { + // don't save empty arrays + originalAttrs.put(a); + } + + // possible to set an already existing attribute to an empty array + if (updateMode && isChanged(name, values, orderMatters)) { + updatedAttrs.put(a); + } + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#update() + */ + public void update() { + NamingEnumeration attributesEnumeration = null; + + try { + attributesEnumeration = updatedAttrs.getAll(); + + // find what to update + while (attributesEnumeration.hasMore()) { + Attribute a = (Attribute) attributesEnumeration.next(); + + // if it does not exist it should be added + if (isEmptyAttribute(a)) { + originalAttrs.remove(a.getID()); + } + else { + // Otherwise it should be set. + originalAttrs.put(a); + } + } + } + catch (NamingException e) { + throw LdapUtils.convertLdapException(e); + } + finally { + closeNamingEnumeration(attributesEnumeration); + } + + // Reset the attributes to be updated + updatedAttrs = new BasicAttributes(true); + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#getStringAttributes(java.lang.String) + */ + public String[] getStringAttributes(String name) { + String[] attributes; + + Attribute attribute = originalAttrs.get(name); + if (attribute != null && attribute.size() > 0) { + attributes = new String[attribute.size()]; + for (int i = 0; i < attribute.size(); i++) { + try { + attributes[i] = (String) attribute.get(i); + } + catch (NamingException e) { + throw LdapUtils.convertLdapException(e); + } + } + } + else { + return null; + } + + return attributes; + } + + /* + * @see org.springframework.ldap.support.DirContextOperations#getAttributeSortedStringSet(java.lang.String) + */ + public SortedSet getAttributeSortedStringSet(String name) { + TreeSet attrSet = new TreeSet(); + + Attribute attribute = originalAttrs.get(name); + if (attribute != null) { + for (int i = 0; i < attribute.size(); i++) { + try { + attrSet.add(attribute.get(i)); + } + catch (NamingException e) { + throw LdapUtils.convertLdapException(e); + } + } + } + else { + return null; + } + + return attrSet; + } + + /** + * Set the supplied attribute. + * + * @param attribute the attribute to set. + */ + public void setAttribute(Attribute attribute) { + if (!updateMode) { + originalAttrs.put(attribute); + } + else { + updatedAttrs.put(attribute); + } + } + + /** + * Get all attributes. + * + * @return all attributes. + */ + public Attributes getAttributes() { + return originalAttrs; + } + + /** + * @see javax.naming.directory.DirContext#getAttributes(Name) + */ + public Attributes getAttributes(Name name) throws NamingException { + return getAttributes(name.toString()); + } + + /** + * @see javax.naming.directory.DirContext#getAttributes(String) + */ + public Attributes getAttributes(String name) throws NamingException { + if (!StringUtils.isEmpty(name)) { + throw new NameNotFoundException(); + } + return (Attributes) originalAttrs.clone(); + } + + /** + * @see javax.naming.directory.DirContext#getAttributes(Name, String[]) + */ + public Attributes getAttributes(Name name, String[] attrIds) throws NamingException { + return getAttributes(name.toString(), attrIds); + } + + /** + * @see javax.naming.directory.DirContext#getAttributes(String, String[]) + */ + public Attributes getAttributes(String name, String[] attrIds) throws NamingException { + if (!StringUtils.isEmpty(name)) { + throw new NameNotFoundException(); + } + + Attributes a = new BasicAttributes(true); + Attribute target; + for (int i = 0; i < attrIds.length; i++) { + target = originalAttrs.get(attrIds[i]); + if (target != null) { + a.put(target); + } + } + + return a; + } + + /** + * @see javax.naming.directory.DirContext#modifyAttributes(javax.naming.Name, + * int, javax.naming.directory.Attributes) + */ + public void modifyAttributes(Name name, int modOp, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#modifyAttributes(String, int, + * Attributes) + */ + public void modifyAttributes(String name, int modOp, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#modifyAttributes(Name, + * ModificationItem[]) + */ + public void modifyAttributes(Name name, ModificationItem[] mods) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#modifyAttributes(String, + * ModificationItem[]) + */ + public void modifyAttributes(String name, ModificationItem[] mods) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#bind(Name, Object, Attributes) + */ + public void bind(Name name, Object obj, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#bind(String, Object, Attributes) + */ + public void bind(String name, Object obj, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#rebind(Name, Object, Attributes) + */ + public void rebind(Name name, Object obj, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#rebind(String, Object, Attributes) + */ + public void rebind(String name, Object obj, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#createSubcontext(Name, Attributes) + */ + public DirContext createSubcontext(Name name, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#createSubcontext(String, + * Attributes) + */ + public DirContext createSubcontext(String name, Attributes attrs) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#getSchema(Name) + */ + public DirContext getSchema(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#getSchema(String) + */ + public DirContext getSchema(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#getSchemaClassDefinition(Name) + */ + public DirContext getSchemaClassDefinition(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#getSchemaClassDefinition(String) + */ + public DirContext getSchemaClassDefinition(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(Name, Attributes, String[]) + */ + public NamingEnumeration search(Name name, Attributes matchingAttributes, String[] attributesToReturn) + throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(String, Attributes, + * String[]) + */ + public NamingEnumeration search(String name, Attributes matchingAttributes, String[] attributesToReturn) + throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(Name, Attributes) + */ + public NamingEnumeration search(Name name, Attributes matchingAttributes) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(String, Attributes) + */ + public NamingEnumeration search(String name, Attributes matchingAttributes) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(Name, String, + * SearchControls) + */ + public NamingEnumeration search(Name name, String filter, SearchControls cons) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(String, String, + * SearchControls) + */ + public NamingEnumeration search(String name, String filter, SearchControls cons) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(Name, String, Object[], + * SearchControls) + */ + public NamingEnumeration search(Name name, String filterExpr, Object[] filterArgs, SearchControls cons) + throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.directory.DirContext#search(String, String, Object[], + * SearchControls) + */ + public NamingEnumeration search(String name, String filterExpr, Object[] filterArgs, SearchControls cons) + throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#lookup(Name) + */ + public Object lookup(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#lookup(String) + */ + public Object lookup(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#bind(Name, Object) + */ + public void bind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#bind(String, Object) + */ + public void bind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#rebind(Name, Object) + */ + public void rebind(Name name, Object obj) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#rebind(String, Object) + */ + public void rebind(String name, Object obj) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#unbind(Name) + */ + public void unbind(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#unbind(String) + */ + public void unbind(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#rename(Name, Name) + */ + public void rename(Name oldName, Name newName) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#rename(String, String) + */ + public void rename(String oldName, String newName) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#list(Name) + */ + public NamingEnumeration list(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#list(String) + */ + public NamingEnumeration list(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#listBindings(Name) + */ + public NamingEnumeration listBindings(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#listBindings(String) + */ + public NamingEnumeration listBindings(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#destroySubcontext(Name) + */ + public void destroySubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#destroySubcontext(String) + */ + public void destroySubcontext(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#createSubcontext(Name) + */ + public Context createSubcontext(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#createSubcontext(String) + */ + public Context createSubcontext(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#lookupLink(Name) + */ + public Object lookupLink(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#lookupLink(String) + */ + public Object lookupLink(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#getNameParser(Name) + */ + public NameParser getNameParser(Name name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#getNameParser(String) + */ + public NameParser getNameParser(String name) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#composeName(Name, Name) + */ + public Name composeName(Name name, Name prefix) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#composeName(String, String) + */ + public String composeName(String name, String prefix) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#addToEnvironment(String, Object) + */ + public Object addToEnvironment(String propName, Object propVal) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#removeFromEnvironment(String) + */ + public Object removeFromEnvironment(String propName) throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#getEnvironment() + */ + public Hashtable getEnvironment() throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#close() + */ + public void close() throws NamingException { + throw new UnsupportedOperationException("Not implemented."); + } + + /** + * @see javax.naming.Context#getNameInNamespace() + */ + public String getNameInNamespace() { + DistinguishedName result = new DistinguishedName(dn); + result.prepend(base); + return result.toString(); + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.DirContextOperations#getDn() + */ + public Name getDn() { + return dn; + } + + /* + * (non-Javadoc) + * + * @see org.springframework.ldap.support.DirContextOperations#setDn(javax.naming.Name) + */ + public final void setDn(Name dn) { + if (!updateMode) { + this.dn = new DistinguishedName(dn.toString()); + } + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object obj) { + // A subclass with identical values should NOT be considered equal. + // EqualsBuilder in commons-lang cannot handle subclasses correctly. + if (obj == null || obj.getClass() != this.getClass()) { + return false; + } + return EqualsBuilder.reflectionEquals(this, obj); + } + + /** + * @see Object#hashCode() + */ + public int hashCode() { + return HashCodeBuilder.reflectionHashCode(this); + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append(getClass().getName()); + buf.append(":"); + if (dn != null) { + buf.append(" dn=" + dn); + } + buf.append(" {"); + + try { + for (NamingEnumeration i = originalAttrs.getAll(); i.hasMore();) { + Attribute attribute = (Attribute) i.next(); + if (attribute.size() == 1) { + buf.append(attribute.getID()); + buf.append('='); + buf.append(attribute.get()); + } + else { + for (int j = 0; j < attribute.size(); j++) { + if (j > 0) { + buf.append(", "); + } + buf.append(attribute.getID()); + buf.append('['); + buf.append(j); + buf.append("]="); + buf.append(attribute.get(j)); + } + } + + if (i.hasMore()) { + buf.append(", "); + } + } + } + catch (NamingException e) { + log.warn("Error in toString()"); + } + buf.append('}'); + + return buf.toString(); + } } diff --git a/mvn-build/core/src/test/java/org/springframework/ldap/core/DirContextAdapterTest.java b/mvn-build/core/src/test/java/org/springframework/ldap/core/DirContextAdapterTest.java index 526381c3..da6c4405 100644 --- a/mvn-build/core/src/test/java/org/springframework/ldap/core/DirContextAdapterTest.java +++ b/mvn-build/core/src/test/java/org/springframework/ldap/core/DirContextAdapterTest.java @@ -34,972 +34,970 @@ import junit.framework.TestCase; * @author Mattias Arthursson */ public class DirContextAdapterTest extends TestCase { - private static final DistinguishedName BASE_NAME = new DistinguishedName( - "dc=jayway, dc=se"); - - private static final DistinguishedName DUMMY_NAME = new DistinguishedName( - "c=SE, dc=jayway, dc=se"); - - private DirContextAdapter tested; - - protected void setUp() throws Exception { - super.setUp(); - tested = new DirContextAdapter(); - } - - protected void tearDown() throws Exception { - super.tearDown(); - } - - public void testSetUpdateMode() throws Exception { - assertFalse(tested.isUpdateMode()); - tested.setUpdateMode(true); - assertTrue(tested.isUpdateMode()); - tested.setUpdateMode(false); - assertFalse(tested.isUpdateMode()); - } - - public void testGetModificationItems() throws Exception { - ModificationItem[] items = tested.getModificationItems(); - assertEquals(0, items.length); - tested.setUpdateMode(true); - assertEquals(0, items.length); - } - - public void testAlwaysReplace() throws Exception { - ModificationItem[] items = tested.getModificationItems(); - assertEquals(0, items.length); - tested.setUpdateMode(true); - assertEquals(0, items.length); - } - - public void testGetStringAttributeNotExists() throws Exception { - String s = tested.getStringAttribute("does not exist"); - assertNull(s); - } - - public void testGetStringAttributeExists() throws Exception { - final Attributes attrs = new BasicAttributes(); - attrs.put(new BasicAttribute("abc", "def")); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(attrs, null); - } - } - tested = new TestableDirContextAdapter(); - String s = tested.getStringAttribute("abc"); - assertEquals("def", s); - } - - public void testGetStringAttributesExists() throws Exception { - final Attributes attrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("234"); - attrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(attrs, null); - } - } - tested = new TestableDirContextAdapter(); - String s[] = tested.getStringAttributes("abc"); - assertEquals("123", s[0]); - assertEquals("234", s[1]); - assertEquals(2, s.length); - } - - public void testGetStringAttributesNotExists() throws Exception { - String s[] = tested.getStringAttributes("abc"); - assertNull(s); - } - - public void testAddAttributeValue() throws NamingException { - // Perform test - tested.addAttributeValue("abc", "123"); - - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertEquals("123", (String) attr.get()); - } - - public void testAddAttributeValueAttributeWithOtherValueExists() - throws NamingException { - tested.setAttribute(new BasicAttribute("abc", "321")); - - // Perform test - tested.addAttributeValue("abc", "123"); - - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertEquals("321", (String) attr.get(0)); - assertEquals("123", (String) attr.get(1)); - } - - public void testAddAttributeValueAttributeWithSameValueExists() - throws NamingException { - tested.setAttribute(new BasicAttribute("abc", "123")); - - // Perform test - tested.addAttributeValue("abc", "123"); - - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertEquals(1, attr.size()); - assertEquals("123", (String) attr.get(0)); - } - - public void testAddAttributeValueInUpdateMode() throws NamingException { - tested.setUpdateMode(true); - tested.addAttributeValue("abc", "123"); - - // Perform test - Attributes attrs = tested.getAttributes(); - assertNull(attrs.get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute attribute = modificationItems[0].getAttribute(); - assertEquals("abc", attribute.getID()); - assertEquals("123", attribute.get()); - } - - public void testAddAttributeValueInUpdateModeAttributeWithOtherValueExistsInOrigAttrs() - throws NamingException { - - tested.setAttribute(new BasicAttribute("abc", "321")); - tested.setUpdateMode(true); - - // Perform test - tested.addAttributeValue("abc", "123"); - - Attributes attrs = tested.getAttributes(); - assertNotNull(attrs.get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute attribute = modificationItems[0].getAttribute(); - assertEquals(1, attribute.size()); - assertEquals("abc", attribute.getID()); - assertEquals("123", attribute.get()); - } - - public void testAddAttributeValueInUpdateModeAttributeWithSameValueExistsInOrigAttrs() - throws NamingException { - - tested.setAttribute(new BasicAttribute("abc", "123")); - tested.setUpdateMode(true); - - // Perform test - tested.addAttributeValue("abc", "123"); - - Attributes attrs = tested.getAttributes(); - assertNotNull(attrs.get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(0, modificationItems.length); - } - - public void testAddAttributeValueInUpdateModeAttributeWithOtherValueExistsInUpdAttrs() - throws NamingException { - tested.setUpdateMode(true); - tested.setAttributeValue("abc", "321"); - - // Perform test - tested.addAttributeValue("abc", "123"); - - Attributes attrs = tested.getAttributes(); - assertNull(attrs.get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute attribute = modificationItems[0].getAttribute(); - assertEquals("abc", attribute.getID()); - assertEquals("321", attribute.get(0)); - assertEquals("123", attribute.get(1)); - } - - public void testAddAttributeValueInUpdateModeAttributeWithSameValueExistsInUpdAttrs() - throws NamingException { - tested.setUpdateMode(true); - tested.setAttributeValue("abc", "123"); - - // Perform test - tested.addAttributeValue("abc", "123"); - - Attributes attrs = tested.getAttributes(); - assertNull(attrs.get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute attribute = modificationItems[0].getAttribute(); - assertEquals(1, attribute.size()); - assertEquals("abc", attribute.getID()); - assertEquals("123", attribute.get()); - } - - public void testRemoveAttributeValueAttributeDoesntExist() { - // Perform test - tested.removeAttributeValue("abc", "123"); - - Attributes attributes = tested.getAttributes(); - assertNull(attributes.get("abc")); - } - - public void testRemoveAttributeValueAttributeWithOtherValueExists() - throws NamingException { - tested.setAttribute(new BasicAttribute("abc", "321")); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - Attributes attributes = tested.getAttributes(); - Attribute attr = attributes.get("abc"); - assertNotNull(attr); - assertEquals(1, attr.size()); - assertEquals("321", attr.get()); - } - - public void testRemoveAttributeValueAttributeWithSameValueExists() { - tested.setAttribute(new BasicAttribute("abc", "123")); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - Attributes attributes = tested.getAttributes(); - Attribute attr = attributes.get("abc"); - assertNull(attr); - } - - public void testRemoveAttributeValueAttributeWithOtherAndSameValueExists() - throws NamingException { - BasicAttribute basicAttribute = new BasicAttribute("abc"); - basicAttribute.add("123"); - basicAttribute.add("321"); - tested.setAttribute(basicAttribute); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - Attributes attributes = tested.getAttributes(); - Attribute attr = attributes.get("abc"); - assertNotNull(attr); - assertEquals(1, attr.size()); - assertEquals("321", attr.get()); - } - - public void testRemoveAttributeValueInUpdateMode() { - tested.setUpdateMode(true); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - assertNull(tested.getAttributes().get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(0, modificationItems.length); - } - - public void testRemoveAttributeValueInUpdateModeSameValueExistsInUpdatedAttrs() { - tested.setUpdateMode(true); - tested.setAttributeValue("abc", "123"); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - assertNull(tested.getAttributes().get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(0, modificationItems.length); - } - - public void testRemoveAttributeValueInUpdateModeOtherValueExistsInUpdatedAttrs() - throws NamingException { - tested.setUpdateMode(true); - tested.setAttributeValue("abc", "321"); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - assertNull(tested.getAttributes().get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute modificationAttribute = modificationItems[0].getAttribute(); - assertEquals("abc", modificationAttribute.getID()); - assertEquals(1, modificationAttribute.size()); - assertEquals("321", modificationAttribute.get()); - } - - public void testRemoveAttributeValueInUpdateModeOtherAndSameValueExistsInUpdatedAttrs() - throws NamingException { - tested.setUpdateMode(true); - tested.setAttributeValues("abc", new String[] { "321", "123" }); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - assertNull(tested.getAttributes().get("abc")); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute modificationAttribute = modificationItems[0].getAttribute(); - assertEquals("abc", modificationAttribute.getID()); - assertEquals(1, modificationAttribute.size()); - } - - public void testRemoveAttributeValueInUpdateModeSameValueExistsInOrigAttrs() { - tested.setAttribute(new BasicAttribute("abc", "123")); - tested.setUpdateMode(true); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute modificationAttribute = modificationItems[0].getAttribute(); - assertEquals("abc", modificationAttribute.getID()); - assertEquals(0, modificationAttribute.size()); - assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0] - .getModificationOp()); - } - - public void testRemoveAttributeValueInUpdateModeSameAndOtherValueExistsInOrigAttrs() - throws NamingException { - BasicAttribute basicAttribute = new BasicAttribute("abc"); - basicAttribute.add("123"); - basicAttribute.add("321"); - tested.setAttribute(basicAttribute); - tested.setUpdateMode(true); - - // Perform test - tested.removeAttributeValue("abc", "123"); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - Attribute modificationAttribute = modificationItems[0].getAttribute(); - assertEquals("abc", modificationAttribute.getID()); - assertEquals(1, modificationAttribute.size()); - assertEquals("123", modificationAttribute.get()); - assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0] - .getModificationOp()); - } - - public void testSetStringAttribute() throws Exception { - assertFalse(tested.isUpdateMode()); - tested.setAttributeValue("abc", "123"); - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertEquals("123", (String) attr.get()); - } - - public void testSetStringAttributeNull() throws Exception { - assertFalse(tested.isUpdateMode()); - tested.setAttributeValue("abc", null); - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertNull(attr); - } - - public void testAddAttribute() throws Exception { - tested.setUpdateMode(true); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValue("abc", "123"); - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertNull(attr); - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.ADD_ATTRIBUTE, mods[0].getModificationOp()); - attr = mods[0].getAttribute(); - assertEquals("123", (String) attr.get()); - - String[] modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(1, modNames.length); - assertEquals("abc", modNames[0]); - - tested.update(); - mods = tested.getModificationItems(); - assertEquals(0, mods.length); - modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(0, modNames.length); - attrs = tested.getAttributes(); - attr = attrs.get("abc"); - assertEquals("123", (String) attr.get()); - } - - public void testGetDn() throws Exception { - DirContextAdapter tested = new DirContextAdapter(DUMMY_NAME); - Name result = tested.getDn(); - assertEquals(DUMMY_NAME, result); - } - - public void testGetDn_BasePath() { - DirContextAdapter tested = new DirContextAdapter(null, DUMMY_NAME, - BASE_NAME); - Name result = tested.getDn(); - assertEquals(DUMMY_NAME, result); - } - - public void testGetNameInNamespace() { - DirContextAdapter tested = new DirContextAdapter(DUMMY_NAME); - String result = tested.getNameInNamespace(); - assertEquals(DUMMY_NAME.toString(), result); - } - - public void testGetNameInNamespace_BasePath() { - DirContextAdapter tested = new DirContextAdapter(null, - new DistinguishedName("c=SE"), BASE_NAME); - String result = tested.getNameInNamespace(); - assertEquals(DUMMY_NAME.toString(), result); - } - - public void testAddMultiAttributes() throws Exception { - tested.setUpdateMode(true); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", new String[] { "123", "456" }); - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertNull(attr); - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.ADD_ATTRIBUTE, mods[0].getModificationOp()); - attr = mods[0].getAttribute(); - assertEquals(2, attr.size()); - assertEquals("123", (String) attr.get(0)); - assertEquals("456", (String) attr.get(1)); - - String[] modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(1, modNames.length); - assertEquals("abc", modNames[0]); - - tested.update(); - mods = tested.getModificationItems(); - assertEquals(0, mods.length); - modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(0, modNames.length); - attrs = tested.getAttributes(); - attr = attrs.get("abc"); - assertEquals("123", (String) attr.get(0)); - assertEquals("456", (String) attr.get(1)); - } - - public void testRemoveAttribute() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - fixtureAttrs.put(new BasicAttribute("abc", "123")); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - - tested.setUpdateMode(true); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValue("abc", null); - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertEquals("123", (String) attr.get()); - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.REMOVE_ATTRIBUTE, mods[0].getModificationOp()); - attr = mods[0].getAttribute(); - assertEquals("abc", (String) attr.getID()); - String[] modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(1, modNames.length); - assertEquals("abc", modNames[0]); - - tested.update(); - mods = tested.getModificationItems(); - assertEquals(0, mods.length); - modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(0, modNames.length); - attrs = tested.getAttributes(); - attr = attrs.get("abc"); - assertNull(attr); - } - - public void testRemoveMultiAttribute() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute abc = new BasicAttribute("abc"); - abc.add("123"); - abc.add("456"); - fixtureAttrs.put(abc); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - - tested.setUpdateMode(true); - tested.setAttributeValues("abc", new String[] {}); - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.REMOVE_ATTRIBUTE, mods[0].getModificationOp()); - Attribute attr = mods[0].getAttribute(); - assertEquals("abc", (String) attr.getID()); - assertEquals(0, attr.size()); - } - - public void testChangeAttribute() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - fixtureAttrs.put(new BasicAttribute("abc", "123")); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - tested.setAttributeValue("abc", "234"); // change - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); - Attribute attr = mods[0].getAttribute(); - assertEquals("abc", (String) attr.getID()); - assertEquals("234", (String) attr.get()); - } - - public void testNoChangeAttribute() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - fixtureAttrs.put(new BasicAttribute("abc", "123")); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValue("abc", "123"); // change - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(0, mods.length); - } - - public void testNoChangeMultiAttribute() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", new String[] { "123", "qwe" }); - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(0, mods.length); - String[] modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(0, modNames.length); - } - - public void testNoChangeMultiAttributeOrderDoesNotMatter() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - tested.setAttributeValues("abc", new String[] { "qwe", "123" }); - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(0, mods.length); - String[] modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(0, modNames.length); - } - - public void testChangeMultiAttributeOrderDoesMatter() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", new String[] { "qwe", "123" }, true); - - // change - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); - Attribute attr = mods[0].getAttribute(); - assertEquals("qwe", attr.get(0)); - assertEquals("123", attr.get(1)); - } - - public void testChangeMultiAttribute_AddValue() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested - .setAttributeValues("abc", - new String[] { "123", "qwe", "klytt" }); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - assertEquals(DirContext.ADD_ATTRIBUTE, modificationItems[0] - .getModificationOp()); - assertEquals("klytt", modificationItems[0].getAttribute().get()); - } - - public void testChangeMultiAttribute_RemoveValue() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", new String[] { "123" }); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0] - .getModificationOp()); - assertEquals("qwe", modificationItems[0].getAttribute().get()); - } - - public void testChangeMultiAttribute_RemoveTwoValues() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - multi.add("rty"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", new String[] { "123" }); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0] - .getModificationOp()); - assertEquals("qwe", modificationItems[0].getAttribute().get(0)); - assertEquals("rty", modificationItems[0].getAttribute().get(1)); - } - - public void testChangeMultiAttribute_RemoveAllValues() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", null); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0] - .getModificationOp()); - } - - public void testChangeMultiAttribute_SameValue() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", new String[] { "123", "qwe" }); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(0, modificationItems.length); - } - - public void testChangeMultiAttribute_AddAndRemoveValue() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - multi.add("rty"); - multi.add("uio"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("abc", new String[] { "123", "qwe", "klytt", - "kalle" }); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(2, modificationItems.length); - - Attribute modifiedAttribute = modificationItems[0].getAttribute(); - assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0] - .getModificationOp()); - assertEquals("abc", modifiedAttribute.getID()); - assertEquals(2, modifiedAttribute.size()); - assertEquals("rty", modifiedAttribute.get(0)); - assertEquals("uio", modifiedAttribute.get(1)); - - assertEquals(DirContext.ADD_ATTRIBUTE, modificationItems[1] - .getModificationOp()); - modifiedAttribute = modificationItems[1].getAttribute(); - assertEquals("abc", modifiedAttribute.getID()); - assertEquals(2, modifiedAttribute.size()); - assertEquals("klytt", modifiedAttribute.get(0)); - assertEquals("kalle", modifiedAttribute.get(1)); - } - - public void testAddAttribute_Multivalue() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - Attribute multi = new BasicAttribute("abc"); - multi.add("123"); - multi.add("qwe"); - fixtureAttrs.put(multi); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValues("def", new String[] { "kalle", "klytt" }); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(1, modificationItems.length); - assertEquals("def", modificationItems[0].getAttribute().getID()); - } - - public void testChangeAttributeTwice() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - fixtureAttrs.put(new BasicAttribute("abc", "123")); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValue("abc", "234"); // change - tested.setAttributeValue("abc", "987"); - // change a second time - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); - Attribute attr = mods[0].getAttribute(); - assertEquals("abc", (String) attr.getID()); - assertEquals("987", (String) attr.get()); - - tested.update(); - mods = tested.getModificationItems(); - assertEquals(0, mods.length); - String[] modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(0, modNames.length); - Attributes attrs = tested.getAttributes(); - attr = attrs.get("abc"); - assertEquals("987", (String) attr.get()); - assertEquals("987", tested.getStringAttribute("abc")); - } - - public void testAddReplaceAndChangeAttribute() throws Exception { - final Attributes fixtureAttrs = new BasicAttributes(); - fixtureAttrs.put(new BasicAttribute("abc", "123")); - fixtureAttrs.put(new BasicAttribute("qwe", "42")); - class TestableDirContextAdapter extends DirContextAdapter { - public TestableDirContextAdapter() { - super(fixtureAttrs, null); - setUpdateMode(true); - } - } - tested = new TestableDirContextAdapter(); - assertTrue(tested.isUpdateMode()); - tested.setAttributeValue("abc", "234"); // change - tested.setAttributeValue("qwe", null); // remove - tested.setAttributeValue("zzz", "new"); // new - Attributes attrs = tested.getAttributes(); - Attribute attr = attrs.get("abc"); - assertEquals("123", (String) attr.get()); - assertEquals(2, attrs.size()); - - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(3, mods.length); - String[] modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(3, modNames.length); - - ModificationItem mod = getModificationItem(mods, - DirContext.REPLACE_ATTRIBUTE); - assertNotNull(mod); - attr = mod.getAttribute(); - assertEquals("abc", (String) attr.getID()); - assertEquals("234", (String) attr.get()); - - mod = getModificationItem(mods, DirContext.REMOVE_ATTRIBUTE); - assertNotNull(mod); - attr = mod.getAttribute(); - assertEquals("qwe", (String) attr.getID()); - - mod = getModificationItem(mods, DirContext.ADD_ATTRIBUTE); - assertNotNull(mod); - attr = mod.getAttribute(); - assertEquals("zzz", (String) attr.getID()); - assertEquals("new", (String) attr.get()); - - tested.update(); - mods = tested.getModificationItems(); - assertEquals(0, mods.length); - modNames = tested.getNamesOfModifiedAttributes(); - assertEquals(0, modNames.length); - - attrs = tested.getAttributes(); - assertEquals(2, attrs.size()); - attr = attrs.get("abc"); - assertEquals("234", (String) attr.get()); - assertEquals("new", tested.getStringAttribute("zzz")); - } - - /** - * Test for LDAP-15: DirContextAdapter.setAttribute(). Verifies that setting - * an Attribute should modify updatedAttrs if in update mode. - * - * @throws NamingException - */ - public void testSetAttribute_UpdateMode() throws NamingException { - // Set original attribute value - Attribute attribute = new BasicAttribute("cn", "john doe"); - tested.setAttribute(attribute); - - // Set to update mode - tested.setUpdateMode(true); - - // Perform test - update the attribute - Attribute updatedAttribute = new BasicAttribute("cn", "nisse hult"); - tested.setAttribute(updatedAttribute); - - // Verify result - ModificationItem[] mods = tested.getModificationItems(); - assertEquals(1, mods.length); - assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); - - Attribute modificationAttribute = mods[0].getAttribute(); - assertEquals("cn", modificationAttribute.getID()); - assertEquals("nisse hult", modificationAttribute.get()); - } - - public void testGetStringAttributes_NullValue() { - String result = tested.getStringAttribute("someAbsentAttribute"); - assertNull(result); - } - - public void testGetStringAttributes_AttributeExists_NullValue() { - tested.setAttribute(new BasicAttribute("someAttribute", null)); - String result = tested.getStringAttribute("someAttribute"); - assertNull(result); - } - - private ModificationItem getModificationItem(ModificationItem[] mods, - int operation) { - for (int i = 0; i < mods.length; i++) { - if (mods[i].getModificationOp() == operation) - return mods[i]; - } - return null; - } - - public void testModifyMultiValueAttributeModificationOrder() - throws NamingException { - BasicAttribute attribute = new BasicAttribute("abc"); - attribute.add("Some Person"); - attribute.add("Some Other Person"); - - tested.setAttribute(attribute); - tested.setUpdateMode(true); - - tested.setAttributeValues("abc", new String[] { "some person", - "Some Other Person" }); - - // Perform test - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(2, modificationItems.length); - ModificationItem modificationItem = modificationItems[0]; - assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItem - .getModificationOp()); - assertEquals("Some Person", modificationItem.getAttribute().get()); - modificationItem = modificationItems[1]; - assertEquals(DirContext.ADD_ATTRIBUTE, modificationItem - .getModificationOp()); - assertEquals("some person", modificationItem.getAttribute().get()); - } - - /** - * Test for LDAP-13. - */ - public void testModifyAttributeByteArray() { - tested.setAttribute(new BasicAttribute("abc", new byte[] { 1, 2, 3 })); - - tested.setUpdateMode(true); - - // Perform test - tested.setAttributeValue("abc", new byte[] { 1, 2, 3 }); - - ModificationItem[] modificationItems = tested.getModificationItems(); - assertEquals(0, modificationItems.length); - } + private static final DistinguishedName BASE_NAME = new DistinguishedName("dc=jayway, dc=se"); + + private static final DistinguishedName DUMMY_NAME = new DistinguishedName("c=SE, dc=jayway, dc=se"); + + private DirContextAdapter tested; + + protected void setUp() throws Exception { + super.setUp(); + tested = new DirContextAdapter(); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testSetUpdateMode() throws Exception { + assertFalse(tested.isUpdateMode()); + tested.setUpdateMode(true); + assertTrue(tested.isUpdateMode()); + tested.setUpdateMode(false); + assertFalse(tested.isUpdateMode()); + } + + public void testGetModificationItems() throws Exception { + ModificationItem[] items = tested.getModificationItems(); + assertEquals(0, items.length); + tested.setUpdateMode(true); + assertEquals(0, items.length); + } + + public void testAlwaysReplace() throws Exception { + ModificationItem[] items = tested.getModificationItems(); + assertEquals(0, items.length); + tested.setUpdateMode(true); + assertEquals(0, items.length); + } + + public void testGetStringAttributeNotExists() throws Exception { + String s = tested.getStringAttribute("does not exist"); + assertNull(s); + } + + public void testGetStringAttributeExists() throws Exception { + final Attributes attrs = new BasicAttributes(); + attrs.put(new BasicAttribute("abc", "def")); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(attrs, null); + } + } + tested = new TestableDirContextAdapter(); + String s = tested.getStringAttribute("abc"); + assertEquals("def", s); + } + + public void testGetStringAttributesExists() throws Exception { + final Attributes attrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("234"); + attrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(attrs, null); + } + } + tested = new TestableDirContextAdapter(); + String s[] = tested.getStringAttributes("abc"); + assertEquals("123", s[0]); + assertEquals("234", s[1]); + assertEquals(2, s.length); + } + + public void testGetStringAttributesNotExists() throws Exception { + String s[] = tested.getStringAttributes("abc"); + assertNull(s); + } + + public void testAddAttributeValue() throws NamingException { + // Perform test + tested.addAttributeValue("abc", "123"); + + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertEquals("123", (String) attr.get()); + } + + public void testAddAttributeValueAttributeWithOtherValueExists() throws NamingException { + tested.setAttribute(new BasicAttribute("abc", "321")); + + // Perform test + tested.addAttributeValue("abc", "123"); + + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertEquals("321", (String) attr.get(0)); + assertEquals("123", (String) attr.get(1)); + } + + public void testAddAttributeValueAttributeWithSameValueExists() throws NamingException { + tested.setAttribute(new BasicAttribute("abc", "123")); + + // Perform test + tested.addAttributeValue("abc", "123"); + + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertEquals(1, attr.size()); + assertEquals("123", (String) attr.get(0)); + } + + public void testAddAttributeValueInUpdateMode() throws NamingException { + tested.setUpdateMode(true); + tested.addAttributeValue("abc", "123"); + + // Perform test + Attributes attrs = tested.getAttributes(); + assertNull(attrs.get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute attribute = modificationItems[0].getAttribute(); + assertEquals("abc", attribute.getID()); + assertEquals("123", attribute.get()); + } + + public void testAddAttributeValueInUpdateModeAttributeWithOtherValueExistsInOrigAttrs() throws NamingException { + + tested.setAttribute(new BasicAttribute("abc", "321")); + tested.setUpdateMode(true); + + // Perform test + tested.addAttributeValue("abc", "123"); + + Attributes attrs = tested.getAttributes(); + assertNotNull(attrs.get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute attribute = modificationItems[0].getAttribute(); + assertEquals(1, attribute.size()); + assertEquals("abc", attribute.getID()); + assertEquals("123", attribute.get()); + } + + public void testAddAttributeValueInUpdateModeAttributeWithSameValueExistsInOrigAttrs() throws NamingException { + + tested.setAttribute(new BasicAttribute("abc", "123")); + tested.setUpdateMode(true); + + // Perform test + tested.addAttributeValue("abc", "123"); + + Attributes attrs = tested.getAttributes(); + assertNotNull(attrs.get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(0, modificationItems.length); + } + + public void testAddAttributeValueInUpdateModeAttributeWithOtherValueExistsInUpdAttrs() throws NamingException { + tested.setUpdateMode(true); + tested.setAttributeValue("abc", "321"); + + // Perform test + tested.addAttributeValue("abc", "123"); + + Attributes attrs = tested.getAttributes(); + assertNull(attrs.get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute attribute = modificationItems[0].getAttribute(); + assertEquals("abc", attribute.getID()); + assertEquals("321", attribute.get(0)); + assertEquals("123", attribute.get(1)); + } + + public void testAddAttributeValueInUpdateModeAttributeWithSameValueExistsInUpdAttrs() throws NamingException { + tested.setUpdateMode(true); + tested.setAttributeValue("abc", "123"); + + // Perform test + tested.addAttributeValue("abc", "123"); + + Attributes attrs = tested.getAttributes(); + assertNull(attrs.get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute attribute = modificationItems[0].getAttribute(); + assertEquals(1, attribute.size()); + assertEquals("abc", attribute.getID()); + assertEquals("123", attribute.get()); + } + + public void testRemoveAttributeValueAttributeDoesntExist() { + // Perform test + tested.removeAttributeValue("abc", "123"); + + Attributes attributes = tested.getAttributes(); + assertNull(attributes.get("abc")); + } + + public void testRemoveAttributeValueAttributeWithOtherValueExists() throws NamingException { + tested.setAttribute(new BasicAttribute("abc", "321")); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + Attributes attributes = tested.getAttributes(); + Attribute attr = attributes.get("abc"); + assertNotNull(attr); + assertEquals(1, attr.size()); + assertEquals("321", attr.get()); + } + + public void testRemoveAttributeValueAttributeWithSameValueExists() { + tested.setAttribute(new BasicAttribute("abc", "123")); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + Attributes attributes = tested.getAttributes(); + Attribute attr = attributes.get("abc"); + assertNull(attr); + } + + public void testRemoveAttributeValueAttributeWithOtherAndSameValueExists() throws NamingException { + BasicAttribute basicAttribute = new BasicAttribute("abc"); + basicAttribute.add("123"); + basicAttribute.add("321"); + tested.setAttribute(basicAttribute); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + Attributes attributes = tested.getAttributes(); + Attribute attr = attributes.get("abc"); + assertNotNull(attr); + assertEquals(1, attr.size()); + assertEquals("321", attr.get()); + } + + public void testRemoveAttributeValueInUpdateMode() { + tested.setUpdateMode(true); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + assertNull(tested.getAttributes().get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(0, modificationItems.length); + } + + public void testRemoveAttributeValueInUpdateModeSameValueExistsInUpdatedAttrs() { + tested.setUpdateMode(true); + tested.setAttributeValue("abc", "123"); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + assertNull(tested.getAttributes().get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(0, modificationItems.length); + } + + public void testRemoveAttributeValueInUpdateModeOtherValueExistsInUpdatedAttrs() throws NamingException { + tested.setUpdateMode(true); + tested.setAttributeValue("abc", "321"); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + assertNull(tested.getAttributes().get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute modificationAttribute = modificationItems[0].getAttribute(); + assertEquals("abc", modificationAttribute.getID()); + assertEquals(1, modificationAttribute.size()); + assertEquals("321", modificationAttribute.get()); + } + + public void testRemoveAttributeValueInUpdateModeOtherAndSameValueExistsInUpdatedAttrs() throws NamingException { + tested.setUpdateMode(true); + tested.setAttributeValues("abc", new String[] { "321", "123" }); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + assertNull(tested.getAttributes().get("abc")); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute modificationAttribute = modificationItems[0].getAttribute(); + assertEquals("abc", modificationAttribute.getID()); + assertEquals(1, modificationAttribute.size()); + } + + public void testRemoveAttributeValueInUpdateModeSameValueExistsInOrigAttrs() { + tested.setAttribute(new BasicAttribute("abc", "123")); + tested.setUpdateMode(true); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute modificationAttribute = modificationItems[0].getAttribute(); + assertEquals("abc", modificationAttribute.getID()); + assertEquals(0, modificationAttribute.size()); + assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0].getModificationOp()); + } + + public void testRemoveAttributeValueInUpdateModeSameAndOtherValueExistsInOrigAttrs() throws NamingException { + BasicAttribute basicAttribute = new BasicAttribute("abc"); + basicAttribute.add("123"); + basicAttribute.add("321"); + tested.setAttribute(basicAttribute); + tested.setUpdateMode(true); + + // Perform test + tested.removeAttributeValue("abc", "123"); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + Attribute modificationAttribute = modificationItems[0].getAttribute(); + assertEquals("abc", modificationAttribute.getID()); + assertEquals(1, modificationAttribute.size()); + assertEquals("123", modificationAttribute.get()); + assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0].getModificationOp()); + } + + public void testSetStringAttribute() throws Exception { + assertFalse(tested.isUpdateMode()); + tested.setAttributeValue("abc", "123"); + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertEquals("123", (String) attr.get()); + } + + public void testSetStringAttributeNull() throws Exception { + assertFalse(tested.isUpdateMode()); + tested.setAttributeValue("abc", null); + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertNull(attr); + } + + public void testAddAttribute() throws Exception { + tested.setUpdateMode(true); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValue("abc", "123"); + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertNull(attr); + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.ADD_ATTRIBUTE, mods[0].getModificationOp()); + attr = mods[0].getAttribute(); + assertEquals("123", (String) attr.get()); + + String[] modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(1, modNames.length); + assertEquals("abc", modNames[0]); + + tested.update(); + mods = tested.getModificationItems(); + assertEquals(0, mods.length); + modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(0, modNames.length); + attrs = tested.getAttributes(); + attr = attrs.get("abc"); + assertEquals("123", (String) attr.get()); + } + + public void testGetDn() throws Exception { + DirContextAdapter tested = new DirContextAdapter(DUMMY_NAME); + Name result = tested.getDn(); + assertEquals(DUMMY_NAME, result); + } + + public void testGetDn_BasePath() { + DirContextAdapter tested = new DirContextAdapter(null, DUMMY_NAME, BASE_NAME); + Name result = tested.getDn(); + assertEquals(DUMMY_NAME, result); + } + + public void testGetNameInNamespace() { + DirContextAdapter tested = new DirContextAdapter(DUMMY_NAME); + String result = tested.getNameInNamespace(); + assertEquals(DUMMY_NAME.toString(), result); + } + + public void testGetNameInNamespace_BasePath() { + DirContextAdapter tested = new DirContextAdapter(null, new DistinguishedName("c=SE"), BASE_NAME); + String result = tested.getNameInNamespace(); + assertEquals(DUMMY_NAME.toString(), result); + } + + public void testAddMultiAttributes() throws Exception { + tested.setUpdateMode(true); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "123", "456" }); + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertNull(attr); + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.ADD_ATTRIBUTE, mods[0].getModificationOp()); + attr = mods[0].getAttribute(); + assertEquals(2, attr.size()); + assertEquals("123", (String) attr.get(0)); + assertEquals("456", (String) attr.get(1)); + + String[] modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(1, modNames.length); + assertEquals("abc", modNames[0]); + + tested.update(); + mods = tested.getModificationItems(); + assertEquals(0, mods.length); + modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(0, modNames.length); + attrs = tested.getAttributes(); + attr = attrs.get("abc"); + assertEquals("123", (String) attr.get(0)); + assertEquals("456", (String) attr.get(1)); + } + + public void testRemoveAttribute() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + fixtureAttrs.put(new BasicAttribute("abc", "123")); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + + tested.setUpdateMode(true); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValue("abc", null); + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertEquals("123", (String) attr.get()); + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.REMOVE_ATTRIBUTE, mods[0].getModificationOp()); + attr = mods[0].getAttribute(); + assertEquals("abc", (String) attr.getID()); + String[] modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(1, modNames.length); + assertEquals("abc", modNames[0]); + + tested.update(); + mods = tested.getModificationItems(); + assertEquals(0, mods.length); + modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(0, modNames.length); + attrs = tested.getAttributes(); + attr = attrs.get("abc"); + assertNull(attr); + } + + public void testRemoveMultiAttribute() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute abc = new BasicAttribute("abc"); + abc.add("123"); + abc.add("456"); + fixtureAttrs.put(abc); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + + tested.setUpdateMode(true); + tested.setAttributeValues("abc", new String[] {}); + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.REMOVE_ATTRIBUTE, mods[0].getModificationOp()); + Attribute attr = mods[0].getAttribute(); + assertEquals("abc", (String) attr.getID()); + assertEquals(0, attr.size()); + } + + public void testChangeAttribute() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + fixtureAttrs.put(new BasicAttribute("abc", "123")); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + tested.setAttributeValue("abc", "234"); // change + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); + Attribute attr = mods[0].getAttribute(); + assertEquals("abc", (String) attr.getID()); + assertEquals("234", (String) attr.get()); + } + + public void testNoChangeAttribute() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + fixtureAttrs.put(new BasicAttribute("abc", "123")); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValue("abc", "123"); // change + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(0, mods.length); + } + + public void testNoChangeMultiAttribute() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "123", "qwe" }); + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(0, mods.length); + String[] modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(0, modNames.length); + } + + public void testNoChangeMultiAttributeOrderDoesNotMatter() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + tested.setAttributeValues("abc", new String[] { "qwe", "123" }); + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(0, mods.length); + String[] modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(0, modNames.length); + } + + public void testChangeMultiAttributeOrderDoesMatter() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "qwe", "123" }, true); + + // change + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); + Attribute attr = mods[0].getAttribute(); + assertEquals("qwe", attr.get(0)); + assertEquals("123", attr.get(1)); + } + + /** + * Test case corresponding to LDAP-96 in Spring Jira. + * http://jira.springframework.org/browse/LDAP-96 + */ + public void testChangeMultiAttributeOrderDoesMatterLDAP96() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("title"); + multi.add("Juergen"); + multi.add("George"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("title", new String[] {"Jim", "George", "Juergen" }, true); + + // change + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); + Attribute attr = mods[0].getAttribute(); + assertEquals("Jim", attr.get(0)); + assertEquals("George", attr.get(1)); + assertEquals("Juergen", attr.get(2)); + } + + public void testChangeMultiAttribute_AddValue() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "123", "qwe", "klytt" }); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + assertEquals(DirContext.ADD_ATTRIBUTE, modificationItems[0].getModificationOp()); + assertEquals("klytt", modificationItems[0].getAttribute().get()); + } + + public void testChangeMultiAttribute_RemoveValue() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "123" }); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0].getModificationOp()); + assertEquals("qwe", modificationItems[0].getAttribute().get()); + } + + public void testChangeMultiAttribute_RemoveTwoValues() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + multi.add("rty"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "123" }); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0].getModificationOp()); + assertEquals("qwe", modificationItems[0].getAttribute().get(0)); + assertEquals("rty", modificationItems[0].getAttribute().get(1)); + } + + public void testChangeMultiAttribute_RemoveAllValues() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", null); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0].getModificationOp()); + } + + public void testChangeMultiAttribute_SameValue() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "123", "qwe" }); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(0, modificationItems.length); + } + + public void testChangeMultiAttribute_AddAndRemoveValue() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + multi.add("rty"); + multi.add("uio"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("abc", new String[] { "123", "qwe", "klytt", "kalle" }); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(2, modificationItems.length); + + Attribute modifiedAttribute = modificationItems[0].getAttribute(); + assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItems[0].getModificationOp()); + assertEquals("abc", modifiedAttribute.getID()); + assertEquals(2, modifiedAttribute.size()); + assertEquals("rty", modifiedAttribute.get(0)); + assertEquals("uio", modifiedAttribute.get(1)); + + assertEquals(DirContext.ADD_ATTRIBUTE, modificationItems[1].getModificationOp()); + modifiedAttribute = modificationItems[1].getAttribute(); + assertEquals("abc", modifiedAttribute.getID()); + assertEquals(2, modifiedAttribute.size()); + assertEquals("klytt", modifiedAttribute.get(0)); + assertEquals("kalle", modifiedAttribute.get(1)); + } + + public void testAddAttribute_Multivalue() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + Attribute multi = new BasicAttribute("abc"); + multi.add("123"); + multi.add("qwe"); + fixtureAttrs.put(multi); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValues("def", new String[] { "kalle", "klytt" }); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(1, modificationItems.length); + assertEquals("def", modificationItems[0].getAttribute().getID()); + } + + public void testChangeAttributeTwice() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + fixtureAttrs.put(new BasicAttribute("abc", "123")); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValue("abc", "234"); // change + tested.setAttributeValue("abc", "987"); + // change a second time + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); + Attribute attr = mods[0].getAttribute(); + assertEquals("abc", (String) attr.getID()); + assertEquals("987", (String) attr.get()); + + tested.update(); + mods = tested.getModificationItems(); + assertEquals(0, mods.length); + String[] modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(0, modNames.length); + Attributes attrs = tested.getAttributes(); + attr = attrs.get("abc"); + assertEquals("987", (String) attr.get()); + assertEquals("987", tested.getStringAttribute("abc")); + } + + public void testAddReplaceAndChangeAttribute() throws Exception { + final Attributes fixtureAttrs = new BasicAttributes(); + fixtureAttrs.put(new BasicAttribute("abc", "123")); + fixtureAttrs.put(new BasicAttribute("qwe", "42")); + class TestableDirContextAdapter extends DirContextAdapter { + public TestableDirContextAdapter() { + super(fixtureAttrs, null); + setUpdateMode(true); + } + } + tested = new TestableDirContextAdapter(); + assertTrue(tested.isUpdateMode()); + tested.setAttributeValue("abc", "234"); // change + tested.setAttributeValue("qwe", null); // remove + tested.setAttributeValue("zzz", "new"); // new + Attributes attrs = tested.getAttributes(); + Attribute attr = attrs.get("abc"); + assertEquals("123", (String) attr.get()); + assertEquals(2, attrs.size()); + + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(3, mods.length); + String[] modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(3, modNames.length); + + ModificationItem mod = getModificationItem(mods, DirContext.REPLACE_ATTRIBUTE); + assertNotNull(mod); + attr = mod.getAttribute(); + assertEquals("abc", (String) attr.getID()); + assertEquals("234", (String) attr.get()); + + mod = getModificationItem(mods, DirContext.REMOVE_ATTRIBUTE); + assertNotNull(mod); + attr = mod.getAttribute(); + assertEquals("qwe", (String) attr.getID()); + + mod = getModificationItem(mods, DirContext.ADD_ATTRIBUTE); + assertNotNull(mod); + attr = mod.getAttribute(); + assertEquals("zzz", (String) attr.getID()); + assertEquals("new", (String) attr.get()); + + tested.update(); + mods = tested.getModificationItems(); + assertEquals(0, mods.length); + modNames = tested.getNamesOfModifiedAttributes(); + assertEquals(0, modNames.length); + + attrs = tested.getAttributes(); + assertEquals(2, attrs.size()); + attr = attrs.get("abc"); + assertEquals("234", (String) attr.get()); + assertEquals("new", tested.getStringAttribute("zzz")); + } + + /** + * Test for LDAP-15: DirContextAdapter.setAttribute(). Verifies that setting + * an Attribute should modify updatedAttrs if in update mode. + * + * @throws NamingException + */ + public void testSetAttribute_UpdateMode() throws NamingException { + // Set original attribute value + Attribute attribute = new BasicAttribute("cn", "john doe"); + tested.setAttribute(attribute); + + // Set to update mode + tested.setUpdateMode(true); + + // Perform test - update the attribute + Attribute updatedAttribute = new BasicAttribute("cn", "nisse hult"); + tested.setAttribute(updatedAttribute); + + // Verify result + ModificationItem[] mods = tested.getModificationItems(); + assertEquals(1, mods.length); + assertEquals(DirContext.REPLACE_ATTRIBUTE, mods[0].getModificationOp()); + + Attribute modificationAttribute = mods[0].getAttribute(); + assertEquals("cn", modificationAttribute.getID()); + assertEquals("nisse hult", modificationAttribute.get()); + } + + public void testGetStringAttributes_NullValue() { + String result = tested.getStringAttribute("someAbsentAttribute"); + assertNull(result); + } + + public void testGetStringAttributes_AttributeExists_NullValue() { + tested.setAttribute(new BasicAttribute("someAttribute", null)); + String result = tested.getStringAttribute("someAttribute"); + assertNull(result); + } + + private ModificationItem getModificationItem(ModificationItem[] mods, int operation) { + for (int i = 0; i < mods.length; i++) { + if (mods[i].getModificationOp() == operation) + return mods[i]; + } + return null; + } + + public void testModifyMultiValueAttributeModificationOrder() throws NamingException { + BasicAttribute attribute = new BasicAttribute("abc"); + attribute.add("Some Person"); + attribute.add("Some Other Person"); + + tested.setAttribute(attribute); + tested.setUpdateMode(true); + + tested.setAttributeValues("abc", new String[] { "some person", "Some Other Person" }); + + // Perform test + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(2, modificationItems.length); + ModificationItem modificationItem = modificationItems[0]; + assertEquals(DirContext.REMOVE_ATTRIBUTE, modificationItem.getModificationOp()); + assertEquals("Some Person", modificationItem.getAttribute().get()); + modificationItem = modificationItems[1]; + assertEquals(DirContext.ADD_ATTRIBUTE, modificationItem.getModificationOp()); + assertEquals("some person", modificationItem.getAttribute().get()); + } + + /** + * Test for LDAP-13. + */ + public void testModifyAttributeByteArray() { + tested.setAttribute(new BasicAttribute("abc", new byte[] { 1, 2, 3 })); + + tested.setUpdateMode(true); + + // Perform test + tested.setAttributeValue("abc", new byte[] { 1, 2, 3 }); + + ModificationItem[] modificationItems = tested.getModificationItems(); + assertEquals(0, modificationItems.length); + } }