javax.naming.ldap
public class: Rdn [javadoc |
source]
java.lang.Object
javax.naming.ldap.Rdn
All Implemented Interfaces:
Comparable, java$io$Serializable
This class represents a relative distinguished name, or RDN, which is a
component of a distinguished name as specified by
RFC 2253.
An example of an RDN is "OU=Sales+CN=J.Smith". In this example,
the RDN consist of multiple attribute type/value pairs. The
RDN is parsed as described in the class description for
LdapName .
The Rdn class represents an RDN as attribute type/value mappings,
which can be viewed using
Attributes .
In addition, it contains convenience methods that allow easy retrieval
of type and value when the Rdn consist of a single type/value pair,
which is how it appears in a typical usage.
It also contains helper methods that allow escaping of the unformatted
attribute value and unescaping of the value formatted according to the
escaping syntax defined in RFC2253. For methods that take or return
attribute value as an Object, the value is either a String
(in unescaped form) or a byte array.
Rdn
will properly parse all valid RDNs, but
does not attempt to detect all possible violations when parsing
invalid RDNs. It is "generous" in accepting invalid RDNs.
The "validity" of a name is determined ultimately when it
is supplied to an LDAP server, which may accept or
reject the name based on factors such as its schema information
and interoperability considerations.
The following code example shows how to construct an Rdn using the
constructor that takes type and value as arguments:
Rdn rdn = new Rdn("cn", "Juicy, Fruit");
System.out.println(rdn.toString());
The last line will print
cn=Juicy\, Fruit. The
unescapeValue() method can be
used to unescape the escaped comma resulting in the original
value
"Juicy, Fruit". The
escapeValue() method adds the escape back preceding the comma.
This class can be instantiated by a string representation
of the RDN defined in RFC 2253 as shown in the following code example:
Rdn rdn = new Rdn("cn=Juicy\\, Fruit");
System.out.println(rdn.toString());
The last line will print
cn=Juicy\, Fruit.
Concurrent multithreaded read-only access of an instance of
Rdn need not be synchronized.
Unless otherwise noted, the behavior of passing a null argument
to a constructor or method in this class will cause NullPointerException
to be thrown.
Method from javax.naming.ldap.Rdn Summary: |
---|
compareTo, equals, escapeValue, getType, getValue, hashCode, put, size, sort, toAttributes, toString, unescapeValue |
Methods from java.lang.Object: |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Method from javax.naming.ldap.Rdn Detail: |
public int compareTo(Object obj) {
if (!(obj instanceof Rdn)) {
throw new ClassCastException("The obj is not a Rdn");
}
if (obj == this) {
return 0;
}
Rdn that = (Rdn) obj;
int minSize = Math.min(entries.size(), that.entries.size());
for (int i = 0; i < minSize; i++) {
// Compare a single pair of type/value pairs.
int diff = ((RdnEntry) entries.get(i)).compareTo(
that.entries.get(i));
if (diff != 0) {
return diff;
}
}
return (entries.size() - that.entries.size()); // longer RDN wins
}
Compares this Rdn with the specified Object for order.
Returns a negative integer, zero, or a positive integer as this
Rdn is less than, equal to, or greater than the given Object.
If obj is null or not an instance of Rdn, ClassCastException
is thrown.
The attribute type and value pairs of the RDNs are lined up
against each other and compared lexicographically. The order of
components in multi-valued Rdns (such as "ou=Sales+cn=Bob") is not
significant. |
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (!(obj instanceof Rdn)) {
return false;
}
Rdn that = (Rdn) obj;
if (entries.size() != that.size()) {
return false;
}
for (int i = 0; i < entries.size(); i++) {
if (!entries.get(i).equals(that.entries.get(i))) {
return false;
}
}
return true;
}
Compares the specified Object with this Rdn for equality.
Returns true if the given object is also a Rdn and the two Rdns
represent the same attribute type and value mappings. The order of
components in multi-valued Rdns (such as "ou=Sales+cn=Bob") is not
significant.
Type and value equalilty matching is done as below:
- The types are compared for equality with their case ignored.
- String values with different but equivalent usage of quoting,
escaping, or UTF8-hex-encoding are considered equal.
The case of the values is ignored during the comparison.
If obj is null or not an instance of Rdn, false is returned.
|
public static String escapeValue(Object val) {
return (val instanceof byte[])
? escapeBinaryValue((byte[])val)
: escapeStringValue((String)val);
}
Given the value of an attribute, returns a string escaped according
to the rules specified in
RFC 2253.
For example, if the val is "Sue, Grabbit and Runn", the escaped
value returned by this method is "Sue\, Grabbit and Runn".
A string value is represented as a String and binary value
as a byte array. |
public String getType() {
return ((RdnEntry) entries.get(0)).getType();
}
Retrieves one of this Rdn's type.
This is a convenience method for obtaining the type,
when the RDN contains a single type and value mapping,
which is the common RDN usage.
For a multi-valued RDN, the type/value pairs have
no specific order defined on them. In that case, this method
returns type of one of the type/value pairs.
The getValue() method returns the
value corresponding to the type returned by this method. |
public Object getValue() {
return ((RdnEntry) entries.get(0)).getValue();
}
Retrieves one of this Rdn's value.
This is a convenience method for obtaining the value,
when the RDN contains a single type and value mapping,
which is the common RDN usage.
For a multi-valued RDN, this method returns value corresponding
to the type returned by getType() method. |
public int hashCode() {
// Sum up the hash codes of the components.
int hash = 0;
// For each type/value pair...
for (int i = 0; i < entries.size(); i++) {
hash += entries.get(i).hashCode();
}
return hash;
}
Returns the hash code of this RDN. Two RDNs that are
equal (according to the equals method) will have the same
hash code. |
Rdn put(String type,
Object value) {
// create new Entry
RdnEntry newEntry = new RdnEntry();
newEntry.type = type;
if (value instanceof byte[]) { // clone the byte array
newEntry.value = ((byte[]) value).clone();
} else {
newEntry.value = value;
}
entries.add(newEntry);
return this;
}
|
public int size() {
return entries.size();
}
Retrieves the number of attribute type/value pairs in this Rdn. |
void sort() {
if (entries.size() > 1) {
Collections.sort(entries);
}
}
|
public Attributes toAttributes() {
Attributes attrs = new BasicAttributes(true);
for (int i = 0; i < entries.size(); i++) {
RdnEntry entry = (RdnEntry) entries.get(i);
Attribute attr = attrs.put(entry.getType(), entry.getValue());
if (attr != null) {
attr.add(entry.getValue());
attrs.put(attr);
}
}
return attrs;
}
Retrieves the Attributes
view of the type/value mappings contained in this Rdn. |
public String toString() {
StringBuilder builder = new StringBuilder();
int size = entries.size();
if (size > 0) {
builder.append(entries.get(0));
}
for (int next = 1; next < size; next++) {
builder.append('+');
builder.append(entries.get(next));
}
return builder.toString();
}
Returns this Rdn as a string represented in a format defined by
RFC 2253 and described
in the class description for LdapName . |
public static Object unescapeValue(String val) {
char[] chars = val.toCharArray();
int beg = 0;
int end = chars.length;
// Trim off leading and trailing whitespace.
while ((beg < end) && isWhitespace(chars[beg])) {
++beg;
}
while ((beg < end) && isWhitespace(chars[end - 1])) {
--end;
}
// Add back the trailing whitespace with a preceeding '\'
// (escaped or unescaped) that was taken off in the above
// loop. Whether or not to retain this whitespace is decided below.
if (end != chars.length &&
(beg < end) &&
chars[end - 1] == '\\') {
end++;
}
if (beg >= end) {
return "";
}
if (chars[beg] == '#') {
// Value is binary (eg: "#CEB1DF80").
return decodeHexPairs(chars, ++beg, end);
}
// Trim off quotes.
if ((chars[beg] == '\"') && (chars[end - 1] == '\"')) {
++beg;
--end;
}
StringBuilder builder = new StringBuilder(end - beg);
int esc = -1; // index of the last escaped character
for (int i = beg; i < end; i++) {
if ((chars[i] == '\\') && (i + 1 < end)) {
if (!Character.isLetterOrDigit(chars[i + 1])) {
++i; // skip backslash
builder.append(chars[i]); // snarf escaped char
esc = i;
} else {
// Convert hex-encoded UTF-8 to 16-bit chars.
byte[] utf8 = getUtf8Octets(chars, i, end);
if (utf8.length > 0) {
try {
builder.append(new String(utf8, "UTF8"));
} catch (java.io.UnsupportedEncodingException e) {
// shouldn't happen
}
i += utf8.length * 3 - 1;
} else { // no utf8 bytes available, invalid DN
// '/' has no meaning, throw exception
throw new IllegalArgumentException(
"Not a valid attribute string value:" +
val + ",improper usage of backslash");
}
}
} else {
builder.append(chars[i]); // snarf unescaped char
}
}
// Get rid of the unescaped trailing whitespace with the
// preceeding '\' character that was previously added back.
int len = builder.length();
if (isWhitespace(builder.charAt(len - 1)) && esc != (end - 1)) {
builder.setLength(len - 1);
}
return builder.toString();
}
Given an attribute value string formated according to the rules
specified in
RFC 2253,
returns the unformated value. Escapes and quotes are
stripped away, and hex-encoded UTF-8 is converted to equivalent
UTF-16 characters. Returns a string value as a String, and a
binary value as a byte array.
Legal and illegal values are defined in RFC 2253.
This method is generous in accepting the values and does not
catch all illegal values.
Therefore, passing in an illegal value might not necessarily
trigger an IllegalArgumentException. |