JDiff support now in jdiff-targets, and with svn access to old versions.

This commit is contained in:
Ulrik Sandberg
2007-01-03 23:10:52 +00:00
parent dc1c1c12ea
commit fdb1915dda
110 changed files with 0 additions and 16141 deletions

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.DataIntegrityViolationException;
/**
* Exception that indicates that an invalid or missing Attribute has been
* supplied to an LDAP operation.
*
* @author Mattias Arthursson
*
*/
public class AttributesIntegrityViolationException extends
DataIntegrityViolationException {
private static final long serialVersionUID = -6368616096960202571L;
public AttributesIntegrityViolationException(String msg) {
super(msg);
}
public AttributesIntegrityViolationException(String msg, Throwable t) {
super(msg, t);
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
/**
* An interface used by LdapTemplate for mapping LDAP Attributes to beans.
* Implementions of this interface perform the actual work of extracting
* results, but need not worry about exception handling. NamingExceptions will
* be caught and handled correctly by the LdapTemplate class.
* <p>
* Typically used in LdapTemplate's search methods. AttributeMapper objects are
* typically stateless and thus reusable; they are ideal for implementing
* attribute-mapping logic in one place.
* <p>
* Alternatively, consider using a {@link ContextMapper} in stead.
*
* @see org.springframework.ldap.LdapTemplate#search(Name, String,
* AttributesMapper)
* @see ContextMapper
*
* @author Mattias Arthursson
*/
public interface AttributesMapper {
/**
* Map Attributes to an object. The supplied attributes are the attributes
* from a single SearchResult.
*
* @param attributes
* attributes from a SearchResult.
* @return an object built from the attributes.
* @throws NamingException if any error occurs mapping the attributes
*/
public Object mapFromAttributes(Attributes attributes)
throws NamingException;
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2002-2005 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;
/**
* An AuthenticationSource is responsible for providing the principal and
* credentials to be used when creating a new context.
*
* @author Mattias Arthursson
*
*/
public interface AuthenticationSource {
/**
* Get the principal to use when creating an authenticated context.
*
* @return the principal (userName).
*/
public String getPrincipal();
/**
* Get the credentials to use when creating an authenticated context.
*
* @return the credentials (userName).
*/
public String getCredentials();
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
/**
* Thrown to indicate that an invalid value has been supplied to an LDAP
* operation. This could be an invalid filter or dn.
*
* @author Mattias Arthursson
*/
public class BadLdapGrammarException extends
InvalidDataAccessResourceUsageException {
private static final long serialVersionUID = 961612585331409470L;
public BadLdapGrammarException(String message) {
super(message);
}
public BadLdapGrammarException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2002-2005 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;
import java.util.LinkedList;
import java.util.List;
import javax.naming.NameClassPair;
/**
* A NameClassPairCallbackHandler to collect all results in an internal List.
*
* @see org.springframework.ldap.LdapTemplate
*
* @author Mattias Arthursson
*/
public abstract class CollectingNameClassPairCallbackHandler implements
NameClassPairCallbackHandler {
private List list = new LinkedList();
/**
* Get the assembled list.
*
* @return the list of all assembled objects.
*/
public List getList() {
return list;
}
/**
* Pass on the supplied NameClassPair to
* {@link #getObjectFromNameClassPair(NameClassPair)} and add the result to
* the internal list.
*/
public void handleNameClassPair(NameClassPair nameClassPair) {
list.add(getObjectFromNameClassPair(nameClassPair));
}
/**
* Handle a NameClassPair and transform it to an Object of the desired type
* and with data from the NameClassPair.
*
* @param nameClassPair
* a NameClassPair from a search operation.
* @return an object constructed from the data in the NameClassPair.
*/
public abstract Object getObjectFromNameClassPair(
NameClassPair nameClassPair);
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2002-2005 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;
/**
* Helper interface to be used by Dao implementations for assembling to and from
* context. Useful if we have assembler classes responsible for mapping to and
* from a specific entry.
*
* @author Mattias Arthursson
*/
public interface ContextAssembler extends ContextMapper {
/**
* Map the supplied object to the specified context.
*
* @param obj
* the object to read data from.
* @param ctx
* the context to map to.
*/
public void mapToContext(Object obj, Object ctx);
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
/**
* Interface for delegating an actual operation to be performed on an
* DirContext. For searches, use {@link org.springframework.ldap.SearchExecutor} in
* stead. A typical usage of this interface could be e.g.:
*
* <pre>
* ContextExecutor executor = new ContextExecutor(){
* public Object executeWithContext(DirContext ctx) throws NamingException{
* return ctx.lookup(dn);
* }
* };
* </pre>
*
* @see org.springframework.ldap.LdapTemplate#executeReadOnly(ContextExecutor)
* @see org.springframework.ldap.LdapTemplate#executeReadWrite(ContextExecutor)
*
* @author Mattias Arthursson
*/
public interface ContextExecutor {
/**
* Perform any operation on the context.
*
* @param ctx
* the DirContext to perform the operation on.
* @return any object resulting from the operation - might be null.
* @throws NamingException
* if the operation resulted in one.
*/
public Object executeWithContext(DirContext ctx) throws NamingException;
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.Binding;
import javax.naming.Name;
import javax.naming.directory.SearchResult;
import org.springframework.ldap.support.DefaultDirObjectFactory;
import org.springframework.ldap.support.DirContextAdapter;
/**
* An interface used by LdapTemplate to map LDAP Contexts to beans. Responsible
* for mapping from LDAP Contexts to beans. When a DirObjectFactory is set on
* the ContextSource, the objects returned from <code>search</code> and
* <code>listBindings</code> operations are automatically transformed to
* DirContext objects (when using the {@link DefaultDirObjectFactory}, you get
* a {@link DirContextAdapter} object). This object will then be passed to the
* ContextMapper implementation for transformation to the desired bean.
* <p>
* ContextMapper implementations are typically stateless and thus reusable; they
* are ideal for implementing mapping logic in one place.
* <p>
* Alternatively, consider using an {@link AttributesMapper} in stead.
*
* @see LdapTemplate#search(Name, String,
* ContextMapper)
* @see LdapTemplate#listBindings(Name, ContextMapper)
* @see LdapTemplate#lookup(Name, ContextMapper)
* @see AttributesMapper
* @see DefaultDirObjectFactory
* @see DirContextAdapter
*
* @author Mattias Arthursson
*/
public interface ContextMapper {
/**
* Map a single LDAP Context to an object. The supplied Object
* <code>ctx</code> is the object from a single {@link SearchResult},
* {@link Binding}, or a lookup operation.
*
* @param ctx
* the context to map to an object.
* @return an object built from the data in the context.
*/
public Object mapFromContext(Object ctx);
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.directory.DirContext;
import org.springframework.dao.DataAccessException;
/**
* Interface used to retrieve and authenticate LDAP contexts.
*
* @see org.springframework.ldap.LdapTemplate
*
* @author Adam Skogman
* @author Mattias Arthursson
*/
public interface ContextSource {
/**
* Gets a read-only DirContext. The returned DirContext must be possible to
* perform read-only operations on.
*
* @return A DirContext instance, never null.
* @throws DataAccessException
* if some error occurs creating an DirContext.
*/
public DirContext getReadOnlyContext() throws DataAccessException;
/**
* Gets a read-write DirContext.
*
* @return A DirContext instance, never null.
* @throws DataAccessException
* if some error occurs creating an DirContext.
*/
public DirContext getReadWriteContext() throws DataAccessException;
}

View File

@@ -1,46 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NameClassPair;
import javax.naming.NamingException;
/**
* The default NameClassPairMapper implementation. This implementation simply
* takes the Name string from the supplied NameClassPair and returns it as
* result.
*
* @author Mattias Arthursson
*
*/
public class DefaultNameClassPairMapper implements NameClassPairMapper {
/**
* Gets the Name from the supplied NameClassPair and returns it as the
* result.
*
* @param nameClassPair
* the NameClassPair to transform.
* @return the Name string from the NameClassPair.
*/
public Object mapFromNameClassPair(NameClassPair nameClassPair)
throws NamingException {
return nameClassPair.getName();
}
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.CommunicationException;
import javax.naming.ContextNotEmptyException;
import javax.naming.LimitExceededException;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.directory.InvalidAttributesException;
import javax.naming.directory.InvalidSearchControlsException;
import javax.naming.directory.InvalidSearchFilterException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
/**
* The default implementation of NamingExceptionTranslator.
*
* @author Mattias Arthursson
*/
public class DefaultNamingExceptionTranslator implements
NamingExceptionTranslator {
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.NamingExceptionTranslator#translate(java.lang.String,
* java.lang.String, java.lang.String, javax.naming.NamingException)
*/
public DataAccessException translate(NamingException namingException) {
if (namingException instanceof NameNotFoundException) {
return new EntryNotFoundException("Entry not found",
namingException);
}
if (namingException instanceof InvalidSearchFilterException) {
return new BadLdapGrammarException("Invalid search filter",
namingException);
}
if (namingException instanceof InvalidSearchControlsException) {
return new InvalidDataAccessApiUsageException(
"Invalid search controls supplied by internal API",
namingException);
}
if (namingException instanceof NameAlreadyBoundException) {
return new DataIntegrityViolationException("Name already bound",
namingException);
}
if (namingException instanceof ContextNotEmptyException) {
return new DataIntegrityViolationException(
"The context needs to be empty in order to be removed",
namingException);
}
if (namingException instanceof InvalidAttributesException) {
return new AttributesIntegrityViolationException(
"Invalid attributes", namingException);
}
if (namingException instanceof LimitExceededException) {
return new SearchLimitExceededException("Too many objects found",
namingException);
}
if (namingException instanceof CommunicationException) {
throw new DataRetrievalFailureException(
"Unable to communicate with LDAP server", namingException);
}
// Fallback - other type of NamingException encountered.
return new UncategorizedLdapException("Operation failed",
namingException);
}
}

View File

@@ -1,49 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
/**
* Interface to be called in search by LdapTemplate before and after the actual
* search and enumeration traversal.
*
* @author Mattias Arthursson
* @author Ulrik Sandberg
*/
public interface DirContextProcessor {
/**
* Perform pre-processing on the supplied DirContext.
*
* @param ctx
* the DirContext instance.
* @throws NamingException
* if thrown by the underlying operation.
*/
public void preProcess(DirContext ctx) throws NamingException;
/**
* Perform post-processing on the supplied DirContext.
*
* @param ctx
* the DirContext instance.
* @throws NamingException
* if thrown by the underlying operation.
*/
public void postProcess(DirContext ctx) throws NamingException;
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.DataRetrievalFailureException;
/**
* Represents that an entry could not be found.
*
* @author Mattias Arthursson
*/
public class EntryNotFoundException extends DataRetrievalFailureException {
private static final long serialVersionUID = -1268390922996332424L;
public EntryNotFoundException(String msg) {
super(msg);
}
public EntryNotFoundException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NameClassPair;
/**
* Callback interface used by LdapTemplate's search, list and listBindings
* methods. Implementations of this interface perform the actual work of
* extracting results from a single NameClassPair (a NameClassPair,
* Binding or SearchResult depending on the search operation) returned by an
* LDAP seach operation, such as search(), list(), and listBindings().
*
* @author Mattias Arthursson
*/
public interface NameClassPairCallbackHandler {
/**
* Handle one entry. This method will be called once for each entry returned
* by a search or list.
*
* @param nameClassPair
* the NameClassPair returned from the NamingEnumeration.
*/
public void handleNameClassPair(NameClassPair nameClassPair);
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NameClassPair;
import javax.naming.NamingException;
/**
* Responsible for mapping NameClassPair objects to beans.
*
* @author Mattias Arthursson
*/
public interface NameClassPairMapper {
/**
* Map NameClassPair to an Object. The supplied NameClassPair is one of the
* results from a search operation (search, list or listBindings). Depending
* on which search operation is being performed, the NameClassPair might be
* a SearchResult, Binding or NameClassPair.
*
* @param nameClassPair
* NameClassPair from a search operation.
* @return and Object built from the NameClassPair.
* @throws NamingException
* if one is encountered in the operation.
*/
public Object mapFromNameClassPair(NameClassPair nameClassPair)
throws NamingException;
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NamingException;
import org.springframework.dao.DataAccessException;
/**
* Interface to be implemented by classes that can translate between
* NamingExceptions and DataAccessExceptions.
*
* @author Mattias Arthursson
*
*/
public interface NamingExceptionTranslator {
/**
* Translate the given NamingException into a generic data access exception.
* @param namingException
* the offending NamingException.
*
* @return the DataAccessException to throw.
*/
public DataAccessException translate(NamingException namingException);
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
/**
* Interface for delegating an actual search operation. The typical
* implementation of executeSearch would be something like:
*
* <pre>
* SearchExecutor executor = new SearchExecutor(){
* public NamingEnumeration executeSearch(DirContext ctx) throws NamingException{
* return ctx.search(dn, filter, searchControls);
* }
* }
* </pre>
*
* @see org.springframework.ldap.LdapTemplate#search(SearchExecutor,
* NameClassPairCallbackHandler)
*
* @author Mattias Arthursson
*/
public interface SearchExecutor {
/**
* Execute the actual search.
*
* @param ctx
* the DirContext on which to work.
* @return the NamingEnumeration resulting from the search operation.
* @throws NamingException
* if the search results in one.
*/
public NamingEnumeration executeSearch(DirContext ctx)
throws NamingException;
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.DataRetrievalFailureException;
/**
* Indicates that the search limit was exceeded in a search.
*
* @author Mattias Arthursson
*
*/
public class SearchLimitExceededException extends DataRetrievalFailureException {
private static final long serialVersionUID = 6899885947075235580L;
public SearchLimitExceededException(String msg) {
super(msg);
}
public SearchLimitExceededException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.UncategorizedDataAccessException;
/**
* Indicates that an unknown NamingException has occurred.
*
* @author Mattias Arthursson
*/
public class UncategorizedLdapException extends
UncategorizedDataAccessException {
private static final long serialVersionUID = -3319936235493869823L;
public UncategorizedLdapException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,3 +0,0 @@
<body>
The core package of the Spring-LDAP library.
</body>

View File

@@ -1,459 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.JdkVersion;
import org.springframework.ldap.AuthenticationSource;
import org.springframework.ldap.ContextSource;
import org.springframework.ldap.DefaultNamingExceptionTranslator;
import org.springframework.ldap.NamingExceptionTranslator;
/**
* Abstract implementation of the ContextSource interface. By default, returns
* an authenticated DirContext implementation for both read-only and read-write
* operations. To have an anonymous environment created for read-only
* operations, set the anonymousReadOnly property to <code>true</code>.
* <p>
* Implementing classes need to implement
* {@link #getDirContextInstance(Hashtable)} to create a DirContext instance of
* the desired type.
* <p>
* If an AuthenticationSource is set, this will be used for getting user name
* and password for each new connection, otherwise a default one will be created
* using the specified userName and password.
* <p>
* <b>Note:</b> When using implementations of this class outside of a Spring
* Context it is necessary to call {@link #afterPropertiesSet()} when all
* properties are set, in order to finish up initialization.
*
* @see org.springframework.ldap.LdapTemplate
* @see org.springframework.ldap.support.DefaultDirObjectFactory
* @see org.springframework.ldap.support.LdapContextSource
* @see org.springframework.ldap.support.DirContextSource
*
* @author Mattias Arthursson
* @author Adam Skogman
* @author Ulrik Sandberg
*/
public abstract class AbstractContextSource implements ContextSource,
InitializingBean {
private static final Class DEFAULT_CONTEXT_FACTORY = com.sun.jndi.ldap.LdapCtxFactory.class;
private static final Class DEFAULT_DIR_OBJECT_FACTORY = DefaultDirObjectFactory.class;
private Class dirObjectFactory = DEFAULT_DIR_OBJECT_FACTORY;
private Class contextFactory = DEFAULT_CONTEXT_FACTORY;
private DistinguishedName base;
protected String userName = "";
protected String password = "";
private String[] urls;
private boolean pooled = true;
private Hashtable baseEnv = new Hashtable();
private Hashtable anonymousEnv;
private AuthenticationSource authenticationSource;
private boolean cacheEnvironmentProperties = true;
private boolean anonymousReadOnly = false;
private NamingExceptionTranslator exceptionTranslator = new DefaultNamingExceptionTranslator();
private static final Log log = LogFactory.getLog(LdapContextSource.class);
public static final String SUN_LDAP_POOLING_FLAG = "com.sun.jndi.ldap.connect.pool";
private static final String JDK_142 = "1.4.2";
public DirContext getReadOnlyContext() {
if (!anonymousReadOnly) {
return createContext(getAuthenticatedEnv());
} else {
return createContext(getAnonymousEnv());
}
}
public DirContext getReadWriteContext() {
return createContext(getAuthenticatedEnv());
}
/**
* Default implementation of setting the environment up to be authenticated.
* Override in subclass if necessary. This is needed for Active Directory
* connectivity, for example.
*
* @param env
* the environment to modify.
*/
protected void setupAuthenticatedEnvironment(Hashtable env) {
env
.put(Context.SECURITY_PRINCIPAL, authenticationSource
.getPrincipal());
log.debug("Principal: '" + userName + "'");
env.put(Context.SECURITY_CREDENTIALS, authenticationSource
.getCredentials());
}
/**
* Close the context and swallow any exceptions.
*
* @param ctx
* the DirContext to close.
*/
private void closeContext(DirContext ctx) {
if (ctx != null) {
try {
ctx.close();
} catch (Exception e) {
}
}
}
/**
* Assemble a valid url String from all registered urls to add as
* PROVIDER_URL to the environment.
*
* @param ldapUrls
* all individual url Strings.
* @return the full url String
*/
protected String assembleProviderUrlString(String[] ldapUrls) {
StringBuffer providerUrlBuffer = new StringBuffer(1024);
for (int i = 0; i < ldapUrls.length; i++) {
providerUrlBuffer.append(ldapUrls[i]);
if (base != null) {
if (!ldapUrls[i].endsWith("/")) {
providerUrlBuffer.append("/");
}
providerUrlBuffer.append(base.toUrl());
}
providerUrlBuffer.append(' ');
}
return providerUrlBuffer.toString().trim();
}
/**
* Set the base suffix from which all operations should origin. If a base
* suffix is set, you will not have to (and, indeed, should not) specify the
* full distinguished names in the operations performed.
*
* @param base
* the base suffix.
*/
public void setBase(String base) {
this.base = new DistinguishedName(base);
}
/**
* Create a DirContext using the supplied environment.
*
* @param environment
* the Ldap environment to use when creating the DirContext.
* @return a new DirContext implpementation initialized with the supplied
* environment.
*/
DirContext createContext(Hashtable environment) {
DirContext ctx = null;
try {
ctx = getDirContextInstance(environment);
if (log.isInfoEnabled()) {
Hashtable ctxEnv = ctx.getEnvironment();
String ldapUrl = (String) ctxEnv.get(Context.PROVIDER_URL);
log.debug("Got Ldap context on server '" + ldapUrl + "'");
}
return ctx;
} catch (NamingException e) {
closeContext(ctx);
throw getExceptionTranslator().translate(e);
}
}
/**
* Set the context factory. Default is com.sun.jndi.ldap.LdapCtxFactory.
*
* @param contextFactory
* the context factory used when creating Contexts.
*/
public void setContextFactory(Class contextFactory) {
this.contextFactory = contextFactory;
}
/**
* Set the DirObjectFactory to use. Default is
* {@link DefaultDirObjectFactory}. The specified class needs to be an
* implementation of javax.naming.spi.DirObjectFactory. <b>Note: </b>Setting
* this value to null may have cause connection leaks when using
* ContextMapper methods in LdapTemplate.
*
* @param dirObjectFactory
* the DirObjectFactory to be used. Null means that no
* DirObjectFactory will be used.
*/
public void setDirObjectFactory(Class dirObjectFactory) {
this.dirObjectFactory = dirObjectFactory;
}
/**
* Checks that all necessary data is set and that there is no compatibility
* issues, after which the instance is initialized. Note that you need to
* call this method explicitly after setting all desired properties if using
* the class outside of a Spring Context.
*/
public void afterPropertiesSet() throws Exception {
if (ArrayUtils.isEmpty(urls)) {
throw new IllegalArgumentException(
"At least one server url must be set");
}
if (base != null && getJdkVersion().compareTo(JDK_142) < 0) {
throw new IllegalArgumentException(
"Base path is not supported for JDK versions < 1.4.2");
}
if (authenticationSource == null) {
log.debug("AuthenticationSource not set - "
+ "using default implementation");
if (StringUtils.isBlank(userName)) {
log
.warn("Property 'userName' not set - "
+ "anonymous context will be used for read-write operations");
} else if (StringUtils.isBlank(password)) {
log.warn("Property 'password' not set - "
+ "blank password will be used");
}
authenticationSource = new SimpleAuthenticationSource();
}
if (cacheEnvironmentProperties) {
anonymousEnv = setupAnonymousEnv();
}
}
private Hashtable setupAnonymousEnv() {
if (pooled) {
baseEnv.put(SUN_LDAP_POOLING_FLAG, "true");
log.debug("Using LDAP pooling.");
} else {
log.debug("Not using LDAP pooling");
}
Hashtable env = new Hashtable(baseEnv);
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory.getName());
env.put(Context.PROVIDER_URL, assembleProviderUrlString(urls));
if (dirObjectFactory != null) {
env.put(Context.OBJECT_FACTORIES, dirObjectFactory.getName());
}
if (base != null) {
// Save the base path for use in the DefaultDirObjectFactory.
env.put(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY, base);
}
log.debug("Trying provider Urls: " + assembleProviderUrlString(urls));
return env;
}
/**
* Set the password (credentials) to use for getting authenticated contexts.
*
* @param password
* the password.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Set the user name (principal) to use for getting authenticated contexts.
*
* @param userName
* the user name.
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* Set the urls of the LDAP servers. Use this method if several servers are
* required.
*
* @param urls
* the urls of all servers.
*/
public void setUrls(String[] urls) {
this.urls = urls;
}
/**
* Set the url of the LDAP server. Utility method if only one server is
* used.
*
* @param url
* the url of the LDAP server.
*/
public void setUrl(String url) {
this.urls = new String[] { url };
}
/**
* Set whether the pooling flag should be set. Default is true.
*
* @param pooled
* whether Contexts should be pooled.
*/
public void setPooled(boolean pooled) {
this.pooled = pooled;
}
/**
* If any custom environment properties are needed, these can be set using
* this method.
*
* @param baseEnvironmentProperties
*/
public void setBaseEnvironmentProperties(Map baseEnvironmentProperties) {
this.baseEnv = new Hashtable(baseEnvironmentProperties);
}
String getJdkVersion() {
return JdkVersion.getJavaVersion();
}
protected Hashtable getAnonymousEnv() {
if (cacheEnvironmentProperties) {
return anonymousEnv;
} else {
return setupAnonymousEnv();
}
}
protected Hashtable getAuthenticatedEnv() {
// The authenticated environment should always be rebuilt.
Hashtable env = new Hashtable(getAnonymousEnv());
setupAuthenticatedEnvironment(env);
return env;
}
public void setAuthenticationSource(
AuthenticationSource authenticationProvider) {
this.authenticationSource = authenticationProvider;
}
/**
* Set whether environment properties should be cached between requsts for
* anonymous environment. Default is true; setting this property to false
* causes the environment Hashmap to be rebuilt from the current property
* settings of this instance between each request for an anonymous
* environment.
*
* @param cacheEnvironmentProperties
* true causes that the anonymous environment properties should
* be cached, false causes the Hashmap to be rebuilt for each
* request.
*/
public void setCacheEnvironmentProperties(boolean cacheEnvironmentProperties) {
this.cacheEnvironmentProperties = cacheEnvironmentProperties;
}
/**
* Set whether an anonymous environment should be used for read-only
* operations. Default is <code>false</code>.
*
* @param anonymousReadOnly
* <code>true</code> if and anonymous environment should be
* used for read-only operations, <code>false</code> otherwise.
*/
public void setAnonymousReadOnly(boolean anonymousReadOnly) {
this.anonymousReadOnly = anonymousReadOnly;
}
/**
* Set the NamingExceptionTranslator to be used by this instance. By
* default, a {@link DefaultNamingExceptionTranslator} will be used.
*
* @param exceptionTranslator
* the NamingExceptionTranslator to use.
*/
public void setExceptionTranslator(
NamingExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator;
}
/**
* Get the NamingExceptionTranslator used by this instance.
*
* @return the NamingExceptionTranslator.
*/
public NamingExceptionTranslator getExceptionTranslator() {
return exceptionTranslator;
}
/**
* Implement in subclass to create a DirContext of the desired type (e.g.
* InitialDirContext or InitialLdapContext).
*
* @param environment
* the environment to use when creating the instance.
* @return a new DirContext instance.
* @throws NamingException
* if one is encountered when creating the instance.
*/
protected abstract DirContext getDirContextInstance(Hashtable environment)
throws NamingException;
class SimpleAuthenticationSource implements AuthenticationSource {
public String getPrincipal() {
return userName;
}
public String getCredentials() {
return password;
}
}
protected String[] getUrls() {
return urls;
}
}

View File

@@ -1,72 +0,0 @@
package org.springframework.ldap.support;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.springframework.ldap.DirContextProcessor;
/**
* Manages a sequence of DirContextProcessor instances. Applies
* {@link #preProcess(DirContext)} and {@link #postProcess(DirContext)}
* respectively in sequence on the managed objects.
*
* @author Mattias Arthursson
* @author Ulrik Sandberg
*/
public class AggregateDirContextProcessor implements DirContextProcessor {
private List dirContextProcessors = new LinkedList();
/**
* Add the supplied DirContextProcessor to the list of managed objects.
*
* @param processor
* the DirContextpProcessor to add.
*/
public void addDirContextProcessor(DirContextProcessor processor) {
dirContextProcessors.add(processor);
}
/**
* Get the list of managed DirContextProcessors.
*
* @return the managed list of {@link DirContextProcessor} instances.
*/
public List getDirContextProcessors() {
return dirContextProcessors;
}
/**
* Set the list of managed {@link DirContextProcessor} instances.
*
* @param dirContextProcessors
* the list of {@link DirContextProcessor} instances to set.
*/
public void setDirContextProcessors(List dirContextProcessors) {
this.dirContextProcessors = dirContextProcessors;
}
/*
* @see org.springframework.ldap.DirContextProcessor#preProcess(javax.naming.directory.DirContext)
*/
public void preProcess(DirContext ctx) throws NamingException {
for (Iterator iter = dirContextProcessors.iterator(); iter.hasNext();) {
DirContextProcessor processor = (DirContextProcessor) iter.next();
processor.preProcess(ctx);
}
}
/*
* @see org.springframework.ldap.DirContextProcessor#postProcess(javax.naming.directory.DirContext)
*/
public void postProcess(DirContext ctx) throws NamingException {
for (Iterator iter = dirContextProcessors.iterator(); iter.hasNext();) {
DirContextProcessor processor = (DirContextProcessor) iter.next();
processor.postProcess(ctx);
}
}
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import javax.naming.directory.ModificationItem;
/**
* Indicates that the implementor is capable of keeping track of any attribute
* modifications and return them as ModificationItems.
*
* @author Mattias Arthursson
*
*/
public interface AttributeModificationsAware {
/**
* Creates an array of which attributes have been changed or added or removed.
*
* @return an array of modification items
*/
public ModificationItem[] getModificationItems();
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import javax.naming.NameClassPair;
import org.springframework.ldap.NameClassPairCallbackHandler;
/**
* A NameClassPairCallbackHandler for counting all returned entries.
*
* @author Mattias Arthursson
*
*/
public class CountNameClassPairCallbackHandler implements
NameClassPairCallbackHandler {
private int noOfRows = 0;
/**
* Get the number of rows that was returned by the search.
*
* @return the number of entries that have been handled.
*/
public int getNoOfRows() {
return noOfRows;
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.SearchResultCallbackHandler#handleSearchResult(javax.naming.directory.SearchResult)
*/
public void handleNameClassPair(NameClassPair nameClassPair) {
noOfRows++;
}
}

View File

@@ -1,93 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.directory.Attributes;
import javax.naming.spi.DirObjectFactory;
/**
* Default implementation of the DirObjectFactory interface. Creates a
* DirContextAdapter from the supplied arguments.
*
* @author Mattias Arthursson
*/
public class DefaultDirObjectFactory implements DirObjectFactory {
/**
* Key to use in the ContextSource implementation to store the value of the
* base path suffix, if any, in the Ldap Environment.
*/
public static final String JNDI_ENV_BASE_PATH_KEY = "org.springframework.ldap.base.path";
/**
* Creates a DirContextAdapter from the supplied arguments.
*
* @param obj
* @param name
* @param nameCtx
* @param environment
* @param attrs
* @return a new DirContextAdapter from the attributes and name.
* @throws Exception
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment, Attributes attrs) throws Exception {
try {
DirContextAdapter dirContextAdapter = new DirContextAdapter(attrs,
name, (Name) environment.get(JNDI_ENV_BASE_PATH_KEY));
dirContextAdapter.setUpdateMode(true);
return dirContextAdapter;
} finally {
// It seems that the object supplied to the obj parameter is a
// DirContext instance with reference to the same Ldap connection as
// the original context. Since it is not the same instance (that's
// the nameCtx parameter) this one really needs to be closed in
// order to correctly clean up and return the connection to the pool
// when we're finished with the surrounding operation.
if (obj instanceof Context) {
Context ctx = (Context) obj;
try {
ctx.close();
} catch (Exception e) {
// Never mind this
}
}
}
}
/**
* Returns null.
*
* @param obj
* @param name
* @param nameCtx
* @param environment
* @return null.
* @throws Exception
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment) throws Exception {
return null;
}
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.io.StringReader;
/**
* A factory for creating DnParser instances. The actual implementation of
* DnParser is generated using javacc and should not be constructed directly.
*
* @author Mattias Arthursson
*
*/
public class DefaultDnParserFactory {
/**
* Create a new DnParser instance.
*
* @param string
* the DN String to be parsed.
* @return a new DnParser instance for parsing the supplied DN string.
*/
public static DnParser createDnParser(String string) {
return new DnParserImpl(new StringReader(string));
}
}

View File

@@ -1,161 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.SortedSet;
import javax.naming.Name;
import javax.naming.directory.DirContext;
/**
* Interface for DirContextAdapter to simplify mock testing.
*
* @author Mattias Arthursson
*/
public interface DirContextOperations extends DirContext,
AttributeModificationsAware {
/**
* Gets the update mode. The update mode should be <code>true</code> for a
* new entry and <code>true</code> for an existing entry that is being
* updated.
*
* @return update mode
*/
public boolean isUpdateMode();
/**
* Creates a String array of the names of the attributes which have been
* changed.
*
* If this is a new entry, all set entries will be in the list. If this is
* an updated entry, only changed and removed entries will be in the array.
*
* @return Array of String
*/
public String[] getNamesOfModifiedAttributes();
/**
* Get the value of a String attribute.
*
* @param name
* name of the attribute.
* @return the value of the attribute.
*/
public String getStringAttribute(String name);
/**
* Get the value of an Object attribute.
*
* @param name
* name of the attribute.
* @return the attribute value as an object if it exists, or
* <code>null</code> otherwise.
*/
public Object getObjectAttribute(String name);
/**
* Set the with the name <code>name</code> to the <code>value</code>.
*
* @param name
* name of the attribute.
* @param value
* value to set the attribute to.
*/
public void setAttributeValue(String name, Object value);
/**
* Sets a multivalue attribute, disregarding the order of the values.
*
* If value is null or value.length == 0 then the attribute will be removed.
*
* If update mode, changes will be made only if the array has more or less
* objects or if one or more object has changed. Reordering the objects will
* not cause an update.
*
* @param name
* The id of the attribute.
* @param values
* Attribute values.
*/
public void setAttributeValues(String name, Object[] values);
/**
* Sets a multivalue attribute.
*
* If value is null or value.length == 0 then the attribute will be removed.
*
* If update mode, changes will be made if the array has more or less
* objects or if one or more string has changed.
*
* Reordering the objects will only cause an update if orderMatters is set
* to true.
*
* @param name
* The id of the attribute.
* @param values
* Attribute values.
* @param orderMatters
* If <code>true</code>, it will be changed even if data was
* just reordered.
*/
public void setAttributeValues(String name, Object[] values,
boolean orderMatters);
/**
* Update the attributes. This will mean that the getters
* (getStringAttribute methods) will return the updated values. Remove the
* attributes to be updated.
*/
public void update();
/**
* Get all values of a String attribute.
*
* @param name
* name of the attribute.
*
* @return all registered values of the attribute.
*/
public String[] getStringAttributes(String name);
/**
* Get all String values of the attribute as a SortedSet.
*
* @param name
* name of the attribute.
* @return a SortedSet containing all values of the attribute.
*/
public SortedSet getAttributeSortedStringSet(String name);
/**
* Returns DN, without the base path.
*
* @return The distinguished name of the current context.
*
* @see DirContextAdapter#getNameInNamespace()
*/
public Name getDn();
/**
* Set the dn of this entry.
*
* @param dn
* the dn.
*/
public void setDn(Name dn);
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
/**
* ContextSource implementation which creates InitialDirContext instances, for
* LDAPv2 compatibility. For configuration information, see
* {@link org.springframework.ldap.support.AbstractContextSource AbstractContextSource}.
*
* @see org.springframework.ldap.support.AbstractContextSource
*
* @author Mattias Arthursson
*/
public class DirContextSource extends AbstractContextSource {
/**
* Create a new InitialDirContext instance.
*
* @param environment
* the environment to use when creating the context.
* @return a new InitialDirContext implementation.
*/
protected DirContext getDirContextInstance(Hashtable environment)
throws NamingException {
return new InitialDirContext(environment);
}
}

View File

@@ -1,629 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import javax.naming.CompositeName;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.BadLdapGrammarException;
import org.springframework.ldap.util.ListComparator;
/**
* Default implementation of a Name corresponding to an LDAP path. A
* DistinguishedName implementation is included in JDK1.5 (LdapName), but not in
* prior releases.
*
* An DistinguishedName is particularly useful when building or modifying an
* Ldap path dynamically, as escaping will be taken care of.
*
* A path is split into several names. The Name interface specifies that the
* most significant part be in position 0, i.e.
*
* The path: uid=adam.skogman, ou=People, ou=EU Name[0]: ou=EU Name[1]:
* ou=People Name[2]: uid=adam.skogman
* <p>
* Useful for parsing and building LDAP paths.
*
* <pre>
* DistinguishedName path = new DistinguishedName();
* path.addLast(&quot;cn&quot;, entry.getUid());
* path.addLast(&quot;ou&quot;, &quot;users&quot;);
* path.append(new DistinguishedName(helpdesk.getSomeSuffix()));
* String dn = path.toString();
* </pre>
*
* @author Adam Skogman
* @author Mattias Arthursson
*/
public class DistinguishedName implements Name {
private static final long serialVersionUID = 3514344371999042586L;
/**
* An empty, unmodifiable DistinguishedName.
*/
public static final DistinguishedName EMPTY_PATH = new DistinguishedName(
Collections.EMPTY_LIST);
private List names;
/**
* Construct a new DistinguishedName with no components.
*/
public DistinguishedName() {
names = new LinkedList();
}
/**
* Construct a new DistinguishedName from a String.
*
* @param path
* a String corresponding to a (syntactically) valid LDAP path.
*/
public DistinguishedName(String path) {
if (StringUtils.isBlank(path)) {
names = new LinkedList();
} else {
parse(path);
}
}
/**
* Construct a new DistinguishedName from the supplied List of LdapRdn
* objects.
*
* @param list
* the components that this instance will consist of.
*/
public DistinguishedName(List list) {
this.names = list;
}
/**
* Construct a new DistinguishedName from the supplied Name. The parts of
* the supplied Name must be syntactically correct LdapRdns.
*
* @param name
* the Name to construct a new DistinguishedName from.
*/
public DistinguishedName(Name name) {
names = new LinkedList();
for (int i = 0; i < name.size(); i++) {
names.add(new LdapRdn(name.get(i)));
}
}
/**
* Parse the supplied String and make this instance represent the
* corresponding distinguished name.
*
* @param path
* the LDAP path to parse.
*/
protected void parse(String path) {
DnParser parser = DefaultDnParserFactory
.createDnParser(unmangleCompositeName(path));
DistinguishedName dn;
try {
dn = parser.dn();
} catch (ParseException e) {
throw new BadLdapGrammarException("Failed to parse DN", e);
} catch (TokenMgrError e) {
throw new BadLdapGrammarException("Failed to parse DN", e);
}
this.names = dn.names;
}
/**
* If path is surrounded by quotes, strip them. JNDI considers forward slash
* ('/') special, but LDAP doesn't. {@link CompositeName#toString()} tends
* to mangle a Name with a slash by surrounding it with quotes ('"').
*
* @param path
* Path to check and possibly strip.
* @return A String with the possibly stripped path.
*/
private String unmangleCompositeName(String path) {
String tempPath;
// Check if CompositeName has mangled the name with quotes
if (path.startsWith("\"") && path.endsWith("\"")) {
tempPath = path.substring(1, path.length() - 1);
} else {
tempPath = path;
}
return tempPath;
}
/**
* Get the LdapRdn at a specified position.
*
* @param index
* the LdapRdn to retrieve.
* @return the LdapRdn at the requested position.
*/
public LdapRdn getLdapRdn(int index) {
return (LdapRdn) names.get(index);
}
/**
* Get the name list.
*
* @return the list of LdapRdns that this DistinguishedName consists of.
*/
public List getNames() {
return names;
}
/**
* Get the String representation of this DistinguishedName.
*
* @return a syntactically correct, escaped String representation of the
* DistinguishedName.
*/
public String toString() {
return encode();
}
/**
* Builds a complete LDAP path, ldap encoded, useful as a DN.
*
* Always uses lowercase, always separates with ", " i.e. comma and a space.
*
* @return the LDAP path.
*/
public String encode() {
// empty path
if (names.size() == 0)
return "";
StringBuffer buffer = new StringBuffer(256);
ListIterator i = names.listIterator(names.size());
while (i.hasPrevious()) {
LdapRdn rdn = (LdapRdn) i.previous();
buffer.append(rdn.getLdapEncoded());
// add comma, except in last iteration
if (i.hasPrevious())
buffer.append(", ");
}
return buffer.toString();
}
/**
* Builds a complete LDAP path, ldap and url encoded. Separates only with
* ",".
*
* @return the LDAP path, for use in an url.
*/
public String toUrl() {
StringBuffer buffer = new StringBuffer(256);
for (int i = names.size() - 1; i >= 0; i--) {
LdapRdn n = (LdapRdn) names.get(i);
buffer.append(n.encodeUrl());
if (i > 0) {
buffer.append(",");
}
}
return buffer.toString();
}
/**
* Determines if a ldap path contains another path.
*
* @param path
* the path to check.
* @return true if the supplied path is conained in this instance, false
* otherwise.
*/
public boolean contains(DistinguishedName path) {
List shortlist = path.getNames();
// this path must be at least as long
if (getNames().size() < shortlist.size())
return false;
// must have names
if (shortlist.size() == 0)
return false;
Iterator longiter = getNames().iterator();
Iterator shortiter = shortlist.iterator();
LdapRdn longname = (LdapRdn) longiter.next();
LdapRdn shortname = (LdapRdn) shortiter.next();
// find first match
while (!longname.equals(shortname) && longiter.hasNext()) {
longname = (LdapRdn) longiter.next();
}
// Done?
if (!shortiter.hasNext() && longname.equals(shortname))
return true;
if (!longiter.hasNext())
return false;
// compare
while (longname.equals(shortname) && longiter.hasNext()
&& shortiter.hasNext()) {
longname = (LdapRdn) longiter.next();
shortname = (LdapRdn) shortiter.next();
}
// Done
if (!shortiter.hasNext() && longname.equals(shortname))
return true;
else
return false;
}
/**
* Add a LDAP path first
*
* @param path
*/
public void append(DistinguishedName path) {
getNames().addAll(path.getNames());
}
/**
* Add a LDAP path first
*
* @param path
*/
public void prepend(DistinguishedName path) {
ListIterator i = path.getNames().listIterator(path.getNames().size());
while (i.hasPrevious()) {
names.add(0, i.previous());
}
}
/**
* Remove the first part of this DistinguishedName.
*
* @return the removed entry.
*/
public LdapRdn removeFirst() {
return (LdapRdn) names.remove(0);
}
/**
* Remove the supplied path from the beginning of this DistinguishedName if
* this instance starts with <path>. Useful for stripping base path suffix
* from a DistinguishedName.
*
* @param path
* the path to remove from the beginning of this instance.
*/
public void removeFirst(Name path) {
if (path != null && this.startsWith(path)) {
for (int i = 0; i < path.size(); i++)
this.removeFirst();
}
}
/**
* @see java.lang.Object#clone()
*/
public Object clone() {
// just duplicate the list, the rdns are immutable.
LinkedList list = new LinkedList(getNames());
return new DistinguishedName(list);
}
/**
* @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;
}
DistinguishedName name = (DistinguishedName) obj;
// compare the lists
return getNames().equals(name.getNames());
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return this.getClass().hashCode() ^ getNames().hashCode();
}
/**
* Compare this instance to another object. Note that the comparison is done
* in order of significance, so the most significant Rdn is compared first,
* then the second and so on.
*
* @see javax.naming.Name#compareTo(java.lang.Object)
*/
public int compareTo(Object obj) {
DistinguishedName that = (DistinguishedName) obj;
ListComparator comparator = new ListComparator();
return comparator.compare(this.names, that.names);
}
public int size() {
return names.size();
}
public boolean isEmpty() {
return names.size() == 0;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#getAll()
*/
public Enumeration getAll() {
LinkedList strings = new LinkedList();
for (Iterator iter = names.iterator(); iter.hasNext();) {
LdapRdn rdn = (LdapRdn) iter.next();
strings.add(rdn.getLdapEncoded());
}
return Collections.enumeration(strings);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#get(int)
*/
public String get(int index) {
LdapRdn rdn = (LdapRdn) names.get(index);
return rdn.getLdapEncoded();
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#getPrefix(int)
*/
public Name getPrefix(int index) {
LinkedList newNames = new LinkedList();
for (int i = 0; i < index; i++) {
newNames.add(names.get(i));
}
return new DistinguishedName(newNames);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#getSuffix(int)
*/
public Name getSuffix(int index) {
if (index > names.size()) {
throw new ArrayIndexOutOfBoundsException();
}
LinkedList newNames = new LinkedList();
for (int i = index; i < names.size(); i++) {
newNames.add(names.get(i));
}
return new DistinguishedName(newNames);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#startsWith(javax.naming.Name)
*/
public boolean startsWith(Name name) {
if (name.size() == 0) {
return false;
}
DistinguishedName start = null;
if (name instanceof DistinguishedName) {
start = (DistinguishedName) name;
} else {
return false;
}
if (start.size() > this.size()) {
return false;
}
Iterator longiter = names.iterator();
Iterator shortiter = start.getNames().iterator();
while (shortiter.hasNext()) {
Object longname = longiter.next();
Object shortname = shortiter.next();
if (!longname.equals(shortname)) {
return false;
}
}
// All names in shortiter matched.
return true;
}
/**
* Determines if this ldap path ends with a certian path.
*
* If the argument path is empty (no names in path) this methid will return
* false.
*
* @param name
* The suffix to check for
*
*/
public boolean endsWith(Name name) {
DistinguishedName path = null;
if (name instanceof DistinguishedName) {
path = (DistinguishedName) name;
} else {
return false;
}
List shortlist = path.getNames();
// this path must be at least as long
if (getNames().size() < shortlist.size())
return false;
// must have names
if (shortlist.size() == 0)
return false;
ListIterator longiter = getNames().listIterator(getNames().size());
ListIterator shortiter = shortlist.listIterator(shortlist.size());
while (shortiter.hasPrevious()) {
LdapRdn longname = (LdapRdn) longiter.previous();
LdapRdn shortname = (LdapRdn) shortiter.previous();
if (!longname.equals(shortname))
return false;
}
// if short list ended, all were equal
return true;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#addAll(javax.naming.Name)
*/
public Name addAll(Name name) throws InvalidNameException {
return addAll(names.size(), name);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#addAll(int, javax.naming.Name)
*/
public Name addAll(int arg0, Name name) throws InvalidNameException {
DistinguishedName distinguishedName = null;
try {
distinguishedName = (DistinguishedName) name;
} catch (ClassCastException e) {
throw new InvalidNameException("Invalid name type");
}
names.addAll(arg0, distinguishedName.getNames());
return this;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#add(java.lang.String)
*/
public Name add(String string) throws InvalidNameException {
return add(names.size(), string);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#add(int, java.lang.String)
*/
public Name add(int index, String string) throws InvalidNameException {
try {
names.add(index, new LdapRdn(string));
} catch (BadLdapGrammarException e) {
throw new InvalidNameException("Failed to parse rdn '" + string
+ "'");
}
return this;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#remove(int)
*/
public Object remove(int arg0) throws InvalidNameException {
LdapRdn rdn = (LdapRdn) names.remove(arg0);
return rdn.getLdapEncoded();
}
/**
* Remove the ldast part of this DistinguishedName.
*
* @return the removed LdapRdn.
*/
public LdapRdn removeLast() {
return (LdapRdn) names.remove(names.size() - 1);
}
/**
* Add a new LdapRdn using the supplied key and value.
*
* @param key
* the key of the LdapRdn.
* @param value
* the value of the LdapRdn.
*/
public void add(String key, String value) {
names.add(new LdapRdn(key, value));
}
/**
* Add the supplied LdapRdn last in the list of Rdns.
*
* @param rdn
* the LdapRdn to add.
*/
public void add(LdapRdn rdn) {
names.add(rdn);
}
/**
* Add the supplied LdapRdn att the specified index.
*
* @param idx
* the index at which to add the LdapRdn.
* @param rdn
* the LdapRdn to add.
*/
public void add(int idx, LdapRdn rdn) {
names.add(idx, rdn);
}
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2005 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.support;
/**
* A parser for RFC2253-compliant Distinguished Names.
*
* @author Mattias Arthursson
*
*/
public interface DnParser {
/**
* Parse a full Distinguished Name.
*
* @return the DistinguishedName corresponding to the parsed stream.
*/
public DistinguishedName dn() throws ParseException;
/**
* Parse a Relative Distinguished Name.
*
* @return the next rdn on the stream.
*/
public LdapRdn rdn() throws ParseException;
}

View File

@@ -1,92 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.ControlFactory;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapContext;
import com.sun.jndi.ldap.ctl.ResponseControlFactory;
/**
* ContextSource implementation which creates an <code>InitialLdapContext</code>
* instance. For configuration information, see
* {@link org.springframework.ldap.support.AbstractContextSource AbstractContextSource}.
*
* @see org.springframework.ldap.support.AbstractContextSource
*
* @author Mattias Arthursson
* @author Adam Skogman
* @author Ulrik Sandberg
*/
public class LdapContextSource extends AbstractContextSource {
private static final Class DEFAULT_RESPONSE_CONTROL_FACTORY = ResponseControlFactory.class;
private Class responseControlFactory = DEFAULT_RESPONSE_CONTROL_FACTORY;
protected Hashtable getAnonymousEnv() {
Hashtable env = super.getAnonymousEnv();
env
.put(LdapContext.CONTROL_FACTORIES, responseControlFactory
.getName() + ".trasig");
return env;
}
/*
* @see org.springframework.ldap.support.AbstractContextSource#getDirContextInstance(java.util.Hashtable)
*/
protected DirContext getDirContextInstance(Hashtable environment)
throws NamingException {
return new InitialLdapContext(environment, null);
}
/**
* Set the ResponseControlFactory to use. Default is
* {@link com.sun.jndi.ldap.ctl.ResponseControlFactory}. The specified
* class needs to be an implementation of
* {@link javax.naming.ldap.ControlFactory}.
*
* @param responseControlFactory
* the ResponseControlFactory to be used. Null means reset to the
* default.
*/
public void setResponseControlFactory(Class responseControlFactory) {
if (responseControlFactory == null) {
this.responseControlFactory = DEFAULT_RESPONSE_CONTROL_FACTORY;
} else if (ControlFactory.class
.isAssignableFrom(responseControlFactory)) {
this.responseControlFactory = responseControlFactory;
} else {
throw new IllegalArgumentException(
"Invalid ReponseControlFactory: " + responseControlFactory
+ " is not an implementation of "
+ ControlFactory.class.getName());
}
}
/**
* @return the current ResponseControlFactory.
*/
Class getResponseControlFactory() {
return responseControlFactory;
}
}

View File

@@ -1,235 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.BadLdapGrammarException;
/**
* Helper class to encode and decode ldap names and values.
*
* @author Adam Skogman
*/
public class LdapEncoder {
static private String[] nameEscapeTable = new String[96];
static private String[] filterEscapeTable = new String['\\' + 1];
/**
* Pattern for matching escaped ldap name values.
*
* Double escaping: \ -> \\ (in pattern) -> \\\\ (in java string literal)
*
* Group 1: Hex escapes = \XX -> \p{XDigit}{2} Group 2: Ordinary escapes =
* \x -> \. Group 3: Anything but \ [^\\]
*
* Note that the \ is not part of the match.
*/
static private final Pattern VALUE_DECODE_PATTERN = Pattern
.compile("(?:\\\\(\\p{XDigit}{2}))|(?:\\\\(.))|([^\\\\])");
static {
// Name encoding table -------------------------------------
// all below 0x20 (control chars)
for (char c = 0; c < ' '; c++) {
nameEscapeTable[c] = "\\" + toTwoCharHex(c);
}
nameEscapeTable['#'] = "\\#";
nameEscapeTable[','] = "\\,";
nameEscapeTable[';'] = "\\;";
nameEscapeTable['='] = "\\=";
nameEscapeTable['+'] = "\\+";
nameEscapeTable['<'] = "\\<";
nameEscapeTable['>'] = "\\>";
// nameEscapeTable['\''] = "\\";
nameEscapeTable['\"'] = "\\\"";
// nameEscapeTable['/'] = "\\" + toTwoCharHex('/');
nameEscapeTable['\\'] = "\\\\";
// Filter encoding table -------------------------------------
// fill with char itself
for (char c = 0; c < filterEscapeTable.length; c++) {
filterEscapeTable[c] = String.valueOf(c);
}
// escapes (RFC2254)
filterEscapeTable['*'] = "\\2a";
filterEscapeTable['('] = "\\28";
filterEscapeTable[')'] = "\\29";
filterEscapeTable['\\'] = "\\5c";
filterEscapeTable[0] = "\\00";
}
static protected String toTwoCharHex(char c) {
String raw = Integer.toHexString(c).toUpperCase();
if (raw.length() > 1)
return raw;
else
return "0" + raw;
}
/**
* All static methods
*/
private LdapEncoder() {
}
static public String filterEncode(String value) {
if (value == null)
return null;
// make buffer roomy
StringBuffer encodedValue = new StringBuffer(value.length() * 2);
int length = value.length();
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
if (c < filterEscapeTable.length) {
encodedValue.append(filterEscapeTable[c]);
} else {
// default: add the char
encodedValue.append(c);
}
}
return encodedValue.toString();
}
/**
* LDAP Encodes a value for use with a DN. Escapes for LDAP, not JNDI!
*
* <br/>Escapes:<br/> ' ' [space] - "\ " [if first or last] <br/> '#'
* [hash] - "\#" <br/> ',' [comma] - "\," <br/> ';' [semicolon] - "\;" <br/> '=
* [equals] - "\=" <br/> '+' [plus] - "\+" <br/> '&lt;' [less than] -
* "\&lt;" <br/> '&gt;' [greater than] - "\&gt;" <br/> '"' [double quote] -
* "\"" <br/> '\' [backslash] - "\\" <br/>
*
* @param value
* @return The escaped value
*/
static public String nameEncode(String value) {
if (value == null)
return null;
// make buffer roomy
StringBuffer encodedValue = new StringBuffer(value.length() * 2);
int length = value.length();
int last = length - 1;
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
// space first or last
if (c == ' ' && (i == 0 || i == last)) {
encodedValue.append("\\ ");
continue;
}
if (c < nameEscapeTable.length) {
// check in table for escapes
String esc = nameEscapeTable[c];
if (esc != null) {
encodedValue.append(esc);
continue;
}
}
// default: add the char
encodedValue.append(c);
}
return encodedValue.toString();
}
/**
* Decodes a value. Converts escaped chars to ordinary chars.
*
* @param value
* Trimmed value, so no leading an trailing blanks, except an
* escaped space last.
* @return The decoded value as a string.
* @throws BadLdapGrammarException
*/
static public String nameDecode(String value)
throws BadLdapGrammarException {
if (value == null)
return null;
// make buffer same size
StringBuffer decoded = new StringBuffer(value.length());
Matcher matcher = VALUE_DECODE_PATTERN.matcher(value);
int end = 0;
while (matcher.find()) {
end = matcher.end();
// group 1
if (matcher.group(1) != null) {
// parse as hex = base 16
try {
char c = (char) Integer.parseInt(matcher.group(1), 16);
decoded.append(c);
} catch (NumberFormatException e) {
throw new BadLdapGrammarException(
"Escaped hex value Could not be parsed. Found '\\"
+ matcher.group(1) + "'");
}
} else if (matcher.group(2) != null) {
// just add, we stripped away the \
decoded.append(matcher.group(2));
} else if (matcher.group(3) != null) {
// just add
decoded.append(matcher.group(3));
}
}
// end is match + +1 so it should be same as length, i.e.
// last + 1
if (end < value.length()) {
throw new BadLdapGrammarException(
"RDN could not be parsed fully, remaining '"
+ StringUtils.substring(value, end) + "'");
}
return decoded.toString();
}
}

View File

@@ -1,198 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.io.Serializable;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.springframework.ldap.BadLdapGrammarException;
import org.springframework.ldap.util.ListComparator;
/**
* Datatype for a LDAP name, a part of a path.
*
* The name: uid=adam.skogman Key: uid Value: adam.skogman
*
* @author Adam Skogman
* @author Mattias Arthursson
*/
public class LdapRdn implements Serializable, Comparable {
private static final long serialVersionUID = 5681397547245228750L;
private List components = new LinkedList();
/**
* Default constructor.
*/
public LdapRdn() {
}
/**
* Parse the supplied string and construct this instance accordingly.
*
* @param string
* the string to parse.
*/
public LdapRdn(String string) {
DnParser parser = DefaultDnParserFactory.createDnParser(string);
LdapRdn rdn;
try {
rdn = parser.rdn();
} catch (ParseException e) {
throw new BadLdapGrammarException("Failed to parse Rdn", e);
} catch (TokenMgrError e) {
throw new BadLdapGrammarException("Failed to parse Rdn", e);
}
this.components = rdn.components;
}
/**
* Construct an LdapRdn using the supplied key and value.
*
* @param key
* @param value
*/
public LdapRdn(String key, String value) {
components.add(new LdapRdnComponent(key, value));
}
/**
* Add an LdapRdnComponent to this LdapRdn.
*
* @param rdnComponent
* the LdapRdnComponent to add.s
*/
public void addComponent(LdapRdnComponent rdnComponent) {
components.add(rdnComponent);
}
/**
* Gets all components in this LdapRdn.
*
* @return the List of all LdapRdnComponents composing this LdapRdn.
*/
public List getComponents() {
return components;
}
/**
* Gets the first LdapRdnComponent of this LdapRdn.
*
* @return The first LdapRdnComponent of this LdapRdn.
* @throws IndexOutOfBoundsException
* if no components have been added.
*/
public LdapRdnComponent getComponent() {
return (LdapRdnComponent) components.get(0);
}
/**
* Get the LdapRdnComponent at index <code>idx</code>.
*
* @param idx
* the 0-based index of the component to get.
* @return the LdapRdnComponent at indet <code>idx</code>.
* @throws IndexOutOfBoundsException
* if no component exists at index <code>idx</code>.
*/
public LdapRdnComponent getComponent(int idx) {
return (LdapRdnComponent) components.get(idx);
}
/**
* Get a properly rfc2253-encoded String representation to this LdapRdn.
*
* @return an encoded String corresponding to this LdapRdn.
*/
public String getLdapEncoded() {
if (components.size() == 0) {
throw new IndexOutOfBoundsException("No components in Rdn.");
}
StringBuffer sb = new StringBuffer(100);
for (Iterator iter = components.iterator(); iter.hasNext();) {
LdapRdnComponent component = (LdapRdnComponent) iter.next();
sb.append(component.encodeLdap());
if (iter.hasNext()) {
sb.append("+");
}
}
return sb.toString();
}
/**
* Get a String representation of this LdapRdn for use in urls.
*
* @return a String representation of this LdapRdn for use in urls.
*/
public String encodeUrl() {
StringBuffer sb = new StringBuffer(100);
for (Iterator iter = components.iterator(); iter.hasNext();) {
LdapRdnComponent component = (LdapRdnComponent) iter.next();
sb.append(component.encodeUrl());
if (iter.hasNext()) {
sb.append("+");
}
}
return sb.toString();
}
/**
* Compare this LdapRdn to another object.
*
* @param obj
* the object to compare to.
* @throws ClassCastException
* if the supplied object is not an LdapRdn instance.
*/
public int compareTo(Object obj) {
LdapRdn that = (LdapRdn) obj;
Comparator comparator = new ListComparator();
return comparator.compare(this.components, that.components);
}
public boolean equals(Object obj) {
if (obj == null || obj.getClass() != this.getClass()) {
return false;
}
LdapRdn that = (LdapRdn) obj;
return this.getComponents().equals(that.getComponents());
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return this.getClass().hashCode() ^ getComponents().hashCode();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
return getLdapEncoded();
}
}

View File

@@ -1,163 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.net.URI;
import java.net.URISyntaxException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
/**
* Represents part of an LdapRdn. As specified in RFC2253 an LdapRdn may be
* composed of several attributes, separated by &quot;+&quot;. An
* LdapRdnComponent represents one of these attributes.
*
* @author Mattias Arthursson
*
*/
public class LdapRdnComponent implements Comparable {
public static final boolean DONT_DECODE_VALUE = false;
private String key;
private String value;
/**
* Constructs an LdapRdnComponent without decoding the value.
*
* @param key
* the Atttribute name.
* @param value
* the Attribute value.
*/
public LdapRdnComponent(String key, String value) {
this(key, value, DONT_DECODE_VALUE);
}
/**
* Constructs an LdapRdnComponent, optionally decoding the value.
*
* @param key
* the Atttribute name.
* @param value
* the Attribute value.
* @param decodeValue
* if <code>true</code> the value is decoded (typically used
* when a DN is parsed from a String), otherwise the value is
* used as specified.
*/
public LdapRdnComponent(String key, String value, boolean decodeValue) {
Validate.notEmpty(key, "Key must not be empty");
Validate.notEmpty(value, "Value must not be empty");
this.key = StringUtils.lowerCase(key);
if (decodeValue) {
this.value = LdapEncoder.nameDecode(value);
} else {
this.value = value;
}
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
/**
* Encode key and value to ldap
*
* @return The ldap encoded rdn
*/
protected String encodeLdap() {
StringBuffer buff = new StringBuffer(key.length() + value.length() * 2);
buff.append(key);
buff.append('=');
buff.append(LdapEncoder.nameEncode(value));
return buff.toString();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
public String toString() {
return getLdapEncoded();
}
/**
* @return The LdapRdn as a string where the value is LDAP-encoded.
*/
public String getLdapEncoded() {
return encodeLdap();
}
public String encodeUrl() {
// Use the URI class to properly URL encode the value.
try {
URI valueUri = new URI(null, null, value, null);
return key + "=" + valueUri.toString();
} catch (URISyntaxException e) {
// This should really never happen...
return key + "=" + "value";
}
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return key.hashCode() ^ value.hashCode();
}
public boolean equals(Object obj) {
if (obj != null && obj.getClass() == LdapRdnComponent.class) {
LdapRdnComponent that = (LdapRdnComponent) obj;
return StringUtils.equalsIgnoreCase(this.key, that.key)
&& StringUtils.equalsIgnoreCase(this.value, that.value);
} else {
return false;
}
}
/**
* Compare this instance to the supplied object.
*
* @param obj
* the object to compare to.
* @throws ClassCastException
* if the object is not possible to cast to an LdapRdnComponent.
*/
public int compareTo(Object obj) {
LdapRdnComponent that = (LdapRdnComponent) obj;
return this.toString().compareTo(that.toString());
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2002-2005 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.support.authentication;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.AuthenticationSource;
/**
* An AuthenticationSource to retrieve authentication information stored in
* Acegi's SecurityContextHolder. Use Acegi's LdapAuthenticationProvider have a
* LdapUserDetails object placed in the authentication.
*
* @author Mattias Arthursson
*
*/
public class AcegiAuthenticationSource implements AuthenticationSource {
private static final Log log = LogFactory
.getLog(AcegiAuthenticationSource.class);
/**
* Get the principals of the logged in user, in this case the distinguished
* name.
*
* @return the distinguished name of the logged in user.
*/
public String getPrincipal() {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (authentication != null) {
Object principal = authentication.getPrincipal();
if (!(principal instanceof LdapUserDetails)) {
throw new IllegalArgumentException(
"The principal property of the authentication object -"
+ "needs to be a LdapUserDetails.");
} else {
LdapUserDetails details = (LdapUserDetails) principal;
return details.getDn();
}
} else {
log.warn("No Authentication object set in SecurityContext - "
+ "returning empty String as Principal");
return "";
}
}
/*
* @see org.springframework.ldap.AuthenticationSource#getCredentials()
*/
public String getCredentials() {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (authentication != null) {
return (String) authentication.getCredentials();
} else {
log.warn("No Authentication object set in SecurityContext - "
+ "returning empty String as Credentials");
return "";
}
}
}

View File

@@ -1,157 +0,0 @@
/*
* Copyright 2002-2005 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.support.authentication;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.ldap.AuthenticationSource;
/**
* Decorator on AuthenticationSource to have default authentication information
* be returned should the target return empty principal and credentials. Useful
* in combination with {@link AcegiAuthenticationSource} if users are to be
* allowed to read some information even though they are not logged in.
* <p>
* <b>Note:</b> The <code>defaultUser</code> should be an non-privileged
* user. This is important as this is the one that will be used when no user is
* logged in (i.e. empty principal is returned from the target
* AuthenticationSource).
*
* @author Mattias Arthursson
*
*/
public class DefaultValuesAuthenticationSourceDecorator implements
AuthenticationSource, InitializingBean {
private AuthenticationSource target;
private String defaultUser;
private String defaultPassword;
/**
* Constructor for bean usage.
*/
public DefaultValuesAuthenticationSourceDecorator() {
}
/**
* Constructor to setup instance directly.
*
* @param target
* the target AuthenticationSource.
* @param defaultUser
* dn of the user to use when the target returns an empty
* principal.
* @param defaultPassword
* password of the user to use when the target returns an empty
* principal.
*/
public DefaultValuesAuthenticationSourceDecorator(
AuthenticationSource target, String defaultUser,
String defaultPassword) {
this.target = target;
this.defaultUser = defaultUser;
this.defaultPassword = defaultPassword;
}
/**
* Checks if the target's principal is not empty; if not, the credentials
* from the target is returned - otherwise return the
* <code>defaultPassword</code>.
*
* @return the target's password if the target's principal is not empty, the
* <code>defaultPassword</code> otherwise.
*/
public String getCredentials() {
if (StringUtils.isNotEmpty(target.getPrincipal())) {
return target.getCredentials();
} else {
return defaultPassword;
}
}
/**
* Checks if the target's principal is not empty; if not, this is returned -
* otherwise return the <code>defaultUser</code>.
*
* @return the target's principal if it is not empty, the
* <code>defaultUser</code> otherwise.
*/
public String getPrincipal() {
String principal = target.getPrincipal();
if (StringUtils.isNotEmpty(principal)) {
return principal;
} else {
return defaultUser;
}
}
/**
* Set the password of the default user.
*
* @param defaultPassword
* the password of the default user.
*/
public void setDefaultPassword(String defaultPassword) {
this.defaultPassword = defaultPassword;
}
/**
* Set the default user DN. This should be a non-privileged user, since it
* will be used when no authentication information is returned from the
* target.
*
* @param defaultUser
* DN of the default user.
*/
public void setDefaultUser(String defaultUser) {
this.defaultUser = defaultUser;
}
/**
* Set the target AuthenticationSource.
*
* @param target
* the target AuthenticationSource.
*/
public void setTarget(AuthenticationSource target) {
this.target = target;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
if (target == null) {
throw new IllegalArgumentException(
"Property 'target' must be set.'");
}
if (defaultUser == null) {
throw new IllegalArgumentException(
"Property 'defaultUser' must be set.'");
}
if (defaultPassword == null) {
throw new IllegalArgumentException(
"Property 'defaultPassword' must be set.'");
}
}
}

View File

@@ -1,3 +0,0 @@
<body>
Support classes for custom authentication.
</body>

View File

@@ -1,90 +0,0 @@
/*
* Copyright 2002-2005 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.support.control;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.LdapContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.DirContextProcessor;
/**
* Abstract superclass with responsibility to apply a single RequestControl on
* an LdapContext, preserving any existing controls. Subclasses should implement
* {@link DirContextProcessor#postProcess(DirContext)} and template method
* {@link #createRequestControl()}.
*
* @author Mattias Arthursson
* @author Ulrik Sandberg
*/
public abstract class AbstractRequestControlDirContextProcessor implements
DirContextProcessor {
protected Log log = LogFactory
.getLog(AbstractRequestControlDirContextProcessor.class);
/**
* Get the existing RequestControls from the LdapContext, call
* {@link #createRequestControl()} to get a new instance, build a new array
* of Controls and set it on the LdapContext.
* <p>
* The {@link Control} feature is specific for LDAP v3 and thus applies only
* to {@link LdapContext}. However, the generic DirContextProcessor
* mechanism used for calling <code>preProcess</code> and
* <code>postProcess</code> uses DirContext, since it also works for LDAP
* v2. This is the reason that DirContext has to be cast into LdapContext.
*
* @param ctx
* an LdapContext instance.
* @throws NamingException
* @throws IllegalArgumentException
* if the supplied DirContext is not an LdapContext.
*/
public void preProcess(DirContext ctx) throws NamingException {
LdapContext ldapContext;
if (ctx instanceof LdapContext) {
ldapContext = (LdapContext) ctx;
} else {
throw new IllegalArgumentException(
"Request Control operations require LDAPv3 - "
+ "Context must be of type LdapContext");
}
Control[] requestControls = ldapContext.getRequestControls();
Control newControl = createRequestControl();
Control[] newControls = new Control[requestControls.length + 1];
for (int i = 0; i < requestControls.length; i++) {
newControls[i] = requestControls[i];
}
// Add the new Control at the end of the array.
newControls[newControls.length - 1] = newControl;
ldapContext.setRequestControls(newControls);
}
/**
* Create an instance of the appropriate RequestControl.
*
* @return the new instance.
*/
public abstract Control createRequestControl();
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2002-2005 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.support.control;
import com.sun.jndi.ldap.ctl.PagedResultsControl;
/**
* Wrapper class for the cookie returned when using the
* {@link PagedResultsControl}.
*
* @author Mattias Arthursson
* @author Ulrik Sandberg
*/
public class PagedResultsCookie {
private byte[] cookie;
/**
* Constructor.
*
* @param cookie
* the cookie returned by a PagedResultsResponseControl.
*/
public PagedResultsCookie(byte[] cookie) {
this.cookie = cookie;
}
/**
* Get the cookie.
*
* @return the cookie.
*/
public byte[] getCookie() {
return cookie;
}
}

View File

@@ -1,200 +0,0 @@
/*
* Copyright 2002-2005 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.support.control;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.Control;
import javax.naming.ldap.LdapContext;
import org.springframework.ldap.UncategorizedLdapException;
import org.springframework.util.ReflectionUtils;
import com.sun.jndi.ldap.ctl.PagedResultsControl;
import com.sun.jndi.ldap.ctl.PagedResultsResponseControl;
/**
* DirContextProcessor implementation for managing the paged results.
*
* @author Mattias Arthursson
* @author Ulrik Sandberg
*/
public class PagedResultsRequestControl extends
AbstractRequestControlDirContextProcessor {
private static final Class DEFAULT_RESPONSE_CONTROL = PagedResultsResponseControl.class;
private static final boolean CRITICAL_CONTROL = true;
private static final String JAVA5_RESPONSE_CONTROL = "javax.naming.ldap.PagedResultsResponseControl";
private int pageSize;
private PagedResultsCookie cookie;
private int resultSize;
private Class responseControlClass = DEFAULT_RESPONSE_CONTROL;
private Class fallbackResponseControlClass;
private Class currentResponseControlClass;
public PagedResultsRequestControl(int pageSize) {
this(pageSize, null);
}
public PagedResultsRequestControl(int pageSize, PagedResultsCookie cookie) {
this.pageSize = pageSize;
this.cookie = cookie;
fallbackResponseControlClass = loadFallbackResponseControlClass();
}
public PagedResultsCookie getCookie() {
return cookie;
}
public int getPageSize() {
return pageSize;
}
public int getResultSize() {
return resultSize;
}
/**
* Set the class of the expected ResponseControl for the paged results
* response. The default is {@link PagedResultsResponseControl}.
*
* @param responseControlClass
* Class of the expected response control.
*/
public void setResponseControlClass(Class responseControlClass) {
this.responseControlClass = responseControlClass;
}
/*
* @see org.springframework.ldap.support.control.AbstractRequestControlDirContextProcessor#createRequestControl()
*/
public Control createRequestControl() {
try {
if (cookie != null) {
return new PagedResultsControl(pageSize, cookie.getCookie(),
CRITICAL_CONTROL);
} else {
return new PagedResultsControl(pageSize);
}
} catch (IOException e) {
throw new UncategorizedLdapException(
"Error creating PagedResultsControl", e);
}
}
/*
* @see org.springframework.ldap.DirContextProcessor#postProcess(javax.naming.directory.DirContext)
*/
public void postProcess(DirContext ctx) throws NamingException {
// initialize from property
currentResponseControlClass = responseControlClass;
LdapContext ldapContext = (LdapContext) ctx;
Control[] responseControls = ldapContext.getResponseControls();
// Go through response controls and get info, regardless of class
for (int i = 0; i < responseControls.length; i++) {
Control responseControl = responseControls[i];
// check for match, try fallback otherwise
if (isPagedResultsResponseControl(responseControl)) {
Object control = responseControl;
byte[] result = (byte[]) invokeMethod("getCookie",
currentResponseControlClass, control);
this.cookie = new PagedResultsCookie(result);
Integer wrapper = (Integer) invokeMethod("getResultSize",
currentResponseControlClass, control);
this.resultSize = wrapper.intValue();
}
}
}
/**
* Check if the given control matches a paged results response control. Try
* the fallback class from Java5 if there is no match. Set the
* {@link #currentResponseControlClass} to the fallback if it matches.
*
* @param responseControl
* the control to check for a match
* @return whether the control is a paged results response control
*/
private boolean isPagedResultsResponseControl(Control responseControl) {
if (responseControl.getClass().isAssignableFrom(
currentResponseControlClass)) {
return true;
}
if (fallbackResponseControlClass != null
&& responseControl.getClass().isAssignableFrom(
fallbackResponseControlClass)) {
currentResponseControlClass = fallbackResponseControlClass;
return true;
}
return false;
}
private Class loadFallbackResponseControlClass() {
Class fallbackResponseControlClass = null;
try {
fallbackResponseControlClass = Class
.forName(JAVA5_RESPONSE_CONTROL);
} catch (ClassNotFoundException e) {
log.debug("Could not load Java5 response control class "
+ JAVA5_RESPONSE_CONTROL);
}
return fallbackResponseControlClass;
}
private Object invokeMethod(String method, Class clazz, Object control) {
// For Spring 2.0 ReflectionUtils could be used for all of this, but
// since we still want to support the 1.2 branch we do it manually and
// only use the stuff present in 1.2.8.
Method actualMethod = null;
Object retval = null;
try {
actualMethod = clazz.getMethod(method, new Class[0]);
} catch (SecurityException e) {
ReflectionUtils.handleReflectionException(e);
} catch (NoSuchMethodException e) {
ReflectionUtils.handleReflectionException(e);
}
try {
retval = actualMethod.invoke(control, new Object[0]);
} catch (IllegalArgumentException e) {
ReflectionUtils.handleReflectionException(e);
} catch (IllegalAccessException e) {
ReflectionUtils.handleReflectionException(e);
} catch (InvocationTargetException e) {
ReflectionUtils.handleReflectionException(e);
}
// Retval will be set unless an exception has been thrown.
return retval;
}
}

View File

@@ -1,3 +0,0 @@
<body>
Support classes for custom request control context processors.
</body>

View File

@@ -1,58 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* Convenience class that implements most of the methods in the Filter
* interface.
*
* @author Adam Skogman
*/
public abstract class AbstractFilter implements Filter {
protected AbstractFilter() {
super();
}
/**
* Prints the query with LDAP encoding to a stringbuffer
*
* @param buff
* The stringbuffer
* @return The very same stringbuffer
*/
public abstract StringBuffer encode(StringBuffer buff);
/**
* Encodes the filter to a string using the (@link #encode(StringBuffer)
* method.
*
* @return The encoded filter
*/
public String encode() {
StringBuffer buff = new StringBuffer(256);
buff = encode(buff);
return buff.toString();
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return encode();
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* A filter for a logical AND. E.g.:
*
* <pre>
* AndFilter filter = new AndFilter();
* filter.and(new EqualsFilter(&quot;objectclass&quot;, &quot;person&quot;);
* filter.and(new EqualsFilter(&quot;cn&quot;, &quot;Some CN&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in: <code>(&amp;(objectclass=person)(cn=Some CN))</code>
*
* @see org.springframework.ldap.support.filter.EqualsFilter
* @author Adam Skogman
* @author Mattias Arthursson
*/
public class AndFilter extends BinaryLogicalFilter {
private static final String AMPERSAND = "&";
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.filter.BinaryLogicalFilter#getLogicalOperator()
*/
protected String getLogicalOperator() {
return AMPERSAND;
}
/**
* Add a query to the and expression
*
* @param query
* The query to and with the rest of the and:ed queries.
* @return This LdapAndQuery
*/
public AndFilter and(Filter query) {
queryList.add(query);
return this;
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Abstract superclass for binary logical operations, that is &quot;and&quot;
* and &quot;or&quot; operations.
*
* @author Mattias Arthursson
*/
public abstract class BinaryLogicalFilter extends AbstractFilter {
protected List queryList = new LinkedList();
/**
* @see org.springframework.ldap.support.filter.Filter#encode(java.lang.StringBuffer)
*/
public StringBuffer encode(StringBuffer buff) {
if (queryList.size() <= 0) {
// only output query if contains anything
return buff;
} else if (queryList.size() == 1) {
// don't add the &
Filter query = (Filter) queryList.get(0);
return query.encode(buff);
} else {
buff.append("(" + getLogicalOperator());
for (Iterator i = queryList.iterator(); i.hasNext();) {
Filter query = (Filter) i.next();
buff = query.encode(buff);
}
buff.append(")");
return buff;
}
}
/**
* Implement this in subclass to return the logical operator, for example
* &qout;&amp;&qout;.
*
* @return the logical operator.
*/
protected abstract String getLogicalOperator();
/**
* Compares each filter in turn
*
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (obj instanceof BinaryLogicalFilter
&& this.getClass() == obj.getClass()) {
return EqualsBuilder.reflectionEquals(this, obj);
} else {
return false;
}
}
/**
* Hashes all contained data
*
* @see org.springframework.ldap.support.filter.Filter#hashCode()
*/
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}

View File

@@ -1,123 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.springframework.ldap.support.LdapEncoder;
/**
* Abstract superclass for filters to compare values.
*
* @author Mattias Arthursson
*/
public abstract class CompareFilter extends AbstractFilter {
private final String attribute;
private final String value;
private final String encodedValue;
public CompareFilter(String attribute, String value) {
this.attribute = attribute;
this.value = value;
this.encodedValue = encodeValue(value);
}
/**
* For testing purposes.
*
* @return the encoded value.
*/
String getEncodedValue() {
return encodedValue;
}
/**
* Override to perform special encoding in subclass.
*
* @param value
* the value to encode.
* @return properly escaped value.
*/
protected String encodeValue(String value) {
return LdapEncoder.filterEncode(value);
}
/**
* Convenience constructor for int values.
*
* @param attribute
* @param value
*/
public CompareFilter(String attribute, int value) {
this.attribute = attribute;
this.value = String.valueOf(value);
this.encodedValue = LdapEncoder.filterEncode(this.value);
}
/*
* @see org.springframework.ldap.support.filter.AbstractFilter#encode(java.lang.StringBuffer)
*/
public StringBuffer encode(StringBuffer buff) {
buff.append('(');
buff.append(attribute).append(getCompareString()).append(encodedValue);
buff.append(')');
return buff;
}
/**
* Compares key and value before encoding.
*
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
*/
public boolean equals(Object o) {
if (o instanceof CompareFilter && o.getClass() == this.getClass()) {
CompareFilter that = (CompareFilter) o;
EqualsBuilder builder = new EqualsBuilder();
builder.append(this.attribute, that.attribute);
builder.append(this.value, that.value);
return builder.isEquals();
} else {
return false;
}
}
/**
* Calculate the hash code for the attribute and the value.
*
* @see org.springframework.ldap.support.filter.Filter#hashCode()
*/
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(attribute);
builder.append(value);
return builder.toHashCode();
}
/**
* Implement this method in subclass to return a String representing the
* operator. The {@link EqualsFilter#getCompareString()} would for example
* return an equals sign, &quot;=&quot;.
*
* @return the String to use as operator in the comparison for the specific
* subclass.
*/
protected abstract String getCompareString();
}

View File

@@ -1,57 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* A filter for 'equals'. The following code:
*
* <pre>
* EqualsFilter filter = new EqualsFilter(&quot;cn&quot;, &quot;Some CN&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in:
* <pre>(cn=Some CN)</pre>
*
* @author Adam Skogman
*/
public class EqualsFilter extends CompareFilter {
private static final String EQUALS_SIGN = "=";
public EqualsFilter(String attribute, String value) {
super(attribute, value);
}
/**
* Convenience constructor for int values.
*
* @param attribute Name of attribute in filter.
* @param value The value of the attribute in the filter.
*/
public EqualsFilter(String attribute, int value) {
super(attribute, value);
}
/*
* @see org.springframework.ldap.support.filter.CompareFilter#getCompareString()
*/
protected String getCompareString() {
return EQUALS_SIGN;
}
}

View File

@@ -1,58 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* Common interface for filters.
*
* @author Adam Skogman
*/
public interface Filter {
/**
* Encodes the filter to a string using the (@link #encode(StringBuffer)
* method.
*
* @return The encoded filter
*/
public String encode();
/**
* Prints the query with LDAP encoding to a stringbuffer
*
* @param buff
* The stringbuffer
* @return The very same stringbuffer
*/
public StringBuffer encode(StringBuffer buff);
/**
* All filters must implement equals.
*
* @param o
* @return <code>true</code> if the objects are equal.
*/
public boolean equals(Object o);
/**
* All filters must implement hashCode()
*
* @return hascode
*/
public int hashCode();
}

View File

@@ -1,52 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* A filter to compare >=. LDAP RFC does not allow > comparison. The following
* code:
*
* <pre>
* GreaterThanOrEqualsFilter filter = new GreaterThanOrEqualsFilter(&quot;cn&quot;,
* &quot;Some CN&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in:
*
* <pre>
* (cn&gt;=Some CN)
* </pre>
*
* @author Mattias Arthursson
*/
public class GreaterThanOrEqualsFilter extends CompareFilter {
private static final String GREATER_THAN_OR_EQUALS = ">=";
public GreaterThanOrEqualsFilter(String attribute, String value) {
super(attribute, value);
}
public GreaterThanOrEqualsFilter(String attribute, int value) {
super(attribute, value);
}
protected String getCompareString() {
return GREATER_THAN_OR_EQUALS;
}
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* A filter to compare <=. LDAP RFC does not allow < comparison. The following
* code:
*
* <pre>
* LessThanOrEqualsFilter filter = new LessThanOrEqualsFilter(&quot;cn&quot;, &quot;Some CN&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in:
*
* <pre>
* (cn&lt;=Some CN)
* </pre>
*
* @author Mattias Arthursson
*/
public class LessThanOrEqualsFilter extends CompareFilter {
private static final String LESS_THAN_OR_EQUALS = "<=";
public LessThanOrEqualsFilter(String attribute, String value) {
super(attribute, value);
}
public LessThanOrEqualsFilter(String attribute, int value) {
super(attribute, value);
}
protected String getCompareString() {
return LESS_THAN_OR_EQUALS;
}
}

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
import org.springframework.ldap.support.LdapEncoder;
/**
* This filter allows the user to specify wildcards (*) by not escaping them in
* the filter. The following code:
*
* <pre>
* LikeFilter filter = new LikeFilter(&quot;cn&quot;, &quot;foo*&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in:
*
* <pre>
* (cn=foo*)
* </pre>
*
* @author Anders Henja
* @author Mattias Arthursson
*/
public class LikeFilter extends EqualsFilter {
public LikeFilter(String attribute, String value) {
super(attribute, value);
}
/**
* Encodes a value according to the rules for this filter.
*
* @param value
* Value to encode.
* @return Encoded value.
*/
protected String encodeValue(String value) {
// just return if blank string
if (value == null) {
return "";
}
String[] substrings = value.split("\\*", -2);
if (substrings.length == 1) {
return LdapEncoder.filterEncode(substrings[0]);
}
StringBuffer buff = new StringBuffer();
for (int i = 0; i < substrings.length; i++) {
buff.append(LdapEncoder.filterEncode(substrings[i]));
if (i < substrings.length - 1) {
buff.append("*");
} else {
if (substrings[i].equals("")) {
continue;
}
}
}
return buff.toString();
}
}

View File

@@ -1,89 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
import org.apache.commons.lang.Validate;
/**
* A filter for 'not'. The following code:
*
* <pre>
* Filter filter = new NotFilter(new EqualsFilter(&quot;cn&quot;, &quot;foo&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in:
*
* <pre>(!(cn=foo))</pre>
*
* @author Adam Skogman
*/
public class NotFilter extends AbstractFilter {
private final Filter filter;
static private final int HASH = "!".hashCode();
/**
* Create a filter that negates the outcome of the given <code>filter</code>.
*
* @param filter
* The filter that should be negated.
*/
public NotFilter(Filter filter) {
Validate.notNull(filter);
this.filter = filter;
}
/**
* @see org.springframework.ldap.support.filter.Filter#encode(java.lang.StringBuffer)
*/
public StringBuffer encode(StringBuffer buff) {
buff.append("(!");
filter.encode(buff);
buff.append(')');
return buff;
}
/**
* Compares key and value before encoding
*
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
*/
public boolean equals(Object o) {
if (o instanceof NotFilter && o.getClass() == this.getClass()) {
NotFilter f = (NotFilter) o;
return this.filter.equals(f.filter);
}
return false;
}
/**
* hash attribute and value
*
* @see org.springframework.ldap.support.filter.Filter#hashCode()
*/
public int hashCode() {
return HASH ^ filter.hashCode();
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* Filter for logical OR.
*
* <pre>
* AndFilter filter = new AndFilter();
* filter.or(new EqualsFilter(&quot;objectclass&quot;, &quot;person&quot;);
* filter.or(new EqualsFilter(&quot;objectclass&quot;, &quot;organizationalUnit&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in:
* <code>(|(objectclass=person)(objectclass=organizationalUnit))</code>
*
* @author Adam Skogman
* @author Mattias Arthursson
*/
public class OrFilter extends BinaryLogicalFilter {
private static final String PIPE_SIGN = "|";
/**
* Add a query to the OR expression
*
* @param query
* The query to or with the rest of the or:ed queries.
* @return This LdapOrQuery
*/
public OrFilter or(Filter query) {
queryList.add(query);
return this;
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.filter.BinaryLogicalFilter#getLogicalOperator()
*/
protected String getLogicalOperator() {
return PIPE_SIGN;
}
}

View File

@@ -1,84 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.support.LdapEncoder;
/**
* This filter automatically converts all whitespace to wildcards (*). The
* following code:
*
* <pre>
* WhitespaceWildcardsFilter filter = new WhitespaceWildcardsFilter(&quot;cn&quot;,
* &quot;Some CN&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in: <code>(cn=*Some*CN*)</code>
*
* @author Adam Skogman
* @author Mattias Arthursson
*/
public class WhitespaceWildcardsFilter extends EqualsFilter {
private static Pattern starReplacePattern = Pattern.compile("\\s+");
public WhitespaceWildcardsFilter(String attribute, String value) {
super(attribute, value);
}
/**
* Encodes a value according to the rules for this filter.
*
* @param value
* Value to encode.
* @return Encoded value.
*/
protected String encodeValue(String value) {
// blank string means just ONE star
if (StringUtils.isBlank(value)) {
return "*";
}
// trim value, we will add in stars first and last anywhay
value = value.trim();
// filter encode so that any stars etc. are preserved
String filterEncoded = LdapEncoder.filterEncode(value);
// Now replace all whitespace with stars
Matcher m = starReplacePattern.matcher(filterEncoded);
// possibly 2 longer (stars at ends)
StringBuffer buff = new StringBuffer(value.length() + 2);
buff.append('*');
while (m.find()) {
m.appendReplacement(buff, "*");
}
m.appendTail(buff);
buff.append('*');
return buff.toString();
}
}

View File

@@ -1,16 +0,0 @@
<body>
Utility classes for dynamically building LDAP
filters. Filters can be nested and wrapped around each other:
<pre>
AndFilter andFilter = new AndFilter();
andFilter.and(new EqualsFilter(&quot;objectclass&quot;, &quot;person&quot;);
andFilter.and(new EqualsFilter(&quot;cn&quot;, &quot;Some CN&quot;);
OrFilter orFilter = new OrFilter();
orFilter.or(andFilter);
orFilter.or(new EqualsFilter(&quot;objectclass&quot;, &quot;organizationalUnit));
System.out.println(orFilter.encode());
</pre>
would result in:
<pre>(|(&(objectclass=person)(cn=Some CN))(objectclass=organizationalUnit))</pre>
</body>

View File

@@ -1,3 +0,0 @@
<body>
Support classes for Spring-LDAP.
</body>

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2002-2005 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.util;
import java.util.Comparator;
import java.util.List;
/**
* Comparator for comparing lists of Comparable objects.
*
* @author Mattias Arthursson
*
*/
public class ListComparator implements Comparator {
/**
* Compare two lists of Comparable objects.
*
* @param o1
* the first object to be compared.
* @param o2
* the second object to be compared.
* @throws ClassCastException
* if either of the lists contains an object that is not
* Comparable.
*/
public int compare(Object o1, Object o2) {
List list1 = (List) o1;
List list2 = (List) o2;
for (int i = 0; i < list1.size(); i++) {
if (list2.size() > i) {
Comparable component1 = (Comparable) list1.get(i);
Comparable component2 = (Comparable) list2.get(i);
int componentsCompared = component1.compareTo(component2);
if (componentsCompared != 0) {
return componentsCompared;
}
} else {
// First instance has more components, so that instance is
// greater.
return 1;
}
}
// All components so far are equal - if the other instance has
// more components it is greater otherwise they are equal.
if (list2.size() > list1.size()) {
return -1;
} else {
return 0;
}
}
}

View File

@@ -1,3 +0,0 @@
<body>
Internal utility classes.
</body>

View File

@@ -1,3 +0,0 @@
<body>
This document is the API specification for the Spring LDAP Framework.
</body>

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.DataIntegrityViolationException;
/**
* Exception that indicates that an invalid or missing Attribute has been
* supplied to an LDAP operation.
*
* @author Mattias Arthursson
*
*/
public class AttributesIntegrityViolationException extends
DataIntegrityViolationException {
private static final long serialVersionUID = -6368616096960202571L;
public AttributesIntegrityViolationException(String msg) {
super(msg);
}
public AttributesIntegrityViolationException(String msg, Throwable t) {
super(msg, t);
}
}

View File

@@ -1,53 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
/**
* An interface used by LdapTemplate for mapping LDAP Attributes to beans.
* Implementions of this interface perform the actual work of extracting
* results, but need not worry about exception handling. NamingExceptions will
* be caught and handled correctly by the LdapTemplate class.
* <p>
* Typically used in LdapTemplate's search methods. AttributeMapper objects are
* typically stateless and thus reusable; they are ideal for implementing
* attribute-mapping logic in one place.
* <p>
* Alternatively, consider using a {@link ContextMapper} in stead.
*
* @see org.springframework.ldap.LdapTemplate#search(Name, String,
* AttributesMapper)
* @see ContextMapper
*
* @author Mattias Arthursson
*/
public interface AttributesMapper {
/**
* Map Attributes to an object. The supplied attributes are the attributes
* from a single SearchResult.
*
* @param attributes
* attributes from a SearchResult.
* @return an object built from the attributes.
* @throws NamingException if any error occurs mapping the attributes
*/
public Object mapFromAttributes(Attributes attributes)
throws NamingException;
}

View File

@@ -1,40 +0,0 @@
/*
* Copyright 2002-2005 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;
/**
* An AuthenticationSource is responsible for providing the principal and
* credentials to be used when creating a new context.
*
* @author Mattias Arthursson
*
*/
public interface AuthenticationSource {
/**
* Get the principal to use when creating an authenticated context.
*
* @return the principal (userName).
*/
public String getPrincipal();
/**
* Get the credentials to use when creating an authenticated context.
*
* @return the credentials (userName).
*/
public String getCredentials();
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.InvalidDataAccessResourceUsageException;
/**
* Thrown to indicate that an invalid value has been supplied to an LDAP
* operation. This could be an invalid filter or dn.
*
* @author Mattias Arthursson
*/
public class BadLdapGrammarException extends
InvalidDataAccessResourceUsageException {
private static final long serialVersionUID = 961612585331409470L;
public BadLdapGrammarException(String message) {
super(message);
}
public BadLdapGrammarException(String message, Throwable cause) {
super(message, cause);
}
}

View File

@@ -1,63 +0,0 @@
/*
* Copyright 2002-2005 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;
import java.util.LinkedList;
import java.util.List;
import javax.naming.NameClassPair;
/**
* A NameClassPairCallbackHandler to collect all results in an internal List.
*
* @see org.springframework.ldap.LdapTemplate
*
* @author Mattias Arthursson
*/
public abstract class CollectingNameClassPairCallbackHandler implements
NameClassPairCallbackHandler {
private List list = new LinkedList();
/**
* Get the assembled list.
*
* @return the list of all assembled objects.
*/
public List getList() {
return list;
}
/**
* Pass on the supplied NameClassPair to
* {@link #getObjectFromNameClassPair(NameClassPair)} and add the result to
* the internal list.
*/
public void handleNameClassPair(NameClassPair nameClassPair) {
list.add(getObjectFromNameClassPair(nameClassPair));
}
/**
* Handle a NameClassPair and transform it to an Object of the desired type
* and with data from the NameClassPair.
*
* @param nameClassPair
* a NameClassPair from a search operation.
* @return an object constructed from the data in the NameClassPair.
*/
public abstract Object getObjectFromNameClassPair(
NameClassPair nameClassPair);
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2002-2005 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;
/**
* Helper interface to be used by Dao implementations for assembling to and from
* context. Useful if we have assembler classes responsible for mapping to and
* from a specific entry.
*
* @author Mattias Arthursson
*/
public interface ContextAssembler extends ContextMapper {
/**
* Map the supplied object to the specified context.
*
* @param obj
* the object to read data from.
* @param ctx
* the context to map to.
*/
public void mapToContext(Object obj, Object ctx);
}

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
/**
* Interface for delegating an actual operation to be performed on an
* DirContext. For searches, use {@link org.springframework.ldap.SearchExecutor} in
* stead. A typical usage of this interface could be e.g.:
*
* <pre>
* ContextExecutor executor = new ContextExecutor(){
* public Object executeWithContext(DirContext ctx) throws NamingException{
* return ctx.lookup(dn);
* }
* };
* </pre>
*
* @see org.springframework.ldap.LdapTemplate#executeReadOnly(ContextExecutor)
* @see org.springframework.ldap.LdapTemplate#executeReadWrite(ContextExecutor)
*
* @author Mattias Arthursson
*/
public interface ContextExecutor {
/**
* Perform any operation on the context.
*
* @param ctx
* the DirContext to perform the operation on.
* @return any object resulting from the operation - might be null.
* @throws NamingException
* if the operation resulted in one.
*/
public Object executeWithContext(DirContext ctx) throws NamingException;
}

View File

@@ -1,61 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.Binding;
import javax.naming.Name;
import javax.naming.directory.SearchResult;
import org.springframework.ldap.support.DefaultDirObjectFactory;
import org.springframework.ldap.support.DirContextAdapter;
/**
* An interface used by LdapTemplate to map LDAP Contexts to beans. Responsible
* for mapping from LDAP Contexts to beans. When a DirObjectFactory is set on
* the ContextSource, the objects returned from <code>search</code> and
* <code>listBindings</code> operations are automatically transformed to
* DirContext objects (when using the {@link DefaultDirObjectFactory}, you get
* a {@link DirContextAdapter} object). This object will then be passed to the
* ContextMapper implementation for transformation to the desired bean.
* <p>
* ContextMapper implementations are typically stateless and thus reusable; they
* are ideal for implementing mapping logic in one place.
* <p>
* Alternatively, consider using an {@link AttributesMapper} in stead.
*
* @see LdapTemplate#search(Name, String,
* ContextMapper)
* @see LdapTemplate#listBindings(Name, ContextMapper)
* @see LdapTemplate#lookup(Name, ContextMapper)
* @see AttributesMapper
* @see DefaultDirObjectFactory
* @see DirContextAdapter
*
* @author Mattias Arthursson
*/
public interface ContextMapper {
/**
* Map a single LDAP Context to an object. The supplied Object
* <code>ctx</code> is the object from a single {@link SearchResult},
* {@link Binding}, or a lookup operation.
*
* @param ctx
* the context to map to an object.
* @return an object built from the data in the context.
*/
public Object mapFromContext(Object ctx);
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.directory.DirContext;
import org.springframework.dao.DataAccessException;
/**
* Interface used to retrieve and authenticate LDAP contexts.
*
* @see org.springframework.ldap.LdapTemplate
*
* @author Adam Skogman
* @author Mattias Arthursson
*/
public interface ContextSource {
/**
* Gets a read-only DirContext. The returned DirContext must be possible to
* perform read-only operations on.
*
* @return A DirContext instance, never null.
* @throws DataAccessException
* if some error occurs creating an DirContext.
*/
public DirContext getReadOnlyContext() throws DataAccessException;
/**
* Gets a read-write DirContext.
*
* @return A DirContext instance, never null.
* @throws DataAccessException
* if some error occurs creating an DirContext.
*/
public DirContext getReadWriteContext() throws DataAccessException;
}

View File

@@ -1,46 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NameClassPair;
import javax.naming.NamingException;
/**
* The default NameClassPairMapper implementation. This implementation simply
* takes the Name string from the supplied NameClassPair and returns it as
* result.
*
* @author Mattias Arthursson
*
*/
public class DefaultNameClassPairMapper implements NameClassPairMapper {
/**
* Gets the Name from the supplied NameClassPair and returns it as the
* result.
*
* @param nameClassPair
* the NameClassPair to transform.
* @return the Name string from the NameClassPair.
*/
public Object mapFromNameClassPair(NameClassPair nameClassPair)
throws NamingException {
return nameClassPair.getName();
}
}

View File

@@ -1,96 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.CommunicationException;
import javax.naming.ContextNotEmptyException;
import javax.naming.LimitExceededException;
import javax.naming.NameAlreadyBoundException;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import javax.naming.directory.InvalidAttributesException;
import javax.naming.directory.InvalidSearchControlsException;
import javax.naming.directory.InvalidSearchFilterException;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
/**
* The default implementation of NamingExceptionTranslator.
*
* @author Mattias Arthursson
*/
public class DefaultNamingExceptionTranslator implements
NamingExceptionTranslator {
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.NamingExceptionTranslator#translate(java.lang.String,
* java.lang.String, java.lang.String, javax.naming.NamingException)
*/
public DataAccessException translate(NamingException namingException) {
if (namingException instanceof NameNotFoundException) {
return new EntryNotFoundException("Entry not found",
namingException);
}
if (namingException instanceof InvalidSearchFilterException) {
return new BadLdapGrammarException("Invalid search filter",
namingException);
}
if (namingException instanceof InvalidSearchControlsException) {
return new InvalidDataAccessApiUsageException(
"Invalid search controls supplied by internal API",
namingException);
}
if (namingException instanceof NameAlreadyBoundException) {
return new DataIntegrityViolationException("Name already bound",
namingException);
}
if (namingException instanceof ContextNotEmptyException) {
return new DataIntegrityViolationException(
"The context needs to be empty in order to be removed",
namingException);
}
if (namingException instanceof InvalidAttributesException) {
return new AttributesIntegrityViolationException(
"Invalid attributes", namingException);
}
if (namingException instanceof LimitExceededException) {
return new SearchLimitExceededException("Too many objects found",
namingException);
}
if (namingException instanceof CommunicationException) {
throw new DataRetrievalFailureException(
"Unable to communicate with LDAP server", namingException);
}
// Fallback - other type of NamingException encountered.
return new UncategorizedLdapException("Operation failed",
namingException);
}
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.DataRetrievalFailureException;
/**
* Represents that an entry could not be found.
*
* @author Mattias Arthursson
*/
public class EntryNotFoundException extends DataRetrievalFailureException {
private static final long serialVersionUID = -1268390922996332424L;
public EntryNotFoundException(String msg) {
super(msg);
}
public EntryNotFoundException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NameClassPair;
/**
* Callback interface used by LdapTemplate's search, list and listBindings
* methods. Implementations of this interface perform the actual work of
* extracting results from a single NameClassPair (a NameClassPair,
* Binding or SearchResult depending on the search operation) returned by an
* LDAP seach operation, such as search(), list(), and listBindings().
*
* @author Mattias Arthursson
*/
public interface NameClassPairCallbackHandler {
/**
* Handle one entry. This method will be called once for each entry returned
* by a search or list.
*
* @param nameClassPair
* the NameClassPair returned from the NamingEnumeration.
*/
public void handleNameClassPair(NameClassPair nameClassPair);
}

View File

@@ -1,42 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NameClassPair;
import javax.naming.NamingException;
/**
* Responsible for mapping NameClassPair objects to beans.
*
* @author Mattias Arthursson
*/
public interface NameClassPairMapper {
/**
* Map NameClassPair to an Object. The supplied NameClassPair is one of the
* results from a search operation (search, list or listBindings). Depending
* on which search operation is being performed, the NameClassPair might be
* a SearchResult, Binding or NameClassPair.
*
* @param nameClassPair
* NameClassPair from a search operation.
* @return and Object built from the NameClassPair.
* @throws NamingException
* if one is encountered in the operation.
*/
public Object mapFromNameClassPair(NameClassPair nameClassPair)
throws NamingException;
}

View File

@@ -1,39 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NamingException;
import org.springframework.dao.DataAccessException;
/**
* Interface to be implemented by classes that can translate between
* NamingExceptions and DataAccessExceptions.
*
* @author Mattias Arthursson
*
*/
public interface NamingExceptionTranslator {
/**
* Translate the given NamingException into a generic data access exception.
* @param namingException
* the offending NamingException.
*
* @return the DataAccessException to throw.
*/
public DataAccessException translate(NamingException namingException);
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2002-2005 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;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
/**
* Interface for delegating an actual search operation. The typical
* implementation of executeSearch would be something like:
*
* <pre>
* SearchExecutor executor = new SearchExecutor(){
* public NamingEnumeration executeSearch(DirContext ctx) throws NamingException{
* return ctx.search(dn, filter, searchControls);
* }
* }
* </pre>
*
* @see org.springframework.ldap.LdapTemplate#search(SearchExecutor,
* NameClassPairCallbackHandler)
*
* @author Mattias Arthursson
*/
public interface SearchExecutor {
/**
* Execute the actual search.
*
* @param ctx
* the DirContext on which to work.
* @return the NamingEnumeration resulting from the search operation.
* @throws NamingException
* if the search results in one.
*/
public NamingEnumeration executeSearch(DirContext ctx)
throws NamingException;
}

View File

@@ -1,37 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.DataRetrievalFailureException;
/**
* Indicates that the search limit was exceeded in a search.
*
* @author Mattias Arthursson
*
*/
public class SearchLimitExceededException extends DataRetrievalFailureException {
private static final long serialVersionUID = 6899885947075235580L;
public SearchLimitExceededException(String msg) {
super(msg);
}
public SearchLimitExceededException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,35 +0,0 @@
/*
* Copyright 2002-2005 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;
import org.springframework.dao.UncategorizedDataAccessException;
/**
* Indicates that an unknown NamingException has occurred.
*
* @author Mattias Arthursson
*/
public class UncategorizedLdapException extends
UncategorizedDataAccessException {
private static final long serialVersionUID = -3319936235493869823L;
public UncategorizedLdapException(String msg, Throwable cause) {
super(msg, cause);
}
}

View File

@@ -1,3 +0,0 @@
<body>
The core package of the Spring-LDAP library.
</body>

View File

@@ -1,455 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import java.util.Map;
import javax.naming.Context;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.JdkVersion;
import org.springframework.ldap.AuthenticationSource;
import org.springframework.ldap.ContextSource;
import org.springframework.ldap.DefaultNamingExceptionTranslator;
import org.springframework.ldap.NamingExceptionTranslator;
/**
* Abstract implementation of the ContextSource interface. By default, returns
* an authenticated DirContext implementation for both read-only and read-write
* operations. To have an anonymous environment created for read-only
* operations, set the anonymousReadOnly property to <code>true</code>.
* <p>
* Implementing classes need to implement
* {@link #getDirContextInstance(Hashtable)} to create a DirContext instance of
* the desired type.
* <p>
* If an AuthenticationSource is set, this will be used for getting user name
* and password for each new connection, otherwise a default one will be created
* using the specified userName and password.
* <p>
* <b>Note:</b> When using implementations of this class outside of a Spring
* Context it is necessary to call {@link #afterPropertiesSet()} when all
* properties are set, in order to finish up initialization.
*
* @see org.springframework.ldap.LdapTemplate
* @see org.springframework.ldap.support.DefaultDirObjectFactory
* @see org.springframework.ldap.support.LdapContextSource
* @see org.springframework.ldap.support.DirContextSource
*
* @author Mattias Arthursson
* @author Adam Skogman
* @author Ulrik Sandberg
*/
public abstract class AbstractContextSource implements ContextSource,
InitializingBean {
private static final Class DEFAULT_CONTEXT_FACTORY = com.sun.jndi.ldap.LdapCtxFactory.class;
private static final Class DEFAULT_DIR_OBJECT_FACTORY = DefaultDirObjectFactory.class;
private Class dirObjectFactory = DEFAULT_DIR_OBJECT_FACTORY;
private Class contextFactory = DEFAULT_CONTEXT_FACTORY;
private DistinguishedName base;
protected String userName = "";
protected String password = "";
private String[] urls;
private boolean pooled = true;
private Hashtable baseEnv = new Hashtable();
private Hashtable anonymousEnv;
private AuthenticationSource authenticationSource;
private boolean cacheEnvironmentProperties = true;
private boolean anonymousReadOnly = false;
private NamingExceptionTranslator exceptionTranslator = new DefaultNamingExceptionTranslator();
private static final Log log = LogFactory.getLog(LdapContextSource.class);
public static final String SUN_LDAP_POOLING_FLAG = "com.sun.jndi.ldap.connect.pool";
private static final String JDK_142 = "1.4.2";
public DirContext getReadOnlyContext() {
if (!anonymousReadOnly) {
return createContext(getAuthenticatedEnv());
} else {
return createContext(getAnonymousEnv());
}
}
public DirContext getReadWriteContext() {
return createContext(getAuthenticatedEnv());
}
/**
* Default implementation of setting the environment up to be authenticated.
* Override in subclass if necessary. This is needed for Active Directory
* connectivity, for example.
*
* @param env
* the environment to modify.
*/
protected void setupAuthenticatedEnvironment(Hashtable env) {
env
.put(Context.SECURITY_PRINCIPAL, authenticationSource
.getPrincipal());
log.debug("Principal: '" + userName + "'");
env.put(Context.SECURITY_CREDENTIALS, authenticationSource
.getCredentials());
}
/**
* Close the context and swallow any exceptions.
*
* @param ctx
* the DirContext to close.
*/
private void closeContext(DirContext ctx) {
if (ctx != null) {
try {
ctx.close();
} catch (Exception e) {
}
}
}
/**
* Assemble a valid url String from all registered urls to add as
* PROVIDER_URL to the environment.
*
* @param ldapUrls
* all individual url Strings.
* @return the full url String
*/
protected String assembleProviderUrlString(String[] ldapUrls) {
StringBuffer providerUrlBuffer = new StringBuffer(1024);
for (int i = 0; i < ldapUrls.length; i++) {
providerUrlBuffer.append(ldapUrls[i]);
if (base != null) {
if (!ldapUrls[i].endsWith("/")) {
providerUrlBuffer.append("/");
}
providerUrlBuffer.append(base.toUrl());
}
providerUrlBuffer.append(' ');
}
return providerUrlBuffer.toString().trim();
}
/**
* Set the base suffix from which all operations should origin. If a base
* suffix is set, you will not have to (and, indeed, should not) specify the
* full distinguished names in the operations performed.
*
* @param base
* the base suffix.
*/
public void setBase(String base) {
this.base = new DistinguishedName(base);
}
/**
* Create a DirContext using the supplied environment.
*
* @param environment
* the Ldap environment to use when creating the DirContext.
* @return a new DirContext implpementation initialized with the supplied
* environment.
*/
DirContext createContext(Hashtable environment) {
DirContext ctx = null;
try {
ctx = getDirContextInstance(environment);
if (log.isInfoEnabled()) {
Hashtable ctxEnv = ctx.getEnvironment();
String ldapUrl = (String) ctxEnv.get(Context.PROVIDER_URL);
log.debug("Got Ldap context on server '" + ldapUrl + "'");
}
return ctx;
} catch (NamingException e) {
closeContext(ctx);
throw getExceptionTranslator().translate(e);
}
}
/**
* Set the context factory. Default is com.sun.jndi.ldap.LdapCtxFactory.
*
* @param contextFactory
* the context factory used when creating Contexts.
*/
public void setContextFactory(Class contextFactory) {
this.contextFactory = contextFactory;
}
/**
* Set the DirObjectFactory to use. Default is
* {@link DefaultDirObjectFactory}. The specified class needs to be an
* implementation of javax.naming.spi.DirObjectFactory. <b>Note: </b>Setting
* this value to null may have cause connection leaks when using
* ContextMapper methods in LdapTemplate.
*
* @param dirObjectFactory
* the DirObjectFactory to be used. Null means that no
* DirObjectFactory will be used.
*/
public void setDirObjectFactory(Class dirObjectFactory) {
this.dirObjectFactory = dirObjectFactory;
}
/**
* Checks that all necessary data is set and that there is no compatibility
* issues, after which the instance is initialized. Note that you need to
* call this method explicitly after setting all desired properties if using
* the class outside of a Spring Context.
*/
public void afterPropertiesSet() throws Exception {
if (ArrayUtils.isEmpty(urls)) {
throw new IllegalArgumentException(
"At least one server url must be set");
}
if (base != null && getJdkVersion().compareTo(JDK_142) < 0) {
throw new IllegalArgumentException(
"Base path is not supported for JDK versions < 1.4.2");
}
if (authenticationSource == null) {
log.debug("AuthenticationSource not set - "
+ "using default implementation");
if (StringUtils.isBlank(userName)) {
log
.warn("Property 'userName' not set - "
+ "anonymous context will be used for read-write operations");
} else if (StringUtils.isBlank(password)) {
log.warn("Property 'password' not set - "
+ "blank password will be used");
}
authenticationSource = new SimpleAuthenticationSource();
}
if (cacheEnvironmentProperties) {
anonymousEnv = setupAnonymousEnv();
}
}
private Hashtable setupAnonymousEnv() {
if (pooled) {
baseEnv.put(SUN_LDAP_POOLING_FLAG, "true");
log.debug("Using LDAP pooling.");
} else {
log.debug("Not using LDAP pooling");
}
Hashtable env = new Hashtable(baseEnv);
env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory.getName());
env.put(Context.PROVIDER_URL, assembleProviderUrlString(urls));
if (dirObjectFactory != null) {
env.put(Context.OBJECT_FACTORIES, dirObjectFactory.getName());
}
if (base != null) {
// Save the base path for use in the DefaultDirObjectFactory.
env.put(DefaultDirObjectFactory.JNDI_ENV_BASE_PATH_KEY, base);
}
log.debug("Trying provider Urls: " + assembleProviderUrlString(urls));
return env;
}
/**
* Set the password (credentials) to use for getting authenticated contexts.
*
* @param password
* the password.
*/
public void setPassword(String password) {
this.password = password;
}
/**
* Set the user name (principal) to use for getting authenticated contexts.
*
* @param userName
* the user name.
*/
public void setUserName(String userName) {
this.userName = userName;
}
/**
* Set the urls of the LDAP servers. Use this method if several servers are
* required.
*
* @param urls
* the urls of all servers.
*/
public void setUrls(String[] urls) {
this.urls = urls;
}
/**
* Set the url of the LDAP server. Utility method if only one server is
* used.
*
* @param url
* the url of the LDAP server.
*/
public void setUrl(String url) {
this.urls = new String[] { url };
}
/**
* Set whether the pooling flag should be set. Default is true.
*
* @param pooled
* whether Contexts should be pooled.
*/
public void setPooled(boolean pooled) {
this.pooled = pooled;
}
/**
* If any custom environment properties are needed, these can be set using
* this method.
*
* @param baseEnvironmentProperties
*/
public void setBaseEnvironmentProperties(Map baseEnvironmentProperties) {
this.baseEnv = new Hashtable(baseEnvironmentProperties);
}
String getJdkVersion() {
return JdkVersion.getJavaVersion();
}
protected Hashtable getAnonymousEnv() {
if (cacheEnvironmentProperties) {
return anonymousEnv;
} else {
return setupAnonymousEnv();
}
}
protected Hashtable getAuthenticatedEnv() {
// The authenticated environment should always be rebuilt.
Hashtable env = new Hashtable(getAnonymousEnv());
setupAuthenticatedEnvironment(env);
return env;
}
public void setAuthenticationSource(
AuthenticationSource authenticationProvider) {
this.authenticationSource = authenticationProvider;
}
/**
* Set whether environment properties should be cached between requsts for
* anonymous environment. Default is true; setting this property to false
* causes the environment Hashmap to be rebuilt from the current property
* settings of this instance between each request for an anonymous
* environment.
*
* @param cacheEnvironmentProperties
* true causes that the anonymous environment properties should
* be cached, false causes the Hashmap to be rebuilt for each
* request.
*/
public void setCacheEnvironmentProperties(boolean cacheEnvironmentProperties) {
this.cacheEnvironmentProperties = cacheEnvironmentProperties;
}
/**
* Set whether an anonymous environment should be used for read-only
* operations. Default is <code>false</code>.
*
* @param anonymousReadOnly
* <code>true</code> if and anonymous environment should be
* used for read-only operations, <code>false</code> otherwise.
*/
public void setAnonymousReadOnly(boolean anonymousReadOnly) {
this.anonymousReadOnly = anonymousReadOnly;
}
/**
* Set the NamingExceptionTranslator to be used by this instance. By
* default, a {@link DefaultNamingExceptionTranslator} will be used.
*
* @param exceptionTranslator
* the NamingExceptionTranslator to use.
*/
public void setExceptionTranslator(
NamingExceptionTranslator exceptionTranslator) {
this.exceptionTranslator = exceptionTranslator;
}
/**
* Get the NamingExceptionTranslator used by this instance.
*
* @return the NamingExceptionTranslator.
*/
public NamingExceptionTranslator getExceptionTranslator() {
return exceptionTranslator;
}
/**
* Implement in subclass to create a DirContext of the desired type (e.g.
* InitialDirContext or InitialLdapContext).
*
* @param environment
* the environment to use when creating the instance.
* @return a new DirContext instance.
* @throws NamingException
* if one is encountered when creating the instance.
*/
protected abstract DirContext getDirContextInstance(Hashtable environment)
throws NamingException;
class SimpleAuthenticationSource implements AuthenticationSource {
public String getPrincipal() {
return userName;
}
public String getCredentials() {
return password;
}
}
}

View File

@@ -1,36 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import javax.naming.directory.ModificationItem;
/**
* Indicates that the implementor is capable of keeping track of any attribute
* modifications and return them as ModificationItems.
*
* @author Mattias Arthursson
*
*/
public interface AttributeModificationsAware {
/**
* Creates an array of which attributes have been changed or added or removed.
*
* @return an array of modification items
*/
public ModificationItem[] getModificationItems();
}

View File

@@ -1,51 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import javax.naming.NameClassPair;
import org.springframework.ldap.NameClassPairCallbackHandler;
/**
* A NameClassPairCallbackHandler for counting all returned entries.
*
* @author Mattias Arthursson
*
*/
public class CountNameClassPairCallbackHandler implements
NameClassPairCallbackHandler {
private int noOfRows = 0;
/**
* Get the number of rows that was returned by the search.
*
* @return the number of entries that have been handled.
*/
public int getNoOfRows() {
return noOfRows;
}
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.SearchResultCallbackHandler#handleSearchResult(javax.naming.directory.SearchResult)
*/
public void handleNameClassPair(NameClassPair nameClassPair) {
noOfRows++;
}
}

View File

@@ -1,115 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.directory.Attributes;
import javax.naming.spi.DirObjectFactory;
/**
* Default implementation of the DirObjectFactory interface. Creates a
* DirContextAdapter from the supplied arguments.
*
* @author Mattias Arthursson
*/
public class DefaultDirObjectFactory implements DirObjectFactory {
/**
* Key to use in the ContextSource implementation to store the value of the
* base path suffix, if any, in the Ldap Environment.
*/
public static final String JNDI_ENV_BASE_PATH_KEY = "org.springframework.ldap.base.path";
/**
* Creates a DirContextAdapter from the supplied arguments.
*
* @param obj
* @param name
* @param nameCtx
* @param environment
* @param attrs
* @return a new DirContextAdapter from the attributes and name.
* @throws Exception
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment, Attributes attrs) throws Exception {
try {
DirContextAdapter dirContextAdapter = new DirContextAdapter(attrs,
stripBasePath(name, environment));
dirContextAdapter.setUpdateMode(true);
return dirContextAdapter;
} finally {
// It seems that the object supplied to the obj parameter is a
// DirContext instance with reference to the same Ldap connection as
// the original context. Since it is not the same instance (that's
// the nameCtx parameter) this one really needs to be closed in
// order to correctly clean up and return the connection to the pool
// when we're finished with the surrounding operation.
if (obj instanceof Context) {
Context ctx = (Context) obj;
try {
ctx.close();
} catch (Exception e) {
// Never mind this
}
}
}
}
/**
* Rather crude method to remove the base suffix if specified in the LDAP
* environment. This could probably be improved to increase performance.
*
* @param name
* the full distinguished name of the found object.
* @param environment
* the context environment.
* @return the DN, without the base suffix.
*/
private Name stripBasePath(Name name, Hashtable environment) {
if (environment.containsKey(JNDI_ENV_BASE_PATH_KEY)) {
DistinguishedName distinguishedName = new DistinguishedName(name
.toString());
distinguishedName.removeFirst((Name) environment
.get(JNDI_ENV_BASE_PATH_KEY));
return distinguishedName;
} else {
return name;
}
}
/**
* Returns null.
*
* @param obj
* @param name
* @param nameCtx
* @param environment
* @return null.
* @throws Exception
*/
public Object getObjectInstance(Object obj, Name name, Context nameCtx,
Hashtable environment) throws Exception {
return null;
}
}

View File

@@ -1,161 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.SortedSet;
import javax.naming.Name;
import javax.naming.directory.DirContext;
/**
* Interface for DirContextAdapter to simplify mock testing.
*
* @author Mattias Arthursson
*/
public interface DirContextOperations extends DirContext,
AttributeModificationsAware {
/**
* Gets the update mode. The update mode should be <code>true</code> for a
* new entry and <code>true</code> for an existing entry that is being
* updated.
*
* @return update mode
*/
public boolean isUpdateMode();
/**
* Creates a String array of the names of the attributes which have been
* changed.
*
* If this is a new entry, all set entries will be in the list. If this is
* an updated entry, only changed and removed entries will be in the array.
*
* @return Array of String
*/
public String[] getNamesOfModifiedAttributes();
/**
* Get the value of a String attribute.
*
* @param name
* name of the attribute.
* @return the value of the attribute.
*/
public String getStringAttribute(String name);
/**
* Get the value of an Object attribute.
*
* @param name
* name of the attribute.
* @return the attribute value as an object if it exists, or
* <code>null</code> otherwise.
*/
public Object getObjectAttribute(String name);
/**
* Set the with the name <code>name</code> to the <code>value</code>.
*
* @param name
* name of the attribute.
* @param value
* value to set the attribute to.
*/
public void setAttributeValue(String name, Object value);
/**
* Sets a multivalue attribute, disregarding the order of the values.
*
* If value is null or value.length == 0 then the attribute will be removed.
*
* If update mode, changes will be made only if the array has more or less
* objects or if one or more object has changed. Reordering the objects will
* not cause an update.
*
* @param name
* The id of the attribute.
* @param values
* Attribute values.
*/
public void setAttributeValues(String name, Object[] values);
/**
* Sets a multivalue attribute.
*
* If value is null or value.length == 0 then the attribute will be removed.
*
* If update mode, changes will be made if the array has more or less
* objects or if one or more string has changed.
*
* Reordering the objects will only cause an update if orderMatters is set
* to true.
*
* @param name
* The id of the attribute.
* @param values
* Attribute values.
* @param orderMatters
* If <code>true</code>, it will be changed even if data was
* just reordered.
*/
public void setAttributeValues(String name, Object[] values,
boolean orderMatters);
/**
* Update the attributes. This will mean that the getters
* (getStringAttribute methods) will return the updated values. Remove the
* attributes to be updated.
*/
public void update();
/**
* Get all values of a String attribute.
*
* @param name
* name of the attribute.
*
* @return all registered values of the attribute.
*/
public String[] getStringAttributes(String name);
/**
* Get all String values of the attribute as a SortedSet.
*
* @param name
* name of the attribute.
* @return a SortedSet containing all values of the attribute.
*/
public SortedSet getAttributeSortedStringSet(String name);
/**
* Returns DN, for example <code>uid=some.user,ou=People,ou=EU</code>.
*
* @return The distinguished name of the current context.
*
* @see DirContextAdapter#getNameInNamespace()
*/
public Name getDn();
/**
* Set the dn of this entry.
*
* @param dn
* the dn.
*/
public void setDn(Name dn);
}

View File

@@ -1,47 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
/**
* ContextSource implementation which creates InitialDirContext instances, for
* LDAPv2 compatibility. For configuration information, see
* {@link org.springframework.ldap.support.AbstractContextSource AbstractContextSource}.
*
* @see org.springframework.ldap.support.AbstractContextSource
*
* @author Mattias Arthursson
*/
public class DirContextSource extends AbstractContextSource {
/**
* Create a new InitialDirContext instance.
*
* @param environment
* the environment to use when creating the context.
* @return a new InitialDirContext implementation.
*/
protected DirContext getDirContextInstance(Hashtable environment)
throws NamingException {
return new InitialDirContext(environment);
}
}

View File

@@ -1,570 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.naming.InvalidNameException;
import javax.naming.Name;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.BadLdapGrammarException;
/**
* Default implementation of a Name corresponding to an LDAP path. A
* DistinguishedName implementation is included in JDK1.5 (LdapName), but not in
* prior releases.
*
* An DistinguishedName is particularly useful when building or modifying an
* Ldap path dynamically, as escaping will be taken care of.
*
* A path is split into several names. The Name interface specifies that the
* most significant part be in position 0, i.e.
*
* The path: uid=adam.skogman, ou=People, ou=EU Name[0]: ou=EU Name[1]:
* ou=People Name[2]: uid=adam.skogman
* <p>
* Useful for parsing and building LDAP paths.
*
* <pre>
* DistinguishedName path = new DistinguishedName();
* path.addLast(&quot;cn&quot;, entry.getUid());
* path.addLast(&quot;ou&quot;, &quot;users&quot;);
* path.append(new DistinguishedName(helpdesk.getSomeSuffix()));
* String dn = path.toString();
* </pre>
*
* TODO: Implement compareTo().
*
* @author Adam Skogman
* @author Mattias Arthursson
*/
public class DistinguishedName implements Name {
private static final long serialVersionUID = 3514344371999042586L;
public static final DistinguishedName EMPTY_PATH = new DistinguishedName();
private LinkedList names;
protected static final Pattern NAME_PATTERN = Pattern
.compile("(.*?[^\\\\])(,|;|$)");
/**
* Construct a new DistinguishedName with no components.
*/
public DistinguishedName() {
names = new LinkedList();
}
/**
* Construct a new DistinguishedName from a String.
*
* @param path
* a String corresponding to a (syntactically) valid LDAP path.
*/
public DistinguishedName(String path) {
parse(path);
}
/**
* Construct a new DistinguishedName from the supplied List of LdapRdn
* objects.
*
* @param list
* the components that this instance will consist of.
*/
public DistinguishedName(LinkedList list) {
this.names = list;
}
/**
* Construct a new DistinguishedName from the supplied Name. The parts of
* the supplied Name must be syntactically correct LdapRdns.
*
* @param name
* the Name to construct a new DistinguishedName from.
*/
public DistinguishedName(Name name) {
names = new LinkedList();
for (int i = 0; i < name.size(); i++) {
names.add(new LdapRdn(name.get(i)));
}
}
/**
* Parse the supplied String and make this instance represent the
* corresponding distinguished name.
*
* @param path
* the LDAP path to parse.
*/
protected void parse(String path) {
names = new LinkedList();
if (!StringUtils.isBlank(path)) {
Matcher matcher = NAME_PATTERN.matcher(path);
while (matcher.find()) {
String rdnString = matcher.group(1);
LdapRdn name = new LdapRdn(rdnString);
names.add(0, name);
}
}
}
/**
* Get the LdapRdn at a specified position.
*
* @param index
* the LdapRdn to retrieve.
* @return the LdapRdn at the requested position.
*/
public LdapRdn getLdapRdn(int index) {
return (LdapRdn) names.get(index);
}
/**
* Get the name list.
*
* @return the list of LdapRdns that this DistinguishedName consists of.
*/
public LinkedList getNames() {
return names;
}
/**
* Get the String representation of this DistinguishedName.
*
* @return a syntactically correct, escaped String representation of the
* DistinguishedName.
*/
public String toString() {
return encode();
}
/**
* Builds a complete LDAP path, ldap encoded, useful as a DN.
*
* Always uses lowercase, always separates with ", " i.e. comma and a space.
*
* @return the LDAP path.
*/
public String encode() {
// empty path
if (names.size() == 0)
return "";
StringBuffer buffer = new StringBuffer(256);
ListIterator i = names.listIterator(names.size());
while (i.hasPrevious()) {
LdapRdn rdn = (LdapRdn) i.previous();
buffer.append(rdn.getLdapEncoded());
// add comma, except in last iteration
if (i.hasPrevious())
buffer.append(", ");
}
return buffer.toString();
}
/**
* Builds a complete LDAP path, ldap and url encoded. Separates only with
* ",".
*
* @return the LDAP path, for use in an url.
*/
public String toUrl() {
StringBuffer buffer = new StringBuffer(256);
for (int i = names.size() - 1; i >= 0; i--) {
LdapRdn n = (LdapRdn) names.get(i);
buffer.append(n.encodeUrl());
if (i > 0) {
buffer.append(",");
}
}
return buffer.toString();
}
/**
* Determines if a ldap path contains another path.
*
* @param path
* the path to check.
* @return true if the supplied path is conained in this instance, false
* otherwise.
*/
public boolean contains(DistinguishedName path) {
List shortlist = path.getNames();
// this path must be at least as long
if (getNames().size() < shortlist.size())
return false;
// must have names
if (shortlist.size() == 0)
return false;
Iterator longiter = getNames().iterator();
Iterator shortiter = shortlist.iterator();
LdapRdn longname = (LdapRdn) longiter.next();
LdapRdn shortname = (LdapRdn) shortiter.next();
// find first match
while (!longname.equals(shortname) && longiter.hasNext()) {
longname = (LdapRdn) longiter.next();
}
// Done?
if (!shortiter.hasNext() && longname.equals(shortname))
return true;
if (!longiter.hasNext())
return false;
// compare
while (longname.equals(shortname) && longiter.hasNext()
&& shortiter.hasNext()) {
longname = (LdapRdn) longiter.next();
shortname = (LdapRdn) shortiter.next();
}
// Done
if (!shortiter.hasNext() && longname.equals(shortname))
return true;
else
return false;
}
/**
* Add a LDAP path first
*
* @param path
*/
public void append(DistinguishedName path) {
getNames().addAll(path.getNames());
}
/**
* Add a LDAP path first
*
* @param path
*/
public void prepend(DistinguishedName path) {
ListIterator i = path.getNames().listIterator(path.getNames().size());
while (i.hasPrevious()) {
getNames().addFirst(i.previous());
}
}
/**
* Remove the first part of this DistinguishedName.
*
* @return the removed entry.
*/
public LdapRdn removeFirst() {
return (LdapRdn) getNames().removeFirst();
}
/**
* Remove the supplied path from the beginning of this DistinguishedName if
* this instance starts with <path>. Useful for stripping base path suffix
* from a DistinguishedName.
*
* @param path
* the path to remove from the beginning of this instance.
*/
public void removeFirst(Name path) {
if (path != null && this.startsWith(path)) {
for (int i = 0; i < path.size(); i++)
this.removeFirst();
}
}
/**
* @see java.lang.Object#clone()
*/
public Object clone() {
// just duplicate the list, the rdns are immutable.
LinkedList list = new LinkedList(getNames());
return new DistinguishedName(list);
}
/**
* @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;
}
DistinguishedName name = (DistinguishedName) obj;
// compare the lists
return getNames().equals(name.getNames());
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return this.getClass().hashCode() ^ getNames().hashCode();
}
public int compareTo(Object o) {
// TODO: Implement this.
return 0;
}
public int size() {
return names.size();
}
public boolean isEmpty() {
return names.size() == 0;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#getAll()
*/
public Enumeration getAll() {
LinkedList strings = new LinkedList();
for (Iterator iter = names.iterator(); iter.hasNext();) {
LdapRdn rdn = (LdapRdn) iter.next();
strings.add(rdn.getLdapEncoded());
}
return Collections.enumeration(strings);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#get(int)
*/
public String get(int index) {
LdapRdn rdn = (LdapRdn) names.get(index);
return rdn.getLdapEncoded();
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#getPrefix(int)
*/
public Name getPrefix(int index) {
LinkedList newNames = new LinkedList();
for (int i = 0; i < index; i++) {
newNames.add(names.get(i));
}
return new DistinguishedName(newNames);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#getSuffix(int)
*/
public Name getSuffix(int index) {
if (index > names.size()) {
throw new ArrayIndexOutOfBoundsException();
}
LinkedList newNames = new LinkedList();
for (int i = index; i < names.size(); i++) {
newNames.add(names.get(i));
}
return new DistinguishedName(newNames);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#startsWith(javax.naming.Name)
*/
public boolean startsWith(Name name) {
if (name.size() == 0) {
return false;
}
DistinguishedName start = null;
if (name instanceof DistinguishedName) {
start = (DistinguishedName) name;
} else {
return false;
}
if (start.size() > this.size()) {
return false;
}
Iterator longiter = names.iterator();
Iterator shortiter = start.getNames().iterator();
while (shortiter.hasNext()) {
Object longname = longiter.next();
Object shortname = shortiter.next();
if (!longname.equals(shortname)) {
return false;
}
}
// All names in shortiter matched.
return true;
}
/**
* Determines if this ldap path ends with a certian path.
*
* If the argument path is empty (no names in path) this methid will return
* false.
*
* @param name
* The suffix to check for
*
*/
public boolean endsWith(Name name) {
DistinguishedName path = null;
if (name instanceof DistinguishedName) {
path = (DistinguishedName) name;
} else {
return false;
}
List shortlist = path.getNames();
// this path must be at least as long
if (getNames().size() < shortlist.size())
return false;
// must have names
if (shortlist.size() == 0)
return false;
ListIterator longiter = getNames().listIterator(getNames().size());
ListIterator shortiter = shortlist.listIterator(shortlist.size());
while (shortiter.hasPrevious()) {
LdapRdn longname = (LdapRdn) longiter.previous();
LdapRdn shortname = (LdapRdn) shortiter.previous();
if (!longname.equals(shortname))
return false;
}
// if short list ended, all were equal
return true;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#addAll(javax.naming.Name)
*/
public Name addAll(Name name) throws InvalidNameException {
return addAll(names.size(), name);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#addAll(int, javax.naming.Name)
*/
public Name addAll(int arg0, Name name) throws InvalidNameException {
DistinguishedName distinguishedName = null;
try {
distinguishedName = (DistinguishedName) name;
} catch (ClassCastException e) {
throw new InvalidNameException("Invalid name type");
}
names.addAll(arg0, distinguishedName.getNames());
return this;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#add(java.lang.String)
*/
public Name add(String string) throws InvalidNameException {
return add(names.size(), string);
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#add(int, java.lang.String)
*/
public Name add(int index, String string) throws InvalidNameException {
try {
names.add(index, new LdapRdn(string));
} catch (BadLdapGrammarException e) {
throw new InvalidNameException("Failed to parse rdn '" + string
+ "'");
}
return this;
}
/*
* (non-Javadoc)
*
* @see javax.naming.Name#remove(int)
*/
public Object remove(int arg0) throws InvalidNameException {
LdapRdn rdn = (LdapRdn) names.remove(arg0);
return rdn.getLdapEncoded();
}
/**
* Remove the ldast part of this DistinguishedName.
*
* @return the removed LdapRdn.
*/
public LdapRdn removeLast() {
return (LdapRdn) getNames().removeLast();
}
public void add(String key, String value) {
names.add(new LdapRdn(key, value));
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.Hashtable;
import javax.naming.NamingException;
import javax.naming.directory.DirContext;
import javax.naming.ldap.InitialLdapContext;
/**
* ContextSource implementation which creates an <code>InitialLdapContext</code>
* instance. For configuration information, see
* {@link org.springframework.ldap.support.AbstractContextSource AbstractContextSource}.
*
* @see org.springframework.ldap.support.AbstractContextSource
*
* @author Mattias Arthursson
* @author Adam Skogman
* @author Ulrik Sandberg
*/
public class LdapContextSource extends AbstractContextSource {
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.AbstractContextSource#getDirContextInstance(java.util.Hashtable)
*/
protected DirContext getDirContextInstance(Hashtable environment)
throws NamingException {
return new InitialLdapContext(environment, null);
}
}

View File

@@ -1,235 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.springframework.ldap.BadLdapGrammarException;
/**
* Helper class to encode and decode ldap names and values.
*
* @author Adam Skogman
*/
public class LdapEncoder {
static private String[] nameEscapeTable = new String[96];
static private String[] filterEscapeTable = new String['\\' + 1];
/**
* Pattern for matching escaped ldap name values.
*
* Double escaping: \ -> \\ (in pattern) -> \\\\ (in java string literal)
*
* Group 1: Hex escapes = \XX -> \p{XDigit}{2} Group 2: Ordinary escapes =
* \x -> \. Group 3: Anything but \ [^\\]
*
* Note that the \ is not part of the match.
*/
static private final Pattern VALUE_DECODE_PATTERN = Pattern
.compile("(?:\\\\(\\p{XDigit}{2}))|(?:\\\\(.))|([^\\\\])");
static {
// Name encoding table -------------------------------------
// all below 0x20 (control chars)
for (char c = 0; c < ' '; c++) {
nameEscapeTable[c] = "\\" + toTwoCharHex(c);
}
nameEscapeTable['#'] = "\\#";
nameEscapeTable[','] = "\\,";
nameEscapeTable[';'] = "\\;";
nameEscapeTable['='] = "\\=";
nameEscapeTable['+'] = "\\+";
nameEscapeTable['<'] = "\\<";
nameEscapeTable['>'] = "\\>";
// nameEscapeTable['\''] = "\\";
nameEscapeTable['\"'] = "\\\"";
// nameEscapeTable['/'] = "\\" + toTwoCharHex('/');
nameEscapeTable['\\'] = "\\\\";
// Filter encoding table -------------------------------------
// fill with char itself
for (char c = 0; c < filterEscapeTable.length; c++) {
filterEscapeTable[c] = String.valueOf(c);
}
// escapes (RFC2254)
filterEscapeTable['*'] = "\\2a";
filterEscapeTable['('] = "\\28";
filterEscapeTable[')'] = "\\29";
filterEscapeTable['\\'] = "\\5c";
filterEscapeTable[0] = "\\00";
}
static protected String toTwoCharHex(char c) {
String raw = Integer.toHexString(c).toUpperCase();
if (raw.length() > 1)
return raw;
else
return "0" + raw;
}
/**
* All static methods
*/
private LdapEncoder() {
}
static public String filterEncode(String value) {
if (value == null)
return null;
// make buffer roomy
StringBuffer encodedValue = new StringBuffer(value.length() * 2);
int length = value.length();
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
if (c < filterEscapeTable.length) {
encodedValue.append(filterEscapeTable[c]);
} else {
// default: add the char
encodedValue.append(c);
}
}
return encodedValue.toString();
}
/**
* LDAP Encodes a value for use with a DN. Escapes for LDAP, not JNDI!
*
* <br/>Escapes:<br/> ' ' [space] - "\ " [if first or last] <br/> '#'
* [hash] - "\#" <br/> ',' [comma] - "\," <br/> ';' [semicolon] - "\;" <br/> '=
* [equals] - "\=" <br/> '+' [plus] - "\+" <br/> '&lt;' [less than] -
* "\&lt;" <br/> '&gt;' [greater than] - "\&gt;" <br/> '"' [double quote] -
* "\"" <br/> '\' [backslash] - "\\" <br/>
*
* @param value
* @return The escaped value
*/
static public String nameEncode(String value) {
if (value == null)
return null;
// make buffer roomy
StringBuffer encodedValue = new StringBuffer(value.length() * 2);
int length = value.length();
int last = length - 1;
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
// space first or last
if (c == ' ' && (i == 0 || i == last)) {
encodedValue.append("\\ ");
continue;
}
if (c < nameEscapeTable.length) {
// check in table for escapes
String esc = nameEscapeTable[c];
if (esc != null) {
encodedValue.append(esc);
continue;
}
}
// default: add the char
encodedValue.append(c);
}
return encodedValue.toString();
}
/**
* Decodes a value. Converts escaped chars to ordinary chars.
*
* @param value
* Trimmed value, so no leading an trailing blanks, except an
* escaped space last.
* @return The decoded value as a string.
* @throws BadLdapGrammarException
*/
static public String nameDecode(String value)
throws BadLdapGrammarException {
if (value == null)
return null;
// make buffer same size
StringBuffer decoded = new StringBuffer(value.length());
Matcher matcher = VALUE_DECODE_PATTERN.matcher(value);
int end = 0;
while (matcher.find()) {
end = matcher.end();
// group 1
if (matcher.group(1) != null) {
// parse as hex = base 16
try {
char c = (char) Integer.parseInt(matcher.group(1), 16);
decoded.append(c);
} catch (NumberFormatException e) {
throw new BadLdapGrammarException(
"Escaped hex value Could not be parsed. Found '\\"
+ matcher.group(1) + "'");
}
} else if (matcher.group(2) != null) {
// just add, we stripped away the \
decoded.append(matcher.group(2));
} else if (matcher.group(3) != null) {
// just add
decoded.append(matcher.group(3));
}
}
// end is match + +1 so it should be same as length, i.e.
// last + 1
if (end < value.length()) {
throw new BadLdapGrammarException(
"RDN could not be parsed fully, remaining '"
+ StringUtils.substring(value, end) + "'");
}
return decoded.toString();
}
}

View File

@@ -1,217 +0,0 @@
/*
* Copyright 2002-2005 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.support;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.BadLdapGrammarException;
/**
* Datatype for a LDAP name, a part of a path.
*
* The name: uid=adam.skogman Key: uid Value: adam.skogman
*
* @author Adam Skogman
*/
public class LdapRdn {
private String key;
private String value;
private String ldapEncoded;
protected static final Pattern RDN_PATTERN = Pattern
.compile("\\s*(\\p{Alnum}+)\\s*=\\s*((\\\\\\p{XDigit}{2}|\\\\.|[^\\\\])+?)\\s*");
private static final Log log = LogFactory.getLog(LdapRdn.class);
/**
* Constructs a RDN from an ldap encoded rdn "foo=bar".
*
* The key will be forced to lowercase. The value is kept as is.
*
* The ldapEncoded value will not be the same, but rather a reencoded value,
* so that all looks the same.
*
* @param ldapRdn
* @throws BadLdapGrammarException
* If the rdn could not be parsed.
*/
public LdapRdn(String ldapRdn) throws BadLdapGrammarException {
parseLdap(ldapRdn);
}
/**
* Constructs a RDN from a key and a value.
*
* The key will be forced to lowercase. The value is kept as is.
*
* @param key
* Not blank
* @param value
* Not blank
*/
public LdapRdn(String key, String value) {
if (StringUtils.isBlank(key))
throw new IllegalArgumentException("Key may not be blank");
if (StringUtils.isBlank(value))
throw new IllegalArgumentException("Value may not be blank");
this.key = key.toLowerCase();
this.value = value;
this.ldapEncoded = encodeLdap();
}
/**
* Encode key and value to ldap
*
* @return The ldap encoded rdn
*/
protected String encodeLdap() {
StringBuffer buff = new StringBuffer(key.length() + value.length() * 2);
buff.append(key);
buff.append('=');
buff.append(LdapEncoder.nameEncode(value));
return buff.toString();
}
/**
* @param rdn
* The ldap rdn to parse
* @throws BadLdapGrammarException if any error occurs parsing the rdn.
*/
protected void parseLdap(String rdn) throws BadLdapGrammarException {
Matcher matcher = RDN_PATTERN.matcher(rdn);
if (!matcher.matches()) {
throw new BadLdapGrammarException(
"Not a proper name (such as key=value): " + rdn);
}
String rawKey = matcher.group(1);
String rawValue = matcher.group(2);
this.key = StringUtils.lowerCase(rawKey);
this.value = LdapEncoder.nameDecode(rawValue);
if (key == null) {
throw new BadLdapGrammarException("Key empty in rdn '" + rdn + "'");
}
if (value == null) {
throw new BadLdapGrammarException("Value empty in rdn '" + rdn
+ "'");
}
this.ldapEncoded = encodeLdap();
}
/**
* Parse the supplied String for a valid LdapRdn. Swallow any exceptions.
*
* @param rdn
* the String to parse.
* @return an LdapRdn corresponding to the supplied String if the format was
* valid, null otherwise.
*/
public static LdapRdn parse(String rdn) {
try {
return new LdapRdn(rdn);
} catch (BadLdapGrammarException e) {
return null;
}
}
public String getKey() {
return key;
}
public String getValue() {
return value;
}
/**
*
*
* @see java.lang.Object#toString()
*/
public String toString() {
return ldapEncoded;
}
/**
* @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;
}
LdapRdn rdn = (LdapRdn) obj;
return StringUtils.equalsIgnoreCase(rdn.key, this.key)
&& StringUtils.equalsIgnoreCase(rdn.value, this.value);
}
public Object encodeUrl() {
// Use the URI class to properly URL encode the value.
try {
URI valueUri = new URI(null, null, value, null);
return key + "=" + valueUri.toString();
} catch (URISyntaxException e) {
// This should really never happen...
log.error("Failed to URL encode value " + value, e);
return key + "=" + "value";
}
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return key.hashCode() ^ value.hashCode();
}
/**
* @return The LdapRdn as a string where the value is LDAP-encoded.
*/
public String getLdapEncoded() {
return ldapEncoded;
}
}

View File

@@ -1,81 +0,0 @@
/*
* Copyright 2002-2005 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.support.authentication;
import org.acegisecurity.Authentication;
import org.acegisecurity.context.SecurityContextHolder;
import org.acegisecurity.userdetails.ldap.LdapUserDetails;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.ldap.AuthenticationSource;
/**
* An AuthenticationSource to retrieve authentication information stored in
* Acegi's SecurityContextHolder. Use Acegi's LdapAuthenticationProvider have a
* LdapUserDetails object placed in the authentication.
*
* @author Mattias Arthursson
*
*/
public class AcegiAuthenticationSource implements AuthenticationSource {
private static final Log log = LogFactory
.getLog(AcegiAuthenticationSource.class);
/**
* Get the principals of the logged in user, in this case the distinguished
* name.
*
* @return the distinguished name of the logged in user.
*/
public String getPrincipal() {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (authentication != null) {
Object principal = authentication.getPrincipal();
if (!(principal instanceof LdapUserDetails)) {
throw new IllegalArgumentException(
"The principal property of the authentication object -"
+ "needs to be a LdapUserDetails.");
} else {
LdapUserDetails details = (LdapUserDetails) principal;
return details.getDn();
}
} else {
log.warn("No Authentication object set in SecurityContext - "
+ "returning empty String as Principal");
return "";
}
}
/*
* @see org.springframework.ldap.AuthenticationSource#getCredentials()
*/
public String getCredentials() {
Authentication authentication = SecurityContextHolder.getContext()
.getAuthentication();
if (authentication != null) {
return (String) authentication.getCredentials();
} else {
log.warn("No Authentication object set in SecurityContext - "
+ "returning empty String as Credentials");
return "";
}
}
}

View File

@@ -1,157 +0,0 @@
/*
* Copyright 2002-2005 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.support.authentication;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.ldap.AuthenticationSource;
/**
* Decorator on AuthenticationSource to have default authentication information
* be returned should the target return empty principal and credentials. Useful
* in combination with {@link AcegiAuthenticationSource} if users are to be
* allowed to read some information even though they are not logged in.
* <p>
* <b>Note:</b> The <code>defaultUser</code> should be an non-privileged
* user. This is important as this is the one that will be used when no user is
* logged in (i.e. empty principal is returned from the target
* AuthenticationSource).
*
* @author Mattias Arthursson
*
*/
public class DefaultValuesAuthenticationSourceDecorator implements
AuthenticationSource, InitializingBean {
private AuthenticationSource target;
private String defaultUser;
private String defaultPassword;
/**
* Constructor for bean usage.
*/
public DefaultValuesAuthenticationSourceDecorator() {
}
/**
* Constructor to setup instance directly.
*
* @param target
* the target AuthenticationSource.
* @param defaultUser
* dn of the user to use when the target returns an empty
* principal.
* @param defaultPassword
* password of the user to use when the target returns an empty
* principal.
*/
public DefaultValuesAuthenticationSourceDecorator(
AuthenticationSource target, String defaultUser,
String defaultPassword) {
this.target = target;
this.defaultUser = defaultUser;
this.defaultPassword = defaultPassword;
}
/**
* Checks if the target's principal is not empty; if not, the credentials
* from the target is returned - otherwise return the
* <code>defaultPassword</code>.
*
* @return the target's password if the target's principal is not empty, the
* <code>defaultPassword</code> otherwise.
*/
public String getCredentials() {
if (StringUtils.isNotEmpty(target.getPrincipal())) {
return target.getCredentials();
} else {
return defaultPassword;
}
}
/**
* Checks if the target's principal is not empty; if not, this is returned -
* otherwise return the <code>defaultUser</code>.
*
* @return the target's principal if it is not empty, the
* <code>defaultUser</code> otherwise.
*/
public String getPrincipal() {
String principal = target.getPrincipal();
if (StringUtils.isNotEmpty(principal)) {
return principal;
} else {
return defaultUser;
}
}
/**
* Set the password of the default user.
*
* @param defaultPassword
* the password of the default user.
*/
public void setDefaultPassword(String defaultPassword) {
this.defaultPassword = defaultPassword;
}
/**
* Set the default user DN. This should be a non-privileged user, since it
* will be used when no authentication information is returned from the
* target.
*
* @param defaultUser
* DN of the default user.
*/
public void setDefaultUser(String defaultUser) {
this.defaultUser = defaultUser;
}
/**
* Set the target AuthenticationSource.
*
* @param target
* the target AuthenticationSource.
*/
public void setTarget(AuthenticationSource target) {
this.target = target;
}
/*
* (non-Javadoc)
*
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
public void afterPropertiesSet() throws Exception {
if (target == null) {
throw new IllegalArgumentException(
"Property 'target' must be set.'");
}
if (defaultUser == null) {
throw new IllegalArgumentException(
"Property 'defaultUser' must be set.'");
}
if (defaultPassword == null) {
throw new IllegalArgumentException(
"Property 'defaultPassword' must be set.'");
}
}
}

View File

@@ -1,3 +0,0 @@
<body>
Support classes for custom authentication.
</body>

View File

@@ -1,58 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* Convenience class that implements most of the methods in the Filter
* interface.
*
* @author Adam Skogman
*/
public abstract class AbstractFilter implements Filter {
protected AbstractFilter() {
super();
}
/**
* Prints the query with LDAP encoding to a stringbuffer
*
* @param buff
* The stringbuffer
* @return The very same stringbuffer
*/
public abstract StringBuffer encode(StringBuffer buff);
/**
* Encodes the filter to a string using the (@link #encode(StringBuffer)
* method.
*
* @return The encoded filter
*/
public String encode() {
StringBuffer buff = new StringBuffer(256);
buff = encode(buff);
return buff.toString();
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return encode();
}
}

View File

@@ -1,59 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
/**
* A filter for a logical AND. E.g.:
*
* <pre>
* AndFilter filter = new AndFilter();
* filter.and(new EqualsFilter(&quot;objectclass&quot;, &quot;person&quot;);
* filter.and(new EqualsFilter(&quot;cn&quot;, &quot;Some CN&quot;);
* System.out.println(filter.ecode());
* </pre>
*
* would result in: <code>(&amp;(objectclass=person)(cn=Some CN))</code>
*
* @see org.springframework.ldap.support.filter.EqualsFilter
* @author Adam Skogman
* @author Mattias Arthursson
*/
public class AndFilter extends BinaryLogicalFilter {
private static final String AMPERSAND = "&";
/*
* (non-Javadoc)
*
* @see org.springframework.ldap.support.filter.BinaryLogicalFilter#getLogicalOperator()
*/
protected String getLogicalOperator() {
return AMPERSAND;
}
/**
* Add a query to the and expression
*
* @param query
* The query to and with the rest of the and:ed queries.
* @return This LdapAndQuery
*/
public AndFilter and(Filter query) {
queryList.add(query);
return this;
}
}

View File

@@ -1,95 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Abstract superclass for binary logical operations, that is &quot;and&quot;
* and &quot;or&quot; operations.
*
* @author Mattias Arthursson
*/
public abstract class BinaryLogicalFilter extends AbstractFilter {
protected List queryList = new LinkedList();
/**
* @see org.springframework.ldap.support.filter.Filter#encode(java.lang.StringBuffer)
*/
public StringBuffer encode(StringBuffer buff) {
if (queryList.size() <= 0) {
// only output query if contains anything
return buff;
} else if (queryList.size() == 1) {
// don't add the &
Filter query = (Filter) queryList.get(0);
return query.encode(buff);
} else {
buff.append("(" + getLogicalOperator());
for (Iterator i = queryList.iterator(); i.hasNext();) {
Filter query = (Filter) i.next();
buff = query.encode(buff);
}
buff.append(")");
return buff;
}
}
/**
* Implement this in subclass to return the logical operator, for example
* &qout;&amp;&qout;.
*
* @return the logical operator.
*/
protected abstract String getLogicalOperator();
/**
* Compares each filter in turn
*
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (obj instanceof BinaryLogicalFilter
&& this.getClass() == obj.getClass()) {
return EqualsBuilder.reflectionEquals(this, obj);
} else {
return false;
}
}
/**
* Hashes all contained data
*
* @see org.springframework.ldap.support.filter.Filter#hashCode()
*/
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this);
}
}

View File

@@ -1,123 +0,0 @@
/*
* Copyright 2002-2005 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.support.filter;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.springframework.ldap.support.LdapEncoder;
/**
* Abstract superclass for filters to compare values.
*
* @author Mattias Arthursson
*/
public abstract class CompareFilter extends AbstractFilter {
private final String attribute;
private final String value;
private final String encodedValue;
public CompareFilter(String attribute, String value) {
this.attribute = attribute;
this.value = value;
this.encodedValue = encodeValue(value);
}
/**
* For testing purposes.
*
* @return the encoded value.
*/
String getEncodedValue() {
return encodedValue;
}
/**
* Override to perform special encoding in subclass.
*
* @param value
* the value to encode.
* @return properly escaped value.
*/
protected String encodeValue(String value) {
return LdapEncoder.filterEncode(value);
}
/**
* Convenience constructor for int values.
*
* @param attribute
* @param value
*/
public CompareFilter(String attribute, int value) {
this.attribute = attribute;
this.value = String.valueOf(value);
this.encodedValue = LdapEncoder.filterEncode(this.value);
}
/*
* @see org.springframework.ldap.support.filter.AbstractFilter#encode(java.lang.StringBuffer)
*/
public StringBuffer encode(StringBuffer buff) {
buff.append('(');
buff.append(attribute).append(getCompareString()).append(encodedValue);
buff.append(')');
return buff;
}
/**
* Compares key and value before encoding.
*
* @see org.springframework.ldap.support.filter.Filter#equals(java.lang.Object)
*/
public boolean equals(Object o) {
if (o instanceof CompareFilter && o.getClass() == this.getClass()) {
CompareFilter that = (CompareFilter) o;
EqualsBuilder builder = new EqualsBuilder();
builder.append(this.attribute, that.attribute);
builder.append(this.value, that.value);
return builder.isEquals();
} else {
return false;
}
}
/**
* Calculate the hash code for the attribute and the value.
*
* @see org.springframework.ldap.support.filter.Filter#hashCode()
*/
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(attribute);
builder.append(value);
return builder.toHashCode();
}
/**
* Implement this method in subclass to return a String representing the
* operator. The {@link EqualsFilter#getCompareString()} would for example
* return an equals sign, &quot;=&quot;.
*
* @return the String to use as operator in the comparison for the specific
* subclass.
*/
protected abstract String getCompareString();
}

Some files were not shown because too many files have changed in this diff Show More