Java tutorial
/* * Copyright 2005-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.ldap.core; import java.util.ArrayList; import java.util.Hashtable; import java.util.LinkedList; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import javax.naming.Context; import javax.naming.Name; import javax.naming.NameNotFoundException; import javax.naming.NameParser; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.directory.BasicAttributes; import javax.naming.directory.DirContext; import javax.naming.directory.ModificationItem; import javax.naming.directory.SearchControls; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.ldap.NoSuchAttributeException; import org.springframework.ldap.support.LdapUtils; import org.springframework.util.StringUtils; /** * Adapter that implements the interesting methods of the DirContext interface. * In particular it contains utility methods for getting and setting attributes. * Using the * {@link org.springframework.ldap.core.support.DefaultDirObjectFactory} in your * <code>ContextSource</code> (which is the default) you will receive instances * of this class from searches and lookups. This can be particularly useful when * updating data, since this class implements * {@link AttributeModificationsAware}, providing a * {@link #getModificationItems()} method. When in update mode, an object of * this class keeps track of the changes made to its attributes, making them * available as an array of <code>ModificationItem</code> objects, suitable as * input to {@link LdapTemplate#modifyAttributes(DirContextOperations)}. * * Note that this is not a complete implementation of DirContext. Several * methods are not relevant for the intended usage of this class, so they * throw UnsupportOperationException. * * @see #setAttributeValue(String, Object) * @see #setAttributeValues(String, Object[]) * @see #getStringAttribute(String) * @see #getStringAttributes(String) * @see #getObjectAttribute(String) * @see #addAttributeValue(String, Object) * @see #removeAttributeValue(String, Object) * @see #setUpdateMode(boolean) * @see #isUpdateMode() * * @author Magnus Robertsson * @author Andreas Ronge * @author Adam Skogman * @author Mattias Hellborg Arthursson */ public class DirContextAdapter implements DirContextOperations { private static final boolean DONT_ADD_IF_DUPLICATE_EXISTS = false; private static final String EMPTY_STRING = ""; 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; private String referralUrl; /** * Default constructor. */ public DirContextAdapter() { this(null, null, null); } /** * Create a new DirContextAdapter from the supplied DN String. * @param dnString the DN string. Must be syntactically correct, or an * exception will be thrown. */ public DirContextAdapter(String dnString) { this(new DistinguishedName(dnString)); } /** * 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) { this(attrs, dn, base, null); } /** * Create a new adapter from the supplied attributes, dn, base, and referral * url. * @param attrs the attributes. * @param dn the dn. * @param base the base. * @param referralUrl the referral url (if this instance results from a * referral). */ public DirContextAdapter(Attributes attrs, Name dn, Name base, String referralUrl) { if (attrs != null) { this.originalAttrs = attrs; } else { this.originalAttrs = new BasicAttributes(true); } if (dn != null) { this.dn = new DistinguishedName(dn); } else { this.dn = new DistinguishedName(); } if (base != null) { this.base = new DistinguishedName(base); } else { this.base = new DistinguishedName(); } if (referralUrl != null) { this.referralUrl = referralUrl; } else { this.referralUrl = EMPTY_STRING; } } /** * 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 <code>false</code> for a * new entry and <code>true</code> 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; } /* * @seeorg.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 } } /* * @seeorg.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 <code>name</code> with the values on the * array <code>values</code>. The order of the array must be the same order * as the existing multivalued attribute. * <p> * Also handles the case where the values have been reset to the original * values after a previous change. For example, changing * <code>[a,b,c]</code> to <code>[a,b]</code> and then back to * <code>[a,b,c]</code> again must result in this method returning * <code>true</code> 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 || oneAttr.size() == 0) { // LDAP-215 return null; } try { return oneAttr.get(); } catch (NamingException e) { throw LdapUtils.convertLdapException(e); } } // LDAP-215 /* (non-Javadoc) * @see org.springframework.ldap.core.DirContextOperations#attributeExists(java.lang.String) */ public boolean attributeExists(String name) { Attribute oneAttr = originalAttrs.get(name); if (oneAttr == null) { return false; } else { return true; } } /* * @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) { addAttributeValue(name, value, DONT_ADD_IF_DUPLICATE_EXISTS); } public void addAttributeValue(String name, Object value, boolean addIfDuplicateExists) { 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(); if (addIfDuplicateExists || !attr.contains(value)) { attr.add(value); } updatedAttrs.put(attr); } } else { attr.add(value); } } } /* * (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.core.DirContextOperations#getStringAttributes * (java.lang.String) */ public String[] getStringAttributes(String name) { try { return (String[]) collectAttributeValuesAsList(name).toArray(new String[0]); } catch (NoSuchAttributeException e) { // The attribute does not exist - contract says to return null. return null; } } /* * (non-Javadoc) * * @see * org.springframework.ldap.core.DirContextOperations#getObjectAttributes * (java.lang.String) */ public Object[] getObjectAttributes(String name) { try { return collectAttributeValuesAsList(name).toArray(new Object[0]); } catch (NoSuchAttributeException e) { // The attribute does not exist - contract says to return null. return null; } } private List collectAttributeValuesAsList(String name) { List list = new LinkedList(); LdapUtils.collectAttributeValues(originalAttrs, name, list); return list; } /* * @seeorg.springframework.ldap.support.DirContextOperations# * getAttributeSortedStringSet(java.lang.String) */ public SortedSet getAttributeSortedStringSet(String name) { try { TreeSet attrSet = new TreeSet(); LdapUtils.collectAttributeValues(originalAttrs, name, attrSet); return attrSet; } catch (NoSuchAttributeException e) { // The attribute does not exist - contract says to return null. return null; } } /** * 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.hasLength(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.hasLength(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 new DistinguishedName(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()); } else { throw new IllegalStateException("Not possible to call setDn() on a DirContextAdapter in update mode"); } } /** * @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(); } /* * (non-Javadoc) * * @see org.springframework.ldap.core.DirContextOperations#getReferralUrl() */ public String getReferralUrl() { return referralUrl; } /* * (non-Javadoc) * * @see org.springframework.ldap.core.DirContextOperations#isReferral() */ public boolean isReferral() { return StringUtils.hasLength(referralUrl); } }