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