org.springframework.ldap.core.DirContextAdapter Maven / Gradle / Ivy
/*
* Copyright 2005-2013 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 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;
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 java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;
/**
* 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
* ContextSource
(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 ModificationItem
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 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;
}
/*
* @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 && originalClone.size() == originalAttr.size()) {
// This is actually a complete replacement of the attribute values.
// Fall back to REPLACE
modificationList.add(new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
addedValuesAttribute));
} else {
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 || 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);
}
}