|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object issrg.utils.RFC2253NameParser
public class RFC2253NameParser
This is an implementation of an RFC2253 LDAP DN parser. Many existing parsers are burdained with semantics interpretation, so the parsers look after the attribute type names and OIDs. This is not so useful in this developing world. Many people invent their own attributes, just for their own LDAP directory, and such parsers will obviously fail. However, it would be so simple to just return the DN divided into RDNs, each of them separated into AVAs with attribute value represented as an unescaped String or a binary value. Let the caller cope with the attribute type names and OIDs!
Note also, that due to a common misconception people often join RDNs, separating them with comma-space, instead of just comma, as is specified in the RFC.
Also I want to share some ambiguity I find in the said RFC (not the only ambiguity found, though!): it says to join the RDNs in reverse order, but it does not tell to parse them in the reverse order; which means that the DN will be reversed after each parse-compose operation.
This parser supports OSF-syntax DNs as well, but not all of such DNs can be represented in RFC2253 form (a valid OSF DN "/C=gb/etc" cannot be converted into RFC2253 DN, because the last component doesn't have an attribute type).
Field Summary | |
---|---|
static char |
ASSIGN_CHAR
|
static char |
COMMA_CHAR
|
static char |
PLUS_CHAR
|
Constructor Summary | |
---|---|
RFC2253NameParser()
|
Method Summary | |
---|---|
protected static boolean |
ALPHA(char c)
The ALPHA terminal. |
protected static boolean |
ASSIGNMENT(char c)
The ASSIGNMENT terminal. |
protected static java.lang.String |
attributeType(java.text.CharacterIterator ci,
boolean OSF)
The attributeType non-terminal. |
protected static java.lang.String[] |
attributeTypeAndValue(java.text.CharacterIterator ci,
boolean OSF)
The attributeTypeAndValue non-terminal. |
protected static java.lang.String |
attributeValue(java.text.CharacterIterator ci,
boolean OSF)
The attributeValue non-terminal. |
protected static boolean |
COMMA(char c)
The COMMA terminal. |
protected static boolean |
DIGIT(char c)
The DIGIT terminal. |
static java.lang.String[][][] |
distinguishedName(java.lang.String Name)
The starting non-terminal, distinguishedName. |
static java.lang.String |
escapeString(java.lang.String s)
Same as escapeString( s, true ); |
static java.lang.String |
escapeString(java.lang.String s,
boolean escape)
This routine gets a Unicode String on input, and converts any character, that is outside latin alphabet and numbers, to hexpair, and escapes all special characters. |
protected static boolean |
hexchar(char c)
The hexchar terminal. |
protected static java.lang.String |
hexpair(java.text.CharacterIterator ci)
The hexpair non-terminal. |
protected static java.lang.String |
hexstring(java.text.CharacterIterator ci)
The hexstring non-terminal. |
protected static boolean |
keychar(char c)
The keychar terminal. |
protected static java.lang.String[][] |
name_component(java.text.CharacterIterator ci,
boolean OSF)
The name-component non-terminal. |
protected static java.lang.String[][][] |
name(java.text.CharacterIterator n,
boolean OSF)
The name non-terminal. |
protected static java.lang.String |
oid(java.text.CharacterIterator ci)
The oid non-terminal. |
protected static int |
onePair(java.text.CharacterIterator ci,
boolean OSF)
|
protected static char |
pair(java.text.CharacterIterator ci,
boolean OSF)
The pair non-terminal. |
protected static boolean |
PLUS(char c)
The PLUS terminal. |
protected static boolean |
QUOTATION(char c,
boolean OSF)
The QUOTATION terminal. |
protected static boolean |
quotechar(char c,
boolean OSF)
The quotechar terminal. |
protected static void |
skip_spaces(java.text.CharacterIterator ci)
The skip_spaces() non-terminal. |
protected static boolean |
SLASH(char c)
The SLASH terminal. |
protected static boolean |
special(char c,
boolean OSF)
The special terminal. |
protected static java.lang.String |
string(java.text.CharacterIterator ci,
boolean OSF)
The string non-terminal. |
protected static boolean |
stringchar(char c,
boolean OSF)
The stringchar terminal. |
static java.lang.String |
toCanonicalDN(java.lang.String dn)
This method will attempt to convert a given DN to canonical DN. |
static java.lang.String |
toCanonicalDN(java.lang.String[][][] dn)
Same as toCanonicalDN( dn, true ); |
static java.lang.String |
toCanonicalDN(java.lang.String[][][] dn,
boolean escape)
This method returns the canonical representation of the DN separated into arrays of strings, optionally escaping non-ASCII characters. |
static java.lang.String |
toHexString(byte[] b)
This routine converts a given byte array into a hexstring, prepended with a HASH_CHAR. |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
Field Detail |
---|
public static final char ASSIGN_CHAR
public static final char COMMA_CHAR
public static final char PLUS_CHAR
Constructor Detail |
---|
public RFC2253NameParser()
Method Detail |
---|
public static java.lang.String[][][] distinguishedName(java.lang.String Name) throws RFC2253ParsingException
distinguishedName = [name]
Name
- a string to be parsed into a Disitnguished Name
toCanonicalName
method.
Note also, that the method simply returns an array of arrays of
AttributeValueAssertions. The latter is an array of two strings:
attribute type and attribute value; not to mess with extra classes.
RFC2253ParsingException,
- which will always contain a nested
exception. The exception contains basic information: at what
position the parsing error occured, and there is not much
use in printing its stack. The details of the fault are
contained in the nested exception, and the actual error point
in the code as well, if you want to print the stack trace.
The code does not throw any other exceptions, even run-time
ones, except for IllegalArgumentException, which may occur in
case
a null string is passed as a Name parameter.
RFC2253ParsingException
public static java.lang.String toCanonicalDN(java.lang.String[][][] dn, boolean escape)
It simply combines the parts of the dn in the following way: the attribute types in each AVA are converted to upper case (because some applications allow lowercase input of these), attribute values are taken as is, and then all AVAs in the same RDN are combined using "=", after that all RDNs are concatenated using ",".
dn is an array of RDNs. RDN is an array of AVA (Attribute Value Assertion). AVA is an array of two strings (after parsing using distinguishedName method). The string with index 0 is the attribute type. The string with index 1 is the attribute value. The value will be escaped using escapeString method.
If AVA is an array of more than two strings (the reference in RDN
can be replaced
by the user), and the string with index 2 is not null, it will be
placed as the
attribute value as is, instead of escaped string with index 1. This
allows the user
to provide the values of attributes that should be compared as
binary (for example,
"# In the example above the distinguished name will be parsed as an
array of two RDNs,
each of them having only one AVA. We are accessing the leftmost RDN.
We are interested
in replacing the AVA in it that corresponds to the "uid" attribute
type, so the uid will
be case sensitive ("aBc" is not the same as "ABC"). So we replace
the corresponding
AVA in the RDN with the new value - an array containing the
user-defined string to
be put in the RDN.
Note that in most cases conversion to the canonic DN will look
like this:
String [][][] dn = distinguishedName("uid=aBc , c=gb");
String [][] uid_rdn = dn[0];
String [] uid_ava = uid_rdn[0];
uid_rdn[0] = new String[]{ uid_ava[0], uid_ava[1], toHexString(uid_ava[1].getBytes()) };
String canonicalDN = toCanonicalDN(dn);
String canonicalDN = toCanonicalDN(distinguishedName( nonCanonical ));
dn
- is the parsed DN with the array format as described aboveescape
- if true, non-ASCII characters will be escaped as a hex
pair; if false, the Unicode values will be returned as is
java.lang.NullPointerException
- and IndexOutOfRange in case the dn is a
malformed
input (AVA is less than 2 elements, or null pointer encountered)
public static java.lang.String toCanonicalDN(java.lang.String[][][] dn)
public static java.lang.String toCanonicalDN(java.lang.String dn)
This is the same as calling toCanonicalDN(distinguishedName(dn)), but is more convenient, because it doesn't throw exceptions.
dn
- - the DN to convert to canonical form; can be null
protected static java.lang.String[][][] name(java.text.CharacterIterator n, boolean OSF) throws RFC2253ParsingException
n
- - the CharacterIterator where the current position points to
a distinguished nameOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
RFC2253ParsingException
protected static java.lang.String[][] name_component(java.text.CharacterIterator ci, boolean OSF) throws RFC2253ParsingException
ci
- - the CharacterIterator, where the current position points
to a RDNOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
RFC2253ParsingException
protected static java.lang.String[] attributeTypeAndValue(java.text.CharacterIterator ci, boolean OSF) throws RFC2253ParsingException
ci
- - the CharacterIterator, where the current position points
to an AVAOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
RFC2253ParsingException
protected static java.lang.String attributeType(java.text.CharacterIterator ci, boolean OSF) throws RFC2253ParsingException
attributeType = (ALPHA 1*keychar) / oid
should perhaps read
attributeType = (ALPHA *keychar) / oid
Otherwise, attributeType L (locality) would not be accepted.
ci
- - the CharacterIterator, where the current position points
to an attribute typeOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
RFC2253ParsingException
protected static boolean keychar(char c)
c
- - the character to test
protected static java.lang.String oid(java.text.CharacterIterator ci) throws RFC2253ParsingException
ci
- - the CharacterIterator, where the current position points
to an attribute type expressed as an OID
RFC2253ParsingException
protected static java.lang.String attributeValue(java.text.CharacterIterator ci, boolean OSF) throws RFC2253ParsingException
ci
- - the CharacterIterator, where the current position points
to an attribute valueOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
RFC2253ParsingException
protected static java.lang.String string(java.text.CharacterIterator ci, boolean OSF) throws RFC2253ParsingException
ci
- - the CharacterIterator, where the current position points
to a string value of an attributeOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
RFC2253ParsingException
protected static boolean quotechar(char c, boolean OSF)
c
- - the character to be testedOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
protected static boolean special(char c, boolean OSF)
c
- - the character to be testedOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
protected static char pair(java.text.CharacterIterator ci, boolean OSF) throws RFC2253ParsingException
It may read multiple hex pairs escaped with "\" to fully decode the UTF-8 character.
ci
- - the CharacterIterator, where the current position points
to a character expressed through the escape character "\" and
the character codeOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
RFC2253ParsingException,
- and restores the ci pointer to the
position it was on input; thus acting similar to the terminals:
a pointer can move over the whole entity, or it does not move at
all.
RFC2253ParsingException
protected static int onePair(java.text.CharacterIterator ci, boolean OSF) throws RFC2253ParsingException
RFC2253ParsingException
protected static boolean stringchar(char c, boolean OSF)
c
- - the character to be testedOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
protected static java.lang.String hexstring(java.text.CharacterIterator ci) throws RFC2253ParsingException
ci
- - the CharacterIterator, where the current position points
to a value expressed as a hexstring
RFC2253ParsingException
protected static java.lang.String hexpair(java.text.CharacterIterator ci) throws RFC2253ParsingException
ci
- - the CharacterIterator, where the current position points
to a single hexadecimal digits pair
RFC2253ParsingException,
- but like pair non-terminal, restores
the pointer to the initial position.
RFC2253ParsingException
protected static boolean hexchar(char c)
c
- - the character to be tested
protected static boolean DIGIT(char c)
c
- - the character to be tested
protected static boolean ALPHA(char c)
c
- - the character to be tested
protected static boolean QUOTATION(char c, boolean OSF)
c
- - the character to be testedOSF
- - if true, OSF syntax is assumed; if false, RFC2253 syntax
is assumed
protected static void skip_spaces(java.text.CharacterIterator ci)
skip_spaces = *space
ci
- - the CharacterIterator, where the current position points
to sequence of spacesprotected static boolean COMMA(char c)
COMMA = "," / ";"
c
- - the character to be tested
protected static boolean PLUS(char c)
PLUS = "+"
c
- - the character to be tested
protected static boolean ASSIGNMENT(char c)
ASSIGNMENT = "="
c
- - the character to be tested
protected static boolean SLASH(char c)
SLASH = "/"
c
- - the character to be tested
public static java.lang.String toHexString(byte[] b)
b
- - the byte array to be converted into a hexstring
public static java.lang.String escapeString(java.lang.String s, boolean escape)
s
- - the string to convert
public static java.lang.String escapeString(java.lang.String s)
|
|||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | ||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |