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.List; 024 025 import org.apache.directory.shared.i18n.I18n; 026 import org.apache.directory.shared.ldap.exception.LdapException; 027 import org.apache.directory.shared.ldap.schema.registries.Registries; 028 import org.apache.directory.shared.ldap.schema.syntaxCheckers.OctetStringSyntaxChecker; 029 030 031 /** 032 * A syntax definition. Each attribute stored in a directory has a defined 033 * syntax (i.e. data type) which constrains the structure and format of its 034 * values. The description of each syntax specifies how attribute or assertion 035 * values conforming to the syntax are normally represented when transferred in 036 * LDAP operations. This representation is referred to as the LDAP-specific 037 * encoding to distinguish it from other methods of encoding attribute values. 038 * <p> 039 * According to ldapbis [MODELS]: 040 * </p> 041 * 042 * <pre> 043 * 4.1.5. LDAP Syntaxes 044 * 045 * LDAP Syntaxes of (attribute and assertion) values are described in 046 * terms of ASN.1 [X.680] and, optionally, have an octet string encoding 047 * known as the LDAP-specific encoding. Commonly, the LDAP-specific 048 * encoding is constrained to string of Universal Character Set (UCS) 049 * [ISO10646] characters in UTF-8 [UTF-8] form. 050 * 051 * Each LDAP syntax is identified by an object identifier (OID). 052 * 053 * LDAP syntax definitions are written according to the ABNF: 054 * 055 * SyntaxDescription = LPAREN WSP 056 * numericoid ; object identifier 057 * [ SP "DESC" SP qdstring ] ; description 058 * extensions WSP RPAREN ; extensions 059 * 060 * where: 061 * [numericoid] is object identifier assigned to this LDAP syntax; 062 * DESC [qdstring] is a short descriptive string; and 063 * [extensions] describe extensions. 064 * </pre> 065 * 066 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html"> RFC2252 Section 4.3.3</a> 067 * @see <a href= 068 * "http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-09.txt"> 069 * ldapbis [MODELS]</a> 070 * @see DescriptionUtils#getDescription(Syntax) 071 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 072 * @version $Rev: 437007 $ 073 */ 074 public class LdapSyntax extends AbstractSchemaObject 075 { 076 /** The serialVersionUID */ 077 public static final long serialVersionUID = 1L; 078 079 /** the human readable flag */ 080 protected boolean isHumanReadable = false; 081 082 /** The associated SyntaxChecker */ 083 protected SyntaxChecker syntaxChecker; 084 085 086 /** 087 * Creates a Syntax object using a unique OID. 088 * 089 * @param oid the OID for this Syntax 090 */ 091 public LdapSyntax( String oid ) 092 { 093 super( SchemaObjectType.LDAP_SYNTAX, oid ); 094 } 095 096 097 /** 098 * Creates a Syntax object using a unique OID. 099 * 100 * @param oid the OID for this Syntax 101 */ 102 public LdapSyntax( String oid, String description ) 103 { 104 super( SchemaObjectType.LDAP_SYNTAX, oid ); 105 this.description = description; 106 } 107 108 109 /** 110 * Creates a Syntax object using a unique OID. 111 * 112 * @param oid the OID for this Syntax 113 */ 114 public LdapSyntax( String oid, String description, boolean isHumanReadable ) 115 { 116 super( SchemaObjectType.LDAP_SYNTAX, oid ); 117 this.description = description; 118 this.isHumanReadable = isHumanReadable; 119 } 120 121 122 /** 123 * Gets whether or not the Syntax is human readable. 124 * 125 * @return true if the syntax can be interpreted by humans, false otherwise 126 */ 127 public boolean isHumanReadable() 128 { 129 return isHumanReadable; 130 } 131 132 133 /** 134 * Sets the human readable flag value. 135 * 136 * @param isHumanReadable the human readable flag value to set 137 */ 138 public void setHumanReadable( boolean isHumanReadable ) 139 { 140 if ( locked ) 141 { 142 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 143 } 144 145 if ( !isReadOnly ) 146 { 147 this.isHumanReadable = isHumanReadable; 148 } 149 } 150 151 152 /** 153 * Gets the SyntaxChecker used to validate values in accordance with this 154 * Syntax. 155 * 156 * @return the SyntaxChecker 157 */ 158 public SyntaxChecker getSyntaxChecker() 159 { 160 return syntaxChecker; 161 } 162 163 164 /** 165 * Sets the associated SyntaxChecker 166 * 167 * @param syntaxChecker The associated SyntaxChecker 168 */ 169 public void setSyntaxChecker( SyntaxChecker syntaxChecker ) 170 { 171 if ( locked ) 172 { 173 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 174 } 175 176 if ( !isReadOnly ) 177 { 178 this.syntaxChecker = syntaxChecker; 179 } 180 } 181 182 183 /** 184 * Update the associated SyntaxChecker, even if the SchemaObject is readOnly 185 * 186 * @param syntaxChecker The associated SyntaxChecker 187 */ 188 public void updateSyntaxChecker( SyntaxChecker syntaxChecker ) 189 { 190 if ( locked ) 191 { 192 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 193 } 194 195 this.syntaxChecker = syntaxChecker; 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 * Inject the Syntax into the registries, updating the references to 210 * other SchemaObject 211 * 212 * @param registries The Registries 213 * @exception If the addition failed 214 */ 215 public void addToRegistries( List<Throwable> errors, Registries registries ) throws LdapException 216 { 217 if ( registries != null ) 218 { 219 try 220 { 221 // Gets the associated SyntaxChecker 222 syntaxChecker = registries.getSyntaxCheckerRegistry().lookup( oid ); 223 } 224 catch ( LdapException ne ) 225 { 226 // No SyntaxChecker ? Associate the Syntax to a catch all SyntaxChecker 227 syntaxChecker = new OctetStringSyntaxChecker( oid ); 228 } 229 230 // Add the references for S : 231 // S -> SC 232 if ( syntaxChecker != null ) 233 { 234 registries.addReference( this, syntaxChecker ); 235 } 236 } 237 } 238 239 240 /** 241 * Remove the SDyntax from the registries, updating the references to 242 * other SchemaObject. 243 * 244 * If one of the referenced SchemaObject does not exist (), 245 * an exception is thrown. 246 * 247 * @param registries The Registries 248 * @exception If the Syntx is not valid 249 */ 250 public void removeFromRegistries( List<Throwable> errors, Registries registries ) throws LdapException 251 { 252 if ( registries != null ) 253 { 254 /** 255 * Remove the Syntax references (using and usedBy) : 256 * S -> SC 257 */ 258 if ( syntaxChecker != null ) 259 { 260 registries.delReference( this, syntaxChecker ); 261 } 262 } 263 } 264 265 266 /** 267 * Copy a LdapSyntax 268 */ 269 public LdapSyntax copy() 270 { 271 LdapSyntax copy = new LdapSyntax( oid ); 272 273 // Copy the SchemaObject common data 274 copy.copy( this ); 275 276 // Copy the HR flag 277 copy.isHumanReadable = isHumanReadable; 278 279 // All the references to other Registries object are set to null. 280 copy.syntaxChecker = null; 281 282 return copy; 283 } 284 285 286 /** 287 * @see Object#equals() 288 */ 289 public boolean equals( Object o ) 290 { 291 if ( !super.equals( o ) ) 292 { 293 return false; 294 } 295 296 if ( !( o instanceof LdapSyntax ) ) 297 { 298 return false; 299 } 300 301 LdapSyntax that = ( LdapSyntax ) o; 302 303 // IsHR 304 if ( isHumanReadable != that.isHumanReadable ) 305 { 306 return false; 307 } 308 309 // Check the SyntaxChecker (not a equals) 310 return syntaxChecker.getOid().equals( that.syntaxChecker.getOid() ); 311 } 312 313 314 /** 315 * {@inheritDoc} 316 */ 317 public void clear() 318 { 319 // Clear the common elements 320 super.clear(); 321 322 // Clear the references 323 syntaxChecker = null; 324 } 325 }