blob: 23833b4210fd92e131b6208f47e2bd43b5a5f7b6 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/
package org.apache.directory.shared.ldap.schema;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.exception.LdapException;
import org.apache.directory.shared.ldap.schema.registries.AttributeTypeRegistry;
import org.apache.directory.shared.ldap.schema.registries.Registries;
/**
* A nameForm description. NameForms define the relationship between a
* STRUCTURAL objectClass definition and the attributeTypes allowed to be used
* for the naming of an Entry of that objectClass: it defines which attributes
* can be used for the RDN.
* <p>
* According to ldapbis [MODELS]:
* </p>
*
* <pre>
* 4.1.7.2. Name Forms
*
* A name form &quot;specifies a permissible RDN for entries of a particular
* structural object class. A name form identifies a named object
* class and one or more attribute types to be used for naming (i.e.
* for the RDN). Name forms are primitive pieces of specification
* used in the definition of DIT structure rules&quot; [X.501].
*
* Each name form indicates the structural object class to be named,
* a set of required attribute types, and a set of allowed attributes
* types. A particular attribute type cannot be listed in both sets.
*
* Entries governed by the form must be named using a value from each
* required attribute type and zero or more values from the allowed
* attribute types.
*
* Each name form is identified by an object identifier (OID) and,
* optionally, one or more short names (descriptors).
*
* Name form descriptions are written according to the ABNF:
*
* NameFormDescription = LPAREN WSP
* numericoid ; object identifier
* [ SP &quot;NAME&quot; SP qdescrs ] ; short names (descriptors)
* [ SP &quot;DESC&quot; SP qdstring ] ;String description
* [ SP &quot;OBSOLETE&quot; ] ; not active
* SP &quot;OC&quot; SP oid ; structural object class
* SP &quot;MUST&quot; SP oids ; attribute types
* [ SP &quot;MAY&quot; SP oids ] ; attribute types
* extensions WSP RPAREN ; extensions
*
* where:
*
* [numericoid] is object identifier which identifies this name form;
* NAME [qdescrs] are short names (descriptors) identifying this name
* form;
* DESC [qdstring] is a short descriptive string;
* OBSOLETE indicates this name form is not active;
* OC identifies the structural object class this rule applies to,
* MUST and MAY specify the sets of required and allowed, respectively,
* naming attributes for this name form; and
* [extensions] describe extensions.
*
* All attribute types in the required (&quot;MUST&quot;) and allowed (&quot;MAY&quot;) lists
* shall be different.
* </pre>
*
* @see <a href="http://www.faqs.org/rfcs/rfc225String2.html">RFC2252 Section 6.22</a>
* @see <a
* href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
* [MODELS]</a>
* @see DescriptionUtils#getDescription(NameForm)
* @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
* @version $Rev$
*/
public class NameForm extends AbstractSchemaObject
{
/** The serialVersionUID */
private static final long serialVersionUID = 1L;
/** The structural object class OID this rule applies to */
private String structuralObjectClassOid;
/** The structural object class this rule applies to */
private ObjectClass structuralObjectClass;
/** The set of required attribute OIDs for this name form */
private List<String> mustAttributeTypeOids;
/** The set of required AttributeTypes for this name form */
private List<AttributeType> mustAttributeTypes;
/** The set of allowed attribute OIDs for this name form */
private List<String> mayAttributeTypeOids;
/** The set of allowed AttributeTypes for this name form */
private List<AttributeType> mayAttributeTypes;
/**
* Creates a new instance of MatchingRule.
*
* @param oid The MatchingRule OID
*/
public NameForm( String oid )
{
super( SchemaObjectType.NAME_FORM, oid );
mustAttributeTypeOids = new ArrayList<String>();
mayAttributeTypeOids = new ArrayList<String>();
mustAttributeTypes = new ArrayList<AttributeType>();
mayAttributeTypes = new ArrayList<AttributeType>();
}
/**
* Inject the NameForm into the registries, updating the references to
* other SchemaObject
*
* @param registries The Registries
*/
public void addToRegistries( Registries registries ) throws LdapException
{
if ( registries != null )
{
AttributeTypeRegistry atRegistry = registries.getAttributeTypeRegistry();
structuralObjectClass = registries.getObjectClassRegistry().lookup( structuralObjectClassOid );
if ( mayAttributeTypeOids != null )
{
mayAttributeTypes = new ArrayList<AttributeType>( mayAttributeTypeOids.size() );
for ( String oid : mayAttributeTypeOids )
{
mayAttributeTypes.add( atRegistry.lookup( oid ) );
}
}
if ( mustAttributeTypeOids != null )
{
mustAttributeTypes = new ArrayList<AttributeType>( mustAttributeTypeOids.size() );
for ( String oid : mustAttributeTypeOids )
{
mustAttributeTypes.add( atRegistry.lookup( oid ) );
}
}
}
}
/**
* Gets the STRUCTURAL ObjectClass this name form specifies naming
* attributes for.
*
* @return the ObjectClass's oid this NameForm is for
*/
public String getStructuralObjectClassOid()
{
return structuralObjectClassOid;
}
/**
* Gets the STRUCTURAL ObjectClass this name form specifies naming
* attributes for.
*
* @return the ObjectClass this NameForm is for
* @throws LdapException If the structuralObjectClass is invalid
*/
public ObjectClass getStructuralObjectClass()
{
return structuralObjectClass;
}
/**
* Sets the structural object class this rule applies to
*
* @param structuralObjectClassOid the structural object class to set
*/
public void setStructuralObjectClassOid( String structuralObjectClassOid )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
this.structuralObjectClassOid = structuralObjectClassOid;
}
}
/**
* Sets the structural object class this rule applies to
*
* @param structuralObjectClass the structural object class to set
*/
public void setStructuralObjectClass( ObjectClass structuralObjectClass )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
this.structuralObjectClass = structuralObjectClass;
this.structuralObjectClassOid = structuralObjectClass.getOid();
}
}
/**
* Gets all the AttributeTypes OIDs of the attributes this NameForm specifies as
* having to be used in the given objectClass for naming: as part of the
* Rdn.
*
* @return the AttributeTypes OIDs of the must use attributes
* @throws LdapException if there is a failure resolving one AttributeTyoe
*/
public List<String> getMustAttributeTypeOids()
{
return Collections.unmodifiableList( mustAttributeTypeOids );
}
/**
* Gets all the AttributeTypes of the attributes this NameForm specifies as
* having to be used in the given objectClass for naming: as part of the
* Rdn.
*
* @return the AttributeTypes of the must use attributes
*/
public List<AttributeType> getMustAttributeTypes()
{
return Collections.unmodifiableList( mustAttributeTypes );
}
/**
* Sets the list of required AttributeTypes OIDs
*
* @param mustAttributeTypeOids the list of required AttributeTypes OIDs
*/
public void setMustAttributeTypeOids( List<String> mustAttributeTypeOids )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
this.mustAttributeTypeOids = mustAttributeTypeOids;
}
}
/**
* Sets the list of required AttributeTypes
*
* @param mustAttributeTypes the list of required AttributeTypes
*/
public void setMustAttributeTypes( List<AttributeType> mustAttributeTypes )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
this.mustAttributeTypes = mustAttributeTypes;
// update the OIDS now
mustAttributeTypeOids.clear();
for ( AttributeType may : mustAttributeTypes )
{
mustAttributeTypeOids.add( may.getOid() );
}
}
}
/**
* Add a required AttributeType OID
*
* @param oid The attributeType OID
*/
public void addMustAttributeTypeOids( String oid )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
mustAttributeTypeOids.add( oid );
}
}
/**
* Add a required AttributeType
*
* @param attributeType The attributeType
*/
public void addMustAttributeTypes( AttributeType attributeType )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly && !mustAttributeTypeOids.contains( attributeType.getOid() ) )
{
mustAttributeTypes.add( attributeType );
mustAttributeTypeOids.add( attributeType.getOid() );
}
}
/**
* Gets all the AttributeTypes OIDs of the attribute this NameForm specifies as
* being usable without requirement in the given objectClass for naming: as
* part of the Rdn.
*
* @return the AttributeTypes OIDs of the may use attributes
* @throws LdapException if there is a failure resolving one AttributeTyoe
*/
public List<String> getMayAttributeTypeOids()
{
return Collections.unmodifiableList( mayAttributeTypeOids );
}
/**
* Gets all the AttributeTypes of the attribute this NameForm specifies as
* being useable without requirement in the given objectClass for naming: as
* part of the Rdn.
*
* @return the AttributeTypes of the may use attributes
*/
public List<AttributeType> getMayAttributeTypes()
{
return Collections.unmodifiableList( mayAttributeTypes );
}
/**
* Sets the list of allowed AttributeTypes
*
* @param mayAttributeTypeOids the list of allowed AttributeTypes
*/
public void setMayAttributeTypeOids( List<String> mayAttributeTypeOids )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
this.mayAttributeTypeOids = mayAttributeTypeOids;
}
}
/**
* Sets the list of allowed AttributeTypes
*
* @param mayAttributeTypes the list of allowed AttributeTypes
*/
public void setMayAttributeTypes( List<AttributeType> mayAttributeTypes )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
this.mayAttributeTypes = mayAttributeTypes;
// update the OIDS now
mayAttributeTypeOids.clear();
for ( AttributeType may : mayAttributeTypes )
{
mayAttributeTypeOids.add( may.getOid() );
}
}
}
/**
* Add an allowed AttributeType
*
* @param oid The attributeType oid
*/
public void addMayAttributeTypeOids( String oid )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly )
{
mayAttributeTypeOids.add( oid );
}
}
/**
* Add an allowed AttributeType
*
* @param attributeType The attributeType
*/
public void addMayAttributeTypes( AttributeType attributeType )
{
if ( locked )
{
throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
}
if ( !isReadOnly && !mayAttributeTypeOids.contains( attributeType.getOid() ) )
{
mayAttributeTypes.add( attributeType );
mayAttributeTypeOids.add( attributeType.getOid() );
}
}
/**
* @see Object#toString()
*/
public String toString()
{
return objectType + " " + DescriptionUtils.getDescription( this );
}
/**
* Copy a NameForm
*/
public NameForm copy()
{
NameForm copy = new NameForm( oid );
// Copy the SchemaObject common data
copy.copy( this );
// Copy the MAY AttributeTypes OIDs
copy.mayAttributeTypeOids = new ArrayList<String>();
for ( String oid : mayAttributeTypeOids )
{
copy.mayAttributeTypeOids.add( oid );
}
// Copy the MAY AttributeTypes (will be empty)
copy.mayAttributeTypes = new ArrayList<AttributeType>();
// Copy the MUST AttributeTypes OIDs
copy.mustAttributeTypeOids = new ArrayList<String>();
for ( String oid : mustAttributeTypeOids )
{
copy.mustAttributeTypeOids.add( oid );
}
// Copy the MUST AttributeTypes ( will be empty )
copy.mustAttributeTypes = new ArrayList<AttributeType>();
// Copy the Structural ObjectClass OID
copy.structuralObjectClassOid = structuralObjectClassOid;
// All the references to other Registries object are set to null.
copy.structuralObjectClass = null;
return copy;
}
/**
* @see Object#equals(Object)
*/
@SuppressWarnings("PMD.UnusedLocalVariable") // Remove me when the TODO is fixed
public boolean equals( Object o )
{
if ( !super.equals( o ) )
{
return false;
}
if ( !( o instanceof NameForm ) )
{
return false;
}
NameForm that = ( NameForm ) o;
// TODO : complete the checks
return true;
}
/**
* {@inheritDoc}
*/
public void clear()
{
// Clear the common elements
super.clear();
// Clear the references
mayAttributeTypes.clear();
mayAttributeTypeOids.clear();
mustAttributeTypes.clear();
mustAttributeTypeOids.clear();
structuralObjectClass = null;
}
}