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