Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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.odm.core.impl;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.naming.Name;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.LdapDataEntry;
import org.springframework.core.SpringVersion;
import org.springframework.ldap.filter.AndFilter;
import org.springframework.ldap.filter.EqualsFilter;
import org.springframework.ldap.filter.Filter;
import org.springframework.ldap.odm.annotations.DnAttribute;
import org.springframework.ldap.odm.core.ObjectDirectoryMapper;
import org.springframework.ldap.odm.typeconversion.ConverterManager;
import org.springframework.ldap.odm.typeconversion.impl.ConversionServiceConverterManager;
import org.springframework.ldap.odm.typeconversion.impl.ConverterManagerImpl;
import org.springframework.ldap.support.LdapNameBuilder;
import org.springframework.ldap.support.LdapUtils;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* Default implementation of {@link ObjectDirectoryMapper}. Unless you need to explicitly configure
* converters there is typically no reason to explicitly consider yourself with this class.
*
* @author Paul Harvey <paul.at.pauls-place.me.uk>
* @author Mattias Hellborg Arthursson
* @since 2.0
*/
public class DefaultObjectDirectoryMapper implements ObjectDirectoryMapper {
private static final Logger LOG = LoggerFactory.getLogger(DefaultObjectDirectoryMapper.class);
// The converter manager to use to translate values between LDAP and Java
private ConverterManager converterManager;
private static final String OBJECT_CLASS_ATTRIBUTE="objectclass";
private static final CaseIgnoreString OBJECT_CLASS_ATTRIBUTE_CI=new CaseIgnoreString(OBJECT_CLASS_ATTRIBUTE);
public DefaultObjectDirectoryMapper() {
this.converterManager = createDefaultConverterManager();
}
private static ConverterManager createDefaultConverterManager() {
String springVersion = SpringVersion.getVersion();
if(springVersion == null) {
LOG.debug("Could not determine the Spring Version. Guessing > Spring 3.0. If this does not work, please ensure to explicitly set converterManager");
return new ConversionServiceConverterManager();
} else if(springVersion.compareTo("3.0") > 0) {
return new ConversionServiceConverterManager();
} else {
return new ConverterManagerImpl();
}
}
public void setConverterManager(ConverterManager converterManager) {
this.converterManager = converterManager;
}
static final class EntityData {
final ObjectMetaData metaData;
final Filter ocFilter;
private EntityData(ObjectMetaData metaData, Filter ocFilter) {
this.metaData=metaData;
this.ocFilter=ocFilter;
}
}
// A map of managed classes to to meta data about those classes
private final ConcurrentMap, EntityData> metaDataMap=new ConcurrentHashMap, EntityData>();
private EntityData getEntityData(Class managedClass) {
EntityData result = metaDataMap.get(managedClass);
if (result == null) {
return addManagedClass(managedClass);
}
return result;
}
@Override
public void manageClass(Class clazz) {
// This throws exception if data is invalid
getEntityData(clazz);
}
/**
* Adds an {@link org.springframework.ldap.odm.annotations} annotated class to the set
* managed by this OdmManager.
*
* @param managedClass The class to add to the managed set.
*/
private EntityData addManagedClass(Class managedClass) {
if (LOG.isDebugEnabled()) {
LOG.debug(String.format("Adding class %1$s to managed set", managedClass));
}
// Extract the meta-data from the class
ObjectMetaData metaData=new ObjectMetaData(managedClass);
// Check we can construct the target type - it must have a zero argument public constructor
try {
managedClass.getConstructor();
} catch (NoSuchMethodException e) {
throw new InvalidEntryException(String.format(
"The class %1$s must have a zero argument constructor to be an Entry", managedClass), e);
}
// Check we have all of the necessary converters for the class
for (Field field : metaData) {
AttributeMetaData attributeInfo = metaData.getAttribute(field);
if (!attributeInfo.isTransient() && !attributeInfo.isId() && !(attributeInfo.isObjectClass())) {
verifyConversion(managedClass, field, attributeInfo);
}
}
// Filter so we only read the object classes supported by the managedClass
AndFilter ocFilter = new AndFilter();
for (CaseIgnoreString oc : metaData.getObjectClasses()) {
ocFilter.and(new EqualsFilter(OBJECT_CLASS_ATTRIBUTE, oc.toString()));
}
EntityData newValue = new EntityData(metaData, ocFilter);
EntityData previousValue = metaDataMap.putIfAbsent(managedClass, newValue);
// Just in case someone beat us to it
if(previousValue != null) {
return previousValue;
}
return newValue;
}
private void verifyConversion(Class managedClass, Field field, AttributeMetaData attributeInfo) {
Class jndiClass = attributeInfo.getJndiClass();
Class javaClass = attributeInfo.getValueClass();
if (!converterManager.canConvert(jndiClass, attributeInfo.getSyntax(), javaClass)) {
throw new InvalidEntryException(String.format(
"Missing converter from %1$s to %2$s, this is needed for field %3$s on Entry %4$s",
jndiClass, javaClass, field.getName(), managedClass));
}
if (!converterManager.canConvert(javaClass, attributeInfo.getSyntax(), jndiClass)) {
throw new InvalidEntryException(String.format(
"Missing converter from %1$s to %2$s, this is needed for field %3$s on Entry %4$s",
javaClass, jndiClass, field.getName(), managedClass));
}
}
@Override
public void mapToLdapDataEntry(Object entry, LdapDataEntry context) {
ObjectMetaData metaData=getEntityData(entry.getClass()).metaData;
Attribute objectclassAttribute = context.getAttributes().get(OBJECT_CLASS_ATTRIBUTE);
if(objectclassAttribute == null || objectclassAttribute.size() == 0) {
// Object classes are set from the metadata obtained from the @Entity annotation,
// but only if this is a new entry.
int numOcs=metaData.getObjectClasses().size();
CaseIgnoreString[] metaDataObjectClasses=metaData.getObjectClasses().toArray(new CaseIgnoreString[numOcs]);
String[] stringOcs=new String[numOcs];
for (int ocIndex=0; ocIndex targetClass = attributeInfo.getJndiClass();
// Multi valued?
if (!attributeInfo.isCollection()) {
populateSingleValueAttribute(entry, context, field, attributeInfo, targetClass);
} else {
// Multi-valued
populateMultiValueAttribute(entry, context, field, attributeInfo, targetClass);
}
} catch (IllegalAccessException e) {
throw new InvalidEntryException(String.format("Can't set attribute %1$s", attributeInfo.getName()),
e);
}
}
}
}
private void populateMultiValueAttribute(Object entry, LdapDataEntry context, Field field, AttributeMetaData attributeInfo, Class targetClass) throws IllegalAccessException {
// We need to build up a list of of the values
List