nkinder%redhat.com 7aa6718020 Resolves: 380215
Summary:  Fixed javadoc comments that were causing warnings at build time.


git-svn-id: svn://10.0.0.236/trunk@226263 18797224-902f-48f8-a5cc-f745e15eee43
2007-05-10 17:35:41 +00:00

492 lines
16 KiB
Java

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
package netscape.ldap.util;
import java.util.*;
/**
* Objects of this class represent the components of a distinguished
* name (DN). (In some situations, these components are referred to
* as relative distinguished names, or RDNs.) For example, the
* DN "uid=bjensen, ou=People, o=Airius.com" has three components:
* "uid=bjensen", "ou=People", and "o=Airius.com".
* <P>
*
* Each DN component consists of an attribute type and a value.
* For example, in "o=Airius.com", the attribute type is "o"
* and the value is "Airius.com".
* <P>
*
* You can use objects of this class to add components to an
* existing <CODE>DN</CODE> object.
* <P>
*
* @version 1.0
* @see netscape.ldap.util.DN
*/
public final class RDN implements java.io.Serializable {
static final long serialVersionUID = 7895454691174650321L;
/**
* List of RDNs. DN consists of one or more RDNs.
*/
private String[] m_type = null;
private String[] m_value = null;
private boolean m_ismultivalued = false;
/**
* Hash table of case sensitive attributes
*/
private static Hashtable m_attributehash = new Hashtable();
/**
* Constructs a new <CODE>RDN</CODE> object from the specified
* DN component.
* @param rdn DN component
*/
public RDN( String rdn ) {
String neutralRDN = neutralizeEscapes(rdn);
if (neutralRDN == null) {
return; // malformed RDN
}
int index = neutralRDN.indexOf( "=" );
int next_plus;
// if the rdn doesnt have = or = positions right at the beginning of the rdn
if (index <= 0)
return;
Vector values = new Vector();
Vector types = new Vector();
types.addElement( rdn.substring( 0, index ).trim() );
next_plus = neutralRDN.indexOf( '+', index );
while ( next_plus != -1 ) {
m_ismultivalued = true;
values.addElement( rdn.substring( index + 1, next_plus).trim() );
index = neutralRDN.indexOf( "=", next_plus + 1 );
if ( index == -1 ) {
// malformed RDN?
return;
}
types.addElement( rdn.substring( next_plus + 1, index ).trim() );
next_plus = neutralRDN.indexOf('+', index );
}
values.addElement( rdn.substring( index + 1 ).trim() );
m_type = new String[types.size()];
m_value = new String[values.size()];
for( int i = 0; i < types.size(); i++ ) {
m_type[i] = (String)types.elementAt( i );
if (!isValidType(m_type[i])) {
m_type = m_value = null;
return; // malformed
}
m_value[i] = (String)values.elementAt( i );
if (!isValidValue(m_value[i])) {
m_type = m_value = null;
return; // malformed
}
}
}
/**
* Neutralize backslash escapes and quoted sequences for easy parsing.
* @return rdn string with disabled escapes or null if malformed rdn
*/
static String neutralizeEscapes(String rdn) {
if (rdn == null) {
return null;
}
StringBuffer sb = new StringBuffer(rdn);
boolean quoteOn = false;
// first pass, disable backslash escapes
for (int i=0; i < sb.length(); i++) {
if (sb.charAt(i) =='\\') {
sb.setCharAt(i, 'x');
if (i < sb.length()-1) {
sb.setCharAt(i+1, 'x');
}
else {
return null;
}
}
}
// second pass, disable quoted sequences
for (int i=0; i < sb.length(); i++) {
if (sb.charAt(i) == '"') {
quoteOn = !quoteOn;
continue;
}
if (quoteOn) {
sb.setCharAt(i, 'x');
}
}
return quoteOn ? null : sb.toString();
}
/**
* Type names can not contain any DN special characters
*/
private boolean isValidType(String type) {
if (type == null || type.length() < 1) {
return false;
}
for (int i=0; i< type.length(); i++) {
for (int j=0; j < DN.ESCAPED_CHAR.length; j++) {
if (type.charAt(i) == DN.ESCAPED_CHAR[j]) {
return false;
}
}
}
return true;
}
/**
* Values can contain only single quote sequence, where quotes are
* at the beginning and the end of the sequence
*/
private boolean isValidValue(String val) {
if (val == null || val.length() < 1) {
return false;
}
// count unescaped '"'
int cnt=0, i=0;
while (i >=0 && i < val.length()) {
i = val.indexOf('"', i);
if (i >= 0) {
if (i==0 || (val.charAt(i-1) != '\\')) {
cnt++;
}
i++;
}
}
if (cnt == 0) {
return true;
}
else if (cnt != 2) { // can have only two of them surrounding the value
return false;
}
else if (val.charAt(0) != '"' || val.charAt(val.length()-1) != '"') {
return false;
}
return true;
}
/**
* Returns the DN component as the first element in an
* array of strings.
* @param noType specify <code>true</code> to ignore the attribute type and
* equals sign (for example, "cn=") and return only the value
* @return an array of strings representing the DN component.
* @deprecated use <code>toString</code> or <code>getValues</code> instead.
*/
public String[] explodeRDN(boolean noType) {
if (m_type == null)
return null;
String str[] = new String[1];
if (noType) {
str[0] = getValue();
} else {
str[0] = toString();
}
return str;
}
/**
* Returns the attribute type of the DN component.
* @return rdn the attribute type of the DN component.
* @deprecated use <code>getTypes()</code> instead.
*/
public String getType() {
if (m_type != null && m_type.length > 0) {
return m_type[0];
}
return null;
}
/**
* Returns the attribute types of the DN component.
* @return rdn the attribute types of the DN component.
*/
public String[] getTypes() {
return m_type;
}
/**
* Returns the value of the DN component.
* @return rdn the value of the DN component.
* @deprecated use <code>getValues()</code> instead.
*/
public String getValue() {
if (m_value != null && m_value.length > 0) {
return m_value[0];
}
return null;
}
/**
* Returns the values of the DN component.
* @return rdn the values of the DN component.
*/
public String[] getValues() {
return m_value;
}
/**
* Returns <code>true</code> if the RDN is multi-valued.
* @return <code>true</code> if the RDN is multi-valued.
*/
public boolean isMultivalued() {
return m_ismultivalued;
}
/**
* Returns the string representation of the DN component.
* @return the string representation of the DN component.
*/
public String toString() {
StringBuffer buf = new StringBuffer();
for ( int i = 0; m_type != null && i < m_type.length; i++ ) {
if ( i != 0) {
buf.append(" + ");
}
buf.append( m_type[i] + "=" + m_value[i]);
}
return buf.toString();
}
/**
* Determines if the specified string is a distinguished name component.
* @param rdn the string to check
* @return <code>true</code> if the string is a distinguished name component.
*/
public static boolean isRDN(String rdn) {
RDN newrdn = new RDN(rdn);
return ((newrdn.getTypes() != null) && (newrdn.getValues() != null));
}
/**
* Determines if the current DN component is equal to the specified
* DN component. Uses an internal table of ces (case exact string)
* attributes to determine how the attributes should be compared.
* @param rdn the DN component to compare against the
* current DN component.
* @return <code>true</code> if the two DN components are equal.
* @see netscape.ldap.util.RDN#registerAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributeSyntax
*/
public boolean equals(RDN rdn) {
String[] this_types = (String[])getTypes().clone();
String[] this_values = (String[])getValues().clone();
String[] rdn_types = (String[])rdn.getTypes().clone();
String[] rdn_values = (String[])rdn.getValues().clone();
if ( this_types.length != rdn_types.length ) {
return false;
}
sortTypesAndValues( this_types, this_values );
sortTypesAndValues( rdn_types, rdn_values );
for (int i = 0; i < this_types.length; i++ ) {
if ( !this_types[i].equalsIgnoreCase( rdn_types[i] ) ) {
return false;
}
if ( CES_SYNTAX.equals( getAttributeSyntax( this_types[i] ) ) ) {
if ( !this_values[i].equals( rdn_values[i] ) ) {
return false;
}
} else {
if ( !this_values[i].equalsIgnoreCase( rdn_values[i] ) ) {
return false;
}
}
}
return true;
}
/* sorts the rdn components by attribute to make comparison easier */
void sortTypesAndValues( String[] types, String[] values ) {
boolean no_changes;
do {
no_changes = true;
for ( int i = 0; i < types.length - 1; i++ ) {
if ( types[i].toLowerCase().compareTo( types[i + 1].toLowerCase() ) > 0 ) {
String tmp_type = types[i];
String tmp_value = values[i];
types[i] = types[i + 1];
values[i] = values[i + 1];
types[i + 1] = tmp_type;
values[i + 1] = tmp_value;
no_changes = false;
}
}
} while ( no_changes = false );
}
/**
* Registers the the given attribute for the given syntax in an
* internal table. This table is used for attribute comparison in the
* <code>equals()</code> method.
* @param attr the attribute to register.
* @param oid the syntax to register with the attribute.
* @see netscape.ldap.util.RDN#equals
* @see netscape.ldap.util.RDN#unregisterAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributesForSyntax
*/
public static void registerAttributeSyntax( String attr, String oid ) {
m_attributehash.put( attr.toLowerCase(), oid );
}
/**
* Removes the the given attribute from the attribute syntax table.
* @param attr the attribute to remove.
* @see netscape.ldap.util.RDN#registerAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributesForSyntax
*/
public static void unregisterAttributeSyntax( String attr ) {
m_attributehash.remove( attr.toLowerCase() );
}
/**
* Returns the syntax for the attribute if the given attribute is registered
* in the internal attribute table.
* @param attr the attribute to lookup in the table.
* @return the syntax of the attribute if found, null otherwise.
* @see netscape.ldap.util.RDN#unregisterAttributeSyntax
* @see netscape.ldap.util.RDN#registerAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributesForSyntax
*/
public static String getAttributeSyntax( String attr ) {
return (String)m_attributehash.get( attr.toLowerCase() );
}
/**
* Returns all attributes registered for the given syntax as a
* <code>String</code> Array.
* @param oid the syntax to look up in the table.
* @return all attributes for the given syntax as a <code>String[]</code>
* @see netscape.ldap.util.RDN#unregisterAttributeSyntax
* @see netscape.ldap.util.RDN#registerAttributeSyntax
* @see netscape.ldap.util.RDN#getAttributeSyntax
*/
public static String[] getAttributesForSyntax( String oid ) {
Enumeration itr = m_attributehash.keys();
Vector key_v = new Vector();
String tmp_str = null;
while ( itr.hasMoreElements() ) {
tmp_str = (String)itr.nextElement();
if ( oid.equals( (String)m_attributehash.get( tmp_str ) ) ) {
key_v.addElement( tmp_str );
}
}
String[] str = new String[key_v.size()];
for ( int i = 0; i < str.length; i++ ) {
str[i] = new String( (String)key_v.elementAt( i ) );
}
return str;
}
public static final String[] _cesAttributes = {
"adminurl",
"altserver",
"automountinformation",
"bootfile",
"bootparameter",
"cirbindcredentials",
"generation",
"homedirectory",
"internationalisdnnumber",
"labeleduri",
"membercertificatedescription",
"membernisnetgroup",
"memberuid",
"memberurl",
"nismapentry",
"nisnetgrouptriple",
"nsaddressbooksyncurl",
"presentationaddress",
"ref",
"replicaentryfilter",
"searchguide",
"subtreeaci",
"vlvfilter",
"vlvname",
"x121address"
};
public static final String CES_SYNTAX = "1.3.6.1.4.1.1466.115.121.1.26";
static {
/* static initializer to fill the ces attribute hash
* this list was generated from the slapd.at.conf that
* ships with Netscape Directory Server 4.1
*/
for ( int i = 0; i < _cesAttributes.length; i++ ) {
registerAttributeSyntax( _cesAttributes[i], CES_SYNTAX );
}
}
}