package com.hwlcn.ldap.ldap.sdk.migrate.jndi;
import java.util.Collection;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.ModificationItem;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.BasicControl;
import javax.naming.ldap.ExtendedResponse;
import com.hwlcn.ldap.asn1.ASN1Exception;
import com.hwlcn.ldap.asn1.ASN1OctetString;
import com.hwlcn.ldap.ldap.sdk.Attribute;
import com.hwlcn.ldap.ldap.sdk.Control;
import com.hwlcn.ldap.ldap.sdk.Entry;
import com.hwlcn.ldap.ldap.sdk.ExtendedRequest;
import com.hwlcn.ldap.ldap.sdk.ExtendedResult;
import com.hwlcn.ldap.ldap.sdk.Modification;
import com.hwlcn.ldap.ldap.sdk.ModificationType;
import com.hwlcn.core.annotation.NotMutable;
import com.hwlcn.core.annotation.ThreadSafety;
import com.hwlcn.ldap.util.ThreadSafetyLevel;
import static com.hwlcn.ldap.util.StaticUtils.*;
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class JNDIConverter
{
private static final Attribute[] NO_ATTRIBUTES = new Attribute[0];
private static final javax.naming.ldap.Control[] NO_JNDI_CONTROLS =
new javax.naming.ldap.Control[0];
private static final Modification[] NO_MODIFICATIONS = new Modification[0];
private static final ModificationItem[] NO_MODIFICATION_ITEMS =
new ModificationItem[0];
private static final Control[] NO_SDK_CONTROLS = new Control[0];
private JNDIConverter()
{
}
public static Attribute convertAttribute(
final javax.naming.directory.Attribute a)
throws NamingException
{
if (a == null)
{
return null;
}
final String name = a.getID();
final ASN1OctetString[] values = new ASN1OctetString[a.size()];
for (int i=0; i < values.length; i++)
{
final Object value = a.get(i);
if (value instanceof byte[])
{
values[i] = new ASN1OctetString((byte[]) value);
}
else
{
values[i] = new ASN1OctetString(String.valueOf(value));
}
}
return new Attribute(name, values);
}
public static javax.naming.directory.Attribute convertAttribute(
final Attribute a)
{
if (a == null)
{
return null;
}
final BasicAttribute attr = new BasicAttribute(a.getName(), true);
for (final String v : a.getValues())
{
attr.add(v);
}
return attr;
}
public static Attribute[] convertAttributes(final Attributes a)
throws NamingException
{
if (a == null)
{
return NO_ATTRIBUTES;
}
int i=0;
final Attribute[] attributes = new Attribute[a.size()];
final NamingEnumeration<? extends javax.naming.directory.Attribute> e =
a.getAll();
try
{
while (e.hasMoreElements())
{
attributes[i++] = convertAttribute(e.next());
}
}
finally
{
e.close();
}
return attributes;
}
public static Attributes convertAttributes(final Attribute... a)
{
final BasicAttributes attrs = new BasicAttributes(true);
if (a == null)
{
return attrs;
}
for (final Attribute attr : a)
{
attrs.put(convertAttribute(attr));
}
return attrs;
}
public static Attributes convertAttributes(final Collection<Attribute> a)
{
final BasicAttributes attrs = new BasicAttributes(true);
if (a == null)
{
return attrs;
}
for (final Attribute attr : a)
{
attrs.put(convertAttribute(attr));
}
return attrs;
}
public static Control convertControl(final javax.naming.ldap.Control c)
throws NamingException
{
if (c == null)
{
return null;
}
final ASN1OctetString value;
final byte[] valueBytes = c.getEncodedValue();
if ((valueBytes == null) || (valueBytes.length == 0))
{
value = null;
}
else
{
try
{
value = ASN1OctetString.decodeAsOctetString(valueBytes);
}
catch (ASN1Exception ae)
{
throw new NamingException(getExceptionMessage(ae));
}
}
return new Control(c.getID(), c.isCritical(), value);
}
public static javax.naming.ldap.Control convertControl(final Control c)
{
if (c == null)
{
return null;
}
final ASN1OctetString value = c.getValue();
if (value == null)
{
return new BasicControl(c.getOID(), c.isCritical(), null);
}
else
{
return new BasicControl(c.getOID(), c.isCritical(), value.encode());
}
}
public static Control[] convertControls(final javax.naming.ldap.Control... c)
throws NamingException
{
if (c == null)
{
return NO_SDK_CONTROLS;
}
final Control[] controls = new Control[c.length];
for (int i=0; i < controls.length; i++)
{
controls[i] = convertControl(c[i]);
}
return controls;
}
public static javax.naming.ldap.Control[] convertControls(final Control... c)
{
if (c == null)
{
return NO_JNDI_CONTROLS;
}
final javax.naming.ldap.Control[] controls =
new javax.naming.ldap.Control[c.length];
for (int i=0; i < controls.length; i++)
{
controls[i] = convertControl(c[i]);
}
return controls;
}
public static ExtendedRequest convertExtendedRequest(
final javax.naming.ldap.ExtendedRequest r)
throws NamingException
{
if (r == null)
{
return null;
}
return JNDIExtendedRequest.toSDKExtendedRequest(r);
}
public static javax.naming.ldap.ExtendedRequest convertExtendedRequest(
final ExtendedRequest r)
{
if (r == null)
{
return null;
}
return new JNDIExtendedRequest(r);
}
public static ExtendedResult convertExtendedResponse(final ExtendedResponse r)
throws NamingException
{
if (r == null)
{
return null;
}
return JNDIExtendedResponse.toSDKExtendedResult(r);
}
public static ExtendedResponse convertExtendedResult(final ExtendedResult r)
{
if (r == null)
{
return null;
}
return new JNDIExtendedResponse(r);
}
public static Modification convertModification(final ModificationItem m)
throws NamingException
{
if (m == null)
{
return null;
}
final ModificationType modType;
switch (m.getModificationOp())
{
case DirContext.ADD_ATTRIBUTE:
modType = ModificationType.ADD;
break;
case DirContext.REMOVE_ATTRIBUTE:
modType = ModificationType.DELETE;
break;
case DirContext.REPLACE_ATTRIBUTE:
modType = ModificationType.REPLACE;
break;
default:
throw new NamingException("Unsupported modification type " + m);
}
final Attribute a = convertAttribute(m.getAttribute());
return new Modification(modType, a.getName(), a.getRawValues());
}
public static ModificationItem convertModification(final Modification m)
throws NamingException
{
if (m == null)
{
return null;
}
final int modType;
switch (m.getModificationType().intValue())
{
case ModificationType.ADD_INT_VALUE:
modType = DirContext.ADD_ATTRIBUTE;
break;
case ModificationType.DELETE_INT_VALUE:
modType = DirContext.REMOVE_ATTRIBUTE;
break;
case ModificationType.REPLACE_INT_VALUE:
modType = DirContext.REPLACE_ATTRIBUTE;
break;
default:
throw new NamingException("Unsupported modification type " + m);
}
return new ModificationItem(modType, convertAttribute(m.getAttribute()));
}
public static Modification[] convertModifications(final ModificationItem... m)
throws NamingException
{
if (m == null)
{
return NO_MODIFICATIONS;
}
final Modification[] mods = new Modification[m.length];
for (int i=0; i < m.length; i++)
{
mods[i] = convertModification(m[i]);
}
return mods;
}
public static ModificationItem[] convertModifications(final Modification... m)
throws NamingException
{
if (m == null)
{
return NO_MODIFICATION_ITEMS;
}
final ModificationItem[] mods = new ModificationItem[m.length];
for (int i=0; i < m.length; i++)
{
mods[i] = convertModification(m[i]);
}
return mods;
}
public static Entry convertSearchEntry(final SearchResult r)
throws NamingException
{
if (r == null)
{
return null;
}
return new Entry(r.getName(), convertAttributes(r.getAttributes()));
}
public static SearchResult convertSearchEntry(final Entry e)
{
if (e == null)
{
return null;
}
final Collection<Attribute> attrs = e.getAttributes();
final Attribute[] attributes = new Attribute[attrs.size()];
attrs.toArray(attributes);
return new SearchResult(e.getDN(), null, convertAttributes(attributes));
}
}