package org.constretto.internal.store.ldap; import com.google.gson.Gson; import org.constretto.ConfigurationStore; import org.constretto.exception.ConstrettoException; import org.constretto.model.ConfigurationValue; import org.constretto.model.TaggedPropertySet; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import java.util.*; /** * @author <a href=mailto:zapodot@gmail.com>Sondre Eikanger Kvalø</a> */ public class LdapConfigurationStore implements ConfigurationStore { private Map<String, Attributes> keyAttributesMap = Collections.emptyMap(); private List<String> tags = Collections.emptyList(); private final Gson gsonSerializer = new Gson(); public LdapConfigurationStore() { tags = Arrays.asList(ConfigurationValue.DEFAULT_TAG); } private LdapConfigurationStore(List<String> tags) { this.tags = tags; } public LdapConfigurationStore(LdapConfigurationStore oldStore, String key, Attributes attributes, String... tags) { this(tags == null || tags.length == 0 ? Arrays.asList(ConfigurationValue.DEFAULT_TAG) : Arrays.asList(tags)); this.keyAttributesMap = new HashMap<String, Attributes>(oldStore.keyAttributesMap.size() + 1); this.keyAttributesMap.putAll(oldStore.keyAttributesMap); this.keyAttributesMap.put(key, attributes); } public LdapConfigurationStore(LdapConfigurationStore oldStore, Attributes attributes, String... tags) { this(oldStore, null, attributes, tags); } public Collection<TaggedPropertySet> parseConfiguration() { Map<String, String> properties = new HashMap<String, String>(keyAttributesMap.size()); for (String key : keyAttributesMap.keySet()) { properties.putAll(convertAttributesToProperties(key, keyAttributesMap.get(key))); } return createTaggedPropertySetsFromProperties(properties); } private List<TaggedPropertySet> createTaggedPropertySetsFromProperties(Map<String, String> properties) { List<TaggedPropertySet> taggedPropertySets = new ArrayList<TaggedPropertySet>(tags.size()); for (String tag : tags) { taggedPropertySets.add(new TaggedPropertySet(tag, properties, getClass())); } return taggedPropertySets; } private Map<String, String> convertAttributesToProperties(String key, Attributes attributes) { Map<String, String> properties = new HashMap<String, String>(keyAttributesMap.size()); try { final NamingEnumeration<? extends Attribute> attributesAll = attributes.getAll(); while (attributesAll.hasMore()) { final Attribute attribute = attributesAll.next(); if (!attribute.getID().contains("password")) { properties.put(mergeKeyAndId(key, attribute.getID()), convertAttribute(attribute)); } } } catch (NamingException e) { throw new ConstrettoException("Could not read attributes from LDAP"); } return properties; } private String convertAttribute(Attribute attribute) throws NamingException { final int subElementsCount = attribute.size(); if(subElementsCount == 1) { return attribute.get().toString(); } else { List<String> multiValue = new ArrayList<String>(subElementsCount); for(int i=0; i < subElementsCount; i++) { multiValue.add(attribute.get(i).toString()); } return gsonSerializer.toJson(multiValue); } } private String mergeKeyAndId(String key, String id) { return key == null ? id : key + "." + id; } }