/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in * compliance with the NPL. You may obtain a copy of the NPL at * http://www.mozilla.org/NPL/ * * Software distributed under the NPL is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL * for the specific language governing rights and limitations under the * NPL. * * The Initial Developer of this code under the NPL is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1999 Netscape Communications Corporation. All Rights * Reserved. */ package netscape.ldap; import java.util.*; /** * The definition of an object class in the schema. * RFC 2252, Lightweight Directory Access Protocol (v3): * Attribute Syntax Definitions covers the types of information * that need to be specified in the definition of an object class. * According to the RFC, the description of an object class can * include the following information: *

* *

*

* * When you construct an LDAPObjectSchema object, you can specify * these types of information as arguments to the constructor or in the * ObjectClassDescription format specified in RFC 2252. * When an LDAP client searches an LDAP server for the schema, the server * returns schema information as an object with attribute values in this * format. *

* * RFC 2252 also notes that you can specify whether or not an object class * is abstract, structural, or auxiliary in the object description. * Abstract object classes are used only to derive other object classes. * Entries cannot belong to an abstract object class. top * is an abstract object class. Entries must belong to a structural * object class, so most object classes are structural object classes. * Objects of the LDAPObjectClassSchema class are structural * object classes by default. Auxiliary object classes can be used to * add attributes to entries of different types. For example, an * auxiliary object class might be used to specify personal preference * attributes. An entry can not contain just that object class, but may * include it along with a structural object class, for example * inetOrgPerson. * If the definition of an object (in ObjectClassDescription format) * specifies the AUXILIARY keyword, an LDAPObjectClassSchema * object created from that description represents an auxiliary object class. *

* * You can get the name, OID, and description of this object class * definition by using the getName, getOID, and * getDescription methods inherited from the abstract class * LDAPSchemaElement. Optional and custom qualifiers are * accessed with getQualifier and getQualifierNames * from LDAPSchemaElement. *

* * To add or remove this object class definition from the * schema, use the add and remove * methods, which this class inherits from the LDAPSchemaElement * abstract class. *

* RFC 2252 defines ObjectClassDescription as follows: *

