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 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 069 */ 070public class LdapSyntax extends AbstractSchemaObject 071{ 072 /** The mandatory serialVersionUID */ 073 public static final long serialVersionUID = 1L; 074 075 /** the human readable flag */ 076 protected boolean isHumanReadable = false; 077 078 /** A flag set to true if the Syntax has a X-NOT-HUMAN-READABLE extension */ 079 private boolean hasHumanReadableFlag = false; 080 081 /** The associated SyntaxChecker */ 082 protected SyntaxChecker syntaxChecker; 083 084 085 /** 086 * Creates a Syntax object using a unique OID. 087 * 088 * @param oid the OID for this Syntax 089 */ 090 public LdapSyntax( String oid ) 091 { 092 super( SchemaObjectType.LDAP_SYNTAX, oid ); 093 } 094 095 096 /** 097 * Creates a Syntax object using a unique OID. 098 * 099 * @param oid the OID for this syntax 100 * @param description the description for this syntax 101 */ 102 public LdapSyntax( String oid, String description ) 103 { 104 super( SchemaObjectType.LDAP_SYNTAX, oid ); 105 this.description = description; 106 this.hasHumanReadableFlag = false; 107 } 108 109 110 /** 111 * Creates a Syntax object using a unique OID. 112 * 113 * @param oid the OID for this syntax 114 * @param description the description for this syntax 115 * @param isHumanReadable true if this syntax is human readable 116 */ 117 public LdapSyntax( String oid, String description, boolean isHumanReadable ) 118 { 119 super( SchemaObjectType.LDAP_SYNTAX, oid ); 120 this.description = description; 121 this.isHumanReadable = isHumanReadable; 122 this.hasHumanReadableFlag = true; 123 } 124 125 126 /** 127 * Gets whether or not the Syntax is human readable. 128 * 129 * @return true if the syntax can be interpreted by humans, false otherwise 130 */ 131 public boolean isHumanReadable() 132 { 133 if ( hasHumanReadableFlag ) 134 { 135 return isHumanReadable; 136 } 137 else 138 { 139 List<String> values = getExtension( MetaSchemaConstants.X_NOT_HUMAN_READABLE_AT ); 140 141 if ( ( values == null ) || values.isEmpty() ) 142 { 143 // Default to String if the flag is not set 144 return true; 145 } 146 else 147 { 148 String value = values.get( 0 ); 149 hasHumanReadableFlag = true; 150 151 if ( "FALSE".equalsIgnoreCase( value ) ) 152 { 153 isHumanReadable = true; 154 return true; 155 } 156 else 157 { 158 isHumanReadable = false; 159 return false; 160 } 161 } 162 } 163 } 164 165 166 /** 167 * Sets the human readable flag value. 168 * 169 * @param humanReadable the human readable flag value to set 170 */ 171 public void setHumanReadable( boolean humanReadable ) 172 { 173 if ( locked ) 174 { 175 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 176 } 177 178 if ( !isReadOnly ) 179 { 180 this.isHumanReadable = humanReadable; 181 this.hasHumanReadableFlag = true; 182 } 183 } 184 185 186 /** 187 * Gets the SyntaxChecker used to validate values in accordance with this 188 * Syntax. 189 * 190 * @return the SyntaxChecker 191 */ 192 public SyntaxChecker getSyntaxChecker() 193 { 194 return syntaxChecker; 195 } 196 197 198 /** 199 * Sets the associated SyntaxChecker 200 * 201 * @param syntaxChecker The associated SyntaxChecker 202 */ 203 public void setSyntaxChecker( SyntaxChecker syntaxChecker ) 204 { 205 if ( locked ) 206 { 207 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 208 } 209 210 if ( !isReadOnly ) 211 { 212 this.syntaxChecker = syntaxChecker; 213 } 214 } 215 216 217 /** 218 * Update the associated SyntaxChecker, even if the SchemaObject is readOnly 219 * 220 * @param newSyntaxChecker The associated SyntaxChecker 221 */ 222 public void updateSyntaxChecker( SyntaxChecker newSyntaxChecker ) 223 { 224 if ( locked ) 225 { 226 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) ); 227 } 228 229 this.syntaxChecker = newSyntaxChecker; 230 } 231 232 233 /** 234 * {@inheritDoc} 235 */ 236 @Override 237 public String toString() 238 { 239 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this ); 240 } 241 242 243 /** 244 * {@inheritDoc} 245 */ 246 @Override 247 public LdapSyntax copy() 248 { 249 LdapSyntax copy = new LdapSyntax( oid ); 250 251 // Copy the SchemaObject common data 252 copy.copy( this ); 253 254 // Copy the HR flag 255 copy.isHumanReadable = isHumanReadable; 256 257 // Copy the HR presence flag 258 copy.hasHumanReadableFlag = hasHumanReadableFlag; 259 260 // All the references to other Registries object are set to null. 261 copy.syntaxChecker = null; 262 263 return copy; 264 } 265 266 267 /** 268 * {@inheritDoc} 269 */ 270 @Override 271 public boolean equals( Object o ) 272 { 273 if ( !super.equals( o ) ) 274 { 275 return false; 276 } 277 278 if ( !( o instanceof LdapSyntax ) ) 279 { 280 return false; 281 } 282 283 LdapSyntax that = ( LdapSyntax ) o; 284 285 // IsHR 286 if ( isHumanReadable != that.isHumanReadable ) 287 { 288 return false; 289 } 290 291 // Check the SyntaxChecker (not a equals) 292 if ( syntaxChecker != null ) 293 { 294 if ( that.syntaxChecker == null ) 295 { 296 return false; 297 } 298 299 return syntaxChecker.getOid().equals( that.syntaxChecker.getOid() ); 300 } 301 else 302 { 303 return that.syntaxChecker == null; 304 } 305 } 306 307 308 /** 309 * {@inheritDoc} 310 */ 311 @Override 312 public void clear() 313 { 314 // Clear the common elements 315 super.clear(); 316 317 // Clear the references 318 syntaxChecker = null; 319 } 320}