package org.argeo.cms.directory.ldap; import java.util.Dictionary; import java.util.Enumeration; import javax.naming.NamingEnumeration; import javax.naming.NamingException; import javax.naming.directory.Attribute; import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; public class AttributesDictionary extends Dictionary { private final Attributes attributes; /** The provided attributes is wrapped, not copied. */ public AttributesDictionary(Attributes attributes) { if (attributes == null) throw new IllegalArgumentException("Attributes cannot be null"); this.attributes = attributes; } @Override public int size() { return attributes.size(); } @Override public boolean isEmpty() { return attributes.size() == 0; } @Override public Enumeration keys() { NamingEnumeration namingEnumeration = attributes.getIDs(); return new Enumeration() { @Override public boolean hasMoreElements() { return namingEnumeration.hasMoreElements(); } @Override public String nextElement() { return namingEnumeration.nextElement(); } }; } @Override public Enumeration elements() { NamingEnumeration namingEnumeration = attributes.getIDs(); return new Enumeration() { @Override public boolean hasMoreElements() { return namingEnumeration.hasMoreElements(); } @Override public Object nextElement() { String key = namingEnumeration.nextElement(); return get(key); } }; } @Override /** @returns a String or String[] */ public Object get(Object key) { try { if (key == null) throw new IllegalArgumentException("Key cannot be null"); Attribute attr = attributes.get(key.toString()); if (attr == null) return null; if (attr.size() == 0) throw new IllegalStateException("There must be at least one value"); else if (attr.size() == 1) { return attr.get().toString(); } else {// multiple String[] res = new String[attr.size()]; for (int i = 0; i < attr.size(); i++) { Object value = attr.get(); if (value == null) throw new RuntimeException("Values cannot be null"); res[i] = attr.get(i).toString(); } return res; } } catch (NamingException e) { throw new RuntimeException("Cannot get value for " + key, e); } } @Override public Object put(String key, Object value) { if (key == null) throw new IllegalArgumentException("Key cannot be null"); if (value == null) throw new IllegalArgumentException("Value cannot be null"); Object oldValue = get(key); Attribute attr = attributes.get(key); if (attr == null) { attr = new BasicAttribute(key); attributes.put(attr); } if (value instanceof String[]) { String[] values = (String[]) value; // clean additional values for (int i = values.length; i < attr.size(); i++) attr.remove(i); // set values for (int i = 0; i < values.length; i++) { attr.set(i, values[i]); } } else { if (attr.size() > 1) throw new IllegalArgumentException("Attribute " + key + " is multi-valued"); if (attr.size() == 1) { try { if (!attr.get(0).equals(value)) attr.set(0, value.toString()); } catch (NamingException e) { throw new RuntimeException("Cannot check existing value", e); } } else { attr.add(value.toString()); } } return oldValue; } @Override public Object remove(Object key) { if (key == null) throw new IllegalArgumentException("Key cannot be null"); Object oldValue = get(key); if (oldValue == null) return null; return attributes.remove(key.toString()); } /** * Copy the content of an {@link Attributes} to the provided * {@link Dictionary}. */ public static void copy(Attributes attributes, Dictionary dictionary) { AttributesDictionary ad = new AttributesDictionary(attributes); Enumeration keys = ad.keys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); dictionary.put(key, ad.get(key)); } } /** * Copy a {@link Dictionary} into an {@link Attributes}. */ public static void copy(Dictionary dictionary, Attributes attributes) { AttributesDictionary ad = new AttributesDictionary(attributes); Enumeration keys = dictionary.keys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); ad.put(key, dictionary.get(key)); } } }