1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * https://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20 package org.apache.directory.api.ldap.model.schema;
21
22
23 import java.util.ArrayList;
24 import java.util.List;
25
26 import org.apache.directory.api.i18n.I18n;
27
28
29 /**
30 * A dITStructureRule definition. A dITStructureRules is a rule governing the
31 * structure of the DIT by specifying a permitted superior to subordinate entry
32 * relationship. A structure rule relates a nameForm, and therefore a STRUCTURAL
33 * objectClass, to superior dITStructureRules. This permits entries of the
34 * STRUCTURAL objectClass identified by the nameForm to exist in the DIT as
35 * subordinates to entries governed by the indicated superior dITStructureRules.
36 * Hence dITStructureRules only apply to structural object classes.
37 * <p>
38 * According to ldapbis [MODELS]:
39 * </p>
40 *
41 * <pre>
42 * DIT structure rule descriptions are written according to the ABNF:
43 *
44 * DITStructureRuleDescription = LPAREN WSP
45 * ruleid ; rule identifier
46 * [ SP "NAME" SP qdescrs ] ; short names (descriptors)
47 * [ SP "DESC" SP qdstring ] ; description
48 * [ SP "OBSOLETE" ] ; not active
49 * SP "FORM" SP oid ; NameForm
50 * [ SP "SUP" ruleids ] ; superior rules
51 * extensions WSP RPAREN ; extensions
52 *
53 * ruleids = ruleid / ( LPAREN WSP ruleidlist WSP RPAREN )
54 *
55 * ruleidlist = ruleid *( SP ruleid )
56 *
57 * ruleid = number
58 *
59 * where:
60 * [ruleid] is the rule identifier of this DIT structure rule;
61 * NAME [qdescrs] are short names (descriptors) identifying this DIT
62 * structure rule;
63 * DESC [qdstring] is a short descriptive string;
64 * OBSOLETE indicates this DIT structure rule use is not active;
65 * FORM is specifies the name form associated with this DIT structure
66 * rule;
67 * SUP identifies superior rules (by rule id); and
68 * [extensions] describe extensions.
69 *
70 * If no superior rules are identified, the DIT structure rule applies
71 * to an autonomous administrative point (e.g. the root vertex of the
72 * subtree controlled by the subschema) [X.501].
73 * </pre>
74 *
75 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html">RFC2252 Section 6.33</a>
76 * @see <a
77 * href="http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-11.txt">ldapbis
78 * [MODELS]</a>
79 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
80 */
81 public class DitStructureRule extends AbstractSchemaObject
82 {
83 /** The mandatory serialVersionUID */
84 public static final long serialVersionUID = 1L;
85
86 /** The rule ID. A DSR does not have an OID */
87 private int ruleId;
88
89 /** The associated NameForm */
90 private String form;
91
92 /** The list of superiors rules */
93 private List<Integer> superRules;
94
95
96 /**
97 * Creates a new instance of DitStructureRule
98 *
99 * @param ruleId The RuleId for this 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<>();
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 ( locked )
127 {
128 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
129 }
130
131 this.form = form;
132 }
133
134
135 /**
136 * @return The Rule ID
137 */
138 public int getRuleId()
139 {
140 return ruleId;
141 }
142
143
144 /**
145 * Sets the rule identifier of this DIT structure rule;
146 *
147 * @param ruleId the rule identifier of this DIT structure rule;
148 */
149 public void setRuleId( int ruleId )
150 {
151 if ( locked )
152 {
153 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
154 }
155
156 this.ruleId = ruleId;
157 }
158
159
160 /**
161 * @return The list of superiors RuleIDs
162 */
163 public List<Integer> getSuperRules()
164 {
165 return superRules;
166 }
167
168
169 /**
170 * Sets the list of superior RuleIds
171 *
172 * @param superRules the list of superior RuleIds
173 */
174 public void setSuperRules( List<Integer> superRules )
175 {
176 if ( locked )
177 {
178 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
179 }
180
181 this.superRules = superRules;
182 }
183
184
185 /**
186 * Adds a new superior RuleId
187 *
188 * @param superRule The superior RuleID to add
189 */
190 public void addSuperRule( Integer superRule )
191 {
192 if ( locked )
193 {
194 throw new UnsupportedOperationException( I18n.err( I18n.ERR_13700_CANNOT_MODIFY_LOCKED_SCHEMA_OBJECT, getName() ) );
195 }
196
197 superRules.add( superRule );
198 }
199
200
201 /**
202 * The DIT structure rule does not have an OID
203 *
204 * {@inheritDoc}
205 */
206 @Override
207 public String getOid()
208 {
209 // We cannot throw exception here. E.g. SchemaObjectWrapper will try to use this in hashcode.
210 return null;
211 }
212
213
214 /**
215 * {@inheritDoc}
216 */
217 @Override
218 public String toString()
219 {
220 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
221 }
222
223
224 /**
225 * {@inheritDoc}
226 */
227 @Override
228 public DitStructureRule copy()
229 {
230 DitStructureRule copy = new DitStructureRule( ruleId );
231
232 // Copy the SchemaObject common data
233 copy.copy( this );
234
235 // Copy the Superiors rules
236 copy.superRules = new ArrayList<>();
237
238 // Copy the form
239 copy.form = form;
240
241 for ( int superRule : superRules )
242 {
243 copy.superRules.add( superRule );
244 }
245
246 return copy;
247 }
248
249
250 /**
251 * @see Object#equals(Object)
252 */
253 @Override
254 public int hashCode()
255 {
256 int hash = h;
257
258 hash = hash * 17 + ruleId;
259
260 if ( form != null )
261 {
262 hash = hash * 17 + form.hashCode();
263 }
264
265 if ( superRules != null )
266 {
267 int tempHash = 0;
268
269 for ( int superRule : superRules )
270 {
271 tempHash += superRule;
272 }
273
274 hash = hash * 17 + tempHash;
275 }
276
277 return hash;
278 }
279
280
281 /**
282 * {@inheritDoc}
283 */
284 @Override
285 public boolean equals( Object o )
286 {
287 if ( !super.equals( o ) )
288 {
289 return false;
290 }
291
292 if ( !( o instanceof DitStructureRule ) )
293 {
294 return false;
295 }
296
297 @SuppressWarnings("unused")
298 DitStructureRule that = ( DitStructureRule ) o;
299
300 // TODO : complete the test
301 return true;
302 }
303
304
305 /**
306 * {@inheritDoc}
307 */
308 @Override
309 public void clear()
310 {
311 // Clear the common elements
312 super.clear();
313
314 // Clear the references
315 superRules.clear();
316 }
317 }