You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by el...@apache.org on 2006/12/14 16:38:35 UTC
svn commit: r487240 - in
/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name:
LdapDN.java LdapDnParser.java Rdn.java RdnParser.java
Author: elecharny
Date: Thu Dec 14 07:38:34 2006
New Revision: 487240
URL: http://svn.apache.org/viewvc?view=rev&rev=487240
Log:
Added an isvalid() method in LdapDN to allow the SyntaxChecker to validate a DN without
building the object.
Fixed some warnings
Modified:
directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java
directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java
directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java
directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java
Modified: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java?view=diff&rev=487240&r1=487239&r2=487240
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java (original)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDN.java Thu Dec 14 07:38:34 2006
@@ -61,7 +61,7 @@
public class LdapDN /* extends LdapString */implements Name
{
/** The LoggerFactory used by this class */
- private static Logger log = LoggerFactory.getLogger( LdapDN.class );
+ protected static Logger log = LoggerFactory.getLogger( LdapDN.class );
/**
* Declares the Serial Version Uid.
@@ -81,7 +81,7 @@
// ~ Static fields/initializers
// -----------------------------------------------------------------
/** The RDNs that are elements of the DN */
- private List<Rdn> rdns = new ArrayList<Rdn>( 5 );
+ protected List<Rdn> rdns = new ArrayList<Rdn>( 5 );
/** The user provided name */
private String upName;
@@ -120,7 +120,7 @@
{
for ( int ii = 0; ii < name.size(); ii++ )
{
- String nameComponent = ( String ) name.get( ii );
+ String nameComponent = name.get( ii );
add( nameComponent );
}
}
@@ -524,7 +524,11 @@
*/
public boolean startsWith( Name name )
{
- if ( name instanceof LdapDN )
+ if ( name == null )
+ {
+ return true;
+ }
+ else if ( name instanceof LdapDN )
{
LdapDN nameDN = ( LdapDN ) name;
@@ -555,7 +559,7 @@
return true;
}
- else if ( name instanceof Name )
+ else
{
if ( name.size() == 0 )
{
@@ -578,7 +582,7 @@
try
{
- nameRdn = new Rdn( ( String ) name.get( name.size() - i - 1 ) );
+ nameRdn = new Rdn( name.get( name.size() - i - 1 ) );
}
catch ( InvalidNameException e )
{
@@ -594,11 +598,6 @@
return true;
}
- else
- {
- // We don't accept a Name which is not a LdapName
- return name == null;
- }
}
@@ -738,7 +737,7 @@
*
* @return All the components
*/
- public List getRdns()
+ public List<Rdn> getRdns()
{
List<Rdn> newRdns = new ArrayList<Rdn>();
@@ -1028,7 +1027,7 @@
* if adding <tt>RDN</tt> would violate the syntax rules of
* this name
*/
- public Name add( Rdn newRdn ) throws InvalidNameException
+ public Name add( Rdn newRdn )
{
rdns.add( 0, newRdn );
normalizeInternal();
@@ -1255,7 +1254,7 @@
if ( oidNormalizer != null )
{
- return new AttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(), ( String ) oidNormalizer.getNormalizer()
+ return new AttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(), oidNormalizer.getNormalizer()
.normalize( atav.getValue() ) );
}
@@ -1335,7 +1334,7 @@
value = DefaultStringNormalizer.normalizeString( ( String ) value );
rdn.addAttributeTypeAndValue( oidNormalizer.getAttributeTypeOid(),
- ( String ) oidNormalizer.getNormalizer()
+ oidNormalizer.getNormalizer()
.normalize( value ) );
}
@@ -1423,18 +1422,30 @@
return;
}
- Enumeration<Rdn> rdns = getAllRdn();
+ Enumeration<Rdn> localRdns = getAllRdn();
// Loop on all RDNs
- while ( rdns.hasMoreElements() )
+ while ( localRdns.hasMoreElements() )
{
- Rdn rdn = rdns.nextElement();
- String upName = rdn.getUpName();
+ Rdn rdn = localRdns.nextElement();
+ String localUpName = rdn.getUpName();
rdnOidToName( rdn, oidsMap );
rdn.normalize();
- rdn.setUpName( upName );
+ rdn.setUpName( localUpName );
}
normalizeInternal();
+ }
+
+ /**
+ * Check if a DistinguishedName is syntaxically valid
+ *
+ * @param dn The DN to validate
+ * @return <code>true></code> if the DN is valid, <code>false</code>
+ * otherwise
+ */
+ public static boolean isValid( String dn )
+ {
+ return LdapDnParser.validateInternal( dn );
}
}
Modified: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java?view=diff&rev=487240&r1=487239&r2=487240
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java (original)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/LdapDnParser.java Thu Dec 14 07:38:34 2006
@@ -77,6 +77,7 @@
*/
private LdapDnParser()
{
+ // Nothing to do
}
@@ -146,6 +147,60 @@
else
{
throw new InvalidNameException( "Bad DN : " + dn );
+ }
+ }
+
+
+ /**
+ * Validate a DN
+ *
+ * @param dn
+ * The DN to be parsed
+ *
+ * @return <code>true</code> if the DN is valid
+ */
+ public static boolean validateInternal( String dn )
+ {
+ if ( dn.length() == 0 )
+ {
+ // We have an empty DN, just get out of the function.
+ return true;
+ }
+
+ Position pos = new Position();
+ pos.start = 0;
+
+ // <name> ::= <name-component> <name-components>
+ // <name-components> ::= <spaces> <separator> <spaces> <name-component>
+ // <name-components> | e
+ if ( RdnParser.isValid( dn, pos, true ) )
+ {
+ // Now, parse the following nameComponents
+ do
+ {
+ if ( ( StringTools.isCharASCII( dn, pos.start, ',' ) == false )
+ && ( StringTools.isCharASCII( dn, pos.start, ';' ) == false ) )
+ {
+
+ if ( pos.start != dn.length() )
+ {
+ return false;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ pos.start++;
+ }
+ while ( RdnParser.isValid( dn, pos, false ) );
+
+ return true;
+ }
+ else
+ {
+ return false;
}
}
Modified: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java?view=diff&rev=487240&r1=487239&r2=487240
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java (original)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/Rdn.java Thu Dec 14 07:38:34 2006
@@ -152,7 +152,7 @@
* case where we only have a single type=value. This will be 99.99% the
* case. This avoids the creation of a HashMap.
*/
- private AttributeTypeAndValue atav = null;
+ protected AttributeTypeAndValue atav = null;
/**
* The number of atavs. We store this number here to avoid complex
@@ -277,7 +277,7 @@
while ( iter.hasNext() )
{
- AttributeTypeAndValue currentAtav = ( AttributeTypeAndValue ) iter.next();
+ AttributeTypeAndValue currentAtav = iter.next();
atavs.add( (AttributeTypeAndValue)currentAtav.clone() );
atavTypes.put( currentAtav.getType(), currentAtav );
}
@@ -522,7 +522,7 @@
default:
if ( atavTypes.containsKey( normalizedType ) )
{
- return ( AttributeTypeAndValue ) atavTypes.get( normalizedType );
+ return atavTypes.get( normalizedType );
}
else
{
@@ -564,7 +564,7 @@
public void remove()
{
-
+ // nothing to do
}
};
}
@@ -855,7 +855,7 @@
return false;
}
- return compareTo( ( Rdn ) rdn ) == EQUALS;
+ return compareTo( rdn ) == EQUALS;
}
@@ -1021,7 +1021,7 @@
{
if ( StringTools.isHex( chars, i ) )
{
- pair += ( byte ) StringTools.HEX_VALUE[chars[i]];
+ pair += StringTools.HEX_VALUE[chars[i]];
bytes[pos++] = pair;
}
}
Modified: directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java
URL: http://svn.apache.org/viewvc/directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java?view=diff&rev=487240&r1=487239&r2=487240
==============================================================================
--- directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java (original)
+++ directory/trunks/shared/ldap/src/main/java/org/apache/directory/shared/ldap/name/RdnParser.java Thu Dec 14 07:38:34 2006
@@ -156,6 +156,71 @@
}
}
+ /**
+ * Validate this rule : <br>
+ * <p>
+ * <oidValue> ::= [0-9] <digits> <oids>
+ * </p>
+ *
+ * @param chars
+ * The char array to parse
+ * @param pos
+ * The current position in the byte buffer
+ * @return <code>true</code> if this is a valid OID
+ */
+ private static boolean isValidOidValue( String string, Position pos )
+ {
+ pos.start += pos.length;
+ pos.end = pos.start;
+
+ // <attributType> ::= [0-9] <digits> <oids>
+ if ( StringTools.isDigit( string, pos.start ) == false )
+ {
+ // Nope... An error
+ return false;
+ }
+ else
+ {
+ // Let's process an oid
+ pos.end++;
+
+ while ( StringTools.isDigit( string, pos.end ) )
+ {
+ pos.end++;
+ }
+
+ // <oids> ::= '.' [0-9] <digits> <oids> | e
+ if ( StringTools.isCharASCII( string, pos.end, '.' ) == false )
+ {
+ return false;
+ }
+ else
+ {
+ do
+ {
+ pos.end++;
+
+ if ( StringTools.isDigit( string, pos.end ) == false )
+ {
+ return false;
+ }
+ else
+ {
+ pos.end++;
+
+ while ( StringTools.isDigit( string, pos.end ) )
+ {
+ pos.end++;
+ }
+ }
+
+ }
+ while ( StringTools.isCharASCII( string, pos.end, '.' ) );
+
+ return true;
+ }
+ }
+ }
/**
* Parse this rule : <br>
@@ -241,6 +306,61 @@
}
}
+ /**
+ * Parse this rule : <br>
+ * <p>
+ * <attributType> ::= [a-zA-Z] <keychars> | <oidPrefix>
+ * [0-9] <digits> <oids> | [0-9] <digits> <oids>
+ * </p>
+ * The string *MUST* be an ASCII string, not an unicode string.
+ *
+ * @param chars
+ * The char array to parse
+ * @param pos
+ * The current position in the char array
+ * @return The new position in the char array, or PARSING_ERROR if the rule
+ * does not apply to the char array
+ */
+ private static boolean isValidAttributeType( String string, Position pos )
+ {
+ // <attributType> ::= [a-zA-Z] <keychars> | <oidPrefix> [0-9] <digits>
+ // <oids> | [0-9] <digits> <oids>
+ if ( StringTools.isAlphaASCII( string, pos.start ) )
+ {
+ // <attributType> ::= [a-zA-Z] <keychars> | <oidPrefix> [0-9]
+ // <digits> <oids>
+
+ // We have got an Alpha char, it may be the begining of an OID ?
+ if ( parseOidPrefix( string, pos ) != DNUtils.PARSING_ERROR )
+ {
+ pos.length = 4;
+
+ return isValidOidValue( string, pos );
+ }
+ else
+ {
+ // It's not an oid, it's a String (ASCII)
+ // <attributType> ::= [a-zA-Z] <keychars>
+ // <keychars> ::= [a-zA-Z] <keychar> | [0-9] <keychar> | '-'
+ // <keychar> | e
+ pos.end++;
+
+ while ( StringTools.isAlphaDigitMinus( string, pos.end ) )
+ {
+ pos.end++;
+ }
+
+ return true;
+ }
+ }
+ else
+ {
+ // An oid
+ // <attributType> ::= [0-9] <digits> <oids>
+ return isValidOidValue( string, pos );
+ }
+ }
+
/**
* Parse this rule : <br>
@@ -448,6 +568,163 @@
}
}
+ /**
+ * Validate this rule : <br>
+ * <p>
+ * <attributeValue> ::= <pairs-or-strings> | '#'
+ * <hexstring> |'"' <quotechar-or-pairs> '"' <br>
+ * <pairs-or-strings> ::= '\' <pairchar>
+ * <pairs-or-strings> | <stringchar> <pairs-or-strings> | |
+ * e <br>
+ * <quotechar-or-pairs> ::= <quotechar>
+ * <quotechar-or-pairs> | '\' <pairchar>
+ * <quotechar-or-pairs> | e <br>
+ * </p>
+ *
+ * @param chars
+ * The char array to parse
+ * @param pos
+ * The current position in the char array
+ * @return <code>true</code> if the rule is valid
+ */
+ private static boolean isValidAttributeValue( String string, Position pos )
+ {
+ char c = StringTools.charAt( string, pos.start );
+
+ if ( c == '#' )
+ {
+ pos.start++;
+ int nbHex = 0;
+ int currentPos = pos.start;
+
+ // First, we will count the number of hexPairs
+ while ( DNUtils.parseHexPair( string, currentPos ) >= 0 )
+ {
+ nbHex++;
+ currentPos += DNUtils.TWO_CHARS;
+ }
+
+ byte[] hexValue = new byte[nbHex];
+
+ // Now, convert the value
+ // <attributeValue> ::= '#' <hexstring>
+ if ( DNUtils.parseHexString( string, hexValue, pos ) == DNUtils.PARSING_ERROR )
+ {
+ return false;
+ }
+
+ pos.start--;
+ StringTools.trimRight( string, pos );
+ pos.length = pos.end - pos.start;
+
+ return true;
+ }
+ else if ( c == '"' )
+ {
+ pos.start++;
+ pos.length = 0;
+ pos.end = pos.start;
+ int nbBytes = 0;
+
+ // <attributeValue> ::= '"' <quotechar-or-pair> '"'
+ // <quotechar-or-pairs> ::= <quotechar> <quotechar-or-pairs> | '\'
+ // <pairchar> <quotechar-or-pairs> | e
+ while ( true )
+ {
+ if ( StringTools.isCharASCII( string, pos.end, '\\' ) )
+ {
+ pos.end++;
+ int nbChars = 0;
+
+ if ( ( nbChars = DNUtils.isPairChar( string, pos.start ) ) != DNUtils.PARSING_ERROR )
+ {
+ pos.end += nbChars;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else if ( ( nbBytes = DNUtils.isQuoteChar( string, pos.end ) ) != DNUtils.PARSING_ERROR )
+ {
+ pos.end += nbBytes;
+ }
+ else
+ {
+ pos.length = pos.end - pos.start;
+ break;
+ }
+ }
+
+ if ( StringTools.isCharASCII( string, pos.end, '"' ) )
+ {
+ pos.end++;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ else
+ {
+ while ( true )
+ {
+ if ( StringTools.isCharASCII( string, pos.end, '\\' ) )
+ {
+ // '\' <pairchar> <pairs-or-strings>
+ pos.end++;
+
+ int nbChars = 0;
+
+ if ( ( nbChars = DNUtils.isPairChar( string, pos.end ) ) == DNUtils.PARSING_ERROR )
+ {
+ return false;
+ }
+ else
+ {
+ pos.end += nbChars;
+ }
+ }
+ else
+ {
+ int nbChars = 0;
+
+ // <stringchar> <pairs-or-strings>
+ if ( ( nbChars = DNUtils.isStringChar( string, pos.end ) ) != DNUtils.PARSING_ERROR )
+ {
+ // A special case : if we have some spaces before the
+ // '+' character,
+ // we MUST skip them.
+ if ( StringTools.isCharASCII( string, pos.end, '+' ) )
+ {
+ //StringTools.trimLeft( string, pos );
+
+ if ( ( DNUtils.isStringChar( string, pos.end ) == DNUtils.PARSING_ERROR )
+ && ( StringTools.isCharASCII( string, pos.end, '\\' ) == false ) )
+ {
+ // Ok, we are done with the stringchar.
+ return true;
+ }
+ else
+ {
+ pos.end++;
+ }
+ }
+ else
+ {
+ pos.end += nbChars;
+ }
+ }
+ else
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
/**
* Parse this rule : <br>
@@ -526,6 +803,71 @@
/**
+ * Validate this rule : <br>
+ * <p>
+ * <nameComponents> ::= <spaces> '+' <spaces>
+ * <attributeType> <spaces> '=' <spaces>
+ * <attributeValue> <nameComponents> | e
+ * </p>
+ *
+ * @param chars
+ * The char buffer to parse
+ * @param pos
+ * The current position in the byte buffer
+ * @return <code>true</code> if the rule is valid
+ */
+ private static boolean isValidNameComponents( String string, Position pos, boolean isFirstRdn )
+ {
+ int newStart = 0;
+
+ while ( true )
+ {
+ StringTools.trimLeft( string, pos );
+
+ if ( StringTools.isCharASCII( string, pos.end, '+' ) )
+ {
+ pos.start++;
+ }
+ else
+ {
+ // <attributeTypeAndValues> ::= e
+ return true;
+ }
+
+ StringTools.trimLeft( string, pos );
+
+ if ( !isValidAttributeType( string, pos ) )
+ {
+ return false;
+ }
+
+ pos.start = pos.end;
+
+ StringTools.trimLeft( string, pos );
+
+ if ( StringTools.isCharASCII( string, pos.end, '=' ) )
+ {
+ pos.start++;
+ }
+ else
+ {
+ return false;
+ }
+
+ StringTools.trimLeft( string, pos );
+
+ if ( !isValidAttributeValue( string, pos ) )
+ {
+ return false;
+ }
+
+ newStart = pos.end;
+ pos.start = newStart;
+ pos.end = newStart;
+ }
+ }
+
+ /**
* Unescape pairChars.
*
* A PairChar can be a char if it's
@@ -629,6 +971,62 @@
return DNUtils.PARSING_OK;
}
+ /**
+ * Validate a NameComponent : <br>
+ * <p>
+ * <name-component> ::= <attributeType> <spaces> '='
+ * <spaces> <attributeValue> <nameComponents>
+ * </p>
+ *
+ * @param dn The String to parse
+ * @param pos The current position in the buffer
+ * @return <code>true</code> if the RDN is valid
+ */
+ public static boolean isValid( String dn, Position pos, boolean isfirstRdn )
+ {
+ StringTools.trimLeft( dn, pos );
+
+ pos.end = pos.start;
+ pos.length = 0;
+
+ if ( !isValidAttributeType( dn, pos ) )
+ {
+ return false;
+ }
+
+ pos.start = pos.end;
+
+ StringTools.trimLeft( dn, pos );
+
+ if ( StringTools.isCharASCII( dn, pos.start, '=' ) == false )
+ {
+ return false;
+ }
+ else
+ {
+ pos.start++;
+ }
+
+ StringTools.trimLeft( dn, pos );
+
+ pos.end = pos.start;
+
+ if ( !isValidAttributeValue( dn, pos ) )
+ {
+ return false;
+ }
+
+ pos.start = pos.end;
+ pos.length = 0;
+
+ if ( !isValidNameComponents( dn, pos, isfirstRdn ) )
+ {
+ return false;
+ }
+
+ pos.start = pos.end;
+ return true;
+ }
/**
* Parse a NameComponent : <br>
@@ -647,5 +1045,24 @@
{
parse( string, new Position(), rdn );
rdn.normalize();
+ }
+
+ /**
+ * Validtae a NameComponent : <br>
+ * <p>
+ * <name-component> ::= <attributeType> <spaces> '='
+ * <spaces> <attributeValue> <nameComponents>
+ * </p>
+ *
+ * @param string
+ * The buffer to parse
+ * @param rdn
+ * The RDN to fill. Beware that if the RDN is not empty, the new
+ * AttributeTypeAndValue will be added.
+ * @return <code>true</code> if the RDN is valid
+ */
+ public static boolean isValid( String string )
+ {
+ return isValid( string, new Position(), false );
}
}