| /* |
| * 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 "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" [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 "NAME" SP qdescrs ] ; short names (descriptors) |
| * [ SP "DESC" SP qdstring ] ;String description |
| * [ SP "OBSOLETE" ] ; not active |
| * SP "OC" SP oid ; structural object class |
| * SP "MUST" SP oids ; attribute types |
| * [ SP "MAY" 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 ("MUST") and allowed ("MAY") 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; |
| } |
| } |