org.springframework.ldap.core.support.BaseLdapPathBeanPostProcessor Maven / Gradle / Ivy
/*
* Copyright 2005-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.ldap.core.support;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.Ordered;
import org.springframework.ldap.core.DistinguishedName;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.util.StringUtils;
import javax.naming.ldap.LdapName;
import java.util.Collection;
/**
* This BeanPostProcessor
checks each bean if it implements
* {@link BaseLdapNameAware} or {@link BaseLdapPathAware}.
* If it does, the default context base LDAP path will be determined,
* and that value will be injected to the {@link BaseLdapNameAware#setBaseLdapPath(javax.naming.ldap.LdapName)}
* or {@link BaseLdapPathAware#setBaseLdapPath(DistinguishedName)} method of the
* processed bean.
*
* If the baseLdapPath
property of this
* BeanPostProcessor
is set, that value will be used. Otherwise, in
* order to determine which base LDAP path to supply to the instance the
* ApplicationContext
is searched for any beans that are
* implementations of {@link BaseLdapPathSource}. If one single occurrence is
* found, that instance is queried for its base path, and that is what will be
* injected. If more than one {@link BaseLdapPathSource} instance is configured
* in the ApplicationContext
, the name of the one to use will need
* to be specified to the baseLdapPathSourceName
property;
* otherwise the post processing will fail. If no {@link BaseLdapPathSource}
* implementing bean is found in the context and the basePath
* property is not set, post processing will also fail.
*
* @author Mattias Hellborg Arthursson
* @since 1.2
*/
public class BaseLdapPathBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware, Ordered {
private ApplicationContext applicationContext;
private LdapName basePath;
private String baseLdapPathSourceName;
private int order = Ordered.LOWEST_PRECEDENCE;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
if(bean instanceof BaseLdapNameAware) {
BaseLdapNameAware baseLdapNameAware = (BaseLdapNameAware) bean;
if (basePath != null) {
baseLdapNameAware.setBaseLdapPath(LdapUtils.newLdapName(basePath));
}
else {
BaseLdapPathSource ldapPathSource = getBaseLdapPathSourceFromApplicationContext();
baseLdapNameAware.setBaseLdapPath(LdapUtils.newLdapName(ldapPathSource.getBaseLdapName()));
}
} else if (bean instanceof BaseLdapPathAware) {
BaseLdapPathAware baseLdapPathAware = (BaseLdapPathAware) bean;
if (basePath != null) {
baseLdapPathAware.setBaseLdapPath(new DistinguishedName(basePath));
}
else {
BaseLdapPathSource ldapPathSource = getBaseLdapPathSourceFromApplicationContext();
baseLdapPathAware.setBaseLdapPath(ldapPathSource.getBaseLdapPath().immutableDistinguishedName());
}
}
return bean;
}
BaseLdapPathSource getBaseLdapPathSourceFromApplicationContext() {
if (StringUtils.hasLength(baseLdapPathSourceName)) {
return applicationContext.getBean(baseLdapPathSourceName, BaseLdapPathSource.class);
}
Collection beans = applicationContext.getBeansOfType(BaseLdapPathSource.class).values();
if (beans.isEmpty()) {
throw new NoSuchBeanDefinitionException("No BaseLdapPathSource implementation definition found");
} else if (beans.size() == 1) {
return beans.iterator().next();
} else {
BaseLdapPathSource found = null;
// Try to find the correct one
for (BaseLdapPathSource bean : beans) {
if(bean instanceof AbstractContextSource) {
if(found != null) {
// More than one found - nothing much to do.
throw new NoSuchBeanDefinitionException(
"More than BaseLdapPathSource implementation definition found in current ApplicationContext; " +
"unable to determine the one to use. Please specify 'baseLdapPathSourceName'");
}
found = bean;
}
}
if(found == null) {
throw new NoSuchBeanDefinitionException(
"More than BaseLdapPathSource implementation definition found in current ApplicationContext; " +
"unable to determine the one to use (one of them should be an AbstractContextSource instance). " +
"Please specify 'baseLdapPathSourceName'");
}
return found;
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
// Do nothing for this implementation
return bean;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* Set the base path to be injected in all {@link BaseLdapPathAware} beans.
* If this property is not set, the default base path will be determined
* from any defined {@link BaseLdapPathSource} instances available in the
* ApplicationContext
.
*
* @param basePath the base path.
* @deprecated {@link DistinguishedName} and associated classes and methods are deprecated as of 2.0.
*/
public void setBasePath(DistinguishedName basePath) {
this.basePath = LdapUtils.newLdapName(basePath);
}
public void setBasePath(String basePath) {
this.basePath = LdapUtils.newLdapName(basePath);
}
/**
* Set the name of the ContextSource
bean to use for getting
* the base path. This method is typically useful if several ContextSource
* instances have been configured.
*
* @param contextSourceName the name of the ContextSource
bean
* to use for determining the base path.
*/
public void setBaseLdapPathSourceName(String contextSourceName) {
this.baseLdapPathSourceName = contextSourceName;
}
/**
* Set the order value of this object for sorting purposes.
*
* @param order the order of this instance. Defaults to Ordered.LOWEST_PRECEDENCE
.
* @see Ordered
* @since 1.3.2
*/
public void setOrder(int order) {
this.order = order;
}
public int getOrder() {
return order;
}
}