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 = 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 }