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 */ 020package org.apache.directory.api.ldap.model.schema; 021 022 023import java.util.ArrayList; 024import java.util.List; 025 026import org.apache.directory.api.i18n.I18n; 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 "NAME" SP qdescrs ] ; short names (descriptors) 047 * [ SP "DESC" SP qdstring ] ; description 048 * [ SP "OBSOLETE" ] ; not active 049 * SP "FORM" SP oid ; NameForm 050 * [ SP "SUP" 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 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 080 */ 081public class DitStructureRule extends AbstractSchemaObject 082{ 083 /** The mandatory serialVersionUID */ 084 public static final long serialVersionUID = 1L; 085 086 /** The rule ID. A DSR does not have an OID */ 087 private int ruleId; 088 089 /** The associated NameForm */ 090 private String form; 091 092 /** The list of superiors rules */ 093 private List<Integer> superRules; 094 095 096 /** 097 * Creates a new instance of DitStructureRule 098 * 099 * @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}