001    /*
002     *  Licensed to the Apache Software Foundation (ASF) under one
003     *  or more contributor license agreements.  See the NOTICE file
004     *  distributed with this work for additional information
005     *  regarding copyright ownership.  The ASF licenses this file
006     *  to you under the Apache License, Version 2.0 (the
007     *  "License"); you may not use this file except in compliance
008     *  with the License.  You may obtain a copy of the License at
009     *  
010     *    http://www.apache.org/licenses/LICENSE-2.0
011     *  
012     *  Unless required by applicable law or agreed to in writing,
013     *  software distributed under the License is distributed on an
014     *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     *  KIND, either express or implied.  See the License for the
016     *  specific language governing permissions and limitations
017     *  under the License. 
018     *  
019     */
020    package org.apache.directory.shared.ldap.schema;
021    
022    
023    import java.util.ArrayList;
024    import java.util.List;
025    
026    import org.apache.directory.shared.ldap.NotImplementedException;
027    
028    
029    /**
030     * A dITStructureRule definition. A dITStructureRules is a rule governing the
031     * structure of the DIT by specifying a permitted superior to subordinate entry
032     * relationship. A structure rule relates a nameForm, and therefore a STRUCTURAL
033     * objectClass, to superior dITStructureRules. This permits entries of the
034     * STRUCTURAL objectClass identified by the nameForm to exist in the DIT as
035     * subordinates to entries governed by the indicated superior dITStructureRules.
036     * Hence dITStructureRules only apply to structural object classes.
037     * <p>
038     * According to ldapbis [MODELS]:
039     * </p>
040     * 
041     * <pre>
042     *  DIT structure rule descriptions are written according to the ABNF:
043     *  
044     *    DITStructureRuleDescription = LPAREN WSP
045     *        ruleid                    ; rule identifier
046     *        [ SP &quot;NAME&quot; SP qdescrs ]  ; short names (descriptors)
047     *        [ SP &quot;DESC&quot; SP qdstring ] ; description
048     *        [ SP &quot;OBSOLETE&quot; ]         ; not active
049     *        SP &quot;FORM&quot; SP oid          ; NameForm
050     *        [ SP &quot;SUP&quot; ruleids ]      ; superior rules
051     *        extensions WSP RPAREN     ; extensions
052     * 
053     *    ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
054     * 
055     *    ruleidlist = ruleid *( SP ruleid )
056     * 
057     *    ruleid = number
058     * 
059     *  where:
060     *    [ruleid] is the rule identifier of this DIT structure rule;
061     *    NAME [qdescrs] are short names (descriptors) identifying this DIT
062     *        structure rule;
063     *    DESC [qdstring] is a short descriptive string;
064     *    OBSOLETE indicates this DIT structure rule use is not active;
065     *    FORM is specifies the name form associated with this DIT structure
066     *        rule;
067     *    SUP identifies superior rules (by rule id); and
068     *    [extensions] describe extensions.
069     *  
070     *  If no superior rules are identified, the DIT structure rule applies
071     *  to an autonomous administrative point (e.g. the root vertex of the
072     *  subtree controlled by the subschema) [X.501].
073     * </pre>
074     * 
075     * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC2252 Section 6.33</a>
076     * @see <a
077     *      href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
078     *      [MODELS]</a>
079     * @see DescriptionUtils#getDescription(DITStructureRule)
080     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
081     * @version $Rev: 896579 $
082     */
083    public class DITStructureRule extends AbstractSchemaObject
084    {
085        /** The serialVersionUID */
086        private static final long serialVersionUID = 1L;
087    
088        /** The rule ID. A DSR does not have an OID */
089        private int ruleId;
090    
091        /** The associated NameForm */
092        private String form;
093    
094        /** The list of superiors rules */
095        private List<Integer> superRules;
096    
097    
098        /**
099         * Creates a new instance of DITStructureRule
100         */
101        public DITStructureRule( int ruleId )
102        {
103            super( SchemaObjectType.DIT_STRUCTURE_RULE, null );
104            this.ruleId = ruleId;
105            form = null;
106            superRules = new ArrayList<Integer>();
107        }
108    
109    
110        /**
111         *  @return The associated NameForm's OID
112         */
113        public String getForm()
114        {
115            return form;
116        }
117    
118    
119        /**
120         * Sets the associated NameForm's OID
121         *
122         * @param form The NameForm's OID
123         */
124        public void setForm( String form )
125        {
126            if ( !isReadOnly )
127            {
128                this.form = form;
129            }
130        }
131    
132    
133        /**
134         * @return The Rule ID
135         */
136        public int getRuleId()
137        {
138            return ruleId;
139        }
140    
141    
142        /**
143         * Sets the rule identifier of this DIT structure rule;
144         *
145         * @param ruleId the rule identifier of this DIT structure rule;
146         */
147        public void setRuleId( int ruleId )
148        {
149            if ( !isReadOnly )
150            {
151                this.ruleId = ruleId;
152            }
153        }
154    
155    
156        /**
157         * @return The list of superiors RuleIDs
158         */
159        public List<Integer> getSuperRules()
160        {
161            return superRules;
162        }
163    
164    
165        /**
166         * Sets the list of superior RuleIds
167         * 
168         * @param superRules the list of superior RuleIds
169         */
170        public void setSuperRules( List<Integer> superRules )
171        {
172            if ( !isReadOnly )
173            {
174                this.superRules = superRules;
175            }
176        }
177    
178    
179        /**
180         * Adds a new superior RuleId
181         *
182         * @param superRule The superior RuleID to add
183         */
184        public void addSuperRule( Integer superRule )
185        {
186            superRules.add( superRule );
187        }
188    
189    
190        /**
191         * The DSR does not have an OID, so throw an exception
192         */
193        public String getOid()
194        {
195            throw new NotImplementedException();
196        }
197    
198    
199        /**
200         * @see Object#toString()
201         */
202        public String toString()
203        {
204            return objectType + " " + DescriptionUtils.getDescription( this );
205        }
206    
207    
208        /**
209         * Copy a DITStructureRule
210         */
211        public DITStructureRule copy()
212        {
213            DITStructureRule copy = new DITStructureRule( ruleId );
214    
215            // Copy the SchemaObject common data
216            copy.copy( this );
217    
218            // Copy the Superiors rules
219            copy.superRules = new ArrayList<Integer>();
220    
221            // Copy the form
222            copy.form = form;
223    
224            for ( int ruleId : superRules )
225            {
226                copy.superRules.add( ruleId );
227            }
228    
229            return copy;
230        }
231    
232    
233        /**
234         * @see Object#equals(Object)
235         */
236        public boolean equals( Object o )
237        {
238            if ( !super.equals( o ) )
239            {
240                return false;
241            }
242    
243            if ( !( o instanceof DITStructureRule ) )
244            {
245                return false;
246            }
247    
248            DITStructureRule that = ( DITStructureRule ) o;
249    
250            // TODO : complete the test
251            return true;
252        }
253    
254    
255        /**
256         * {@inheritDoc}
257         */
258        public void clear()
259        {
260            // Clear the common elements
261            super.clear();
262    
263            // Clear the references
264            superRules.clear();
265        }
266    }