*

 *    ObjectClassDescription = "(" whsp
 *        numericoid whsp      ; ObjectClass identifier
 *        [ "NAME" qdescrs ]
 *        [ "DESC" qdstring ]
 *        [ "OBSOLETE" whsp ]
 *        [ "SUP" oids ]       ; Superior ObjectClasses
 *        [ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
 *                             ; default structural
 *        [ "MUST" oids ]      ; AttributeTypes
 *        [ "MAY" oids ]       ; AttributeTypes
 *    whsp ")"
 * 
* * @version 1.0 * @see netscape.ldap.LDAPSchemaElement **/ public class LDAPObjectClassSchema extends LDAPSchemaElement { /** * Constructs an object class definition, using the specified * information. * @param name Name of the object class. * @param oid Object identifier (OID) of the object class * in dotted-string format (for example, "1.2.3.4"). * @param description Description of the object class. * @param superior Name of the parent object class * (the object class that the new object class inherits from). * @param required Array of the names of the attributes required * in this object class. * @param optional Array of the names of the optional attributes * allowed in this object class. */ public LDAPObjectClassSchema( String name, String oid, String superior, String description, String[] required, String[] optional ) { super( name, oid, description ); attrName = "objectclasses"; this.superiors = new String[] { superior }; for( int i = 0; i < required.length; i++ ) { must.addElement( required[i] ); } for( int i = 0; i < optional.length; i++ ) { may.addElement( optional[i] ); } } /** * Constructs an object class definition, using the specified * information. * @param name Name of the object class. * @param oid Object identifier (OID) of the object class * in dotted-string format (for example, "1.2.3.4"). * @param description Description of the object class. * @param superiors Name of parent object classes * (the object class that the new object class inherits from). * @param required Array of the names of the attributes required * in this object class. * @param optional Array of the names of the optional attributes * allowed in this object class. * @param type Either ABSTRACT, STRUCTURAL, or AUXILIARY */ public LDAPObjectClassSchema( String name, String oid, String[] superiors, String description, String[] required, String[] optional, int type ) { this( name, oid, superiors[0], description, required, optional ); this.superiors = superiors; this.type = type; } /** * Constructs an object class definition based on a description in * the ObjectClassDescription format. For information on this format, * (see RFC 2252, Lightweight Directory Access Protocol (v3): * Attribute Syntax Definitions. This is the format that LDAP servers * and clients use to exchange schema information. (For example, when * you search an LDAP server for its schema, the server returns an entry * with the attributes "objectclasses" and "attributetypes". The * values of the "objectclasses" attribute are object class descriptions * in this format.) *

* * @param raw Definition of the object in the ObjectClassDescription * format. */ public LDAPObjectClassSchema( String raw ) { attrName = "objectclasses"; parseValue( raw ); String[] vals = getQualifier( SUPERIOR ); if ( vals != null ) { superiors = vals; setQualifier( SUPERIOR, (String)null ); } if ( properties.containsKey( "AUXILIARY" ) ) { type = AUXILIARY; } else if ( properties.containsKey( "ABSTRACT" ) ) { type = ABSTRACT; } else if ( properties.containsKey( "STRUCTURAL" ) ) { type = STRUCTURAL; } obsolete = properties.containsKey( OBSOLETE ); Vector v = (Vector)properties.get( "MAY" ); if ( v != null ) { may = v; } v = (Vector)properties.get( "MUST" ); if ( v != null ) { must = v; } } /** * Get the name of the object class that this class inherits from. * @return The name of the object class that this class * inherits from. */ public String getSuperior() { return superiors[0]; } /** * Get the names of all object classes that this class inherits * from. Typically only one, but RFC 2252 allows multiple * inheritance. * @return The names of the object classes that this class * inherits from. */ public String[] getSuperiors() { return superiors; } /** * Get an enumeration of the names of the required attribute for * this object class. * @return An enumeration of the names of the required attributes * for this object class. */ public Enumeration getRequiredAttributes() { return must.elements(); } /** * Get an enumeration of names of optional attributes allowed * in this object class. * @return An enumeration of the names of optional attributes * allowed in this object class. */ public Enumeration getOptionalAttributes() { return may.elements(); } /** * Get the type of the object class. * @return STRUCTURAL, ABSTRACT, or AUXILIARY */ public int getType() { return type; } /** * Prepare a value in RFC 2252 format for submitting to a server * * @param quotingBug true if SUP and SYNTAX values are to * be quoted. That is to satisfy bugs in certain LDAP servers. * @return A String ready to be submitted to an LDAP server */ String getValue( boolean quotingBug ) { String s = getValuePrefix(); s += getValue( SUPERIOR, quotingBug ); s += ' '; String val = getOptionalValues( NOVALS ); if ( val.length() > 0 ) { s += val + ' '; } s += getValue( "MUST", false ); s += ' '; s += getValue( "MAY", false ); s += ' '; val = getCustomValues(); if ( val.length() > 0 ) { s += val + ' '; } s += ')'; return s; } /** * Get the definition of the object class in a user friendly format. * This is the format that the object class definition uses when * you print the object class or the schema. * @return Definition of the object class in a user friendly format. */ public String toString() { String s = "Name: " + name + "; OID: " + oid + "; Superior: "; for( int i = 0; i < superiors.length; i++ ) { s += superiors[i]; if ( i < (superiors.length-1) ) { s += ", "; } } s += "; Description: " + description + "; Required: "; int i = 0; Enumeration e = getRequiredAttributes(); while( e.hasMoreElements() ) { if ( i > 0 ) s += ", "; i++; s += (String)e.nextElement(); } s += "; Optional: "; e = getOptionalAttributes(); i = 0; while( e.hasMoreElements() ) { if ( i > 0 ) s += ", "; i++; s += (String)e.nextElement(); } switch ( type ) { case STRUCTURAL: break; case ABSTRACT: s += "; ABSTRACT"; break; case AUXILIARY: s += "; AUXILIARY"; break; } if ( obsolete ) { s += "; OBSOLETE"; } s += getQualifierString( IGNOREVALS ); return s; } public static final int STRUCTURAL = 0; public static final int ABSTRACT = 1; public static final int AUXILIARY = 2; private String[] superiors = { "" }; private Vector must = new Vector(); private Vector may = new Vector(); private int type = STRUCTURAL; // Qualifers known to not have values static String[] NOVALS = { "ABSTRACT", "STRUCTURAL", "AUXILIARY" }; static { for( int i = 0; i < NOVALS.length; i++ ) { novalsTable.put( NOVALS[i], NOVALS[i] ); } } static String[] IGNOREVALS = { "ABSTRACT", "STRUCTURAL", "AUXILIARY", "MUST", "MAY" }; }