/* See LICENSE for licensing and NOTICE for copyright. */
package org.ldaptive.asn1;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.ldaptive.LdapUtils;
/**
* A sequence of RDN values.
*
* @author Middleware Services
*/
public class DN implements DEREncoder
{
/** hash code seed. */
private static final int HASH_CODE_SEED = 631;
/** RDNs in this RDN sequence. */
private final RDN[] rdns;
/**
* Creates a new DN.
*
* @param names RDNs in this sequence
*/
public DN(final Collection<RDN> names)
{
rdns = names.toArray(new RDN[names.size()]);
}
/**
* Creates a new DN.
*
* @param names RDNs in this sequence
*/
public DN(final RDN... names)
{
rdns = names;
}
/**
* Returns the RDNs in this DN.
*
* @return RDNs
*/
public RDN[] getRDNs()
{
return rdns;
}
@Override
public byte[] encode()
{
final List<DEREncoder> typeEncoders = new ArrayList<>();
for (final RDN rdn : rdns) {
typeEncoders.add(rdn::encode);
}
final ConstructedDEREncoder se = new ConstructedDEREncoder(
UniversalDERTag.SEQ,
typeEncoders.toArray(new DEREncoder[typeEncoders.size()]));
return se.encode();
}
/**
* Converts bytes in the buffer to a DN by reading from the current position to the limit.
*
* @param encoded buffer containing DER-encoded data where the buffer is positioned at the tag of the DN and the
* limit is set beyond the last byte of DN data.
*
* @return decoded bytes as a DN
*/
public static DN decode(final ByteBuffer encoded)
{
return new DN(RDN.decode(encoded));
}
@Override
public boolean equals(final Object o)
{
if (o == this) {
return true;
}
if (o instanceof DN) {
final DN v = (DN) o;
return LdapUtils.areEqual(rdns, v.rdns);
}
return false;
}
@Override
public int hashCode()
{
return LdapUtils.computeHashCode(HASH_CODE_SEED, (Object) rdns);
}
@Override
public String toString()
{
return String.format("[%s@%d::rdns=%s]", getClass().getName(), hashCode(), Arrays.toString(rdns));
}
}