< prev index next >

src/java.naming/share/classes/javax/naming/ldap/Rdn.java

Print this page




  33 
  34 import javax.naming.InvalidNameException;
  35 import javax.naming.directory.BasicAttributes;
  36 import javax.naming.directory.Attributes;
  37 import javax.naming.directory.Attribute;
  38 import javax.naming.NamingEnumeration;
  39 import javax.naming.NamingException;
  40 
  41 import java.io.Serializable;
  42 import java.io.ObjectOutputStream;
  43 import java.io.ObjectInputStream;
  44 import java.io.IOException;
  45 
  46 /**
  47  * This class represents a relative distinguished name, or RDN, which is a
  48  * component of a distinguished name as specified by
  49  * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
  50  * An example of an RDN is "OU=Sales+CN=J.Smith". In this example,
  51  * the RDN consist of multiple attribute type/value pairs. The
  52  * RDN is parsed as described in the class description for
  53  * {@link javax.naming.ldap.LdapName <tt>LdapName</tt>}.
  54  * <p>
  55  * The Rdn class represents an RDN as attribute type/value mappings,
  56  * which can be viewed using
  57  * {@link javax.naming.directory.Attributes Attributes}.
  58  * In addition, it contains convenience methods that allow easy retrieval
  59  * of type and value when the Rdn consist of a single type/value pair,
  60  * which is how it appears in a typical usage.
  61  * It also contains helper methods that allow escaping of the unformatted
  62  * attribute value and unescaping of the value formatted according to the
  63  * escaping syntax defined in RFC2253. For methods that take or return
  64  * attribute value as an Object, the value is either a String
  65  * (in unescaped form) or a byte array.
  66  * <p>
  67  * <code>Rdn</code> will properly parse all valid RDNs, but
  68  * does not attempt to detect all possible violations when parsing
  69  * invalid RDNs. It is "generous" in accepting invalid RDNs.
  70  * The "validity" of a name is determined ultimately when it
  71  * is supplied to an LDAP server, which may accept or
  72  * reject the name based on factors such as its schema information
  73  * and interoperability considerations.
  74  *
  75  * <p>
  76  * The following code example shows how to construct an Rdn using the
  77  * constructor that takes type and value as arguments:
  78  * <pre>
  79  *      Rdn rdn = new Rdn("cn", "Juicy, Fruit");
  80  *      System.out.println(rdn.toString());
  81  * </pre>
  82  * The last line will print <tt>cn=Juicy\, Fruit</tt>. The
  83  * {@link #unescapeValue(String) <tt>unescapeValue()</tt>} method can be
  84  * used to unescape the escaped comma resulting in the original
  85  * value <tt>"Juicy, Fruit"</tt>. The {@link #escapeValue(Object)
  86  * <tt>escapeValue()</tt>} method adds the escape back preceding the comma.
  87  * <p>
  88  * This class can be instantiated by a string representation
  89  * of the RDN defined in RFC 2253 as shown in the following code example:
  90  * <pre>
  91  *      Rdn rdn = new Rdn("cn=Juicy\\, Fruit");
  92  *      System.out.println(rdn.toString());
  93  * </pre>
  94  * The last line will print <tt>cn=Juicy\, Fruit</tt>.
  95  * <p>
  96  * Concurrent multithreaded read-only access of an instance of
  97  * <tt>Rdn</tt> need not be synchronized.
  98  * <p>
  99  * Unless otherwise noted, the behavior of passing a null argument
 100  * to a constructor or method in this class will cause NullPointerException
 101  * to be thrown.
 102  *
 103  * @since 1.5
 104  */
 105 
 106 public class Rdn implements Serializable, Comparable<Object> {
 107 
 108     private transient ArrayList<RdnEntry> entries;
 109 
 110     // The common case.
 111     private static final int DEFAULT_SIZE = 1;
 112 
 113     private static final long serialVersionUID = -5994465067210009656L;
 114 
 115     /**
 116      * Constructs an Rdn from the given attribute set. See
 117      * {@link javax.naming.directory.Attributes Attributes}.
 118      * <p>
 119      * The string attribute values are not interpreted as
 120      * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
 121      * formatted RDN strings. That is, the values are used
 122      * literally (not parsed) and assumed to be unescaped.
 123      *
 124      * @param attrSet The non-null and non-empty attributes containing
 125      * type/value mappings.
 126      * @throws InvalidNameException If contents of <tt>attrSet</tt> cannot
 127      *          be used to construct a valid RDN.
 128      */
 129     public Rdn(Attributes attrSet) throws InvalidNameException {
 130         if (attrSet.size() == 0) {
 131             throw new InvalidNameException("Attributes cannot be empty");
 132         }
 133         entries = new ArrayList<>(attrSet.size());
 134         NamingEnumeration<? extends Attribute> attrs = attrSet.getAll();
 135         try {
 136             for (int nEntries = 0; attrs.hasMore(); nEntries++) {
 137                 RdnEntry entry = new RdnEntry();
 138                 Attribute attr = attrs.next();
 139                 entry.type = attr.getID();
 140                 entry.value = attr.get();
 141                 entries.add(nEntries, entry);
 142             }
 143         } catch (NamingException e) {
 144             InvalidNameException e2 = new InvalidNameException(
 145                                         e.getMessage());
 146             e2.initCause(e);


 149         sort(); // arrange entries for comparison
 150     }
 151 
 152     /**
 153      * Constructs an Rdn from the given string.
 154      * This constructor takes a string formatted according to the rules
 155      * defined in <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
 156      * and described in the class description for
 157      * {@link javax.naming.ldap.LdapName}.
 158      *
 159      * @param rdnString The non-null and non-empty RFC2253 formatted string.
 160      * @throws InvalidNameException If a syntax error occurs during
 161      *                  parsing of the rdnString.
 162      */
 163     public Rdn(String rdnString) throws InvalidNameException {
 164         entries = new ArrayList<>(DEFAULT_SIZE);
 165         (new Rfc2253Parser(rdnString)).parseRdn(this);
 166     }
 167 
 168     /**
 169      * Constructs an Rdn from the given <tt>rdn</tt>.
 170      * The contents of the <tt>rdn</tt> are simply copied into the newly
 171      * created Rdn.
 172      * @param rdn The non-null Rdn to be copied.
 173      */
 174     public Rdn(Rdn rdn) {
 175         entries = new ArrayList<>(rdn.entries.size());
 176         entries.addAll(rdn.entries);
 177     }
 178 
 179     /**
 180      * Constructs an Rdn from the given attribute type and
 181      * value.
 182      * The string attribute values are not interpreted as
 183      * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
 184      * formatted RDN strings. That is, the values are used
 185      * literally (not parsed) and assumed to be unescaped.
 186      *
 187      * @param type The non-null and non-empty string attribute type.
 188      * @param value The non-null and non-empty attribute value.
 189      * @throws InvalidNameException If type/value cannot be used to
 190      *                  construct a valid RDN.


 566             byte b = val[i];
 567             builder.append(Character.forDigit(0xF & (b >>> 4), 16));
 568             builder.append(Character.forDigit(0xF & b, 16));
 569         }
 570         return builder.toString();
 571     }
 572 
 573     /**
 574      * Given an attribute value string formatted according to the rules
 575      * specified in
 576      * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>,
 577      * returns the unformatted value.  Escapes and quotes are
 578      * stripped away, and hex-encoded UTF-8 is converted to equivalent
 579      * UTF-16 characters. Returns a string value as a String, and a
 580      * binary value as a byte array.
 581      * <p>
 582      * Legal and illegal values are defined in RFC 2253.
 583      * This method is generous in accepting the values and does not
 584      * catch all illegal values.
 585      * Therefore, passing in an illegal value might not necessarily
 586      * trigger an <tt>IllegalArgumentException</tt>.
 587      *
 588      * @param   val     The non-null string to be unescaped.
 589      * @return          Unescaped value.
 590      * @throws          IllegalArgumentException When an Illegal value
 591      *                  is provided.
 592      */
 593     public static Object unescapeValue(String val) {
 594 
 595             char[] chars = val.toCharArray();
 596             int beg = 0;
 597             int end = chars.length;
 598 
 599             // Trim off leading and trailing whitespace.
 600             while ((beg < end) && isWhitespace(chars[beg])) {
 601                 ++beg;
 602             }
 603 
 604             while ((beg < end) && isWhitespace(chars[end - 1])) {
 605                 --end;
 606             }




  33 
  34 import javax.naming.InvalidNameException;
  35 import javax.naming.directory.BasicAttributes;
  36 import javax.naming.directory.Attributes;
  37 import javax.naming.directory.Attribute;
  38 import javax.naming.NamingEnumeration;
  39 import javax.naming.NamingException;
  40 
  41 import java.io.Serializable;
  42 import java.io.ObjectOutputStream;
  43 import java.io.ObjectInputStream;
  44 import java.io.IOException;
  45 
  46 /**
  47  * This class represents a relative distinguished name, or RDN, which is a
  48  * component of a distinguished name as specified by
  49  * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>.
  50  * An example of an RDN is "OU=Sales+CN=J.Smith". In this example,
  51  * the RDN consist of multiple attribute type/value pairs. The
  52  * RDN is parsed as described in the class description for
  53  * {@link javax.naming.ldap.LdapName LdapName}.
  54  * <p>
  55  * The Rdn class represents an RDN as attribute type/value mappings,
  56  * which can be viewed using
  57  * {@link javax.naming.directory.Attributes Attributes}.
  58  * In addition, it contains convenience methods that allow easy retrieval
  59  * of type and value when the Rdn consist of a single type/value pair,
  60  * which is how it appears in a typical usage.
  61  * It also contains helper methods that allow escaping of the unformatted
  62  * attribute value and unescaping of the value formatted according to the
  63  * escaping syntax defined in RFC2253. For methods that take or return
  64  * attribute value as an Object, the value is either a String
  65  * (in unescaped form) or a byte array.
  66  * <p>
  67  * <code>Rdn</code> will properly parse all valid RDNs, but
  68  * does not attempt to detect all possible violations when parsing
  69  * invalid RDNs. It is "generous" in accepting invalid RDNs.
  70  * The "validity" of a name is determined ultimately when it
  71  * is supplied to an LDAP server, which may accept or
  72  * reject the name based on factors such as its schema information
  73  * and interoperability considerations.
  74  *
  75  * <p>
  76  * The following code example shows how to construct an Rdn using the
  77  * constructor that takes type and value as arguments:
  78  * <pre>
  79  *      Rdn rdn = new Rdn("cn", "Juicy, Fruit");
  80  *      System.out.println(rdn.toString());
  81  * </pre>
  82  * The last line will print {@code cn=Juicy\, Fruit}. The
  83  * {@link #unescapeValue(String) unescapeValue()} method can be
  84  * used to unescape the escaped comma resulting in the original
  85  * value {@code "Juicy, Fruit"}. The {@link #escapeValue(Object)
  86  * escapeValue()} method adds the escape back preceding the comma.
  87  * <p>
  88  * This class can be instantiated by a string representation
  89  * of the RDN defined in RFC 2253 as shown in the following code example:
  90  * <pre>
  91  *      Rdn rdn = new Rdn("cn=Juicy\\, Fruit");
  92  *      System.out.println(rdn.toString());
  93  * </pre>
  94  * The last line will print {@code cn=Juicy\, Fruit}.
  95  * <p>
  96  * Concurrent multithreaded read-only access of an instance of
  97  * {@code Rdn} need not be synchronized.
  98  * <p>
  99  * Unless otherwise noted, the behavior of passing a null argument
 100  * to a constructor or method in this class will cause NullPointerException
 101  * to be thrown.
 102  *
 103  * @since 1.5
 104  */
 105 
 106 public class Rdn implements Serializable, Comparable<Object> {
 107 
 108     private transient ArrayList<RdnEntry> entries;
 109 
 110     // The common case.
 111     private static final int DEFAULT_SIZE = 1;
 112 
 113     private static final long serialVersionUID = -5994465067210009656L;
 114 
 115     /**
 116      * Constructs an Rdn from the given attribute set. See
 117      * {@link javax.naming.directory.Attributes Attributes}.
 118      * <p>
 119      * The string attribute values are not interpreted as
 120      * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
 121      * formatted RDN strings. That is, the values are used
 122      * literally (not parsed) and assumed to be unescaped.
 123      *
 124      * @param attrSet The non-null and non-empty attributes containing
 125      * type/value mappings.
 126      * @throws InvalidNameException If contents of {@code attrSet} cannot
 127      *          be used to construct a valid RDN.
 128      */
 129     public Rdn(Attributes attrSet) throws InvalidNameException {
 130         if (attrSet.size() == 0) {
 131             throw new InvalidNameException("Attributes cannot be empty");
 132         }
 133         entries = new ArrayList<>(attrSet.size());
 134         NamingEnumeration<? extends Attribute> attrs = attrSet.getAll();
 135         try {
 136             for (int nEntries = 0; attrs.hasMore(); nEntries++) {
 137                 RdnEntry entry = new RdnEntry();
 138                 Attribute attr = attrs.next();
 139                 entry.type = attr.getID();
 140                 entry.value = attr.get();
 141                 entries.add(nEntries, entry);
 142             }
 143         } catch (NamingException e) {
 144             InvalidNameException e2 = new InvalidNameException(
 145                                         e.getMessage());
 146             e2.initCause(e);


 149         sort(); // arrange entries for comparison
 150     }
 151 
 152     /**
 153      * Constructs an Rdn from the given string.
 154      * This constructor takes a string formatted according to the rules
 155      * defined in <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
 156      * and described in the class description for
 157      * {@link javax.naming.ldap.LdapName}.
 158      *
 159      * @param rdnString The non-null and non-empty RFC2253 formatted string.
 160      * @throws InvalidNameException If a syntax error occurs during
 161      *                  parsing of the rdnString.
 162      */
 163     public Rdn(String rdnString) throws InvalidNameException {
 164         entries = new ArrayList<>(DEFAULT_SIZE);
 165         (new Rfc2253Parser(rdnString)).parseRdn(this);
 166     }
 167 
 168     /**
 169      * Constructs an Rdn from the given {@code rdn}.
 170      * The contents of the {@code rdn} are simply copied into the newly
 171      * created Rdn.
 172      * @param rdn The non-null Rdn to be copied.
 173      */
 174     public Rdn(Rdn rdn) {
 175         entries = new ArrayList<>(rdn.entries.size());
 176         entries.addAll(rdn.entries);
 177     }
 178 
 179     /**
 180      * Constructs an Rdn from the given attribute type and
 181      * value.
 182      * The string attribute values are not interpreted as
 183      * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>
 184      * formatted RDN strings. That is, the values are used
 185      * literally (not parsed) and assumed to be unescaped.
 186      *
 187      * @param type The non-null and non-empty string attribute type.
 188      * @param value The non-null and non-empty attribute value.
 189      * @throws InvalidNameException If type/value cannot be used to
 190      *                  construct a valid RDN.


 566             byte b = val[i];
 567             builder.append(Character.forDigit(0xF & (b >>> 4), 16));
 568             builder.append(Character.forDigit(0xF & b, 16));
 569         }
 570         return builder.toString();
 571     }
 572 
 573     /**
 574      * Given an attribute value string formatted according to the rules
 575      * specified in
 576      * <a href="http://www.ietf.org/rfc/rfc2253.txt">RFC 2253</a>,
 577      * returns the unformatted value.  Escapes and quotes are
 578      * stripped away, and hex-encoded UTF-8 is converted to equivalent
 579      * UTF-16 characters. Returns a string value as a String, and a
 580      * binary value as a byte array.
 581      * <p>
 582      * Legal and illegal values are defined in RFC 2253.
 583      * This method is generous in accepting the values and does not
 584      * catch all illegal values.
 585      * Therefore, passing in an illegal value might not necessarily
 586      * trigger an {@code IllegalArgumentException}.
 587      *
 588      * @param   val     The non-null string to be unescaped.
 589      * @return          Unescaped value.
 590      * @throws          IllegalArgumentException When an Illegal value
 591      *                  is provided.
 592      */
 593     public static Object unescapeValue(String val) {
 594 
 595             char[] chars = val.toCharArray();
 596             int beg = 0;
 597             int end = chars.length;
 598 
 599             // Trim off leading and trailing whitespace.
 600             while ((beg < end) && isWhitespace(chars[beg])) {
 601                 ++beg;
 602             }
 603 
 604             while ((beg < end) && isWhitespace(chars[end - 1])) {
 605                 --end;
 606             }


< prev index next >