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 * http://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.List;
24
25 import org.apache.directory.api.i18n.I18n;
26 import org.apache.directory.api.ldap.model.constants.MetaSchemaConstants;
27
28
29 /**
30 * A syntax definition. Each attribute stored in a directory has a defined
31 * syntax (i.e. data type) which constrains the structure and format of its
32 * values. The description of each syntax specifies how attribute or assertion
33 * values conforming to the syntax are normally represented when transferred in
34 * LDAP operations. This representation is referred to as the LDAP-specific
35 * encoding to distinguish it from other methods of encoding attribute values.
36 * <p>
37 * According to ldapbis [MODELS]:
38 * </p>
39 *
40 * <pre>
41 * 4.1.5. LDAP Syntaxes
42 *
43 * LDAP Syntaxes of (attribute and assertion) values are described in
44 * terms of ASN.1 [X.680] and, optionally, have an octet string encoding
45 * known as the LDAP-specific encoding. Commonly, the LDAP-specific
46 * encoding is constrained to string of Universal Character Set (UCS)
47 * [ISO10646] characters in UTF-8 [UTF-8] form.
48 *
49 * Each LDAP syntax is identified by an object identifier (OID).
50 *
51 * LDAP syntax definitions are written according to the ABNF:
52 *
53 * SyntaxDescription = LPAREN WSP
54 * numericoid ; object identifier
55 * [ SP "DESC" SP qdstring ] ; description
56 * extensions WSP RPAREN ; extensions
57 *
58 * where:
59 * [numericoid] is object identifier assigned to this LDAP syntax;
60 * DESC [qdstring] is a short descriptive string; and
61 * [extensions] describe extensions.
62 * </pre>
63 *
64 * @see <a href="http://www.faqs.org/rfcs/rfc2252.html"> RFC2252 Section 4.3.3</a>
65 * @see <a href=
66 * "http://www.ietf.org/internet-drafts/draft-ietf-ldapbis-models-09.txt">
67 * ldapbis [MODELS]</a>
68 * @see DescriptionUtils#getDescription(Syntax)
69 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
70 */
71 public class LdapSyntax extends AbstractSchemaObject
72 {
73 /** The mandatory serialVersionUID */
74 public static final long serialVersionUID = 1L;
75
76 /** the human readable flag */
77 protected boolean isHumanReadable = false;
78
79 /** A flag set to true if the Syntax has a X-NOT-HUMAN-READABLE extension */
80 private boolean hasHumanReadableFlag = false;
81
82 /** The associated SyntaxChecker */
83 protected SyntaxChecker syntaxChecker;
84
85
86 /**
87 * Creates a Syntax object using a unique OID.
88 *
89 * @param oid the OID for this Syntax
90 */
91 public LdapSyntax( String oid )
92 {
93 super( SchemaObjectType.LDAP_SYNTAX, oid );
94 }
95
96
97 /**
98 * Creates a Syntax object using a unique OID.
99 *
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 = getExtension( 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 true;
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 the SyntaxChecker used to validate values in accordance with this
189 * Syntax.
190 *
191 * @return the SyntaxChecker
192 */
193 public SyntaxChecker getSyntaxChecker()
194 {
195 return syntaxChecker;
196 }
197
198
199 /**
200 * Sets the associated SyntaxChecker
201 *
202 * @param syntaxChecker The associated SyntaxChecker
203 */
204 public void setSyntaxChecker( SyntaxChecker syntaxChecker )
205 {
206 if ( locked )
207 {
208 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
209 }
210
211 if ( !isReadOnly )
212 {
213 this.syntaxChecker = syntaxChecker;
214 }
215 }
216
217
218 /**
219 * Update the associated SyntaxChecker, even if the SchemaObject is readOnly
220 *
221 * @param newSyntaxChecker The associated SyntaxChecker
222 */
223 public void updateSyntaxChecker( SyntaxChecker newSyntaxChecker )
224 {
225 if ( locked )
226 {
227 throw new UnsupportedOperationException( I18n.err( I18n.ERR_04441, getName() ) );
228 }
229
230 this.syntaxChecker = newSyntaxChecker;
231 }
232
233
234 /**
235 * {@inheritDoc}
236 */
237 @Override
238 public String toString()
239 {
240 return SchemaObjectRenderer.OPEN_LDAP_SCHEMA_RENDERER.render( this );
241 }
242
243
244 /**
245 * {@inheritDoc}
246 */
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 public void clear()
312 {
313 // Clear the common elements
314 super.clear();
315
316 // Clear the references
317 syntaxChecker = null;
318 }
319 }